第一部分 Python基础篇(80题)
1、为什么学习Python?
Python相对于其他编程语言有很多优点:
1. 简单:Python是一种代表简单主义思想的语言。阅读一个良好的Python程序就感觉像是在读英语一样。它使你能够专注于解决问题而不是去搞明白语言本身。
2. 易学:Python极其容易上手,因为Python有极其简单的说明文档。
3. 速度快:Python 的底层是用 C 语言写的,很多标准库和第三方库也都是用 C写的,运行速度非常快。
4.高级语言:用Python语言编写程序的时候无需考虑诸如如何管理你的程序使用的内存一类的底层细节。
5. 丰富的库:Python标准库确实很庞大。它可以帮助处理各种工作,包括正则表达式、文档生成、单元测试、线程、数据库、网页浏览器、CGI、FTP、电子邮件、XML、XML-RPC、HTML、WAV文件、密码系统、GUI(图形用户界面)、Tk和其他与系统有关的操作。这被称作Python的“功能齐全”理念。除了标准库以外,还有许多其他高质量的库,如wxPython、Twisted和Python图像库等等。
6. 可移植性:由于它的开源本质,Python已经被移植在许多平台上(经过改动使它能够工作在不同平台上)。
2、通过什么途径学习的Python?
自学,看视频,看书
3、Python和Java、PHP、C、C#、C++等其他语言的对比?
python语言,是一种面向对象、直译式计算机程序设计语言,Python语法简洁而清晰,具有丰富和强大的类库。它常被昵称为胶水语言,它能够很轻松的把用其他语言制作的各种模块(尤其是C/C++)轻松地联结在一起。常见的一种应用情形是,使用python快速生成程序的原型(有时甚至是程序的最终界面),然后对其中有特别要求的部分,用更合适的语言改写。
Python是完全面向对象的语言。函数、模块、数字、字符串都是对象。并且完全支持继承、重载、派生、多继承,有益于增强源代码的复用性。Python支持重载运算符和动态类型。相对于Lisp这种传统的函数式编程语言,Python对函数式设计只提供了有限的支持。有两个标准库(functools, itertools)提供了Haskell和Standard ML中久经考验的函数式程序设计工具。Python本身被设计为可扩充的。并非所有的特性和功能都集成到语言核心。Python提供了丰富的API和工具,以便程序员能够轻松地使用C语言、C++、Cython来编写扩充模块。Python编译器本身也可以被集成到其它需要脚本语言的程序内。因此,很多人还把Python作为一种“胶水语言”(glue language)使用。使用Python将其他语言编写的程序进行集成和封装
4、简述解释型和编译型编程语言?
编译和解释的概述:
计算机是不能理解高级语言的,更不能直接执行高级语言,它只能直接理解机器语言,所以使用任何高级语言编写的程序若想被计算机运行,都必须将其转换成计算机语言,也就是机器码。
而这种转换的方式有两种:
1)编译
2)解释
由此高级语言也分为编译型语言和解释型语言。两种方式只是翻译的时间不同
编译型语言:
使用专门的编译器,针对特定的平台,将高级语言源代码一次性的编译成可被该平台硬件执行的机器码,并包装成该平台所能识别的可执行性程序的格式。
特点:
在编译型语言写的程序执行之前,需要一个专门的编译过程,把源代码编译成机器语言的文件,如exe格式的文件,以后要再运行时,直接使用编译结果即可,如直接运行exe文件。因为只需编译一次,以后运行时不需要编译,所以编译型语言执行效率高。
总结:
1)一次性的编译成平台相关的机器语言文件,运行时脱离开发环境,运行效率高;
2)与特定平台相关,一般无法移植到其他平台;
3)现有的C、C++、Objective等都属于编译型语言。
5、Python解释器种类以及特点?
CPython
当从Python官方网站下载并安装好Python2.7后,就直接获得了一个官方版本的解释器:Cpython,这个解释器是用C语言开发的,所以叫CPython,在命名行下运行python,就是启动CPython解释器,CPython是使用最广的Python解释器。
IPython
IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的,好比很多国产浏览器虽然外观不同,但内核其实是调用了IE。
PyPy
PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。
Jython
Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
IronPython
IronPython和Jython类似,只不过IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
在Python的解释器中,使用广泛的是CPython,对于Python的编译,除了可以采用以上解释器进行编译外,技术高超的开发者还可以按照自己的需求自行编写Python解释器来执行Python代码,十分的方便!
6、位和字节的关系?
1字节(Byte)= 8位(bit)(bit表示二进制的)
7、b、B、KB、MB、GB 的关系?
utf-8种一个字母或者 数字等于一个字节 , 一个汉字等于3个字节,表情等于4个字节
b 比特bit / 位
B——字节
KB——千比特
MB——兆比特
GB——吉比特
1 B = 8b (8个bit/ 位) 一个字节(byte)等于8位(bit)
1 kB = 1024 B (kB - kilobajt)
1 MB = 1024 kB (MB - megabajt)
1 GB = 1024 MB (GB - gigabajt)
英文和数字占一个字节
中文占一个字符,也就是两个字节
字符 不等于 字节。
字符(char)是 Java 中的一种基本数据类型,由 2 个字节组成,范围从 0 开始,到 2^16-1。
字节是一种数据量的单位,一个字节等于 8 位。所有的数据所占空间都可以用字节数来衡量。例如一个字符占 2 个字节,一个 int 占 4 个字节,一个 double 占 8 个字节 等等。
1字符=2字节;
1Byte=8bit
1k=2^10;b:位;B:字节1kb=1024 位1kB=1024 字节
8、请至少列举5个 PEP8 规范(越多越好)。
PEP8 Python 编码规范
一 代码编排
1 缩进。4个空格的缩进(编辑器都可以完成此功能),不使用Tap,更不能混合使用Tap和空格。
2 每行最大长度79,换行可以使用反斜杠,最好使用圆括号。换行点要在操作符的后边敲回车。
3 类和top-level函数定义之间空两行;类中的方法定义之间空一行;函数内逻辑无关段落之间空一行;其他地方尽量不要再空行。
二 文档编排
1 模块内容的顺序:模块说明和docstring—import—globals&constants—其他定义。其中import部分,又按标准、三方和自己编写顺序依次排放,之间空一行。
2 不要在一句import中多个库,比如import os, sys不推荐。
3 如果采用from XX import XX引用库,可以省略‘module.’,都是可能出现命名冲突,这时就要采用import XX。
9、通过代码实现如下转换:
二进制转换成十进制:v = “0b1111011”
十进制转换成二进制:v = 18
八进制转换成十进制:v = “011”
十进制转换成八进制:v = 30
十六进制转换成十进制:v = “0x12”
十进制转换成十六进制:v = 87
10、请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
11、python递归的最大层数?
python默认递归最大的层数是1000
不过这个值是可以通过sys.setrecursionlimit(1000)来设置
12、求结果:
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or Flase and 1
and:前后为真才为真or:有一为真就为真
优先级:()>not>and>or
同等优先级下,从左向右
13、ascii、unicode、utf-8、gbk 区别?
ASCII码使用一个字节编码,所以它的范围基本是只有英文字母、数字和一些特殊符号 ,只有256个字符。
在表示一个Unicode的字符时,通常会用“U+”然后紧接着一组十六进制的数字来表示这一个字符。在基本多文种平面(英文为 Basic Multilingual Plane,简写 BMP。它又简称为“零号平面”, plane 0)里的所有字符,要用四位十六进制数(例如U+4AE0,共支持六万多个字符);在零号平面以外的字符则需要使用五位或六位十六进制数了。旧版的Unicode标准使用相近的标记方法,但却有些微的差异:在Unicode 3.0里使用“U-”然后紧接着八位数,而“U+”则必须随后紧接着四位数。
Unicode能够表示全世界所有的字节
GBK是只用来编码汉字的,GBK全称《汉字内码扩展规范》,使用双字节编码。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,又称万国码。由Ken Thompson于1992年创建。现在已经标准化为RFC 3629。UTF-8用1到6个字节编码UNICODE字符。用在网页上可以同一页面显示中文简体繁体及其它语言(如英文,日文,韩文)。
#Ascii: 1个字节 支持英文
#unicode :所有字符(无论中文、英文等)1个字符:4个字节
#gbk : 1个字符,英文1个字节,中文2个字节。
#utf-8 :英文1个字节,欧洲字符:2个字节, 亚洲: 3个字节。
14、字节码和机器码的区别?
通常意义上来理解的话,机器码就是计算机可以直接执行,并且执行速度最快的代码。
字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
- C代码被编译成机器码(二进制),在机器上直接执行。- Cpython编译你的python源代码,生成字节码。- 机器码快的多,字节码更易迁移,也安全。
15、三元运算规则以及应用场景?
三元运算符就是在赋值变量的时候,可以直接加判断,然后赋值
格式:[on_true] if [expression] else [on_false]
res = 值1 if 条件 else 值2
a = 1
b = 2
c = a if a > 1 else b # 如果a大于1的话,c=a,否则c=b
16、列举 Python2和Python3的区别?
'Print':
py2--print;
py3--print()函数
'编码':
py2默认是ascii码;
py3默认是utf-8'
'字符串':
py2中分ascii(8位)、unicode(16位);
py3中所有字符串都是unicode字符串
'True和False':
py2中是两个全局变量(1和0)可以重新赋值;
py3中为两个关键字,不可重新赋值
'迭代':
py2:xrange;
py3:range
'Nonlocal':
py3专有的(声明为非局部变量)
'经典类&新式类':
py2:经典类和新式类并存;
py3:新式类都默认继承objec
'yield':
py2:yield py3:yield/yieldfrom
'文件操作':
py2:readliens()读取文件的所有行,返回一个列表,包含所有行的结束符
xreadliens()返回一个生成器,循环取值
py3: 只有readlines()
(1)Print
在 Python 2 中, print 被视为一个语句而不是一个函数,这是一个典型的容易弄混的地方,因为在 Python 中的许多操作都需要括号内的参数来执行。如果在 Python 2 中你想要你的控制台输出 ”hellow word”,你应该写下这样的 print 语句:
print "hellow word"
在使用 Python 3 时,print()会被显式地视为一个函数,因此要输出上面相同的字符串,你可以使用这种非常简单且易于使用的函数语法
print("hellow word")
这种改变使得 Python 的语法更加一致,并且在不同的 print 函数之间进行切换更加容易。就方便性而言,print()语法也与 Python 2.7 向后兼容,因此您的 Python 3 print()函数可以在任一版本中运行。
(2)整数的除法
在 Python 2 中,您键入的任何不带小数的数字,将被视为整数的编程类型。虽然乍看起来这似乎是一个简单的处理编程类型的方法,但有时候当你试图除以整数以期望获得一个带小数位的答案(称为浮点数),如:
5 / 2 = 2.5
然而,在 Python 2 中,整数是强类型的,并且不会变成带小数位的浮点数,即使这样做具有直观上的意义。
当除法/符号的任一侧的两个数字是整数时,Python 2进行底除法,使得对于商x,返回的数字是小于或等于x的最大整数。这意味着当你写下 5 / 2 来对这两个数字相除时,Python 2.7 将返回最大的小于或等于 2.5 的整数,在这种情形下:
a = 5 / 2
print a
#a=2
为解决这个问题,你可以在 5.0 / 2.0 中添加小数位,以得到预期的答案 2.5。
在 Python 3 中,整数除法变得更直观,如
(3)支持 Unicode
当编程语言处理字符串类型时,也就是一个字符序列,它们可以用几种不同的方式来做,以便计算机将数字转换为字母和其他符号。
Python 2 默认使用 ASCII 字母表,因此当您输入“Hello word!”时, Python 2 将以 ASCII 格式处理字符串。被限定为在多种扩展形式上的数百个字符,用ASCII 进行字符编码并不是一种非常灵活的方法,特别是使用非英语字符时。
要使用更通用和更强大的Unicode字符编码,这种编码支持超过128,000个跨越现今和历史的脚本和符号集的字符,你必须输入
u“Hello,word!” #前缀 u 代表 Unicode。
Python 3 默认使用 Unicode,这节省了程序员多余的开发时间,并且您可以轻松地在程序中直接键入和显示更多的字符。因为 Unicode 支持更强大的语言字符多样性以及 emoji 的显示,所以将它作为默认字符编码来使用,能确保全球的移动设备在您的开发项目中都能得到支持。
(4)后续发展
Python 3 和 Python 2 之间的最大区别不是语法上的,而是事实上 Python 2.7 将在 2020 年失去后续的支持,Python 3 将继续开发更多的功能和修复更多的错误。
最近的发展包括格式化的字符串,类创建的简单定制,和用一种更干净的句法方式来处理矩阵乘法。
Python 3 的后续开发意味着,开发人员可以对问题被及时解决抱有信心,并且随着时间的推移更多的功能将被添加进来,程序也会变得更加有效。
17、用一行代码实现数值交换:
a = 1
b = 2
18、Python3和Python2中 int 和 long的区别?
int(符号整数):通常被称为是整数或整数,没有小数点的正或负整数
long(长整数):无限大小的整数,这样写整数和一个大写或小写的L。
@py3中没有long整型,统一使用int,大小和py2的long类似。
py2中int最大不能超过sys.maxint,根据不同平台大小不同;
在int类型数字后加L定义成长整型,范围比int更大。
19、xrange和range的区别?
1.range和xrange都是在循环中使用,输出结果一样。
2.range返回的是一个list对象,而xrange返回的是一个生成器对象(xrange object)。
3.xrange则不会直接生成一个list,而是每次调用返回其中的一个值,内存空间使用极少,因而性能非常好。
注意:Python 3.x已经去掉xrange,全部用range代替。
@#range产生的是一个列表,xrange产生的是生成器。
#数据较大时xrange比range好。
#range一下把数据都返回,xrange通过yield每次返回一个。
20、文件操作时:xreadlines和readlines的区别?
二者使用时相同,但返回类型不同,xreadlines返回的是一个生成器,readlines返回的是list
@# Readlines:读取文件的所有行,返回一个列表,包含所有行的结束符
# Xreadlines:返回一个生成器,循环使用和readlines基本一致 。(py2有,py3没有)
21、列举布尔值为False的常见值?
0 , [ ] , " , ( ) , { } , False, None
22、字符串、列表、元组、字典每个常用的5个方法?
Str:
Split:分割
Strip:去掉两边的空格
Startwith:以什么开头
Endwith:以什么结尾
Lower:小写
Upper:大写
List:
Append:追加
Insert:插入
Reverse:反转
Index:索引
Copy:拷贝
Pop:删除指定索引处的值,不指定索引默认删除最后一个。
Tuple:
Count:查看某个元素出现的次数
Index:索引
Dict:
Get:根据key取value
Items:用于循环,取出所有key和value
Keys:取出所有key
Values:取出所有的value
Clear:清空字典
Pop:删除指定键对应的值,有返回值;
23、lambda表达式格式以及应用场景?
lambda表达式,通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用,也就是指匿名函数。
lambda所表示的匿名函数的内容应该是很简单的,如果复杂的话,干脆就重新定义一个函数了,使用lambda就有点过于执拗了。
lambda就是用来定义一个匿名函数的,如果还要给他绑定一个名字的话,就会显得有点画蛇添足,通常是直接使用lambda函数。如下所示:
需求:将列表中的元素按照绝对值大小进行升序排列
@# 格式:匿名函数:res =lambda x:i*x print(res(2))
# 应用场景: Filter(),map(),reduce(),sorted()函数中经常用到,它们都需要函数形参数;
一般定义调用一次。
(reduce()对参数序列中元素进行累积)
24、pass的作用?
1、空语句
2、保证格式完整
3、占位语句
@# Pass一般用于站位语句,保持代码的完整性,不会做任何操作。
25、*arg和**kwarg作用
所以从以上的示例可以看到*arg和**kwarg的作用为:
1、函数调用里的*arg和**kwarg:
(1)*arg:元组或列表“出现”
**kwarg:字典“出没”
(2)分割参数
2、函数定义时传的*arg /**kwarg:
(1)接收参数
@# 他们是一种动态传参,一般不确定需要传入几个参数时,可以使用其定义参数,然后从中取参
'*args':按照位置传参,将传入参数打包成一个‘元组’(打印参数为元组-- tuple)
'**kwargs':按照关键字传参,将传入参数打包成一个‘字典’(打印参数为字典-- dict)
26、is和==的区别
==是python标准操作符中的比较操作符,用来比较判断两个对象的value(值)是否相等
is也被叫做同一性运算符,这个运算符比较判断的是对象间的唯一身份标识,也就是id是否相同。
27、简述Python的深浅拷贝以及应用场景?
字面理解:浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。所以对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等.
应用场景:比如在CMDB系统中,我们定义了一个报警模版call给所有的服务器使用,此时有一批特殊应用的服务器需要不通的报警参数,我们既不想单独新建模版来一个一个添加报警参数,又不想修改默认模版而影响其他机器的报警阈值。此时我们就需要用深拷贝来完成。
@#浅拷贝:不管多么复杂的数据结构,只copy对象最外层本身,该对象引用的其他对象不copy,
内存里两个变量的地址是一样的,一个改变另一个也改变。
#深拷贝:完全复制原变量的所有数据,内存中生成一套完全一样的内容;只是值一样,内存地址不一样,一方修改另一方不受影响
28、Python垃圾回收机制?
Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。
29、Python的可变类型和不可变类型?
可变:列表、字典
对于可变类型,无论创建多少个可变类型,只要值相同,都不指向同个内存地址(除非进行复制操作,那么他们将会指向同一个地址)。
不可变:数字、字符串、元祖
对不可变类型的变量重新赋值,实际上是重新创建一个不可变类型的对象,并将原来的变量重新指向新创建的对象(如果没有其他变量引用原有对象的话(即引用计数为0),原有对象就会被回收)。
@# 可变类型:列表、字典、集合
# 不可变类型:数字、字符串、元祖(可变与否指内存中那块内容value)
30、求结果:
v = dict.fromkeys( ['k1','k2'],[ ] )
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
31、求结果:
32、列举常见的内置函数?
33、filter、map、reduce的作用?
# map:遍历序列,为每一个序列进行操作,获取一个新的序列
# reduce:对于序列里面的所有内容进行累计操作
# filter:对序列里面的元素进行筛选,最终获取符合条件的序列。
34、一行代码实现9*9乘法表
print('\n'.join([' '.join(['%s*%s = % - 2s'%(y, x, x*y) for y in range(1, x+1)]) for x in range(1, 10)]))
35、如何安装第三方模块?以及用过哪些第三方模块?
在Python中,安装第三方模块,是通过setuptools这个工具完成的。Python有两个封装了setuptools的包管理工具:easy_install和pip。目前官方推荐使用pip
如果你正在使用Mac或Linux,安装pip本身这个步骤就可以跳过了。
如果你正在使用Windows,确保安装时勾选了pip和Add python.exe to Path。
在命令提示符窗口下尝试运行pip,如果Windows提示未找到命令,可以重新运行安装程序添加pip。
现在,让我们来安装一个第三方库——bs4
pip install bs4
用过的第三方模块 bs4/pymysql/redis/lxml/tkinter/urllib/requests等
@# a、可以在pycharm的settings里面手动下载添加第三方模块
# b、可以在cmd终端下用pip insatll 安装
# 用过的第三方模块:requests、pymysql、DBUtils等
36、至少列举8个常用模块都有那些?
Django Flask Scrapy Tkinter Pygame numpy pillow-python pymysql pip
@re:正则
os:提供了一种方便的使用操作系统函数的方法。
sys:可供访问由解释器使用或维护的变量和与解释器进行交互的函数。
random:随机数
json:序列化
time:时间
37、re的match和search区别?
match只找字符串的开始位置,而search是全盘查找
@# match:从字符串起始位置开始匹配,如果没有就返回None
# serch:从字符串的起始位置开始匹配,匹配到第一个符合的就不会再去匹配了
38、什么是正则的贪婪匹配?
1、贪婪匹配
总是尝试匹配尽可能多的字符
2、非贪婪匹配
是尝试匹配尽可能少的字符
@# 匹配一个字符串没有节制,能匹配多少就匹配多少,直到匹配完为止
39、求结果: a. [ i % 2 for i in range(10) ] b. ( i % 2 for i in range(10) )
@# a结果是一个列表生成式,结果是一个列表(i % 2为生成的元素): [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
# b结果是一个生成器
40、求结果: a. 1 or 2 b. 1 and 2 c. 1 < (2==2) d. 1 < 2 == 2
41、def func(a,b=[]) 这种写法有什么坑?
@# 函数传参为列表陷阱,列表是可变数据类型,可能会在过程中修改里面的值
42、如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
43、如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
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] ?
46、一行代码实现删除列表中重复的值 ?
47、如何在函数中设置一个全局变量 ?
通过global指定变量,该变量会变成全局变量
48、logging模块的作用?以及应用场景?
可以通过设置不同的日志等级,在release版本中只输出重要信息,而不必显示大量的调试信息;
print将所有信息都输出到标准输出中,严重影响开发者从标准输出中查看其它数据;logging则可以由开发者决定将信息输出到什么地方,以及怎么输出;
@# 作用: 管理我们程序的执行日志,省去用print记录操作日志的操作,并且可以将标准输入输出保存到日志文件# 场景:爬虫爬取数据时,对爬取进行日志记录,方便分析、排错。
49、请用代码简答实现stack 。
50、常用字符串格式化哪几种?
51、简述 生成器、迭代器、可迭代对象 以及应用场景?
# 装饰器:
能够在不修改原函数代码的基础上,在执行前后进行定制操作,闭包函数的一种应用
场景:
- flask路由系统
- flask before_request
- csrf
- django内置认证
- django缓存
# 手写装饰器;import functoolsdef wrapper(func):
@functools.wraps(func)
#不改变原函数属性definner(*args, **kwargs):
执行函数前
returnfunc(*args, **kwargs)
执行函数后
return inner1. 执行wapper函数,并将被装饰的函数当做参数。 wapper(index)2. 将第一步的返回值,重新赋值给 新index = wapper(老index)
@wrapper #index=wrapper(index)def index(x):
returnx+100
# 生成器:一个函数内部存在yield关键字
应用场景:
- rang/xrange
- redis获取值
- conn = Redis(......)
- v=conn.hscan_iter()# 内部通过yield 来返回值- stark组件中
- 前端调用后端的yield
# 迭代器:
内部有__next__和__iter__方法的对象,帮助我们向后一个一个取值,迭代器不一定是生成器
应用场景:
- wtforms里面对form对象进行循环时,显示form中包含的所有字段
- 列表、字典、元组
(可以让一个对象被for循环)
52、用Python实现一个二分查找的函数。
53、谈谈你对闭包的理解?
# 闭包函数就是内部的函数调用外部函数的变量,常用于装饰器。
# 判断闭包函数的方法:__closure__,输出的__closure__有cell元素说明是闭包函数
# 闭包的意义与应用:延迟计算:
54、os和sys模块的作用?
sys模块主要是用于提供对python解释器相关的操作
OS模块是Python标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问
# os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;
# sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python运行环境
55、如何生成一个随机数?
56、如何使用python删除一个文件?
import os
os.remove('文件名以及路径')
57、谈谈你对面向对象的理解?
#封装: 其实就是将很多数据封装到一个对象中,类似于把很多东西放到一个箱子中,
如:一个函数如果好多参数,起始就可以把参数封装到一个对象再传递。
#继承: 如果多个类中都有共同的方法,那么为了避免反复编写,就可以将方法提取到基类中实现,
让所有派生类去继承即可。
#多态:指基类的同一个方法在不同派生类中有着不同功能。python天生支持多态。
58、Python面向对象中的继承有什么特点?
#Python3的继承机制
# 子类在调用某个方法或变量的时候,首先在自己内部查找,如果没有找到,则开始根据继承机制在父类里查找。
# 根据父类定义中的顺序,以深度优先的方式逐一查找父类!继承参数的书写有先后顺序,写在前面的被优先继承。
59、面向对象深度优先和广度优先是什么?
# Python的类可以继承多个类,Python的类如果继承了多个类,那么其寻找方法的方式有两种
当类是经典类时,多继承情况下,会按照深度优先方式查找
当类是新式类时,多继承情况下,会按照广度优先方式查找
简单点说就是:经典类是纵向查找,新式类是横向查找
经典类和新式类的区别就是,在声明类的时候,新式类需要加上object关键字。在python3中默认全是新式类
60、面向对象中super的作用?
主要在子类继承父类的所有属性和方法时来使用
61、是否使用过functools中的函数?其作用是什么?
在装饰器中,会用到;functools.wraps()主要在装饰器中用来装饰函数
Stark上下文管理源码中,走到视图阶段时有用到functools中的偏函数,request = LocalProxy(partial(_lookup_req_object,'request'))
62、列举面向对象中带爽下划线的特殊方法,如:__new__、__init__
63、如何判断是函数还是方法?
# 看他的调用者是谁,如果是类,需要传入参数self,这时就是一个函数;
# 如果调用者是对象,不需要传入参数值self,这时是一个方法。(FunctionType/MethodType)
64、静态方法和类方法区别?
Classmethod必须有一个指向类对象的引用作为第一个参数;
@classmethoddef class_func(cls):
""" 定义类方法,至少有一个cls参数 """print('类方法')
Staticmethod可以没有任何参数。
@staticmethoddef static_func():
""" 定义静态方法 ,无默认参数"""print('静态方法')
65、列举面向对象中的特殊成员以及应用场景
1.__doc__:表示类的描述信息。2.__module__:表示当前操作的对象在那个模块;3.__class__:表示当前操作的对象的类是什么。4.__init__:构造方法,通过类创建对象时,自动触发执行。5.__call__:对象后面加括号,触发执行。6.__dict__:类或对象中的所有成员。7.__str__:如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值。class Foo:
def__str__(self):
return'aaa'obj = Foo()print(obj)# 输出:aaa8.__getitem__、__setitem__、__delitem__:用于索引操作,如字典。以上分别表示获取、设置、删除数据。9.__iter__:用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了__iter__。
66、1、2、3、4、5 能组成多少个互不相同且无重复的三位数
import itertools
print(len(list(itertools.permutations('12345',3))))
#60个
67、什么是反射?以及应用场景?
反射就是以字符串的方式导入模块,以字符串的方式执行函数
# 应用场景:rest framework里面的CBV
68、metaclass作用?以及应用场景?
类的metaclass默认是type。
我们也可以指定类的metaclass值。参考:点击查看
69、用尽量多的方法实现单例模式。
70、装饰器的写法以及应用场景。
# 应用场景- 高阶函数
- 闭包
- 装饰器
- functools.wraps(func)
71、异常处理写法以及如何主动跑出异常(应用场景)
while True:
try:
x = int(input("Please enter a number: "))
breakexcept ValueError:
print("Oops! That was no valid number. Try again ")# raise主动抛出一个异常参考:点击查看
72、什么是面向对象的mro
MRO:方法解析顺序
它定义了 Python 中多继承存在的情况下,解释器查找继承关系的具体顺序
73、isinstance作用以及应用场景?
# 来判断一个对象是否是一个已知的类型。
# 使用isinstance函数还可以来判断'类实例变量'属于哪一个类产生的。
74、写代码并实现:
Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would
have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1]
75、json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
76、json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
import json
a=json.dumps({"xxx":"你好"},ensure_ascii=False)
print(a)#{"xxx": "你好"}
77、什么是断言?应用场景?
#条件成立则继续往下,否则抛出异常;
#一般用于:满足某个条件之后,才能执行,否则应该抛出异常。'
应用场景':rest framework中GenericAPIView类里,要设置queryset,否则断言错误
78、有用过with statement吗?它的好处是什么?
with语句适用于对资源进行访问的场合,确保不管使用过程中是否发生异常都会执行必要的“清理”操作,释放资源,比如文件使用后自动关闭、线程中锁的自动获取和释放等。
79、使用代码实现查看列举目录下的所有文件。
import os
path = os.listdir('.') #查看列举目录下的所有文件。
path = os.listdir(os.getcwd())
print(path)
80、简述 yield和yield from关键字。
1、yield使用
(1)函数中使用yield,可以使函数变成生成器。一个函数如果是生成一个数组,就必须把数据存储在内存中,如果使用生成器,则在调用的时候才生成数据,可以节省内存。
(2)生成器方法调用时,不会立即执行。需要调用next()或者使用for循环来执行。
2、yield from的使用
(1)为了让生成器(带yield函数),能简易的在其他函数中直接调用,就产生了yieldfrom。 参考:点击查看
第二部分 网络编程和并发(34题)
1、简述 OSI 七层协议。
物理层:主要基于电器特性发送高低电压(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的区别?
#TCP协议:面向连接- 通信之前先三次握手
- 断开之前先四次握手
- 必须先启动服务端,再启动客户端-->连接服务端
- 安全、可靠、面向连接(不会丢包)#UDP协议:无连接- 传输速度快
- 先启动哪一端都可以
- 不面向连接,不能保证数据的完整性(如:QQ聊天)
6、什么是局域网和广域网?
局域网和广域网是按规模大小而划分的两种计算机网络。#范围在几千米以内的计算机网络统称为局域网(LAN、私网、内网);#而连接的范围超过10千米的,则称为广域网,因特网(Intenet)就是目前最大的广域网(WAN、公网、外网)。
7、为何基于tcp协议的通信比基于udp协议的通信更可靠?
因为TCP是面向连接的
通信之前先三次握手,通过握手,确保连接成功之后再通信
断开之前先四次挥手;双方互相确认之后再断开连接,这样一来保证了数据的安全、可靠,避免丢包
8、什么是socket?简述基于tcp协议的套接字通信流程。
#服务端: 创建套接字
绑定IP和端口
监听
accept等待连接
通信(收recv、发send)#客户端: 创建套接字
绑定IP和端口
链接服务器
通信(收revc、发send)
9、什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象?
粘包:数据粘在一起,主要因为:接收方不知道消息之间的界限,不知道一次性提取多少字节的数据造成的
数据量比较小,时间间隔比较短,就合并成了一个包,这是底层的一个优化算法(Nagle算法)
10、IO多路复用的作用?
# IO多路复用分为时间上的复用和空间上的复用,# 空间上的复用是指将内存分为几部分,每一部分放一个程序,这样同一时间内存中就有多道程序;# 时间上的复用是指多个程序需要在一个cpu上运行,不同的程序轮流使用cpu,# 当某个程序运行的时间过长或者遇到I/O阻塞,操作系统会把cpu分配给下一个程序,# 保证cpu处于高使用率,实现伪并发。
11、什么是防火墙以及作用?
# 什么是防火墙?防火墙是一个分离器,一个限制器,也是一个分析器,
有效地监控了内部网和Internet之间的任何活动,保证了内部网络的安全。# 作用防火墙可通过监测、限制、更改跨越防火墙的数据流,
尽可能地对外部屏蔽网络内部的信息、结构和运行状况,以此来实现网络的安全保护。
12、select、poll、epoll 模型的区别?
# select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:# 1.单个进程可监视的fd数量被限制# 2.需要维护一个用来存放大量fd的数据结构# 这样会使得用户空间和内核空间在传递该结构时复制开销大# 3.对socket进行扫描时是线性扫描# poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,# 它没有最大连接数的限制,原因是它是基于链表来存储的但是同样有一个缺点:# 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。# epoll支持水平触发和边缘触发,最大的特点在于边缘触发,# 它只告诉进程哪些fd刚刚变为就需态,并且只会通知一次。
13、简述 进程、线程、协程的区别 以及应用场景?
# 进程进程拥有自己独立的堆和栈,既不共享堆,亦不共享栈,进程由操作系统调度。# 线程线程拥有自己独立的栈和共享的堆,共享堆,不共享栈,线程亦由操作系统调度# 协程和线程的区别协程避免了无意义的调度,由此可以提高性能;但同时协程也失去了线程使用多CPU的能力。
14、GIL锁是什么鬼?
# GIL线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采取的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.
对于io密集型任务,python的多线程起到作用,但对于cpu密集型任务,
python的多线程几乎占不到任何优势,还有可能因为争夺资源而变慢。
解决办法就是多进程和下面的协程(协程也只是单CPU,但是能减小切换代价提升性能).
15、Python中如何使用线程池和进程池?
进程池:就是在一个进程内控制一定个数的线程基于concurent.future模块的进程池和线程池 (他们的同步执行和异步执行是一样的)参考:点击查看
16、threading.local的作用?
show
17、进程之间如何进行通信?
# 进程间通讯有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等
18、什么是并发和并行?
# 并发:同一时刻只能处理一个任务,但一个时段内可以对多个任务进行交替处理(一个处理器同时处理多个任务)# 并行:同一时刻可以处理多个任务(多个处理器或者是多核的处理器同时处理多个不同的任务)# 类比:并发是一个人同时吃三个馒头,而并行是三个人同时吃三个馒头。
19、进程锁和线程锁的作用?
线程锁: 大家都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法 /代码块时,同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,其余线程是可以访问该对象中的非加锁代码块的。进程锁: 也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制(操作系统基本知识)。分布式锁: 当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。参考:点击查看
20、解释什么是异步非阻塞?
'非阻塞':
遇到IO阻塞不等待(setblooking=False),(可能会报错->捕捉异常)
- sk=socket.socket()
- sk.setblooking(False)'异步':
回调(ajax),当达到某个指定状态之后,自动调用特定函数
21、路由器和交换机的区别?
'交换机'用于在同一网络内数据快速传输转发,工作在数据链路层;
通过MAC寻址,不能动态划分子网;
只能在一条网络通路中运行,不能动态分配。'路由器'是一个网关设备,内部局域网到公网的一个关卡;
工作在网络层;
通过IP寻址,可以划分子网;
可以在多条网络通道中运行,可以动态分配IP地址。'简单说'交换机就是把一根网线变成多根网线;
路由器就是把一个网络变成多个网络;
如果不上外网,只是局域网,交换机即可;
如果上外网,并且给网络划分不同网段,就必须用路由器。
22、什么是域名解析?
# 在网上,所有的地址都是ip地址,但这些ip地址太难记了,所以就出现了域名(比如http://baidu.com)。# 而域名解析就是将域名,转换为ip地址的这样一种行为。# 例如:访问www.baidu.com,实质是把域名解析成IP。
23、如何修改本地hosts文件?
'hosts':
Hosts就是将一些常用的网址域名与其对应的IP地址建立一个关联“数据库”
可以用来屏蔽一些网站,或者指定一些网站(修改hostsFQ)'修改':
# windows: 位置:C:\Windows\System32\drivers\etc
也可以通过第三方软件,我用的火绒,可以直接进行编辑hosts
# linux:位置:/etc/hosts
修改:vi /etc/hosts
24、生产者消费者模型应用场景及优势?
# 处理数据比较消耗时间,线程独占,生产数据不需要即时的反馈等。
25、什么是cdn?
# 用户获取数据时,不需要直接从源站获取,通过CDN对于数据的分发,# 用户可以从一个较优的服务器获取数据,从而达到快速访问,并减少源站负载压力的目的。
26、LVS是什么及作用?
# LVS即Linux虚拟服务器,是一个虚拟的四层交换器集群系统,# 根据目标地址和目标端口实现用户请求转发,本身不产生流量,只做用户请求转发。
27、Nginx是什么及作用?
Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。参考1:点击查看参考2:点击查看
28、keepalived是什么及作用?
Keepalived是Linux下一个轻量级别的高可用解决方案。高可用,其实两种不同的含义:广义来讲,是指整个系统的高可用行,狭义的来讲就是之主机的冗余和接管,参考:点击查看
29、haproxy是什么以及作用?
HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代 理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进您当前的架中, 同时可以保护你的web服务器不被暴露到网络上。参考:点击查看
30、什么是负载均衡?
负载均衡有两方面的含义:# 首先,大量的并发访问或数据流量分担到多台节点设备上分别处理,减少用户等待响应的时间;# 其次,单个重负载的运算分担到多台节点设备上做并行处理,每个节点设备处理结束后,将结果汇总,返回给用户,系统处理能力得到大幅度提高。
31、什么是rpc及应用场景?
RPC 的全称是 Remote Procedure Call 是一种进程间通信方式。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的,本质上编写的调用代码基本相同(例如QQ远程操作)参考:点击查看
32、简述 asynio模块的作用和应用场景。
asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。asyncio的异步操作,需要在coroutine中通过yield from完成。参考:点击查看
33、简述 gevent模块的作用和应用场景。
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被协作式地调度。 参考:点击查看
34、twisted框架的使用和应用?
Twisted是一个事件驱动型的网络模型。时间驱动模型编程是一种范式,这里程序的执行流由外部决定。特点是:包含一个事件循环,当外部事件发生时,使用回调机制来触发相应的处理。参考:点击查看
第三部分 数据库和缓存(46题)
1、列举常见的关系型数据库和非关系型都有那些?
'关系型':
# sqllite、db2、oracle、access、SQLserver、MySQL# 注意:sql语句通用,需要有表结构'非关系型':
# mongodb、redis、memcache# 非关系型数据库是key-value存储的,没有表结构。
2、MySQL常见数据库引擎及比较?
'Myisam':# 支持全文索引# 查询速度相对较快# 支持表锁# 表锁:select * from tb for update;(锁:for update)'InnoDB':# 支持事务# 支持行锁、表锁# 表锁:select * from tb for update;(锁:for update)# 行锁: select id ,name from tb where id=2 for update;(锁:for update)
3、简述数据三大范式?
# 数据库的三大特性:'实体':表'属性':表中的数据(字段)'关系':表与表之间的关系----------------------------------------------------# 数据库设计三大范式:'第一范式(1NF)' 数据表中的每一列(每个字段),必须是不可拆分的最小单元
也就是确保每一列的原子性。'第二范式(2NF)' 满足第一范式后(1NF),要求表中的所有列,都必须依赖于主键,
而不能有任何一列 与主键没有关系,也就是说一个表只描述一件事。'第三范式(3NF)' 必须先满足第二范式(2NF)
要求:表中每一列只与主键直接相关而不是间接相关(表中每一列只能依赖于主键)
4、什么是事务?MySQL如何支持事务?
'什么是事务' 事务由一个或多个sql语句组成一个整体;
在事务中的操作,要么都执行修改,要么都不执行,
只有在该事务中所有的语句都执行成功才会将修改加入到数据库中,否则回滚到上一步。'Mysql实现事务' InnoDB支持事务,MyISAM不支持
# 启动事务:# start transaction;# update from account set money=money-100 where name='a';# update from account set money=money+100 where name='b';# commit;'start transaction 手动开启事务,commit 手动关闭事务'
5、数据库五大约束
'数据库五大约束'1.primary KEY:设置主键约束;
2.UNIQUE:设置唯一性约束,不能有重复值;
3.DEFAULT 默认值约束
4.NOT NULL:设置非空约束,该字段不能为空;
5.FOREIGN key :设置外键约束。
6、简述数据库设计中一对多和多对多的应用场景?
# 一对一关系示例:一个学生对应一个学生档案材料,或者每个人都有唯一的身份证编号。# 一对多关系示例:(下拉单选)一个学生只属于一个班,但是一个班级有多名学生。# 多对多关系示例:(下拉多选)一个学生可以选择多门课,一门课也有多名学生。
7、如何基于数据库实现商城商品计数器?
参考:点击查看
8、常见SQL(必备)
详见:点击查看
9、简述触发器、函数、视图、存储过程?
'触发器':
对数据库某个表进行【增、删、改】前后,自定义的一些SQL操作'函数':
在SQL语句中使用的函数 #例如:select sleep(2) 聚合函数:max、sam、min、avg
时间格式化:date_format
字符串拼接:concat
自定制函数:(触发函数通过 select)'视图':
对某些表进行SQL查询,将结果实时显示出来(是虚拟表),只能查询不能更新'存储过程':
将提前定义好的SQL语句保存到数据库中并命名;以后在代码中调用时直接通过名称即可
参数类型:in、out、inout
10、MySQL索引种类
'主键索引(单列)':
primary key
加速查找+约束:不能重复、不能为空'普通索引(单列)':
加速查找'唯一索引(单列)':
unique
加速查找+约束:不能重复'联合索引(多列)':
查询时根据多列进行查询(最左前缀)'联合唯一索引(多列)':
遵循最左前缀规则(命中索引)# 其他词语1、索引合并:利用多个单列索引查询
2、覆盖索引:在索引表中就能将想要的数据查询到
11、索引在什么情况下遵循最左前缀的规则?
你可以认为联合索引是闯关游戏的设计
例如你这个联合索引是state/city/zipCode那么state就是第一关 city是第二关, zipCode就是第三关你必须匹配了第一关,才能匹配第二关,匹配了第一关和第二关,才能匹配第三关你不能直接到第二关的索引的格式就是第一层是state,第二层才是city参考:点击查看
12、主键和外键的区别?
'主键' 唯一标识一条记录
用来保证数据的完整性
主键只能有一个'外键' 表的外键是另一个表的主键,外键可以有重复的,可以是空值
用来和其他表建立联系用的
一个表可以有多个外键'索引' 该字段没有重复值,但可以有一个空值
提高查询速度
一个表可以有多个唯一索引
13、MySQL常见的函数?
'当前时间' select now();'时间格式化' select DATE_FORMAT(NOW(), '%Y(年)-%m(月)-%d(日) %H(时):%i(分):%s(秒)')'日期加减' select DATE_ADD(DATE, INTERVAL expr unit)
select DATE_ADD(NOW(), INTERVAL 1 DAY)#当前日期加一天 \expr:正数(加)、负数(减)
\unit:支持毫秒microsecond、秒second、小时hour、天day、周week、年year'类型转换' cast( expr AS TYPE)
select CAST(123 AS CHAR)'字符串拼接' concat(str1,str2,……)
select concat('hello','2','world') --> hellow2world'聚合函数' avg() #平均值count()#返回指定列/行的个数min()#最小值max()#最大值sum()#求和group_concat()#返回属于一组的列值,连接组合而成的结果'数学函数' abs() #绝对值bin()#二进制rand()#随机数
14、列举 创建索引但是无法命中索引的8种情况。
#使用'like ‘%xx’'select *fromtb1 where name like'%cn';#使用'函数'select *fromtb1 where reverse(name)='zgc';#使用'or'select *fromtb1 where nid=1oremail='zgc@gmial.com';
特别的:当or条件中有未建立索引的列才失效,一下会走索引
# select * from tb1 where nid=1 or name='zgc';# select * from tb1 where nid=1 or email='zgc@gmial.com' and name='zgc';#'类型不一致' 如果列是字符串类型,传入条件是必须用引号引起来,不然则可能会无法命中
select *fromtb1 where name=666;#含有'!= 'select *fromtb1 where name !='zgc';
特别的:如果是主键,还是会走索引
# select * from tb1 where nid != 123;#含有'>'select *fromtb1 where name >'zgc';
特别的:如果是主键或者索引是整数类型,则还是会走索引
# select * from tb1 where nid > 123;# select * from tb1 where name > 123;#含有'order by'select emailfrom tb1 order by name desc;
当根据索引排序时,选择的映射如果不是索引,则不走索引
特别的:如果对主键排序,则还是走索引:
# select * from tb1 order by nid desc;#组合索引最左前缀 如果组合索引为:(name,email)
name andemail#使用索引name#使用索引email#不使用索引
15、如何开启慢日志查询?
'可以通过修改配置文件开启'slow_query_log=ON#是否开启慢日志记录long_query_time=2#时间限制,超过此时间,则记录slow_query_log_file=/usr/slow.log#日志文件long_queries_not_using_indexes=ON#是否记录使用索引的搜索
16、数据库导入导出命令(结构+数据)?
#导出:mysqldump --no-defaults -uroot -p 数据库名字 > 导出路径
'--no-defaults':解决“unknown option --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 *from db.tb
\ORM:model.User.object.all().using('default')
\路由:db router7、分库
# 当数据库中的表太多,将某些表分到不同数据库,例如:1W张表时# 代价:连表查询跨数据库,代码变多8、分表
# 水平分表:将某些列拆分到另一张表,例如:博客+博客详情# 垂直分表:将某些历史信息,分到另外一张表中,例如:支付宝账单9、加缓存
# 利用redis、memcache(常用数据放到缓存里,提高取数据速度)# 缓存不够可能会造成雪崩现象10、如果只想获取一条数据
select *fromtb where name ='zgc'limit 1;
18、char和varchar的区别?
#char类型:定长不可变存入字符长度大于设置长度时报错;
存入字符串长度小于设置长度时,用空格填充以达到设置字符串长度;
简单粗暴,浪费空间,存取速度快。#varchar类型:可变存储数据真实内容,不使用空格填充;
会在真实数据前加1-2Bytes的前缀,用来表示真实数据的bytes字节数;
边长、精准、节省空间、存取速度慢。
19、简述MySQL的执行计划?
# explain + SQL语句# SQL在数据库中执行时的表现情况,通常用于SQL性能分析,优化等场景。'explain select * from rbac_userinfo where id=1;'
20、在对name做了唯一索引前提下,简述以下区别:
select *fromtb where name = ‘小明’
select *fromtb where name = ‘小明’ limit 1-------------------------------------------------------------没做唯一索引的话,前者查询会全表扫描,效率低些
limit 1,只要找到对应一条数据,就不继续往下扫描.
然而 name 字段添加唯一索引了,加不加limit 1,意义都不大;
21、1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
# 例如:#limit 100000,20; 从第十万条开始往后取二十条,#limit 20 offset 100000; limit后面是取20条数据,offset后面是从第10W条数据开始读因为当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢--------------------------------------------------------------------------'优化一'先查看主键,再分页:
select *fromtb where idin(select idfromtb where limit 10 offset 30)--------------------------------------------------------------------------'优化二'记录当前页,数据、ID、最大值和最小值(用于where查询)
在翻页时,根据条件进行筛选,筛选完毕后,再根据 limit offset 查询
select *from(select *fromtb where id > 2222) as B limit 10 offset 0;
\如果用户自己修改页码,也可能导致变慢,此时可以对 url 页码进行加密,例如rest framework--------------------------------------------------------------------------'优化三'可以按照当前业务需求,看是否可以设置只允许看前200页;
一般情况下,没人会咔咔看个几十上百页的;
22、什么是索引合并?
# 索引合并访问方法可以在查询中对一个表使用多个索引,对它们同时扫描,并且合并结果。# 此访问方法合并来自单个表的索引扫描; 它不会将扫描合并到多个表中。
23、什么是覆盖索引?
# 解释一:就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。# 解释二:索引是高效找到行的一个方法,当能通过检索索引就可以读取想要的数据,那就不需要再到数据表中读取行了。
如果一个索引包含了(或覆盖了)满足查询语句中字段与条件的数据就叫做覆盖索引。# 注意:MySQL只能使用B-Tree索引做覆盖索引
24、简述数据库读写分离?
#利用数据库的主从分离:主,用于删除、修改、更新;从,用于查#实现:两台服务器同步数据(减轻服务器的压力)原生SQL: select *from db.tb
ORM:model.User.object.all().using('default')
路由:db router
25、简述数据库分库分表?(水平、垂直)
# 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> SELECT 1# 注意: 多个数据库之间并不是完全隔离的
比如FLUSHALL命令可以清空一个Redis实例中所有数据库中的数据。
28、python操作redis的模块?
参考:点击查看
29、如果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配置文件中,添加以下内容:
slaveof 127.0.0.1 6379# 数据同步步骤:(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中写值时:set k1 123 - 将k1通过crc16的算法转换成一个数字,然后再将该数字和16384求余,
- 如果得到的余数 3000,那么就将该值写入到 192.168.1.20 实例中。#集群方案:- redis cluster:官方提供的集群方案。
- codis:豌豆荚技术团队。
- tweproxy:Twiter技术团队。
33、redis中默认有多少个哈希槽?
#redis中默认有16384个哈希槽。
34、简述redis的有哪几种持久化策略及比较?
#RDB:每隔一段时间对redis进行一次持久化。- 缺点:数据不完整
- 优点:速度快#AOF:把所有命令保存起来,如果想重新生成到redis,那么就要把命令重新执行一次。- 缺点:速度慢,文件比较大
- 优点:数据完整
35、列举redis支持的过期策略。
# 数据集(server.db[i].expires)a、voltile-lru:#从已设置过期时间的数据集中,挑选最近频率最少数据淘汰b、volatile-ttl:#从已设置过期时间的数据集中,挑选将要过期的数据淘汰c、volatile-random:#从已设置过期时间的数据集中,任意选择数据淘汰d、allkeys-lru:#从数据集中,挑选最近最少使用的数据淘汰e、allkeys-random:#从数据集中,任意选择数据淘汰f、no-enviction(驱逐):#禁止驱逐数据
36、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据?
# 限定Redis占用的内存,根据自身数据淘汰策略,淘汰冷数据,把热数据加载到内存。# 计算一下 20W 数据大约占用的内存,然后设置一下Redis内存限制即可。
37、写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。
38、如何基于redis实现消息队列?
# 通过发布订阅模式的PUB、SUB实现消息队列# 发布者发布消息到频道了,频道就是一个消息队列。# 发布者:import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
conn.publish('104.9MH',"hahahahahaha")# 订阅者:import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
pub = conn.pubsub()
pub.subscribe('104.9MH')while True:
msg= pub.parse_response()
print(msg)
对了,redis 做消息队列不合适
业务上避免过度复用一个redis,用它做缓存、做计算,还做任务队列,压力太大,不好。
39、如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?
# 发布和订阅,只要有任务就所有订阅者每人一份。发布者:#发布一次import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
conn.publish('104.9MH',"hahahahahaha")
订阅者: #'while True'一直在接收import redis
conn = redis.Redis(host='127.0.0.1',port=6379)
pub = conn.pubsub()
pub.subscribe('104.9MH')
while True:
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事务操作。
import redis
pool = 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实现'import redis
conn = redis.Redis(host='127.0.0.1',port=6379)# conn.set('count',1000)val = conn.get('count')print(val)
with conn.pipeline(transaction=True) as pipe:
# 先监视,自己的值没有被修改过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的实现机制。
# redis分布式锁?# 不是单机操作,又多了一/多台机器# redis内部是单进程、单线程,是数据安全的(只有自己的线程在操作数据)----------------------------------------------------------------#A、B、C,三个实例(主)1、来了一个'隔壁老王'要操作,且不想让别人操作,so,加锁;
加锁:'隔壁老王'自己生成一个随机字符串,设置到A、B、C里(xxx=666)2、来了一个'邻居老李'要操作A、B、C,一读发现里面有字符串,擦,被加锁了,不能操作了,等着吧~3、'隔壁老王'解决完问题,不用锁了,把A、B、C里的key:'xxx'删掉;完成解锁4、'邻居老李'现在可以访问,可以加锁了# 问题:1、如果'隔壁老王'加锁后突然挂了,就没人解锁,就死锁了,其他人干看着没法用咋办?2、如果'隔壁老王'去给A、B、C加锁的过程中,刚加到A,'邻居老李'就去操作C了,加锁成功or失败?3、如果'隔壁老王'去给A、B、C加锁时,C突然挂了,这次加锁是成功还是失败?4、如果'隔壁老王'去给A、B、C加锁时,超时时间为5秒,加一个锁耗时3秒,此次加锁能成功吗?# 解决1、安全起见,让'隔壁老王'加锁时设置超时时间,超时的话就会自动解锁(删除key:'xxx')2、加锁程度达到(1/2)+1个就表示加锁成功,即使没有给全部实例加锁;3、加锁程度达到(1/2)+1个就表示加锁成功,即使没有给全部实例加锁;4、不能成功,锁还没加完就过期,没有意义了,应该合理设置过期时间# 注意使用需要安装redlock-py----------------------------------------------------------------fromredlockimport Redlock
dlm = Redlock(
[
{"host":"localhost","port": 6379,"db": 0},
{"host":"localhost","port": 6379,"db": 0},
{"host":"localhost","port": 6379,"db": 0},
]
)# 加锁,acquiremy_lock = dlm.lock("my_resource_name",10000)if my_lock:
# 进行操作# 解锁,release dlm.unlock(my_lock)else:
print('获取锁失败')#通过sever.eval(self.unlock_script)执行一个lua脚本,用来删除加锁时的key
46、什么是一致性哈希?Python中是否有相应模块?
# 一致性哈希一致性hash算法(DHT)可以通过减少影响范围的方式,解决增减服务器导致的数据散列问题,从而解决了分布式环境下负载均衡问题;
如果存在热点数据,可以通过增添节点的方式,对热点区间进行划分,将压力分配至其他服务器,重新达到负载均衡的状态。# 模块:hash_ring
47、如何高效的找到redis中所有以zhugc开头的key?
redis 有一个keys命令。# 语法:KEYS pattern# 说明:返回与指定模式相匹配的所用的keys。该命令所支持的匹配模式如下:1、?:用于匹配单个字符。例如,h?llo可以匹配hello、hallo和hxllo等;2、*:用于匹配零个或者多个字符。例如,h*llo可以匹配hllo和heeeello等;2、[]:可以用来指定模式的选择区间。例如h[ae]llo可以匹配hello和hallo,但是不能匹配hillo。同时,可以使用“/”符号来转义特殊的字符# 注意KEYS 的速度非常快,但如果数据太大,内存可能会崩掉,
如果需要从一个数据集中查找特定的key,最好还是用Redis的集合结构(set)来代替。
48、悲观锁和乐观锁的区别?
# 悲观锁 从数据开始更改时就将数据锁住,直到更改完成才释放;
会造成访问数据库时间较长,并发性不好,特别是长事务。# 乐观锁 直到修改完成,准备提交修改到数据库时才会锁住数据,完成更改后释放;
相对悲观锁,在现实中使用较多。
第四部分 前端、框架和其他(155题)
1、谈谈你对http协议的认识。
# 通过/r/n分割
# 请求头请求体之间:/r/n/r/n
# 无状态# 短连接
2、谈谈你对websocket协议的认识。
# a.什么是websocket? 是给浏览器新建的一套协议
协议规定:创建连接后不断开
通过'\r\n'分割,让客户端和服务端创建连接后不断开、验证+数据加密#
b.本质:
# 就是一个创建连接后不断开的socket# 当连接成功后:- 客户端(浏览器)会自动向服务端发送消息
- 服务端接收后,会对该数据加密:base64(sha1(swk+magic_string))
- 构造响应头
- 发送给客户端
# 建立双工通道,进行收发数据
# c.框架中是如何使用websocket的?
django:channel
flask:gevent-websocket
tornado:内置
# d.websocket的优缺点
优点:代码简单,不再重复创建连接
缺点:兼容性没有长轮询好,如IE会有不兼容
3、什么是magic string ?
websocket里面的# 客户端向服务端发送消息时,会有一个'sec-websocket-key'和'magic string'的随机字符串(魔法字符串)# 服务端接收到消息后会把他们连接成一个新的key串,进行编码、加密,确保信息的安全性
4、如何创建响应式布局?
# a.可以通过引用Bootstrap实现
# b.通过看Bootstrap源码文件,可知其本质就是通过CSS实现的
/*浏览器窗口宽度大于768,背景色变为 green*/ @media (min-width: 768px) { .pg-header{
background-color: green;} }
/*浏览器窗口宽度大于992,背景色变为 pink*/ @media (min-width: 992px) { .pg-header{
background-color: pink;} }
5、你曾经使用过哪些前端框架?
# Jquery、Vue、Bootstrap、
6、什么是ajax请求?并使用jQuery和XMLHttpRequest对象实现一个ajax请求。
1.没用ajax:浏览器访问服务器请求,用户看得到(页面刷新也就等同于重新发请求,刷新看得到,也就等同于请求看得到)。等请求完,页面刷新,新内容出现,用户看到新内容。2.用ajax:浏览器访问服务器请求,用户看不到,是悄悄进行。等请求完,页面不刷新,新内容也会出现,用户看到新内容。参考:点击查看
7、如何在前端实现轮询?
# 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,# 然后由服务器返回最新的数据给客户端的浏览器。var xhr = new XMLHttpRequest();
setInterval(function(){
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
};
xhr.send();
},1000)
8、如何在前端实现长轮询?
# ajax实现:在发送ajax后,服务器端会阻塞请求直到有数据传递或超时才返回。 # 客户端JavaScript响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。 function ajax(){
var xhr = new XMLHttpRequest();
xhr.open('GET','/user');
xhr.onreadystatechange = function(){
ajax();
};
xhr.send();
}
9、vuex的作用?
1.不同组件之间共享状态,可以进行状态的修改和读取。2.可以理解为是一个全局对象,所有页面都可以访问3.还有比较重要的单一状态树管理,让数据的修改脉络更加清晰,便于定位问题。# 比如用户做了一些加减的操作、三个页面都要用、可以用传参、但是很麻烦、这种时候用vuex就简单一些
10、vue中的路由的拦截器的作用?
# 统一处理所有http请求和响应时,可以用axios的拦截器。# 通过配置http response inteceptor,当后端接口返回401 Unauthorized(未授权),让用户重新登录。# so可以用来做登录拦截验证
11、axios的作用?
# axios是vue-resource后出现的Vue请求数据的插件# 可以做的事情: 从浏览器中创建 XMLHttpRequest
从 node.js 发出 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据
客户端支持防止 CSRF/XSRF
12、列举vue的常见指令。
# 1、v-if指令:判断指令,根据表达式值得真假来插入或删除相应的值。# 2、v-show指令:# 条件渲染指令,无论返回的布尔值是true还是false,元素都会存在html中,# false的元素会隐藏在html中,并不会删除.# 3、v-else指令:配合v-if或v-else使用。# 4、v-for指令:循环指令,相当于遍历。# 5、v-bind:给DOM绑定元素属性。# 6、v-on指令:监听DOM事件。
13、简述jsonp及实现原理?
# 原理:1、先在客户端注册一个callback, 然后把callback的名字传给服务器。
2、此时,服务器先生成 json 数据。
3、然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
4、最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,
传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数) # 注意# JSON 是一种数据格式# JSONP 是一种数据调用的方式
14、是什么cors ?
# 跨域资源共享(Cross-Origin Resource Sharing)# 其本质是设置响应头,使得浏览器允许跨域请求。# 简单请求(一次请求)1、请求方式:HEAD、GET、POST2、请求头信息:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type 对应的值是以下三个中的任意一个
application/x-www-form-urlencoded
multipart/form-data
text/plain# 非简单请求(两次请求)在发送真正的请求之前,会默认发送一个'options'请求,做'预检',预检成功后才发送真正的请求
# 预检: 如果复杂请求是PUT等请求,则服务端需要设置允许某请求,否则“预检”不通过
Access-Control-Request-Method
如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则“预检”不通过
Access-Control-Request-Headers
15、列举Http请求中常见的请求方式?
# http请求方法有8种:'GET''POST''HEAD''OPTIONS''PUT''DELETE''TRACE''CONNECT'
16、列举Http请求中的状态码?
# 2开头(成功)200:请求成功
202:已接受请求,尚未处理
204:请求成功,且不需返回内容# 3开头(重定向)301:永久重定向
302:临时重定向# 4开头(客户端错误)400(Bad Request):请求的语义或是参数有错
403(Forbidden):服务器拒绝了请求(csrf)
404(Not Found):找不到页面(资源)# 5开头(服务器错误)500:服务器遇到错误,无法完成请求
502:网关错误,一般是服务器压力过大导致连接超时
503:服务器宕机
17、列举Http请求中常见的请求头?
# 常见请求头:User-Agent、Referer、Host、Cookie、Connection、Accept
18、看图写结果:
19、看图写结果:
20、看图写结果:
21、看图写结果:
22、看图写结果:
23、看图写结果:
24、django、flask、tornado框架的比较?
25、什么是wsgi?
26、django请求的生命周期?
27、列举django的内置组件?
28、列举django中间件的5个方法?以及django中间件的应用场景?
29、简述什么是FBV和CBV?
30、django的request对象是在什么时候创建的?
31、如何给CBV的程序添加装饰器?
32、列举django orm 中所有的方法(QuerySet对象的所有方法)
33、only和defer的区别?
34、select_related和prefetch_related的区别?
35、filter和exclude的区别?
36、列举django orm中三种能写sql语句的方法。
37、django orm 中如何设置读写分离?
38、F和Q的作用?
39、values和values_list的区别?
40、如何使用django orm批量创建数据?
41、django的Form和ModeForm的作用?
42、django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新。
43、django的Model中的ForeignKey字段中的on_delete参数有什么作用?
44、django中csrf的实现机制?
45、django如何实现websocket?
46、基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token?
47、django中如何实现orm表中添加数据时创建一条日志记录。
48、django缓存如何设置?
49、django的缓存能使用redis吗?如果可以的话,如何配置?
50、django路由系统中name的作用?
51、django的模板中filter和simple_tag的区别?
52、django-debug-toolbar的作用?
53、django中如何实现单元测试?
54、解释orm中 db first 和 code first的含义?
55、django中如何根据数据库表生成model中的类?
56、使用orm和原生sql的优缺点?
57、简述MVC和MTV
58、django的contenttype组件的作用?
59、谈谈你对restfull 规范的认识?
60、接口的幂等性是什么意思?
61、什么是RPC?
62、Http和Https的区别?
63、为什么要使用django rest framework框架?
64、django rest framework框架中都有那些组件?
65、django rest framework框架中的视图都可以继承哪些类?
66、简述 django rest framework框架的认证流程。
67、django rest framework如何实现的用户访问频率控制?
68、Flask框架的优势?
69、Flask框架依赖组件?
70、Flask蓝图的作用?
71、列举使用过的Flask第三方组件?
72、简述Flask上下文管理流程?
73、Flask中的g的作用?
74、Flask中上下文管理主要涉及到了那些相关的类?并描述类主要作用?
75、为什么要Flask把Local对象中的的值stack 维护成一个列表?
76、Flask中多app应用是怎么完成?
77、在Flask中实现WebSocket需要什么组件?
78、wtforms组件的作用?
79、Flask框架默认session处理机制?
80、解释Flask框架中的Local对象和threading.local对象的区别?
81、Flask中 blinker 是什么?
82、SQLAlchemy中的 session和scoped_session 的区别?
83、SQLAlchemy如何执行原生SQL?
84、ORM的实现原理?
85、DBUtils模块的作用?
86、以下SQLAlchemy的字段是否正确?如果不正确请更正:
87、SQLAchemy中如何为表设置引擎和字符编码?
88、SQLAchemy中如何设置联合唯一索引?
89、简述Tornado框架的特点。
90、简述Tornado框架中Future对象的作用?
91、Tornado框架中如何编写WebSocket程序?
92、Tornado中静态文件是如何处理的?如:
93、Tornado操作MySQL使用的模块?
94、Tornado操作redis使用的模块?
95、简述Tornado框架的适用场景?
96、git常见命令作用:
97、简述以下git中stash命令作用以及相关其他命令。
98、git 中 merge 和 rebase命令 的区别。
99、公司如何基于git做的协同开发?
100、如何基于git实现代码review?
101、git如何实现v1.0 、v2.0 等版本的管理?
102、什么是gitlab?
103、github和gitlab的区别?
104、如何为github上牛逼的开源项目贡献代码?
105、git中 .gitignore文件的作用?
106、什么是敏捷开发?
107、简述 jenkins 工具的作用?
108、公司如何实现代码发布?
109、简述 RabbitMQ、Kafka、ZeroMQ的区别?
110、RabbitMQ如何在消费者获取任务后未处理完前就挂掉时,保证数据不丢失?
111、RabbitMQ如何对消息做持久化?
112、RabbitMQ如何控制消息被消费的顺序?
113、以下RabbitMQ的exchange type分别代表什么意思?如:fanout、direct、topic。
114、简述 celery 是什么以及应用场景?
115、简述celery运行机制。
116、celery如何实现定时任务?
117、简述 celery多任务结构目录?
118、celery中装饰器 @app.task 和 @shared_task的区别?
119、简述 requests模块的作用及基本使用?
120、简述 beautifulsoup模块的作用及基本使用?
121、简述 seleninu模块的作用及基本使用?
122、scrapy框架中各组件的工作流程?
123、在scrapy框架中如何设置代理(两种方法)?
124、scrapy框架中如何实现大文件的下载?
125、scrapy中如何实现限速?
126、scrapy中如何实现暂定爬虫?
127、scrapy中如何进行自定制命令?
128、scrapy中如何实现的记录爬虫的深度?
129、scrapy中的pipelines工作原理?
130、scrapy的pipelines如何丢弃一个item对象?
131、简述scrapy中爬虫中间件和下载中间件的作用?
132、scrapy-redis组件的作用?
133、scrapy-redis组件中如何实现的任务的去重?
134、scrapy-redis的调度器如何实现任务的深度优先和广度优先?
135、简述 vitualenv 及应用场景?
136、简述 pipreqs 及应用场景?
137、在Python中使用过什么代码检查工具?
138、简述 saltstack、ansible、fabric、puppet工具的作用?
# Saltstack是一个服务器集中管理中心平台,可以帮助管理员轻松的对若干台服务器进行统一操作。
# 类似的工具还有Ansible,Puppet,func等等。相比于这些工具,salt的特点在于其用python实现,支持各种操作系统类型,采取了C/S架构,部署方便简单, 且可扩展性很强。
# SaltStack 采用 C/S模式,server端就是salt的master,client端就是minion,minion与master之间通过ZeroMQ消息队列通信
# minion上线后先与master端联系,把自己的pub key发过去,这时master端通过salt-key -L命令就会看到minion的key,接受该minion-key后,也就是master与minion已经互信
139、B Tree和B+ Tree的区别?
140、请列举常见排序并通过代码实现任意三种。
141、请列举常见查找并通过代码实现任意三种。
142、请列举你熟悉的设计模式?
143、有没有刷过leetcode?
144、列举熟悉的的Linux命令。
145、公司线上服务器是什么系统?
146、解释 PV、UV 的含义?
147、解释 QPS的含义?
148、uwsgi和wsgi的区别?
149、supervisor的作用?
150、什么是反向代理?
151、简述SSH的整个过程。
152、有问题都去那些找解决方案?
153、是否有关注什么技术类的公众号?
154、最近在研究什么新技术?
155、是否了解过领域驱动模型?
题目出处:https://www.cnblogs.com/wupeiqi/p/9078770.html
https://blog.csdn.net/qq_37275405/article/details/80979437
http://www.cnblogs.com/bigtreei/p/9127672.html#_label0