自己整合的答案,虽有百家之所长,仍很局限,如有需要改进的地方,或者有更好的答案,欢迎提出!
【合理利用Ctrl+F提高查找效率】
1、为什么学习Python?
#因为python相对其他语言非常优雅简洁,有着丰富的第三方库,我感觉很强大、很方便;#还有就是,我感觉python简单易学,生态圈庞大,例如:web开发、爬虫、人工智能等,而且未来发展趋势也很不错。2、通过什么途径学习的Python?
#在系里社团通过学长了解到python根据个人情况而定…………3、Python和Java、PHP、C、C#、C++等其他语言的对比?
#Python、PHP是解释型语言,代码运行期间逐行翻译成目标机器码,下次执行时逐行解释#而C、Java是编译型语言,编译后再执行。4、简述解释型和编译型编程语言?
#解释型:边解释边执行(python、PHP)#编译型:编译后再执行(c、Java、C#)5、Python解释器种类以及特点?
#CPython:C语言开发的,官方推荐,最常用#IPython:基于CPython之上的交互式解释器,只是在交互上有增强#JPython:Java写的解释器#Pypy:Python写的解释器,目前执行速度最快的解释器,采用JIT技术,对Python进行动态编译#IronPython:C#写的解释器6、位和字节的关系?
#1字节=8位#1byte=8bit(数据存储以字节(Byte)为单位)7、b、B、KB、MB、GB的关系?
1B=8bit1个字节(Byte,B)8个比特(bit)1KB=1024B1MB=1024KB1G=1024MB1T=1024G8、请至少列举5个PEP8规范(越多越好)。
#1、空格使用a各种右括号前不要加空格。b逗号、冒号、分号前不要加空格。c函数的左括号前不要加空格。如Func(1)。d序列的左括号前不要加空格。如list[2]。e操作符左右各加一个空格,不要为了对齐增加空格。f函数默认参数使用的赋值符左右省略空格。g不要将多句语句写在同一行,尽管使用‘;’允许。8if/for/while语句中,即使执行语句只有一句,也必须另起一行。#2、代码编排a缩进,4个空格,而不是tab键b每行长度79,换行可使用反斜杠,最好使用圆括号。c类与类之间空两行d方法之间空一行9、通过代码实现如下转换:
二进制转换成十进制:v=“0b1111011”十进制转换成二进制:v=18八进制转换成十进制:v=“011”十进制转换成八进制:v=30十六进制转换成十进制:v=“0x12”十进制转换成十六进制:v=87################################v=0b1111011print(int(v))v=18print(bin(v))v='011'print(int(v))v=30print(oct(v))v=0x12print(int(v))v=87print(hex(v))10、请编写一个函数实现将IP地址转换成一个整数。
Python中默认的递归层数约为998左右(会报错)和计算机性能有关系,我的最大数字在3210-3220之间浮动12、求结果:
v1=1or3--1v2=1and3--3v3=0and2and1--0v4=0and2or1--1v5=0and2or1or4--1v6=0orFlaseand1--False########################and:前后为真才为真or:有一为真就为真优先级:()>not>and>or同等优先级下,从左向右13、ascii、unicode、utf-8、gbk区别?
#Ascii:1个字节支持英文#unicode:所有字符(无论中文、英文等)1个字符:4个字节#gbk:1个字符,英文1个字节,中文2个字节。#utf-8:英文1个字节,欧洲字符:2个字节,亚洲:3个字节。14、字节码和机器码的区别?
-C代码被编译成机器码(二进制),在机器上直接执行。-Cpython编译你的python源代码,生成字节码。-机器码快的多,字节码更易迁移,也安全。15、三元运算规则以及应用场景?
#三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值a=1b=2c=aifa>1elseb#如果a大于1的话,c=a,否则c=b16、列举Python2和Python3的区别?
a=1b=2###########a,b=b,aprint(a,b)18、Python3和Python2中int和long的区别?
py3中没有long整型,统一使用int,大小和py2的long类似。py2中int最大不能超过sys.maxint,根据不同平台大小不同;在int类型数字后加L定义成长整型,范围比int更大。19、xrange和range的区别?
#range产生的是一个列表,xrange产生的是生成器。#数据较大时xrange比range好。#Range一下把数据都返回,xrange通过yield每次返回一个。20、文件操作时:xreadlines和readlines的区别?
#Readlines:读取文件的所有行,返回一个列表,包含所有行的结束符#Xreadlines:返回一个生成器,循环使用和readlines基本一致。(py2有,py3没有)21、列举布尔值为False的常见值?
#[]、{}、None、’’、()、0、False22、字符串、列表、元组、字典每个常用的5个方法?
#Str:Split:分割Strip:去掉两边的空格Startwith:以什么开头Endwith:以什么结尾Lower:小写Upper:大写#List:Append:追加Insert:插入Reverse:反转Index:索引Copy:拷贝Pop:删除指定索引处的值,不指定索引默认删除最后一个。#Tuple:Count:查看某个元素出现的次数Index:索引#Dict:Get:根据key取valueItems:用于循环,取出所有key和valueKeys:取出所有keyValues:取出所有的valueClear:清空字典Pop:删除指定键对应的值,有返回值;show23、lambda表达式格式以及应用场景?
#格式:匿名函数:res=lambdax:i*xprint(res(2))#应用场景:Filter(),map(),reduce(),sorted()函数中经常用到,它们都需要函数形参数;一般定义调用一次。(reduce()对参数序列中元素进行累积)24、pass的作用?
#Pass一般用于站位语句,保持代码的完整性,不会做任何操作。25、*arg和**kwarg作用
#他们是一种动态传参,一般不确定需要传入几个参数时,可以使用其定义参数,然后从中取参'*args':按照位置传参,将传入参数打包成一个‘元组’(打印参数为元组--tuple)'**kwargs':按照关键字传参,将传入参数打包成一个‘字典’(打印参数为字典--dict)26、is和==的区别
==:判断某些值是否一样,比较的是值is:比较的是内存地址(引用的内存地址不一样,唯一标识:id)27、简述Python的深浅拷贝以及应用场景?
#浅拷贝:不管多么复杂的数据结构,只copy对象最外层本身,该对象引用的其他对象不copy,内存里两个变量的地址是一样的,一个改变另一个也改变。#深拷贝:完全复制原变量的所有数据,内存中生成一套完全一样的内容;只是值一样,内存地址不一样,一方修改另一方不受影响28、Python垃圾回收机制?
#可变类型:列表、字典、集合#不可变类型:数字、字符串、元祖(可变与否指内存中那块内容value)30、求结果:
defnum():return[lambdax:i*xforiinrange(4)]#返回一个列表,里面是四个函数对象i=3print([m(2)forminnum()])32、列举常见的内置函数?
#map:遍历序列,为每一个序列进行操作,返回一个结果列表l=[1,2,3,4,5,6,7]defpow2(x):returnx*xres=map(pow2,l)print(list(res))#[1,4,9,16,25,36,49]--------------------------------------------------------------#reduce:对于序列里面的所有内容进行累计操作fromfunctoolsimportreducedefadd(x,y):returnx+yprint(reduce(add,[1,2,3,4]))#10--------------------------------------------------------------#filter:对序列里面的元素进行筛选,最终获取符合条件的序列。l=[1,2,3,4,5]defis_odd(x):#求奇数returnx%2==1print(list(filter(is_odd,l)))#[1,3,5]--------------------------------------------------------------#zip用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组,然后返回由这些元组组成的列表a=[1,2,3]b=[4,5,6]c=[4,5,6,7,8]ziped1=zip(a,b)print('ziped1>>>',list(ziped1))#[(1,4),(2,5),(3,6)]ziped2=zip(a,c)print('ziped2>>>',list(ziped2))#[(1,4),(2,5),(3,6)],以短的为基准常见内置函数33、filter、map、reduce的作用?
#map:遍历序列,为每一个序列进行操作,获取一个新的序列#reduce:对于序列里面的所有内容进行累计操作#filter:对序列里面的元素进行筛选,最终获取符合条件的序列。34、一行代码实现9*9乘法表
print('\n'.join([''.join(['%s*%s=%2s'%(j,i,i*j)forjinrange(1,i+1)])foriinrange(1,10)]))35、如何安装第三方模块?以及用过哪些第三方模块?
#a、可以在pycharm的settings里面手动下载添加第三方模块#b、可以在cmd终端下用pipinsatll安装#用过的第三方模块:requests、pymysql、DBUtils等36、至少列举8个常用模块都有那些?
#match:从字符串起始位置开始匹配,如果没有就返回None#serch:从字符串的起始位置开始匹配,匹配到第一个符合的就不会再去匹配了38、什么是正则的贪婪匹配?
#匹配一个字符串没有节制,能匹配多少就匹配多少,直到匹配完为止39、求结果:a.[i%2foriinrange(10)]b.(i%2foriinrange(10))
#a结果是一个列表生成式,结果是一个列表(i%2为生成的元素):[0,1,0,1,0,1,0,1,0,1]#b结果是一个生成器40、求结果:a.1or2b.1and2c.1<(2==2)d.1<2==2
a=1or2#1b=1and2#2c=1<(2==2)#Falsed=1<2==2#True41、deffunc(a,b=[])这种写法有什么坑?
#函数传参为列表陷阱,列表是可变数据类型,可能会在过程中修改里面的值42、如何实现“1,2,3”变成[‘1’,’2’,’3’]
a='1,2,3'a=a.replace(',','')res=[iforiina]print(res)43、如何实现[‘1’,’2’,’3’]变成[1,2,3]
l=['1','2','3']res=[int(i)foriinl]print(res)44、比较:a=[1,2,3]和b=[(1),(2),(3)]以及b=[(1,),(2,),(3,)]的区别?
前两个列表内是int最后一个列表内是元组45、如何用一行代码生成[1,4,9,16,25,36,49,64,81,100]
l=[i*iforiinrange(1,11)]print(l)46、一行代码实现删除列表中重复的值
l=[1,1,1,2,2,3,3,3,4,4]print(list(set(l)))#[1,2,3,4]47、如何在函数中设置一个全局变量
通过global指定变量,该变量会变成全局变量48、logging模块的作用?以及应用场景?
#作用:管理我们程序的执行日志,省去用print记录操作日志的操作,并且可以将标准输入输出保存到日志文件#场景:爬虫爬取数据时,对爬取进行日志记录,方便分析、排错。49、请用代码简单实现stack。
classStack(object):#初始化栈def__init__(self):self.items=[]#判断栈是否为空defis_empty(self):returnself.items==[]#返回栈顶defpeek(self):returnself.items[len(self.items)-1]#返回栈大小defsize(self):returnlen(self.items)#压栈defpush(self,item):self.items.append(item)#出栈defpop(self):returnself.items.pop()50、常用字符串格式化哪几种?
#%占位符s='Iam%s'%'zhugaochao'print(s)#Iamzhugaochao#format格式化输出i="iam{}".format('zhugaochao')print(i)#iamzhugaochao51、简述生成器、迭代器、可迭代对象以及应用场景?
li=[1,2,3,4,5,6,7,8,9,10]defsearch(zhi,li,start=0,end=None):end=len(li)ifendisNoneelseendzj=(end-start)//2+startifstart<=end:ifzhi>li[zj]:returnsearch(3,li,start=zj+1,end=end)elifzhi
#闭包函数就是内部的函数调用外部函数的变量,常用于装饰器。#判断闭包函数的方法:__closure__,输出的__closure__有cell元素说明是闭包函数#闭包的意义与应用:延迟计算:54、os和sys模块的作用?
#os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;#sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python运行环境55、如何生成一个随机数?
importrandomprint(random.random())print(random.randint(1,10))56、如何使用python删除一个文件?
importosos.remove('文件名以及路径')57、谈谈你对面向对象的理解?
#封装:其实就是将很多数据封装到一个对象中,类似于把很多东西放到一个箱子中,如:一个函数如果好多参数,起始就可以把参数封装到一个对象再传递。#继承:如果多个类中都有共同的方法,那么为了避免反复编写,就可以将方法提取到基类中实现,让所有派生类去继承即可。#多态:指基类的同一个方法在不同派生类中有着不同功能。python天生支持多态。58、Python面向对象中的继承有什么特点?
#Python3的继承机制#子类在调用某个方法或变量的时候,首先在自己内部查找,如果没有找到,则开始根据继承机制在父类里查找。#根据父类定义中的顺序,以深度优先的方式逐一查找父类!继承参数的书写有先后顺序,写在前面的被优先继承。59、面向对象深度优先和广度优先是什么?
主要在子类继承父类的所有属性和方法时来使用61、是否使用过functools中的函数?其作用是什么?
在装饰器中,会用到;functools.wraps()主要在装饰器中用来装饰函数Stark上下文管理源码中,走到视图阶段时有用到functools中的偏函数,request=LocalProxy(partial(_lookup_req_object,'request'))62、列举面向对象中带爽下划线的特殊方法,如:__new__、__init__
#__getattr__CBVdjango配置文件wtforms中的Form()示例化中将"_fields中的数据封装到From类中"#__mro__wtform中FormMeta中继承类的优先级#__dict__是用来存储对象属性的一个字典,其键为属性名,值为属性的值#__new__实例化但是没有给当前对象wtforms,字段实例化时返回:不是StringField,而是UnboundFieldestfraworkmany=Turn中的序列化#__call__flask请求的入口app.run()字段生成标签时:字段.__str__=>字段.__call__=>插件.__call__#__iter__循环对象是,自定义__iter__wtforms中BaseForm中循环所有字段时定义了__iter__#-metaclass作用:用于指定当前类使用哪个类来创建场景:在类创建之前定制操作示例:wtforms中,对字段进行排序。63、如何判断是函数还是方法
#看他的调用者是谁,如果是类,需要传入参数self,这时就是一个函数;#如果调用者是对象,不需要传入参数值self,这时是一个方法。(FunctionType/MethodType)64、静态方法和类方法区别?
Classmethod必须有一个指向类对象的引用作为第一个参数;@classmethoddefclass_func(cls):"""定义类方法,至少有一个cls参数"""print('类方法')---------------------------------------------------------Staticmethod可以没有任何参数。@staticmethoddefstatic_func():"""定义静态方法,无默认参数"""print('静态方法')65、列举面向对象中的特殊成员以及应用场景
1.__doc__:表示类的描述信息。2.__module__:表示当前操作的对象在那个模块;3.__class__:表示当前操作的对象的类是什么。4.__init__:构造方法,通过类创建对象时,自动触发执行。5.__call__:对象后面加括号,触发执行。6.__dict__:类或对象中的所有成员。7.__str__:如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。classFoo:def__str__(self):return'aaa'obj=Foo()print(obj)#输出:aaa8.__getitem__、__setitem__、__delitem__:用于索引操作,如字典。以上分别表示获取、设置、删除数据。9.__iter__:用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了__iter__。66、1、2、3、4、5能组成多少个互不相同且无重复的三位数
importitertoolsprint(len(list(itertools.permutations('12345',3))))#60个67、什么是反射?以及应用场景?
反射就是以字符串的方式导入模块,以字符串的方式执行函数#应用场景:restframework里面的CBV68、metaclass作用?以及应用场景?
importfunctoolsdefwrapper(func):@functools.wraps(func)definner(*args,**kwargs):print('我是装饰器')returnfuncreturninner@wrapperdefindex():print('我是被装饰函数')returnNoneindex()#应用场景-高阶函数-闭包-装饰器-functools.wraps(func)71、异常处理写法以及如何主动抛出异常(应用场景)
MRO:方法解析顺序它定义了Python中多继承存在的情况下,解释器查找继承关系的具体顺序73、isinstance作用以及应用场景?
#来判断一个对象是否是一个已知的类型。#使用isinstance函数还可以来判断'类实例变量'属于哪一个类产生的。74、写代码并实现:
'''Givenanarrayofintegers,returnindicesofthetwonumberssuchthattheyadduptoaspecifictarget.Youmayassumethateachinputwouldhaveexactlyonesolution,andyoumaynotusethesameelementtwice.Example:Givennums=[2,7,11,15],target=9,Becausenums[0]+nums[1]=2+7=9,return[0,1]'''classSolution:deftwoSum(self,nums,target):""":typenums:List[int]:typetarget:int:rtype:List[int]"""#用len()方法取得nums列表长度n=len(nums)#x从0到n取值(不包括n)forxinrange(n):a=target-nums[x]#用in关键字查询nums列表中是否有aifainnums:#用index函数取得a的值在nums列表中的索引y=nums.index(a)#假如x=y,那么就跳过,否则返回x,yifx==y:continueelse:returnx,ybreakelse:continueshow75、json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
importjsona=json.dumps({"xxx":"你好"},ensure_ascii=False)print(a)#{"xxx":"你好"}77、什么是断言?应用场景?
#条件成立则继续往下,否则抛出异常;#一般用于:满足某个条件之后,才能执行,否则应该抛出异常。'应用场景':restframework中GenericAPIView类里,要设置queryset,否则断言错误78、有用过withstatement吗?它的好处是什么?
with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。79、使用代码实现查看列举目录下的所有文件。
importospath=os.listdir('.')#查看列举目录下的所有文件。#path=os.listdir(os.getcwd())print(path)80、简述yield和yieldfrom关键字。
物理层:主要基于电器特性发送高低电压(1、0),设备有集线器、中继器、双绞线等,单位:bit数据链路层:定义了电信号的分组方式,设备:交换机、网卡、网桥,单位:帧网络层:主要功能是将网络地址翻译成对应屋里地址,设备:路由传输层:建立端口之间的通信,tcp、udp协议会话层:建立客户端与服务端连接表示层:对来自应用层的命令和数据进行解释,按照一定格式传给会话层。如编码、数据格式转换、加密解密、压缩解压应用层:规定应用程序的数据格式2、什么是C/S和B/S架构?
#C/S架构:client端与server端的服务架构#B/S架构:隶属于C/S架构,Broswer端(网页端)与server端;优点:统一了所有应用的入口,方便、轻量级3、简述三次握手、四次挥手的流程。
#三次握手:1.客户端(Client)向服务端(Server)发送一次请求2.服务端确认并回复客户端3.客户端检验确认请求,建立连接#四次挥手:1.客户端向服务端发一次请求2.服务端回复客户端(断开客户端-->服务端)3.服务端再次向客户端发请求(告诉客户端可以断开了)4.客户端确认请求,连接断开4、什么是arp协议?
#ARP(地址解析协议)其主要用作将IP地址翻译为以太网的MAC地址#在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。#在以太网中,一个主机要和另一个主机进行直接通信,必须要知道目标主机的MAC地址。#所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。#ARP协议的基本功能就是通过目标设备的IP地址,查询目标设备的MAC地址,以保证通信的顺利进行。5、TCP和UDP的区别?
局域网和广域网是按规模大小而划分的两种计算机网络。#范围在几千米以内的计算机网络统称为局域网(LAN、私网、内网);#而连接的范围超过10千米的,则称为广域网,因特网(Intenet)就是目前最大的广域网(WAN、公网、外网)。
7、为何基于tcp协议的通信比基于udp协议的通信更可靠?
因为TCP是面向连接的通信之前先三次握手,通过握手,确保连接成功之后再通信断开之前先四次挥手;双方互相确认之后再断开连接,这样一来保证了数据的安全、可靠,避免丢包8、什么是socket?简述基于tcp协议的套接字通信流程。
#服务端:创建套接字绑定IP和端口监听accept等待连接通信(收recv、发send)#客户端:创建套接字绑定IP和端口链接服务器通信(收revc、发send)9、什么是粘包?socket中造成粘包的原因是什么?哪些情况会发生粘包现象?
#什么是防火墙?防火墙是一个分离器,一个限制器,也是一个分析器,有效地监控了内部网和Internet之间的任何活动,保证了内部网络的安全。#作用防火墙可通过监测、限制、更改跨越防火墙的数据流,尽可能地对外部屏蔽网络内部的信息、结构和运行状况,以此来实现网络的安全保护。12、select、poll、epoll模型的区别?
#select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:#1.单个进程可监视的fd数量被限制#2.需要维护一个用来存放大量fd的数据结构#这样会使得用户空间和内核空间在传递该结构时复制开销大#3.对socket进行扫描时是线性扫描#poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,#它没有最大连接数的限制,原因是它是基于链表来存储的但是同样有一个缺点:#大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。#epoll支持水平触发和边缘触发,最大的特点在于边缘触发,#它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。13、简述进程、线程、协程的区别以及应用场景?
#进程进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。#线程线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度#协程和线程的区别协程避免了无意义的调度,由此可以提高性能;但同时协程也失去了线程使用多CPU的能力。14、GIL锁是什么鬼?
a.threading.local作用:为每个线程开辟一块空间进行数据存储。问题:自己通过字典创建一个类似于threading.local的东西。storage={4740:{val:0},4732:{val:1},4731:{val:3},}b.自定义Local对象作用:为每个线程(协程)开辟一块空间进行数据存储。try:fromgreenletimportgetcurrentasget_identexceptExceptionase:fromthreadingimportget_identfromthreadingimportThreadimporttimeclassLocal(object):def__init__(self):object.__setattr__(self,'storage',{})def__setattr__(self,k,v):ident=get_ident()ifidentinself.storage:self.storage[ident][k]=velse:self.storage[ident]={k:v}def__getattr__(self,k):ident=get_ident()returnself.storage[ident][k]obj=Local()deftask(arg):obj.val=argobj.xxx=argprint(obj.val)foriinrange(10):t=Thread(target=task,args=(i,))t.start()show17、进程之间如何进行通信?
#进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等18、什么是并发和并行?
#并发:同一时刻只能处理一个任务,但一个时段内可以对多个任务进行交替处理(一个处理器同时处理多个任务)#并行:同一时刻可以处理多个任务(多个处理器或者是多核的处理器同时处理多个不同的任务)#类比:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。19、进程锁和线程锁的作用?
'非阻塞':遇到IO阻塞不等待(setblooking=False),(可能会报错->捕捉异常)-sk=socket.socket()-sk.setblooking(False)'异步':回调(ajax),当达到某个指定状态之后,自动调用特定函数21、路由器和交换机的区别?
'交换机'用于在同一网络内数据快速传输转发,工作在数据链路层;通过MAC寻址,不能动态划分子网;只能在一条网络通路中运行,不能动态分配。'路由器'是一个网关设备,内部局域网到公网的一个关卡;工作在网络层;通过IP寻址,可以划分子网;可以在多条网络通道中运行,可以动态分配IP地址。'简单说'交换机就是把一根网线变成多根网线;路由器就是把一个网络变成多个网络;如果不上外网,只是局域网,交换机即可;如果上外网,并且给网络划分不同网段,就必须用路由器。22、什么是域名解析?
'hosts':Hosts就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”可以用来屏蔽一些网站,或者指定一些网站(修改hostsFQ)'修改':#windows:位置:C:\Windows\System32\drivers\etc也可以通过第三方软件,我用的火绒,可以直接进行编辑hosts#linux:位置:/etc/hosts修改:vi/etc/hosts24、生产者消费者模型应用场景及优势?
#用户获取数据时,不需要直接从源站获取,通过CDN对于数据的分发,#用户可以从一个较优的服务器获取数据,从而达到快速访问,并减少源站负载压力的目的。26、LVS是什么及作用?
#LVS即Linux虚拟服务器,是一个虚拟的四层交换器集群系统,#根据目标地址和目标端口实现用户请求转发,本身不产生流量,只做用户请求转发。27、Nginx是什么及作用?
'关系型':#sqllite、db2、oracle、access、SQLserver、MySQL#注意:sql语句通用,需要有表结构'非关系型':#mongodb、redis、memcache#非关系型数据库是key-value存储的,没有表结构。2、MySQL常见数据库引擎及比较?
'Myisam':#支持全文索引#查询速度相对较快#支持表锁#表锁:select*fromtbforupdate;(锁:forupdate)'InnoDB':#支持事务#支持行锁、表锁#表锁:select*fromtbforupdate;(锁:forupdate)#行锁:selectid,namefromtbwhereid=2forupdate;(锁:forupdate)3、简述数据三大范式?
'什么是事务'事务由一个或多个sql语句组成一个整体;在事务中的操作,要么都执行修改,要么都不执行,只有在该事务中所有的语句都执行成功才会将修改加入到数据库中,否则回滚到上一步。'Mysql实现事务'InnoDB支持事务,MyISAM不支持#启动事务:#starttransaction;#updatefromaccountsetmoney=money-100wherename='a';#updatefromaccountsetmoney=money+100wherename='b';#commit;'starttransaction手动开启事务,commit手动关闭事务'5、数据库五大约束
'数据库五大约束'1.primaryKEY:设置主键约束;2.UNIQUE:设置唯一性约束,不能有重复值;3.DEFAULT默认值约束4.NOTNULL:设置非空约束,该字段不能为空;5.FOREIGNkey:设置外键约束。6、简述数据库设计中一对多和多对多的应用场景?
#一对一关系示例:一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。#一对多关系示例:(下拉单选)一个学生只属于一个班,但是一个班级有多名学生。#多对多关系示例:(下拉多选)一个学生可以选择多门课,一门课也有多名学生。7、如何基于数据库实现商城商品计数器?
'主键索引(单列)':primarykey加速查找+约束:不能重复、不能为空'普通索引(单列)':加速查找'唯一索引(单列)':unique加速查找+约束:不能重复'联合索引(多列)':查询时根据多列进行查询(最左前缀)'联合唯一索引(多列)':遵循最左前缀规则(命中索引)#其他词语1、索引合并:利用多个单列索引查询2、覆盖索引:在索引表中就能将想要的数据查询到11、索引在什么情况下遵循最左前缀的规则?
'主键'唯一标识一条记录用来保证数据的完整性主键只能有一个'外键'表的外键是另一个表的主键,外键可以有重复的,可以是空值用来和其他表建立联系用的一个表可以有多个外键'索引'该字段没有重复值,但可以有一个空值提高查询速度一个表可以有多个唯一索引13、MySQL常见的函数?
#使用'like‘%xx’'select*fromtb1wherenamelike'%cn';#使用'函数'select*fromtb1wherereverse(name)='zgc';#使用'or'select*fromtb1wherenid=1oremail='zgc@gmial.com';特别的:当or条件中有未建立索引的列才失效,一下会走索引#select*fromtb1wherenid=1orname='zgc';#select*fromtb1wherenid=1oremail='zgc@gmial.com'andname='zgc';#'类型不一致'如果列是字符串类型,传入条件是必须用引号引起来,不然则可能会无法命中select*fromtb1wherename=666;#含有'!='select*fromtb1wherename!='zgc';特别的:如果是主键,还是会走索引#select*fromtb1wherenid!=123;#含有'>'select*fromtb1wherename>'zgc';特别的:如果是主键或者索引是整数类型,则还是会走索引#select*fromtb1wherenid>123;#select*fromtb1wherename>123;#含有'orderby'selectemailfromtb1orderbynamedesc;当根据索引排序时,选择的映射如果不是索引,则不走索引特别的:如果对主键排序,则还是走索引:#select*fromtb1orderbyniddesc;#组合索引最左前缀如果组合索引为:(name,email)nameandemail#使用索引name#使用索引email#不使用索引15、如何开启慢日志查询?
#导出:mysqldump--no-defaults-uroot-p数据库名字>导出路径'--no-defaults':解决“unknownoption--no-beep”报错#导入:1、mysqldump-uroot-p数据库名称<路径2、进入数据库;source+要导入数据库文件路径17、数据库优化方案?
1、创建数据表时把固定长度的放在前面2、将固定数据放入内存:choice字段(django中用到,1,2,3对应相应内容)3、char不可变,varchar可变4、联合索引遵循最左前缀(从最左侧开始检索)5、避免使用select*6、读写分离:#利用数据库的主从分离:主,用于删除、修改、更新;从,用于查#实现:两台服务器同步数据\原生SQL:select*fromdb.tb\ORM:model.User.object.all().using('default')\路由:dbrouter7、分库#当数据库中的表太多,将某些表分到不同数据库,例如:1W张表时#代价:连表查询跨数据库,代码变多8、分表#水平分表:将某些列拆分到另一张表,例如:博客+博客详情#垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单9、加缓存#利用redis、memcache(常用数据放到缓存里,提高取数据速度)#缓存不够可能会造成雪崩现象10、如果只想获取一条数据select*fromtbwherename='zgc'limit1;18、char和varchar的区别?
#char类型:定长不可变存入字符长度大于设置长度时报错;存入字符串长度小于设置长度时,用空格填充以达到设置字符串长度;简单粗暴,浪费空间,存取速度快。#varchar类型:可变存储数据真实内容,不使用空格填充;会在真实数据前加1-2Bytes的前缀,用来表示真实数据的bytes字节数;边长、精准、节省空间、存取速度慢。19、简述MySQL的执行计划?
#explain+SQL语句#SQL在数据库中执行时的表现情况,通常用于SQL性能分析,优化等场景。'explainselect*fromrbac_userinfowhereid=1;'20、在对name做了唯一索引前提下,简述以下区别:
select*fromtbwherename=‘小明’select*fromtbwherename=‘小明’limit1-------------------------------------------------------------没做唯一索引的话,前者查询会全表扫描,效率低些limit1,只要找到对应一条数据,就不继续往下扫描.然而name字段添加唯一索引了,加不加limit1,意义都不大;21、1000w条数据,使用limitoffset分页时,为什么越往后翻越慢?如何解决?
#例如:#limit100000,20;从第十万条开始往后取二十条,#limit20offset100000;limit后面是取20条数据,offset后面是从第10W条数据开始读因为当一个数据库表过于庞大,LIMIToffset,length中的offset值过大,则SQL查询语句会非常缓慢--------------------------------------------------------------------------'优化一'先查看主键,再分页:select*fromtbwhereidin(selectidfromtbwherelimit10offset30)--------------------------------------------------------------------------'优化二'记录当前页,数据、ID、最大值和最小值(用于where查询)在翻页时,根据条件进行筛选,筛选完毕后,再根据limitoffset查询select*from(select*fromtbwhereid>2222)asBlimit10offset0;\如果用户自己修改页码,也可能导致变慢,此时可以对url页码进行加密,例如restframework--------------------------------------------------------------------------'优化三'可以按照当前业务需求,看是否可以设置只允许看前200页;一般情况下,没人会咔咔看个几十上百页的;22、什么是索引合并?
#索引合并访问方法可以在查询中对一个表使用多个索引,对它们同时扫描,并且合并结果。#此访问方法合并来自单个表的索引扫描;它不会将扫描合并到多个表中。23、什么是覆盖索引?
#解释一:就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。#解释二:索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。#注意:MySQL只能使用B-Tree索引做覆盖索引24、简述数据库读写分离?
#利用数据库的主从分离:主,用于删除、修改、更新;从,用于查#实现:两台服务器同步数据(减轻服务器的压力)原生SQL:select*fromdb.tbORM:model.User.object.all().using('default')路由:dbrouter25、简述数据库分库分表?(水平、垂直)
#1、分库当数据库中的表太多,将某些表分到不同数据库,例如:1W张表时代价:连表查询跨数据库,代码变多#2、分表水平分表:将某些列拆分到另一张表,例如:博客+博客详情垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单26、redis和memcached比较?
#1.存储容量:memcached超过内存比例会抹掉前面的数据,而redis会存储在磁盘#2.支持数据类型:memcached只支持string;redis支持更多;如:hash、list、集合、有序集合#3.持久化:redis支持数据持久化,可以将内存中的数据保持在磁盘中,memcached无#4.主从:即master-slave模式的数据备份(主从)。#5.特性Redis在很多方面具备数据库的特征,或者说就是一个数据库系统Memcached只是简单的K/V缓存27、redis中数据库默认是多少个db及作用?
#redis默认有16个db,db0~db15(可以通过配置文件支持更多,无上限)#并且每个数据库的数据是隔离的不能共享#可以随时使用SELECT命令更换数据库:redis>SELECT1#注意:多个数据库之间并不是完全隔离的比如FLUSHALL命令可以清空一个Redis实例中所有数据库中的数据。28、python操作redis的模块?
#通过scan_iter分片取,减少内存压力scan_iter(match=None,count=None)增量式迭代获取redis里匹配的的值#match,匹配指定key#count,每次分片最少获取个数r=redis.Redis(connection_pool=pool)forkeyinr.scan_iter(match='PREFIX_*',count=100000):print(key)30、redis如何实现主从复制?以及数据同步机制?
#实现主从复制'创建6379和6380配置文件'redis.conf:6379为默认配置文件,作为Master服务配置;redis_6380.conf:6380为同步配置,作为Slave服务配置;'配置slaveof同步指令'在Slave对应的conf配置文件中,添加以下内容:slaveof127.0.0.16379#数据同步步骤:(1)Slave服务器连接到Master服务器.(2)Slave服务器发送同步(SYCN)命令.(3)Master服务器备份数据库到文件.(4)Master服务器把备份文件传输给Slave服务器.(5)Slave服务器把备份文件数据导入到数据库中.31、redis中的sentinel的作用?
#帮助我们自动在主从之间进行切换(哨兵)#检测主从中主是否挂掉,且超过一半的sentinel检测到挂了之后才进行进行切换。#如果主修复好了,再次启动时候,会变成从。32、如何实现redis集群?
#基于【分片】来完成。-集群是将你的数据拆分到多个Redis实例的过程-可以使用很多电脑的内存总和来支持更大的数据库。-没有分片,你就被局限于单机能支持的内存容量。#redis将所有能放置数据的地方创建了16384个哈希槽。#如果设置集群的话,就可以为每个实例分配哈希槽:-192.168.1.20【0-5000】-192.168.1.21【5001-10000】-192.168.1.22【10001-16384】#以后想要在redis中写值时:setk1123-将k1通过crc16的算法转换成一个数字,然后再将该数字和16384求余,-如果得到的余数3000,那么就将该值写入到192.168.1.20实例中。#集群方案:-rediscluster:官方提供的集群方案。-codis:豌豆荚技术团队。-tweproxy:Twiter技术团队。33、redis中默认有多少个哈希槽?
#redis中默认有16384个哈希槽。34、简述redis的有哪几种持久化策略及比较?
#限定Redis占用的内存,根据自身数据淘汰策略,淘汰冷数据,把热数据加载到内存。#计算一下20W数据大约占用的内存,然后设置一下Redis内存限制即可。37、写代码,基于redis的列表实现先进先出、后进先出队列、优先级队列。???????????????????
38、如何基于redis实现消息队列?
#通过发布订阅模式的PUB、SUB实现消息队列#发布者发布消息到频道了,频道就是一个消息队列。#发布者:importredisconn=redis.Redis(host='127.0.0.1',port=6379)conn.publish('104.9MH',"hahahahahaha")#订阅者:importredisconn=redis.Redis(host='127.0.0.1',port=6379)pub=conn.pubsub()pub.subscribe('104.9MH')whileTrue:msg=pub.parse_response()print(msg)对了,redis做消息队列不合适业务上避免过度复用一个redis,用它做缓存、做计算,还做任务队列,压力太大,不好。39、如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?
#发布和订阅,只要有任务就所有订阅者每人一份。发布者:#发布一次importredisconn=redis.Redis(host='127.0.0.1',port=6379)conn.publish('104.9MH',"hahahahahaha")订阅者:#'whileTrue'一直在接收importredisconn=redis.Redis(host='127.0.0.1',port=6379)pub=conn.pubsub()pub.subscribe('104.9MH')whileTrue:msg=pub.parse_response()print(msg)40、什么是codis及作用?
Codis是一个分布式Redis解决方案,对于上层的应用来说,连接到Codis-Proxy(redis代理服务)和连接原生的Redis-Server没有明显的区别,上层应用可以像使用单机的Redis一样使用,Codis底层会处理请求的转发,不停机的数据迁移等工作,所有后边的一切事情,对于前面的客户端来说是透明的,可以简单的认为后边连接的是一个内存无限大的Redis服务.41、什么是twemproxy及作用?
#什么是Twemproxy是Twtter开源的一个Redis和Memcache代理服务器,主要用于管理Redis和Memcached集群,减少与Cache服务器直接连接的数量。他的后端是多台REDIS或memcached所以也可以被称为分布式中间件。#作用通过代理的方式减少缓存服务器的连接数。自动在多台缓存服务器间共享数据。通过配置的方式禁用失败的结点。运行在多个实例上,客户端可以连接到首个可用的代理服务器。支持请求的流式与批处理,因而能够降低来回的消耗。42、写代码实现redis事务操作。
importredispool=redis.ConnectionPool(host='10.211.55.4',port=6379)conn=redis.Redis(connection_pool=pool)#pipe=r.pipeline(transaction=False)pipe=conn.pipeline(transaction=True)#开始事务pipe.multi()pipe.set('name','zgc')pipe.set('role','haha')pipe.lpush('roless','haha')#提交pipe.execute()'注意':咨询是否当前分布式redis是否支持事务43、redis中的watch的命令的作用?
#用于监视一个或多个key#如果在事务执行之前这个/些key被其他命令改动,那么事务将被打断44、基于redis如何实现商城商品数量计数器?
'通过redis的watch实现'importredisconn=redis.Redis(host='127.0.0.1',port=6379)#conn.set('count',1000)val=conn.get('count')print(val)withconn.pipeline(transaction=True)aspipe:#先监视,自己的值没有被修改过conn.watch('count')#事务开始pipe.multi()old_count=conn.get('count')count=int(old_count)print('现在剩余的商品有:%s',count)input("问媳妇让不让买?")pipe.set('count',count-1)#执行,把所有命令一次性推送过去pipe.execute()数据库的锁45、简述redis分布式锁和redlock的实现机制。
#一致性哈希一致性hash算法(DHT)可以通过减少影响范围的方式,解决增减服务器导致的数据散列问题,从而解决了分布式环境下负载均衡问题;如果存在热点数据,可以通过增添节点的方式,对热点区间进行划分,将压力分配至其他服务器,重新达到负载均衡的状态。#模块:hash_ring47、如何高效的找到redis中所有以zhugc开头的key?
redis有一个keys命令。#语法:KEYSpattern#说明:返回与指定模式相匹配的所用的keys。该命令所支持的匹配模式如下:1、:用于匹配单个字符。例如,hllo可以匹配hello、hallo和hxllo等;2、*:用于匹配零个或者多个字符。例如,h*llo可以匹配hllo和heeeello等;2、[]:可以用来指定模式的选择区间。例如h[ae]llo可以匹配hello和hallo,但是不能匹配hillo。同时,可以使用“/”符号来转义特殊的字符#注意KEYS的速度非常快,但如果数据太大,内存可能会崩掉,如果需要从一个数据集中查找特定的key,最好还是用Redis的集合结构(set)来代替。48、悲观锁和乐观锁的区别?
李杰
武沛奇
老男孩
undefined
Alex
对于django,大而全的框架它的内部组件比较多,内部提供:ORM、Admin、中间件、Form、ModelForm、Session、缓存、信号、CSRF;功能也都挺完善的-flask,微型框架,内部组件就比较少了,但是有很多第三方组件来扩展它,比如说有那个wtform(与django的modelform类似,表单验证)、flask-sqlalchemy(操作数据库的)、flask-session、flask-migrate、flask-script、blinker可扩展强,第三方组件丰富。所以对他本身来说有那种短小精悍的感觉-tornado,异步非阻塞。django和flask的共同点就是,他们2个框架都没有写socket,所以他们都是利用第三方模块wsgi。但是内部使用的wsgi也是有些不同的:django本身运行起来使用wsgiref,而flask使用werkzeugwsgi还有一个区别就是他们的请求管理不太一样:django是通过将请求封装成request对象,再通过参数传递,而flask是通过上下文管理机制Tornado
#是一个轻量级的Web框架,异步非阻塞+内置WebSocket功能。
'目标':通过一个线程处理N个并发请求(处理IO)。
'内部组件
#内部自己实现socket
#路由系统
#视图
#模板#cookie
#csrf
filter:类似管道,只能接受两个参数第一个参数是|前的数据simple_tag:类似函数1、模板继承:{%extends'layouts.html'%}2、自定义方法'filter':只能传递两个参数,可以在if、for语句中使用'simple_tag':可以无线传参,不能在iffor中使用'inclusion_tags':可以使用模板和后端数据3、防xss攻击:'|safe'、'mark_safe'
'一个接口通过1次相同的访问,再对该接口进行N次相同的访问时,对资源不造影响就认为接口具有幂等性。'GET,#第一次获取结果、第二次也是获取结果对资源都不会造成影响,幂等。POST,#第一次新增数据,第二次也会再次新增,非幂等。PUT,#第一次更新数据,第二次不会再次更新,幂等。PATCH,#第一次更新数据,第二次不会再次更新,非幂等。DELTE,#第一次删除数据,第二次不在再删除,幂等。
#在编写接口时可以不使用djangorestframework框架,#不使用:也可以做,可以用django的CBV来实现,开发者编写的代码会更多一些。#使用:内部帮助我们提供了很多方便的组件,我们通过配置就可以完成相应操作,如:'序列化'可以做用户请求数据校验+queryset对象的序列化称为json'解析器'获取用户请求数据request.data,会自动根据content-type请求头的不能对数据进行解析'分页'将从数据库获取到的数据在页面进行分页显示。#还有其他组件:'认证'、'权限'、'访问频率控制
-如何编写?写类并实现authenticators请求进来认证需要编写一个类,类里面有一个authenticators方法,我们可以自定义这个方法,可以定制3类返回值。成功返回元组,返回none为匿名用户,抛出异常为认证失败。源码流程:请求进来先走dispatch方法,然后封装的request对象会执行user方法,由user触发authenticators认证流程-方法中可以定义三种返回值:-(user,auth),认证成功-None,匿名用户-异常,认证失败-流程:-dispatch-再去request中进行认证处理
Flask自由、灵活,可扩展性强,透明可控,第三方库的选择面广,开发时可以结合最流行最强大的Python库,
#依赖jinja2模板引擎#依赖werkzurg协议
#blueprint把实现不同功能的module分开.也就是把一个大的App分割成各自实现不同功能的module.#在一个blueprint中可以调用另一个blueprint的视图函数,但要加相应的blueprint名.
#Flask组件flask-sessionsession放在redisflask-SQLAlchemy如django里的ORM操作flask-migrate数据库迁移flask-script自定义命令blinker信号-触发信号#第三方组件Wtforms快速创建前端标签、文本校验dbutile创建数据库连接池gevnet-websocket实现websocket#自定义Flask组件自定义auth认证参考flask-login组件
#g是贯穿于一次请求的全局变量,当请求进来将g和current_app封装为一个APPContext类,#再通过LocalStack将Appcontext放入Local中,取值时通过偏函数在LocalStack、local中取值;#响应时将local中的g数据删除:
RequestContext#封装进来的请求(赋值给ctx)AppContext#封装app_ctxLocalStack#将local对象中的数据维护成一个栈(先进后出)Local#保存请求上下文对象和app上下文对象
#因为通过维护成列表,可以实现一个栈的数据结构,进栈出栈时只取一个数据,巧妙的简化了问题。#还有,在多app应用时,可以实现数据隔离;列表里不会加数据,而是会生成一个新的列表#local是一个字典,字典里key(stack)是唯一标识,value是一个列表
请求进来时,可以根据URL的不同,交给不同的APP处理。蓝图也可以实现。#app1=Flask('app01')#app2=Flask('app02')#@app1.route('/index')#@app2.route('/index2')源码中在DispatcherMiddleware类里调用app2.__call__,原理其实就是URL分割,然后将请求分发给指定的app。之后app也按单app的流程走。就是从app.__call__走。
gevent-websocket
#快速创建前端标签、文本校验;如django的ModelForm
#前提:不熟的话:记不太清了,应该是……分两个阶段吧#创建:当请求刚进来的时候,会将request和session封装成一个RequestContext()对象,接下来把这个对象通过LocalStack()放入内部的一个Local()对象中;因为刚开始Local的ctx中session是空的;所以,接着执行open_session,将cookie里面的值拿过来,重新赋值到ctx中(Local实现对数据隔离,类似threading.local)#销毁:最后返回时执行save_session()将ctx中的session读出来进行序列化,写到cookie然后给用户,接着把ctxpop掉
#a.threading.local作用:为每个线程开辟一块空间进行数据存储(数据隔离)。问题:自己通过字典创建一个类似于threading.local的东西。storage={4740:{val:0},4732:{val:1},4731:{val:3},}#b.自定义Local对象作用:为每个线程(协程)开辟一块空间进行数据存储(数据隔离)。classLocal(object):def__init__(self):object.__setattr__(self,'storage',{})def__setattr__(self,k,v):ident=get_ident()ifidentinself.storage:self.storage[ident][k]=velse:self.storage[ident]={k:v}def__getattr__(self,k):ident=get_ident()returnself.storage[ident][k]obj=Local()deftask(arg):obj.val=argobj.xxx=argprint(obj.val)foriinrange(10):t=Thread(target=task,args=(i,))t.start()
#flask中的信号blinker信号主要是让开发者可是在flask请求过程中定制一些行为。或者说flask在列表里面预留了几个空列表,在里面存东西。简言之,信号允许某个'发送者'通知'接收者'有事情发生了@before_request有返回值,blinker没有返回值
#10个信号
request_started=_signals.signal('request-started')#请求到来前执行
request_finished=_signals.signal('request-finished')#请求结束后执行
before_render_template=_signals.signal('before-render-template')#模板渲染前执行
template_rendered=_signals.signal('template-rendered')#模板渲染后执行
got_request_exception=_signals.signal('got-request-exception')#请求执行出现异常时执行
request_tearing_down=_signals.signal('request-tearing-down')#请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down=_signals.signal('appcontext-tearing-down')#请求上下文执行完毕后自动执行(无论成功与否)
appcontext_pushed=_signals.signal('appcontext-pushed')#请求app上下文push时执行
appcontext_popped=_signals.signal('appcontext-popped')#请求上下文pop时执行
message_flashed=_signals.signal('message-flashed')#调用flask在其中添加数据时,自动触发
#Session:由于无法提供线程共享功能,开发时要给每个线程都创建自己的session打印sesion可知他是sqlalchemy.orm.session.Session的对象#scoped_session:为每个线程都创建一个session,实现支持线程安全在整个程序运行的过程当中,只存在唯一的一个session对象。创建方式:通过本地线程Threading.Local()#session=scoped_session(Session)创建唯一标识的方法(参考flask请求源码)
#使用execute方法直接操作SQL语句(导入create_engin、sessionmaker)engine=create_engine('mysql://root:*****@127.0.0.1/databasecharset=utf8')DB_Session=sessionmaker(bind=engine)session=DB_Session()session.execute('altertablemytablenamedropcolumnmycolumn;')
fromdatetimeimportdatetime
fromsqlalchemy.ext.declarative
importdeclarative_base
fromsqlalchemyimportColumn,Integer,String,DateTime
Base=declarative_base()
classUserInfo(Base):
__tablename__='userinfo'
id=Column(Integer,primary_key=True,autoincrement=True)
name=Column(String(64),unique=True)
ctime=Column(DateTime,default=datetime.now())
fromdatetimeimportdatetimefromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemyimportColumn,Integer,String,DateTimeBase=declarative_base()classUserInfo(Base):__tablename__='userinfo'id=Column(Integer,primary_key=True,autoincrement=True)name=Column(String(64),unique=True)ctime=Column(DateTime,default=datetime.now())-----------------------------------------------------------------------不正确:Ctime字段中参数应为’default=datetime.now’now后面不应该加括号,加了的话,字段不会实时更新。
sqlalchemy设置编码字符集,一定要在数据库访问的URL上增加'charset=utf8'否则数据库的连接就不是'utf8'的编码格式eng=create_engine('mysql://root:root@localhost:3306/test2charset=utf8',echo=True)1.设置引擎编码方式为utf8。engine=create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01charset=utf8")2.设置数据库表编码方式为utf8classUserType(Base):__tablename__='usertype'id=Column(Integer,primary_key=True)caption=Column(String(50),default='管理员')#添加配置设置编码__table_args__={'mysql_charset':'utf8'}这样生成的SQL语句就自动设置数据表编码为utf8了,__table_args__还可设置存储引擎、外键约束等等信息。
通过'UniqueConstraint'字段来设置联合唯一索引__table_args=(UniqueConstraint('h_id','username',name='_h_username_uc'))#h_id和username组成联合唯一约束
异步非阻塞+websocket
Tornado在websocket模块中提供了一个WebSocketHandler类。这个类提供了和已连接的客户端通信的WebSocket事件和方法的钩子。当一个新的WebSocket连接打开时,open方法被调用,而on_message和on_close方法,分别在连接、接收到新的消息和客户端关闭时被调用。此外,WebSocketHandler类还提供了write_message方法用于向客户端发送消息,close方法用于关闭连接。
#settings.pysettings={"static_path":os.path.join(os.path.dirname(__file__),"static"),#指定了静态文件的位置在当前目录中的"static"目录下"cookie_secret":"61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=","login_url":"/login","xsrf_cookies":True,}经上面配置后static_url()自动去配置的路径下找'commons.css'文件
torndbtorndb是基于mysqldb的再封装,所以使用时要先安装myqldb
tornado-redis
web聊天室,在线投票
'gitstash':将当前工作区所有修改过的内容存储到“某个地方”,将工作区还原到当前版本未修改过的状态'gitstashlist':查看“某个地方”存储的所有记录'gitstashclear':清空“某个地方”'gitstashpop':将第一个记录从“某个地方”重新拿到工作区(可能有冲突)'gitstashapply':编号,将指定编号记录从“某个地方”重新拿到工作区(可能有冲突)'gitstashdrop':编号,删除指定编号的记录
在命令行中,使用“gittag–atagname–m“comment”可以快速创建一个标签。需要注意,命令行创建的标签只存在本地Git库中,还需要使用Gitpush–tags指令发布到服务器的Git库中
gitlab是公司自己搭建的项目代码托管平台
1、gitHub是一个面向开源及私有软件项目的托管平台(创建私有的话,需要购买,最低级的付费为每月7刀,支持5个私有项目)2、gitlab是公司自己搭建的项目托管平台
1、fork需要协作项目2、克隆/关联fork的项目到本地3、新建分支(branch)并检出(checkout)新分支4、在新分支上完成代码开发5、开发完成后将你的代码合并到master分支6、添加原作者的仓库地址作为一个新的仓库地址7、合并原作者的master分支到你自己的master分支,用于和作者仓库代码同步8、push你的本地仓库到GitHub9、在Github上提交pullrequests10、等待管理员(你需要贡献的开源项目管理员)处理
一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。实际项目中,很多文件都是不需要版本管理的,比如Python的.pyc文件和一些包含密码的配置文件等等。
'敏捷开发':是一种以人为核心、迭代、循序渐进的开发方式。它并不是一门技术,而是一种开发方式,也就是一种软件开发的流程。它会指导我们用规定的环节去一步一步完成项目的开发。因为它采用的是迭代式开发,所以这种开发方式的主要驱动核心是人
'Jenkins'是一个可扩展的持续集成引擎。主要用于:持续、自动地构建/测试软件项目。监控一些定时执行的任务。
1、创建队列和发送消息时将设置durable=Ture,如果在接收到消息还没有存储时,消息也有可能丢失,就必须配置publisherconfirmchannel.queue_declare(queue='task_queue',durable=True)2、返回一个ack,进程收到消息并处理完任务后,发给rabbitmq一个ack表示任务已经完成,可以删除该任务3、镜像队列:将queue镜像到cluster中其他的节点之上。在该实现下,如果集群中的一个节点失效了,queue能自动地切换到镜像中的另一个节点以保证服务的可用性
默认消息队列里的数据是按照顺序被消费者拿走,例如:消费者1去队列中获取奇数序列的任务,消费者2去队列中获取偶数序列的任务。channel.basic_qos(prefetch_count=1)表示谁来谁取,不再按照奇偶数排列(同时也保证了公平的消费分发)
#celery实现定时任务启用Celery的定时任务需要设置CELERYBEAT_SCHEDULE。CELERYBEAT_SCHEDULE='djcelery.schedulers.DatabaseScheduler'#定时任务'创建定时任务'#通过配置CELERYBEAT_SCHEDULE:#每30秒调用task.addfromdatetimeimporttimedeltaCELERYBEAT_SCHEDULE={'add-every-30-seconds':{'task':'tasks.add','schedule':timedelta(seconds=30),'args':(16,16)},}
#一般情况使用的是从celeryapp中引入的app作为的装饰器:@app.task#django那种在app中定义的task则需要使用@shared_task
#作用:使用requests可以模拟浏览器的请求#常用参数:url、headers、cookies、datajson、params、proxy#常用返回值:contentiter_contenttextencoding="utf-8"cookie.get_dict()
#BeautifulSoup用于从HTML或XML文件中提取、过滤想要的数据形式#常用方法解析:html.parser或者lxml(需要下载安装)find、find_all、text、attrs、get
Selenium是一个用于Web应用程序测试的工具,他的测试直接运行在浏览器上,模拟真实用户,按照代码做出点击、输入、打开等操作爬虫中使用他是为了解决requests无法解决javascript动态问题
fromtwisted.web.clientimportAgent,getPage,ResponseDone,PotentialDataLossfromtwisted.internetimportdefer,reactor,protocolfromtwisted.web._newclientimportResponsefromioimportBytesIOclass_ResponseReader(protocol.Protocol):def__init__(self,finished,txresponse,file_name):self._finished=finishedself._txresponse=txresponseself._bytes_received=0self.f=open(file_name,mode='wb')defdataReceived(self,bodyBytes):self._bytes_received+=len(bodyBytes)#一点一点的下载self.f.write(bodyBytes)self.f.flush()defconnectionLost(self,reason):ifself._finished.called:returnifreason.check(ResponseDone):#下载完成self._finished.callback((self._txresponse,'success'))elifreason.check(PotentialDataLoss):#下载部分self._finished.callback((self._txresponse,'partial'))else:#下载异常self._finished.errback(reason)self.f.close()
#有些情况下,例如爬取大的站点,我们希望能暂停爬取,之后再恢复运行。#Scrapy通过如下工具支持这个功能:一个把调度请求保存在磁盘的调度器一个把访问请求保存在磁盘的副本过滤器[duplicatesfilter]一个能持续保持爬虫状态(键/值对)的扩展Job路径要启用持久化支持,你只需要通过JOBDIR设置jobdirectory选项。这个路径将会存储所有的请求数据来保持一个单独任务的状态(例如:一次spider爬取(aspiderrun))。必须要注意的是,这个目录不允许被不同的spider共享,甚至是同一个spider的不同jobs/runs也不行。也就是说,这个目录就是存储一个单独job的状态信息。
分布式爬虫的更新中。。。
'vitualenv'是一个独立的python虚拟环境如:当前项目依赖的是一个版本,但是另一个项目依赖的是另一个版本,这样就会造成依赖冲突,而virtualenv就是解决这种情况的,virtualenv通过创建一个虚拟化的python运行环境,将我们所需的依赖安装进去的,不同项目之间相互不干扰简述pipreqs及应用场景?可以通过对项目目录扫描,自动发现使用了那些类库,并且自动生成依赖清单。pipreqs./生成requirements.txt在Python中使用过什么代码检查工具?1)PyFlakes:静态检查Python代码逻辑错误的工具。2)Pep8:静态检查PEP8编码风格的工具。3)NedBatchelder’sMcCabescript:静态分析Python代码复杂度的工具。Python代码分析工具:PyChecker、Pylint