什么是Python垃圾回收机制作为Python用户,Python中的垃圾回收主要是基于引用计数,然后引入标记、清除、分代来解决循环引用问题.当一个对象被引用时,引用计数加1。当对象为del时,引用计数减1。为0时,对象被清除。一般用户不会去操作Python的垃圾回收机制,它留有API接口。元组和列表之间的区别主要区别在于列表是可变的,而元组是不可变的。>>>mylist=[1,3,3]>>>mylist[1]=2>>>mytu??ple=(1,3,3)>>>mytu??ple[1]=2Traceback(mostrecentcallast):File"",line1,intuple可以作为字典的key吗?首先,一个对象能否作为字典的key,取决于它是否有__hash__方法。所以除了容器对象(list/dict/set)和里面包含容器对象的tuple之外,不能作为字典的key,其他对象都可以。Process-thread-coroutineprocess操作系统中资源分配和调度的基本单位。多个进程是独立和稳定的。如果一个进程崩溃了,它不会影响其他进程。但是进程消耗资源多,开启进程数有限。限制线程CPU资源分配和调度的基本单位。线程是进程的一部分。它是一个比进程更小,可以独立运行的基本单元。一个进程下的多个线程可以共享进程的所有资源。如果IO操作比较密集,可以多线程高效运行。缺点是如果一个线程崩溃了,会导致进程崩溃。coroutine子程序调用永远是一次进入,一次返回,调用顺序清晰。协程的调用不同于子程序。协程看起来也像一个子程序,但是在执行过程中,可以在子程序内部中断,然后转而去执行其他的子程序,在适当的时候返回继续执行。赋值、浅拷贝和深拷贝深拷贝就是将一个对象拷贝到另一个对象中,也就是说如果你对一个对象的副本进行修改,不会影响到原来的对象。在Python中,我们使用函数deepcopy()来执行深拷贝。浅拷贝就是将一个对象的引用复制到另一个对象中,所以如果我们在副本中改变它,就会影响到原来的对象。GILGIL是Python的全局解释器锁。同一个进程中如果有多个线程在运行,一个线程在运行一个Python程序时会占用Python解释器(加锁或者GIL),这样进程中的其他线程就无法运行,其他线程只能在这个线程之后运行完成运行。如果在线程运行时遇到耗时操作,则解开解释器锁,让其他线程运行。因此,在多线程中,线程的运行仍然是顺序的,不是同时进行的。在多进程中,由于每个进程都可以由系统分配资源,相当于每个进程都有一个Python解释器,所以多进程可以实现多个进程同时运行。缺点是进程的系统资源开销较大。list的去重是先转换成set去重,再转换成list。最常用的排序算法及其复杂度冒泡排序的外层循环是从1到n-1,内层循环从当前外层元素的下一个位置开始,依次与外层元素比较,交换倒序,通过与相邻元素比较交换,将小数交换到前面。defbubbleSort(array):iflen(array)<2:returnarrayelse:isSorted=Falsecounter=0whilenotisSorted:isSorted=Trueforidxinrange(len(array)-1-counter):ifarray[idx]>array[idx+1]:isSorted=False(array[idx+1],array[idx])=(array[idx],array[idx+1])counter+=1returnarray快速排序通过一次排序将待排序的记录分成两个独立的部分,一部分records如果关键字都小于另一部分中的关键字,则可以将两部分记录分别排序,以达到整个序列的顺序。以R指针为起点选择Pivot的中轴,大于Pivot的数放在Pivot的右边,小于Pivot的数放在Pivot的左边左右子序列重复前三步defquickSort(array):print(array)iflen(array)<2:returnarrayelse:pivot_index=0pivot=array[pivot_index]less_part=[iforiinarray[pivot_index+1:]ifi<=pivot]large_part=[iforiinarray[pivot_index+1:]ifi>pivot]returnquickSort(less_part)+[pivot]+quickSort(large_part)闭包函数的返回值是一个函数对象,只能被外部函数访问,提高了安全性。使用with语句可以简化代码,有效避免资源泄露。打开文件进行读写时可能会出现一些异常情况。如果按照常规的f.open写法,需要try,except,finally进行异常判断,而且无论文件发生什么情况,都必须执行finallyf.close()关闭文件,with方法最后帮助我们实现f.close。实例方法静态方法实例方法只能被实例调用,静态方法(@staticmethod修饰的方法)、类方法(@classmethod修饰的方法),可以被类或类的实例对象调用。实例方法,第一个参数默认必须传递实例对象,一般使用self。静态方法,不需要参数。类方法,默认必须传递第一个参数,一般使用cls。迭代器和生成器迭代器是一种记住遍历位置的对象。迭代器对象从集合的第一个元素开始访问,直到访问完所有元素。迭代器只能前进不能后退。迭代器有两个基本方法:iter()和next()。字符串、列表或元组对象可用于创建迭代器:>>>list=[1,2,3,4]>>>it=iter(list)#Createaniteratorobject>>>print(next(it))#输出迭代器的下一个元素1>>>print(next(it))2>>>Generator使用yield的函数称为生成器。生成器是返回迭代器的函数,迭代器只能用于迭代操作。生成器是迭代器更容易理解。在调用生成器运行的过程中,函数会在每次遇到yield时暂停并保存当前的。运行信息,返回yield的值,当next()方法在下一次执行,16,25]Map、Reduce、FilterMap对可迭代对象中的每个元素执行相同的操作。deffn(x):returnx+1resp=map(fn,li)print(list(resp))[2,3,4]Reduce从左到右对一个序列的项累积应用一个有两个参数的函数到这个合并序列化为单个值。(如累加或相乘列表元素等)fromfunctoolsimportreducenums=[1,2,3,4]deffn(x,y):returnx*yresp=reduce(fn,nums)print(resp)24FilterFilter函数用于过滤sequences,过滤掉不符合条件的元素,返回一个由满足条件的元素组成的新列表。它接受两个参数:第一个是函数,第二个是序列。将序列的每个元素作为参数传递给函数进行判断,然后返回True或False,最后将返回True的元素放入新的列表中。a=[1,2,3,4,5,6,7,8,9,10]deffn(a):返回%2==1newlist=filter(fn,a)newlist=[iforiinnewlist]print(newlist)##Output:[1,3,5,7,9]DjangoWhatisWSGIPythonWebServerGatewayInterface,翻译过来就是PythonWebServerGatewayInterface,其实就是一个协议,我们的应用(Django,Flask)实现的就是WSGI,可以配合实现WSGI(uWSGI、gunicorn)的服务器工作。Django请求发送WSGI的生命周期。Web框架(Flask、Django)中间件对请求进行处理,帮助我们验证请求或在请求对象中添加其他相关数据,如:CSRF、request.session路由匹配、根据当前的URL查找视图功能request,如果是FBV写法,通过判断方法的两种类型找到对应的视图函数;如果是CBV写法,匹配成功后会自动找到Dispatch方法,然后Django会通过Dispatch反射在类中找到对应的方法并执行视图函数。视图函数中业务逻辑的处理可能涉及:orm,view视图渲染数据到模板模板视图函数执行完成后,会返回客户端想要的数据给Dispatch方法,Dispatch方法返回数据给客户端端中间件处理和响应WSGI,并将响应的内容发送给浏览器。浏览器渲染并列出Django的内置组件。Admin:对模型中对应的数据表进行增删改查。代码;2、数据有效性验证;2、验证信息返回显示ModelForm:可用于数据库操作,也可用于用户请求的验证Django中间件的5种方法?以及Django中间件的应用场景:请求进来时,权限认证process_view:路由匹配后,可以获取视图函数process_exception:出现异常时Executeprocess_template_response过程:Executeprocess_responsewhenthetemplaterendered:当请求有响应时执行提高代码的复用性,可以使用面向对象的技术,比如Mixin(MultipleInheritance),可以使用不同的函数来处理不同的HTTP方法,而不是通过许多if判断来提高代码的可读性。Django的Request对象是在classWSGIHandler(base.BaseHandler):request=self.request_class(environ)创建的时候,request转到WSGIHandler类时,执行cell方法将environ封装成一个Request。如何在CBV中添加装饰器方法fromdjango.utils.decoratorsimportmethod_decorator@method_decorator(check_login)defpost(self,request):...Dispatch@method_decorator(check_login)defdispatch(self,request,*args,**kwargs):class@method_decorator(check_login,name="get")@method_decorator(check_login,name="post")classHomeView(View):...列出DjangoORM中的所有方法<1>all():查询所有结果<2>filter(**kwargs):它包含符合给定过滤条件的对象。ReturnNone<3>get(**kwargs):返回符合给定过滤条件的对象,返回一个且仅一个结果。如果有多个对象或没有对象符合过滤条件,则会抛出错误。<4>exclude(**kwargs):包含不符合给定过滤条件的对象<5>order_by(*field):对查询结果进行排序<6>reverse():对查询结果进行反向排序<8>count():返回数据库中匹配query(QuerySet)的对象个数<9>first():返回第一条记录<10>last():返回最后一条记录<11>exists():如果QuerySet包含data,返回True,否则返回False<12>values(*field):返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的不是一系列的模型实例化对象,而是一个可迭代的字典序列<13>values_list(*field):和values()很相似,返回的是元组序列,values返回的是字典序列<14>distinct():从返回结果中去除重复记录select_related和prefetch_related不同的是,当有外键,可以减少数据库请求次数,提高性能。select_related可以通过多表join关联查询一次获取所有数据,而只执行一次sql查询prefetch_related分别查询每张表,然后根据它们之间的关系处理,执行两次查询。Django中CSRF的实现机制第一步:当Django第一次响应某个客户端的请求时,后端随机生成一个Token值,并将该Token保存在Session状态;同时,后端将cookie中的Token放到前端页面。Step2:下次前端需要发起请求时(比如posting),将这个Token值添加到请求数据或者header信息中,传递给后端;Cookies:{csrftoken:xxxxx}第三步:后端验证前端请求带的Token是否与Session中的Token一致。Django中ORM表添加数据时如何创建日志记录#利用Django的信号机制,可以在添加或删除数据前后设置日志记录:pre_init#Django在Django中模型对象执行其构造方法之前,自动触发post_init#DjangoDjango中模型对象执行其构造方法后,自动触发pre_save#Django中模型对象保存前,自动触发post_save#Django中模型对象保存后,自动触发pre_delete#模型前Django中对象删除,自动触发post_delete#Django中模型对象删除后,自动触发#使用@receiver(post_save,sender=Myclass) #信号接收装饰器。由于内置信号,直接接收defsignal_handler(sender,**kwargs): #接收到信号后,在这里进行处理SetCACHES={'default':{'BACKEND':'django.core.cache.backends.dummy.DummyCache',#缓存后台使用的引擎'TIMEOUT':300,#缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)'OPTIONS':{'MAX_ENTRIES':300,#最大缓存记录条数(默认300条)'CULL_FREQUENCY':3,#缓存达到最大条数后,要淘汰的缓存条数的比例,即:1/CULL_FREQUENCY(默认3)},}}Django的缓存可以用Redis吗?如果是,如何配置CACHES={"default":{"BACKEND":"django_redis.cache.RedisCache","LOCATION":"redis://127.0.0.1:6379","OPTIONS":{"CLIENT_CLASS":"django_redis.client.DefaultClient","CONNECTION_POOL_KWARGS":{"max_connections":100}#"PASSWORD":"password",}}}name在Django路由系统中的作用主要是通过查找url地址名字的值,可以理解为反射。在html模板中使用name来体现url的好处是,后面url规则改变后,只需要调整urls.py,所有的模板文件都不需要修改。DjangoRESTFramework框架有那些组件认证权限(authorization)用户访问次数/频率限制版本解析器(parser)序列化分页路由系统viewrenderer简要描述DjangoRESTFramework框架在用户登录时的认证过程,Runtheas_view()方法,进入APIView类的Dispatch方法执行self.initialize_request方法,其中封装了Request、认证对象列表等其他参数。在self.initial方法中执行self.perform_authentication,即运行user方法,然后在user方法中执行self._authenticate()方法