315题

第一部分 Python基础篇(80题)

一、为何学习Python?javascript

# 由于python相对其余语言很是优雅简洁,有着丰富的第三方库,我感受很强大、很方便;

# 还有就是,我感受python简单易学,生态圈庞大,例如:web开发、爬虫、人工智能等,并且将来发展趋势也很不错。

二、经过什么途径学习的Python?php

# 在系里社团经过学长了解到python
根据我的状况而定…………

三、Python和Java、PHP、C、C#、C++等其余语言的对比?css

# Python、PHP是解释型语言,代码运行期间逐行翻译成目标机器码,下次执行时逐行解释
# 而C、Java是编译型语言,编译后再执行。

四、简述解释型和编译型编程语言?html

编译型

优势:编译器通常会有预编译的过程对代码进行优化。由于编译只作一次,运行时不须要编译,因此编译型语言的程序执行效率高。能够脱离语言环境独立运行。
缺点:编译以后若是须要修改就须要整个模块从新编译。编译的时候根据对应的运行环境生成机器码,不一样的操做系统之间移植就会有问题,须要根据运行的操做系统环境编译不一样的可执行文件。

解释型

优势:有良好的平台兼容性,在任何环境中均可以运行,前提是安装了解释器(虚拟机)。灵活,修改代码的时候直接修改就能够,能够快速部署,不用停机维护。

缺点:每次运行的时候都要解释一遍,性能上不如编译型语言。

 五、Python解释器种类以及特色?前端

# CPython:C语言开发的,官方推荐,最经常使用
# IPython:基于CPython之上的交互式解释器,只是在交互上有加强
# JPython:Java写的解释器
# Pypy:Python写的解释器,目前执行速度最快的解释器,采用JIT技术,对Python进行动态编译
# IronPython:C#写的解释器

六、位和字节的关系?vue

#1字节=8位  
#1byte=8bit (数据存储以字节(Byte)为单位)

七、b、B、KB、MB、GB 的关系?java

1B=8bit    1个字节(Byte,B)8个比特(bit)
1KB=1024B
1MB=1024KB
1G=1024MB
1T=1024G

八、请至少列举5个 PEP8 规范(越多越好)。python

复制代码
#一、空格使用
a 各类右括号前不要加空格。
b 逗号、冒号、分号前不要加空格。
c 函数的左括号前不要加空格。如Func(1)。
d 序列的左括号前不要加空格。如list[2]。
e 操做符左右各加一个空格,不要为了对齐增长空格。
f 函数默认参数使用的赋值符左右省略空格。
g 不要将多句语句写在同一行,尽管使用‘;’容许。
8 if/for/while语句中,即便执行语句只有一句,也必须另起一行。
#二、代码编排
   a 缩进,4个空格,而不是tab键
   b 每行长度79,换行可以使用反斜杠,最好使用圆括号。
   c 类与类之间空两行
   d 方法之间空一行
复制代码

九、经过代码实现以下转换:mysql

复制代码
二进制转换成十进制:v = “0b1111011”

十进制转换成二进制:v = 18
 
八进制转换成十进制:v = “011”
 
十进制转换成八进制:v = 30
 
十六进制转换成十进制:v = “0x12”
 
十进制转换成十六进制:v = 87
################################
v = 0b1111011
print(int(v))

v = 18
print(bin(v))

v = '011'
print(int(v))

v = 30
print(oct(v))

v = 0x12
print(int(v))

v = 87
print(hex(v))
复制代码

十、请编写一个函数实现将IP地址转换成一个整数。react

如 10.3.9.12 转换规则为:
        10            00001010

         3            00000011

         9            00001001

        12            00001100

再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
num = bin(10),bin(3),bin(9),bin(12)

def int1():
    global num
    return num,int(bin(10),2) + int(bin(3),2) +int(bin(9),2) +int(bin(12),2)
print(int1())

如 10.3.9.12 转换规则为: 10 00001010
 3 00000011
 9 00001001
 12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?

num = bin(10),bin(3),bin(9),bin(12)
count= 0
for i in num:
    count +=int(i,2)
print(count)

十一、python递归的最大层数?

def foo(n):
    print(n)
    n += 1
    foo(n)
foo(1)

测试完以后为最大998 到了999就超过了最大的递归程度

十二、求结果:

v1 = 1 or 3  -- 1
v2 = 1 and 3  -- 3
v3 = 0 and 2 and 1  -- 0
v4 = 0 and 2 or 1  -- 1
v5 = 0 and 2 or 1 or 4  -- 1
v6 = 0 or Flase and 1  -- False
########################
总结:
 # x or y 若是 x为真,则值为x,   不然为y
 # x and y 若是 x 为真,则值为 y,不然为 x
#and:先后为真才为真
#or:有一为真就为真
#优先级:()>not>and>or 
#同等优先级下,从左向右

# 变态面试题:思考
# print(1 > 2 or 3 and 4 < 6)
# print(2 or 3 and 4 < 6)
#先按优先级算() not and or,第一题 3 and 4 < 6 ,3等于True ,
#4<6等于True ,因此这个and结果为True,最后的or,1 > 2 or True,
#1>2是False ,False or True 就是True
#第二题 3 and 4 < 6 3等于True ,4<6等于True,,因此这个and结果为True,最后的or,2 or True ,就等于x or y ,x为真,返回x,就是2.
1. 求结果:2 & 5
print(2 & 5)  # 10 & 101 => 000 => 0 
2. 求结果:2 ^ 5
print(2 ^ 5)  # 10 ^ 101 => 111 => 1*2**0+1*2**1+1*2**2=1+2+4=7

1三、ascii、unicode、utf-八、gbk 区别?

python2内容进行编码(默认ascii),而python3对内容进行编码的默认为utf-8。
ascii   最多只能用8位来表示(一个字节),即:2**8 = 256,因此,ASCII码最多只能表示 256 个符号。
unicode  万国码,任何一个字符==两个字节
utf-8     万国码的升级版  一个中文字符==三个字节   英文是一个字节  欧洲的是 2个字节
gbk       国内版本  一个中文字符==2个字节   英文是一个字节
gbk 转 utf-8  需经过媒介 unicode

1四、字节码和机器码的区别?

机器码,学名机器语言指令,有时也被称为原生码,是电脑的CPU可直接解读的数据。

字节码是一种中间状态(中间码)的二进制代码(文件)。须要直译器转译后才能成为机器码。

#is  比较的是内存地址
#== 比较的是值
# int     具备范围:-5---256
#对于int 小数据池
 范围:-5----256 建立的相间的数字,都指向同一个内存地址

#对于字符串 (面试)
一、小数据池 若是有空格,那指向两个内存地址,
二、长度不能超过 20
三、不能用特殊字符
 

1五、三元运算规则以及应用场景?

# 三元运算符就是在赋值变量的时候,能够直接加判断,而后赋值
a = 1
b = 2
c = a if a > 1 else b  # 若是a大于1的话,c=a,不然c=b

1六、列举 Python2和Python3的区别?

复制代码
 
  
字符编码
py2: unicode ->压缩(utf8) str=bytes
name = u'alex' name = 'alex'
type(name) type(name)

py3: str ->压缩(utf8) bytes
name = "alex" name = b'alex'
type(name) type(name)
'Print':
    py2--print; 
    py3--print()函数
'编码':
    py2默认是ascii码;
    py3默认是utf-8
'字符串':
    py2中分ascii(8位)、unicode(16位);
    py3中全部字符串都是unicode字符串
'True和False':
    py2中是两个全局变量(1和0)能够从新赋值;
    py3中为两个关键字,不可从新赋值
'迭代':
   python2里,有两种方法得到必定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器
  python3 里,range()返回迭代器,xrange()再也不存在。
'Nonlocal': py3专有的(声明为非局部变量) '经典类&新式类': py2:经典类和新式类并存; py3:新式类都默认继承object 'yield': py2:yield py3:yield/yield from '文件操做': py2:readliens()读取文件的全部行,返回一个列表,包含全部行的结束符 xreadliens()返回一个生成器,循环取值   py3: 只有readlines()
input不一样
python2 :raw_input
python3 :input 统一使用input函数

7:在包的知识点里
包:一群模块文件的集合 + __init__
区别:py2 : 必须有__init__
   py3:不是必须的了
8:不相等操做符"<>"被Python3废弃,统一使用"!="

9:long整数类型被Python3废弃,统一使用int

10:迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)

11:异常StandardError 被Python3废弃,统一使用Exception

12:字典变量的has_key函数被Python废弃,统一使用in关键词

13:file函数被Python3废弃,统一使用open来处理文件,能够经过io.IOBase检查文件类型

  字典类方法HAS_KEY()

  Python2中,字典对象has_key()方法测试字典是否包含指定的键。python3再也不支持这个方法,须要使用in.

 

  全局函数FILTER()

  在python2里,filter()方法返回一个列表,这个列表是经过一个返回值为True或False的函数来检测序列里的每一项的道德。在python3中,filter()函数返回一个迭代器,再也不是列表

 

  MAP()

  跟filter()的改变同样,map()函数如今返回一个迭代器,python2中返回一个列表。

 

  APPLY()

  python2有一个叫作apply()的全局函数,它使用一个函数f和一个列表[a,b,c]做为参数,返回值是f(a,b,c).能够直接调用这个函数,在列表前添加一个星号做为参数传递给它来完成一样的事情。在python3里记,apply()函数再也不存在;必须使用星号标。

 

  EXEC

  就像print语句在python3里变成了一个函数同样,exec语句也是这样的。exec()函数使用一个包含任意python代码的字符串做为参数,而后像执行语句或表达式同样执行它。exec()跟eval()是类似,但exec()更增强大并具备挑战性。eval()函数只能执行单独一条表达式,可是exec()可以执行多条语句,导入(import),  函数声明-实际上整个python程序的字符串表示也能够


   execfile

   python2中的execfile语句能够像执行python代码那样使用字符串。不一样的是exec使用字符串,而execfile使用文件。在python3,execfile语句被去掉了

 

  python2中,文件对象有一个xreadlines()方法,返回一个迭代器,一次读取文件的一行。这在for循环中尤为实用。python3中,xreadlines()方法再也不可用。


  python2,若是须要编写一个遍历元组的列表解析,不须要在元组值周围加上括号。在python3里,这些括号是必需的。


  在python2里,能够经过在类的声明中定义metaclass参数,或者定义一个特殊的类级别(class-level)__metaclass__属性,来建立元类。python3中,__metaclass__属性被取消了
 
复制代码

1七、用一行代码实现数值交换:

a = 1
b = 2
###########
a, b = b, a
print(a, b)

1八、Python3和Python2中 int 和 long的区别?

py3中没有long整型,统一使用int,大小和py2的long相似。
py2中int最大不能超过sys.maxint,根据不一样平台大小不一样;
在int类型数字后加L定义成长整型,范围比int更大。

1九、xrange和range的区别?

python2里,有两种方法得到必定范围内的数字:range(),返回一个列表,还有xrange(),返回一个迭代器。
python3 里,range()返回迭代器,xrange()再也不存在。

20、文件操做时:xreadlines和readlines的区别?

# Readlines:读取文件的全部行,返回一个列表,包含全部行的结束符
# Xreadlines:返回一个生成器,循环使用和readlines基本一致 。(py2有,py3没有)

2一、列举布尔值为False的常见值?

# []、{}、None、’’、()、0、False

2二、字符串、列表、元组、字典每一个经常使用的5个方法?

 

#Str:
    Split:分割
    Strip:去掉两边的空格
    Startwith:以什么开头
    Endwith:以什么结尾
    Lower:小写
    Upper:大写
    find经过元素找索引,可切片,找不到返回-1
    index,找不到报错。
    title,每一个单词的首字母大写。
    format格式化输出
    #format的三种玩法 格式化输出
    res='{} {} {}'.format('egon',18,'male')  ==>  egon 18 male
    res='{1} {0} {1}'.format('egon',18,'male')  ==> 18 egon 18
    res='{name} {age}                 {sex}'.format(sex='male',name='egon',age=18)
    count查找元素的个数,能够切片,若没有返回0 
    replace(old,new,次数) 
    swapcase 大小写翻转 
#List:
    Append:追加
    Insert:按照索引添加,
    Reverse:反转
    Index:索引
    Copy:拷贝
    Pop:删除指定索引处的值,不指定索引默认删除最后一个。
    expend:迭代着添加。
    list.extend(seq) - 在列表末尾一次性追加另外一个序列中的多个值(用新列表扩展原来的列表)
    clear  清空列表
    del 一、能够按照索引去删除 二、切片 3、步长(隔着删)
    remove 能够按照元素去删
注意:List中的元素是能够改变的。
#Tuple:
    Count:查看某个元素出现的次数
    Index:索引
1、cmp(tuple1, tuple2):比较两个元组元素。
2、len(tuple):计算元组元素个数。
3、max(tuple):返回元组中元素最大值。
4、min(tuple):返回元组中元素最小值。
5、tuple(seq):将列表转换为元组。
注意
1、与字符串同样,元组的元素不能修改。
2、元组也能够被索引和切片,方法同样。
3、注意构造包含0或1个元素的元组的特殊语法规则。
四、元组也能够使用+操做符进行拼接。
#Dict:
#字典的键必须是可哈希的   不可变类型。
#在同一个字典中,键(key)必须是惟一的。
    Get:根据key取value
    Items:用于循环,取出全部key和value
    Keys:取出全部key
    Values:取出全部的value
    Clear:清空字典
    Pop:删除指定键对应的值,有返回值;
Set(集合)
:集合(set)是一个无序不重复元素的序列。
能够使用大括号 { } 或者 set() 函数建立集合,注意:建立一个空集合必须用 set() 而不是 { },由于 { } 是用来建立一个空字典。

2三、lambda表达式格式以及应用场景?

匿名函数:为了解决那些功能很简单的需求而设计的一句话函数
函数名 = lambda 参数 :返回值

#参数能够有多个,用逗号隔开
#匿名函数无论逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值
#返回值和正常的函数同样能够是任意数据类型

lambda 表达式
temp = lambda x,y:x+y
print(temp(4,10))   # 14

可替代:
def foo(x,y):
    return x+y
print(foo(4,10))    # 14

 

2四、pass的做用?

# Pass通常用于站位语句,保持代码的完整性,不会作任何操做。

2五、*arg和**kwarg做用

# 他们是一种动态传参,通常不肯定须要传入几个参数时,能够使用其定义参数,而后从中取参

'*args':按照位置传参,将传入参数打包成一个‘元组’(打印参数为元组-- tuple)
'**kwargs':按照关键字传参,将传入参数打包成一个‘字典’(打印参数为字典-- dict)

 

def exmaple2(required_arg, *arg, **kwarg):
    if arg:
        print "arg: ", arg
 
    if kwarg:
        print "kwarg: ", kwarg
 
exmaple2("Hi", 1, 2, 3, keyword1 = "bar", keyword2 = "foo")
 
>> arg:  (1, 2, 3)
>> kwarg:  {'keyword2': 'foo', 'keyword1': 'bar'}

 

def sum(a, b, c):
    return a + b + c
 
a = [1, 2, 3]
 
# the * unpack list a 
print sum(*a)
>> 6

 

2六、is和==的区别

==:判断某些值是否同样,比较的是值
is:比较的是内存地址(引用的内存地址不同,惟一标识:id)

2七、简述Python的深浅拷贝以及应用场景?

#浅拷贝:
无论多么复杂的数据结构,只copy对象最外层自己,而且在其余内存中从新建立了数据,第二层数据与源数据共享内存。
#深拷贝:
彻底复制原变量的全部数据,内存中生成一套彻底同样的内容;只是值同样,内存地址不同,一方修改另外一方不受影响

# 彻底独立的copy一份数据,与原数据没有关系,深copy
# 若是一份数据(列表)第二层时,你想与原数据进行公用,浅copy。


一层的状况:
import copy
 
# 浅拷贝
li1 = [1, 2, 3]
li2 = li1.copy()
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
 
# 深拷贝
li1 = [1, 2, 3]
li2 = copy.deepcopy(li1)
li1.append(4)
print(li1, li2)  # [1, 2, 3, 4] [1, 2, 3]
多层的状况:
import copy
 
# 浅拷贝 指向共有的地址
li1 = [1, 2, 3,[4,5],6]
li2 = li1.copy()
li1[3].append(7)
print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5, 7], 6]
 
# 深拷贝 重指向
li1 = [1, 2, 3,[4,5],6]
li2 = copy.deepcopy(li1)
li1[3].append(7)
print(li1, li2)  # [1, 2, 3, [4, 5, 7], 6] [1, 2, 3, [4, 5], 6]
# 切片属于浅copy
l1 = [1,2,3,[22,33]]
l2 = l1[:]
# print(id(l1),id(l2))
# l1.append(666)
l1[-1].append(666)
print(l1,id(l1))
print(l2,id(l2))

应用场景:
在django开发的crm中,例如分页以后,选择数据进行编辑,编辑保存以后,须要跳转回原页面。
本质:request.GET 进行拷贝,不影响后续其余组件使用request.GET

2八、Python垃圾回收机制?

# Python垃圾回收机制
Python垃圾回收机制,主要使用'引用计数'来跟踪和回收垃圾。
在'引用计数'的基础上,经过'标记-清除'(mark and sweep)解决容器对象可能产生的循环引用问题.
经过'分代回收'以空间换时间的方法提升垃圾回收效率。

'引用计数'
PyObject是每一个对象必有的内容,其中ob_refcnt就是作为引用计数。
当一个对象有新的引用时,它的ob_refcnt就会增长,当引用它的对象被删除,
它的ob_refcnt就会减小.引用计数为0时,该对象生命就结束了。
    \优势:1.简单 2.实时性
    \缺点:1.维护引用计数消耗资源 2.循环引用

'标记-清楚机制'
基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,
遍历以对象为节点、以引用为边构成的图,把全部能够访问到的对象打上标记,
而后清扫一遍内存空间,把全部没标记的对象释放。

'分代技术'
分代回收的总体思想是:
将系统中的全部内存块根据其存活时间划分为不一样的集合,每一个集合就成为一个“代”,
垃圾收集频率随着“代”的存活时间的增大而减少,存活时间一般利用通过几回垃圾回收来度量。
python垃圾回收机制

2九、Python的可变类型和不可变类型?

# 可变类型:列表、字典、集合
# 不可变类型:数字、字符串、元祖
(可变与否指内存中那块内容value)

30、求结果:

v = dict.fromkeys(['k1', 'k2'], [])
# 内存中k1和k2都指向同一个[](内存地址相同),只要指向的[]发生变化,k1和k2都要改变(保持一致)
v['k1'].append(666)
print(v)  # {'k1': [666], 'k2': [666]}
v['k1'] = 777
print(v)  # {'k1': 777, 'k2': [666]}

3一、求结果:

def num():
   return [lambda x: i * x for i in range(4)] #返回一个列表,里面是四个函数对象 i=3
print([m(2) for m in num()])# 6  6 6 6 

等同于:
def num1():
li =[]
for i in range(4):
def func(x):
return i*x
li.append(func)
return li

print([i(2) for i in num1()])


i就是在闭包做用域(enclousing),而Python的闭包是 迟绑定 , 这意味着闭包中用到的变量的值,是在内部函数被调用时查询获得的

3二、列举常见的内置函数?

abs()
返回数字的绝对值

map
根据函数对指定序列作映射
map()函数接收两个参数,一个是函数,一个是可迭代对象,map将传入的函数依次做用到序列的每一个元素,并把结果做为新的list返回。

返回值:
  Python2  返回列表
  Python3  返回迭代器

例子1:
def mul(x):
    return x*x
n=[1,2,3,4,5]
res=list(map(mul,n))
print(res)  #[1, 4, 9, 16, 25]

例子2:abs()  返回数字的绝对值
ret = map(abs,[-1,-5,6,-7])
print(list(ret))
# [1, 5, 6, 7]

filter
filter()函数接收一个函数 f(函数)和一个list(可迭代对象),这个函数 f的做用是对每一个元素进行判断,返回 True或 False,
filter()根据判断结果自动过滤掉不符合条件的元素,返回由符合条件元素组成的新list。
def is_odd(x):
    return x % 2 == 1

v=list(filter(is_odd, [1, 4, 6, 7, 9, 12, 17]))
print(v)  #[1, 7, 9, 17]
map与filter总结
# filter 与 map 总结
# 参数: 都是一个函数名 + 可迭代对象
# 返回值: 都是返回可迭代对象
# 区别:
# filter 是作筛选的,结果仍是原来就在可迭代对象中的项
# map 是对可迭代对象中每一项作操做的,结果不必定是原来就在可迭代对象中的项


isinstance\type
isinstance() 函数来判断一个对象是不是一个已知的类型,相似 type()。
isinstance() 与 type() 区别:
type() 不会认为子类是一种父类类型,不考虑继承关系。
isinstance() 会认为子类是一种父类类型,考虑继承关系。
若是要判断两个类型是否相同推荐使用 isinstance()。
# 例一
a = 2
print(isinstance(a,int))   # True
print(isinstance(a,str))   # False

# type() 与 isinstance() 区别
class A:
    pass

class B(A):
    pass

print("isinstance",isinstance(A(),A))   # isinstance True
print("type",type(A())  == A)    # type True

print('isinstance',isinstance(B(),A) )   # isinstance True
print('type',type(B()) == A)     #  type False


zip 拉链函数
# zip 拉链函数,
# 将对象中对应的元素打包成一个个元组,
# 而后返回由这些元组组成的列表迭代器。
# 若是各个迭代器的元素个数不一致,则返回列表长度与最短的对象相同。
print(list(zip([0,1,3],[5,6,7],['a','b'])))
# [(0, 5, 'a'), (1, 6, 'b')]

zip() 函数用于将可迭代的对象做为参数,将对象中对应的元素打包成一个个元组,而后返回由这些元组组成的列表。
>>>a = [1,2,3]
>>> b = [4,5,6]
>>> c = [4,5,6,7,8]
>>> zipped = zip(a,b)     # 打包为元组的列表
[(1, 4), (2, 5), (3, 6)]
>>> zip(a,c)              # 元素个数与最短的列表一致
[(1, 4), (2, 5), (3, 6)]
>>> zip(*zipped)          # 与 zip 相反,可理解为解压,返回二维矩阵式
[(1, 2, 3), (4, 5, 6)]

reduce
'''
reduce()  函数
reduce() 函数会对参数序列中元素进行累积
函数将一个数据集合(链表、元组等)中的全部数据进行下列操做
'''
注意:
Python3已经将reduce() 函数从全局名字空间里移除了,它如今被放置在 fucntools 模块里,若是想要使用它,则须要经过引入 functools 模块来调用 reduce() 函数:

from functools import reduce
def add(x,y):
    return x + y
print(reduce(add,[1,2,3,4,5]))
#  15
print(reduce(lambda x, y: x+y, [1,2,3,4,5]))  # 15
print(reduce(add,range(1,101)))
#  5050

 

3三、filter、map、reduce的做用?

# map:遍历序列,为每个序列进行操做,获取一个新的序列
# reduce:对于序列里面的全部内容进行累计操做
# filter:对序列里面的元素进行筛选,最终获取符合条件的序列。

3四、一行代码实现9*9乘法表

print('\n'.join(['   '.join(['%s*%s=%2s' % (j, i, i * j) for j in range(1, i + 1)]) for i in range(1, 10)]))

3五、如何安装第三方模块?以及用过哪些第三方模块?

# a、能够在pycharm的settings里面手动下载添加第三方模块
# b、能够在cmd终端下用pip insatll 安装
# 用过的第三方模块:
requests
bs4
sqlalchemy
mysql
redis
 
常见内置模块
json
time
datetime
re
os/sys
logging
 

3六、至少列举8个经常使用模块都有那些?

re:正则
os:提供了一种方便的使用操做系统函数的方法。
sys:可供访问由解释器使用或维护的变量和与解释器进行交互的函数。
random:随机数
json:序列化
time:时间

3七、re的match和search区别?

# match:从字符串起始位置开始匹配,若是没有就返回None
# serch:从字符串的起始位置开始匹配,匹配到第一个符合的就不会再去匹配了

3八、什么是正则的贪婪匹配?

# 匹配一个字符串没有节制,能匹配多少就匹配多少,直到匹配完为止

3九、求结果:
 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结果是一个生成器
#  <generator object <genexpr> at 0x00000000020CEEB8> 生成器
# 在Python中,有一种自定义迭代器的方式,称为生成器(Generator)。
# 定义生成器的两种方式:
# 1.建立一个generator,只要把一个列表生成式的[]改为(),就建立了一个generator:
# generator保存的是算法,每次调用next(),就计算出下一个元素的值,直到计算到最后一个元素,
没有更多的元素时,抛出StopIteration的错误。 # 2.定义generator的另外一种方法。若是一个函数定义中包含yield关键字,那么这个函数就再也不是一个普通函数,
而是一个generator
 

40、求结果:
 a. 1 or 2
 b. 1 and 2
 c. 1 < (2==2)
 d. 1 < 2 == 2

a=1 or 2    #1
b=1 and 2   #2
c=1 < (2==2)    #False 
2==2==true==1
d=1 < 2 == 2 #True

4一、def func(a,b=[]) 这种写法有什么坑?

# 函数传参为列表陷阱,列表是可变数据类型,可能会在过程当中修改里面的值

def func(a,b = []):
b.append(1)
print(a,b)

 
  

func(a=2)
func(2)
func(2)

 
  


'''
[1]
[1, 1]
[1, 1, 1]
函数的默认参数是一个list 当第一次执行的时候实例化了一个list
第二次执行仍是用第一次执行的时候实例化的地址存储
因此三次执行的结果就是 [1, 1, 1] 想每次执行只输出[1] ,默认参数应该设置为None
'''

 

4二、如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?

a = '1,2,3'
a=a.replace(',','')
res = [i for i in a]
print(res)

4三、如何实现[‘1’,’2’,’3’]变成[1,2,3] ?

l = ['1','2','3']
res = [int(i) for i in l]
print(res)

4四、比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?

前两个列表内是int
最后一个列表内是元组

4五、如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?

l = [i*i for i in range(1,11)]
print(l)

# 一个列表A=[2,3,4],Python如何将其转换成B=[(2,3),(3,4),(4,2)]?
# B = zip(A, A[1:]+A[:1])

4六、一行代码实现删除列表中重复的值 ?

l = [1,1,1,2,2,3,3,3,4,4]
print(list(set(l))) # [1, 2, 3, 4]

4七、如何在函数中设置一个全局变量 ?

经过global指定变量,该变量会变成全局变量

x = 2
def func():
global x
x = 1
return x
func()
print(x) # 1

4八、logging模块的做用?以及应用场景?

# 做用:
    管理咱们程序的执行日志,省去用print记录操做日志的操做,而且能够将标准输入输出保存到日志文件
# 场景:
    爬虫爬取数据时,对爬取进行日志记录,方便分析、排错。

4九、请用代码简单实现stack 。

复制代码
class Stack(object):
   # 初始化栈
   def __init__(self):
      self.items = []
   # 判断栈是否为空
   def is_empty(self):
      return self.items == []
   # 返回栈顶
   def peek(self):
      return self.items[len(self.items) - 1]
   # 返回栈大小
   def size(self):
      return len(self.items)
   # 压栈
   def push(self, item):
      self.items.append(item)
   # 出栈
   def pop(self):
      return self.items.pop()
复制代码

50、经常使用字符串格式化哪几种?

#

1.占位符%

 
  

%d 表示那个位置是整数;%f 表示浮点数;%s 表示字符串。

 
  
print('Hello,%s' % 'Python')
print('Hello,%d%s%.2f' % (666, 'Python', 9.99)) # 打印:Hello,666Python10.00
# format格式化输出 i = "i am {}".format('zhugaochao') print(i) #i am zhugaochao

5一、简述 生成器、迭代器、可迭代对象 以及应用场景?

# 装饰器:
可以在不修改原函数代码的基础上,在执行先后进行定制操做,闭包函数的一种应用
场景:
   - flask路由系统
   - flask before_request
   - csrf
   - django内置认证
   - django缓存
# 手写装饰器;
import functools
def wrapper(func):
   @functools.wraps(func)  #不改变原函数属性
   def inner(*args, **kwargs):
      执行函数前
      return func(*args, **kwargs)
      执行函数后
   return inner
1. 执行wapper函数,并将被装饰的函数当作参数。 wapper(index)
2. 将第一步的返回值,从新赋值给  新index =  wapper(老index)
@wrapper    #index=wrapper(index)
def index(x):
   return x+100
# ---------------------------------------------------------------
# 生成器:
一个函数内部存在yield关键字
应用场景:
   - rang/xrange
   - redis获取值
      - conn = Redis(......)
        - v=conn.hscan_iter() # 内部经过yield 来返回值
    - stark组件中
        - 前端调用后端的yield
# ---------------------------------------------------------------
# 迭代器:
内部有__next__和__iter__方法的对象,帮助咱们向后一个一个取值,迭代器不必定是生成器
应用场景:
   - wtforms里面对form对象进行循环时,显示form中包含的全部字段
   - 列表、字典、元组
   (可让一个对象被for循环)
show

5二、用Python实现一个二分查找的函数。

 

li = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def search(someone, li):
    l = -1
    h = len(li)    while l + 1 != h:
        m = int((l + h) / 2)
        if li[m] < someone:
            l = m
        else:
            h = m
    p = h
    if p >= len(li) or li[p] != someone:
        print("元素不存在")
    else:
        str = "元素索引为%d" % p
        print(str)


search(3, li)  # 元素索引为2

5三、谈谈你对闭包的理解?

# 内部函数包含对外部做用域而非全剧做用域变量的引用,该内部函数称为闭包函数,而且外函数的返回值是内函数的引用,经常使用于装饰器。
# 判断闭包函数的方法:__closure__,输出的__closure__有cell元素说明是闭包函数
# 闭包的意义与应用:延迟计算:

def outer(a):
b = 10 # a和b都是闭包变量
c = [a] # 这里对应修改闭包变量的方法2

# inner是内函数
def inner():
# 内函数中想修改闭包变量
# 方法1 nonlocal关键字声明
nonlocal b
b += 1
# 方法二,把闭包变量修改为可变数据类型 好比列表
c[0] += 1
print(c[0])
print(b)

# 外函数的返回值是内函数的引用
return inner


if __name__ == '__main__':
demo = outer(5)
demo() # 6 11

 

5四、os和sys模块的做用?

# os模块负责程序与操做系统的交互,提供了访问操做系统底层的接口;
# sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python运行环境

def add_b():
b = 42
def do_global():
b = 10
print(b)
def dd_nonlocal():
nonlocal b
b = b + 20
print(b)
dd_nonlocal()
print(b)
do_global()
print(b)
add_b()

 
  

nonlocal关键字举例

 

5五、如何生成一个随机数?

import random
print(random.random())
print(random.randint(1, 10))

5六、如何使用python删除一个文件?

import os
os.remove('文件名以及路径')

5七、谈谈你对面向对象的理解?

复制代码
#封装:
   其实就是将不少数据封装到一个对象中,相似于把不少东西放到一个箱子中,
   如:一个函数若是好多参数,起始就能够把参数封装到一个对象再传递。
#继承:
   若是多个类中都有共同的方法,那么为了不反复编写,就能够将方法提取到基类中实现,
   让全部派生类去继承便可。
#多态:
   指基类的同一个方法在不一样派生类中有着不一样功能。python天生支持多态。
# 4. 鸭子模型
# python
"""
def func(arg):
arg.send() # arg能够是任意对象,必须有send方法
"""
复制代码

5八、Python面向对象中的继承有什么特色?

#Python3的继承机制

# 子类在调用某个方法或变量的时候,首先在本身内部查找,若是没有找到,则开始根据继承机制在父类里查找。
# 根据父类定义中的顺序,以深度优先的方式逐一查找父类!
继承参数的书写有前后顺序,写在前面的被优先继承。

5九、面向对象深度优先和广度优先是什么?

复制代码
# Python的类能够继承多个类,Python的类若是继承了多个类,那么其寻找方法的方式有两种

当类是经典类时,多继承状况下,会按照深度优先方式查找
当类是新式类时,多继承状况下,会按照广度优先方式查找
简单点说就是:经典类是纵向查找,新式类是横向查找

经典类和新式类的区别就是,在声明类的时候,新式类须要加上object关键字。在python3中默认全是新式类
复制代码

60、面向对象中super的做用?

主要在子类根据mro的顺序执行相关的方法

6一、是否使用过functools中的函数?其做用是什么?

在装饰器中,会用到;functools.wraps()主要在装饰器中用来装饰函数

Stark上下文管理源码中,走到视图阶段时有用到functools中的偏函数,request = LocalProxy(partial(_lookup_req_object, 'request'))

6二、列举面向对象中带爽下划线的特殊方法,如:__new__、__init__

复制代码
# __getattr__
 CBV
 django配置文件
 wtforms中的Form()示例化中 将"_fields中的数据封装到From类中"
# __mro__ 
 wtform中 FormMeta中继承类的优先级
# __dict__   
是用来存储对象属性的一个字典,其键为属性名,值为属性的值
# __new__ 
实例化可是没有给当前对象
wtforms,字段实例化时返回:不是StringField,而是UnboundField
est frawork many=Turn  中的序列化
# __call__
flask 请求的入口app.run()
字段生成标签时:字段.__str__ => 字段.__call__ => 插件.__call__
# __iter__ 
循环对象是,自定义__iter__
wtforms中BaseForm中循环全部字段时定义了__iter__
# -metaclass
做用:用于指定当前类使用哪一个类来建立
场景:在类建立以前定制操做
示例:wtforms中,对字段进行排序。
__getitem__
__setitem__
__delitem__
class Session(object):

def __setitem__(self, key, value):
print(key,value)

def __getitem__(self, item):
return 1

def __delitem__(self, key):
pass
   obj = Session()
obj['x1'] = 123
obj['x1']
del obj['x1']
__iter__
__enter__
__exit__
复制代码

6三、如何判断是函数仍是方法

# 看他的调用者是谁,若是是类,须要传入参数self,这时就是一个函数;
# 若是调用者是对象,不须要传入参数值self,这时是一个方法。
(FunctionType/MethodType)

6四、静态方法和类方法区别?

复制代码
Classmethod必须有一个指向类对象的引用做为第一个参数;
@classmethod
def class_func(cls):
   """ 定义类方法,至少有一个cls参数 """
   print('类方法')
---------------------------------------------------------
Staticmethod能够没有任何参数。
@staticmethod
def static_func():
   """ 定义静态方法 ,无默认参数"""
   print('静态方法')
复制代码

6五、列举面向对象中的特殊成员以及应用场景

复制代码
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)
# 输出:aaa

8.__getitem____setitem____delitem__:用于索引操做,如字典。以上分别表示获取、设置、删除数据。
9.__iter__:用于迭代器,之因此列表、字典、元组能够进行for循环,是由于类型内部定义了 __iter__
复制代码

6六、一、二、三、四、5 能组成多少个互不相同且无重复的三位数

import itertools
print(len(list(itertools.permutations('12345',3))))
#60个

6七、什么是反射?以及应用场景?

反射就是以字符串的方式导入模块,以字符串的方式执行函数
# 应用场景:
   rest framework里面的CBV
django的中间件的加载 等其余配置均使用了反射。

6八、metaclass做用?以及应用场景?

类的metaclass
默认是type。咱们也能够指定类的metaclass值。
参考:点击查看

6九、用尽可能多的方法实现单例模式。

# 单例模式
'''单例模式是一种经常使用的软件设计模式。在它的核心结构中只包含一个被称为单例类的特殊类。
经过单例模式能够保证系统中一个类只有一个实例并且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
若是但愿在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。'''
# 一、使用__new__方法
    class Singleton(object):
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance
    class MyClass(Singleton):
    a = 1
# 二、共享属性
# 建立实例时把全部实例的__dict__指向同一个字典,这样它们具备相同的属性和方法.
    class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
            ob = super(Borg, cls).__new__(cls, *args, **kw)
            ob.__dict__ = cls._state
            return ob
    class MyClass2(Borg):
        a = 1
# 三、装饰器版本
    def singleton(cls, *args, **kw):
        instances = {}
        def getinstance():
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return getinstance
    @singleton
    class MyClass:
    ...
# 四、import方法
# 做为python的模块是自然的单例模式
    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
    my_singleton = My_Singleton()
    # to use
    from mysingleton import my_singleton
    my_singleton.foo()
show

 

# 11. 手写单例模式(标准无bug,加锁版本)
import time
import threading
class Singleton(object):
    lock = threading.RLock()
    instance = None

    def __new__(cls, *args, **kwargs):
        if cls.instance:
            return cls.instance
        with cls.lock:
            if not cls.instance:
                cls.instance = super().__new__(cls)
            return cls.instance

def task(arg):
    obj = Singleton()
    print(obj)
for i in range(10):
    t = threading.Thread(target=task,args=(i,))
    t.start()
time.sleep(100)

obj = Singleton()

 

 

 

70、装饰器的写法以及应用场景。

复制代码
import functools
def wrapper(func):
    @functools.wraps(func)
    def inner(*args, **kwargs):
        print('我是装饰器')
        return func
  return inner

@wrapper
def index():
    print('我是被装饰函数')
    return None
index()

# 应用场景
flask框架路由
django的csrf
django的缓存
django的auth
- 装饰器 - functools.wraps(func)

# 示例二:写装饰器,重复执行n次
import functools

def couter(times):
def wapper(func):
@functools.wraps(func)
def inner(*args, **kwargs):
for i in range(times):
result = func(*args, **kwargs)
return result
return inner
return wapper

@couter(5)
def f1():
print('f1函数')
f1()
复制代码

7一、异常处理写法以及如何主动抛出异常(应用场景)

复制代码
while True:
   try:
      x = int(input("Please enter a number: "))
      break
   except ValueError:
      print("Oops!  That was no valid number.  Try again   ")
# raise主动抛出一个异常
参考:点击查看
复制代码

7二、什么是面向对象的mro

MRO:方法解析顺序
它定义了 Python 中多继承存在的状况下,解释器查找继承关系的具体顺序

7三、isinstance做用以及应用场景?

# 来判断一个对象是不是一个已知的类型。 
# 使用isinstance函数还能够来判断'类实例变量'属于哪个类产生的。

7四、写代码并实现:

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]
'''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]'''

class Solution:
   def twoSum(self, nums, target):
      """ 
      :type nums: List[int] 
      :type target: int 
      :rtype: List[int] 
      """
      # 用len()方法取得nums列表长度  
      n = len(nums)
      # x从0到n取值(不包括n)  
      for x in range(n):
         a = target - nums[x]
         # 用in关键字查询nums列表中是否有a  
         if a in nums:
            # 用index函数取得a的值在nums列表中的索引  
            y = nums.index(a)
            # 假如x=y,那么就跳过,不然返回x,y  
            if x == y:
               continue
            else:
               return x, y
               break
         else:
            continue  
show

7五、json序列化时,能够处理的数据类型有哪些?如何定制支持datetime类型?

复制代码
# 可序列化数据类型:
字典、列表、数字、字符串、元组;若是是元组,自动转成列表(再转回去的话也是列表)
# 自定义时间序列化转换器
import json
from json import JSONEncoder
from datetime import datetime
class ComplexEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.strftime('%Y-%m-%d %H:%M:%S')
        else:
            return super(ComplexEncoder,self).default(obj)
d = { 'name':'alex','data':datetime.now()}
print(json.dumps(d,cls=ComplexEncoder))
# {"name": "alex", "data": "2018-05-18 19:52:05"}
复制代码

7六、json序列化时,默认遇到中文会转换成unicode,若是想要保留中文怎么办?

import json
a=json.dumps({"xxx":"你好"},ensure_ascii=False)
print(a) #{"xxx": "你好"}

7七、什么是断言?应用场景?

#条件成立则继续往下,不然抛出异常;
#通常用于:知足某个条件以后,才能执行,不然应该抛出异常。
'应用场景':rest framework中GenericAPIView类里,要设置queryset,不然断言错误

7八、有用过with statement吗?它的好处是什么?

with语句适用于对资源进行访问的场合,确保无论使用过程当中是否发生异常都会执行必要的“清理”操做,
释放资源,好比文件使用后自动关闭、线程中锁的自动获取和释放等。

7九、使用代码实现查看列举目录下的全部文件。

import os
path = os.listdir('.') #查看列举目录下的全部文件。
# path = os.listdir(os.getcwd())
print(path)

80、简述 yield和yield from关键字。

复制代码
1、yield使用 
1)函数中使用yield,能够使函数变成生成器。一个函数若是是生成一个数组,就必须把数据存储在内存中,若是使用生成器,则在调用的时候才生成数据,能够节省内存。
2)生成器方法调用时,不会当即执行。须要调用next()或者使用for循环来执行。

二、yield from的使用
1)为了让生成器(带yield函数),能简易的在其余函数中直接调用,就产生了yield from。 

参考:点击查看
复制代码

第二部分 网络编程和并发(34题)

一、简述 OSI 七层协议。

复制代码
物理层:主要基于电器特性发送高低电压(1、0),设备有集线器、中继器、双绞线等,单位:bit
数据链路层:定义了电信号的分组方式,设备:交换机、网卡、网桥,单位:帧
网络层:主要功能是将网络地址翻译成对应屋里地址,设备:路由
传输层:创建端口之间的通讯,tcp、udp协议
会话层:创建客户端与服务端链接
表示层:对来自应用层的命令和数据进行解释,按照必定格式传给会话层。如编码、数据格式转换、加密解密、压缩解压
应用层:规定应用程序的数据格式
复制代码

二、什么是C/S和B/S架构?

#C/S架构:
   client端与server端的服务架构
#B/S架构:
   隶属于C/S架构,Broswer端(网页端)与server端;
   优势:统一了全部应用的入口,方便、轻量级

三、简述 三次握手、四次挥手的流程。

复制代码
 
  
三次握手:
(1)第一次握手:Client向服务端发送一个请求创建链接的数据包,随机产生一个值,等待Server确认。
(2)第二次握手:Server收到数据包确认请求,随机产生一个值,并将该数据包发送给Client以确认链接请求。
(3)第三次握手:Client收到确认后,检测数据包,若是正确则链接创建成功,完成三次握手,随后Client与Server之间能够开始传输数据了。
四次挥手 ---> 断开链接
第一次挥手
    客户端向服务端发起请求断开链接的请求
第二次挥手
    服务端向客户端确认请求
第三次挥手
    服务端向客户端发起断开链接请求
第四次挥手
    客户端向服务端确认断开请求

断开链接是四次而发起链接是三次?
客户端和服务端的接收和发送数据都须要确认,因此是四次。
复制代码

四、什么是arp协议?

复制代码
#ARP(地址解析协议) 其主要用做将IP地址翻译为以太网的MAC地址

#在局域网中,网络中实际传输的是“帧”,帧里面是有目标主机的MAC地址的。

#在以太网中,一个主机要和另外一个主机进行直接通讯,必需要知道目标主机的MAC地址。


#所谓“地址解析”就是主机在发送帧前将目标IP地址转换成目标MAC地址的过程。
#ARP协议的基本功能就是经过目标设备的IP地址,查询目标设备的MAC地址,以保证通讯的顺利进行。
复制代码

五、TCP和UDP的区别?

复制代码
#TCP协议:面向链接
   - 通讯以前先三次握手
   - 断开以前先四次握手
   - 必须先启动服务端,再启动客户端-->链接服务端
   - 安全、可靠、面向链接(不会丢包)
#UDP协议:无链接
   - 传输速度快
   - 先启动哪一端均可以
   - 不面向链接,不能保证数据的完整性(如:QQ聊天)
复制代码

六、什么是局域网和广域网?

局域网和广域网是按规模大小而划分的两种计算机网络。

#范围在几公里之内的计算机网络统称为局域网(LAN、私网、内网);

#而链接的范围超过10公里的,则称为广域网,因特网(Intenet)就是目前最大的广域网(WAN、公网、外网)。

 

七、为什么基于tcp协议的通讯比基于udp协议的通讯更可靠?

由于TCP是面向链接的

通讯以前先三次握手,经过握手,确保链接成功以后再通讯
断开以前先四次挥手;双方互相确认以后再断开链接,这样一来保证了数据的安全、可靠,避免丢包

八、什么是socket?简述基于tcp协议的套接字通讯流程。

复制代码
#服务端:                    
   建立套接字               
   绑定IP和端口             
   监听                  
   accept等待链接          
   通讯(收recv、发send)
#客户端:
   建立套接字
   绑定IP和端口
   连接服务器
   通讯(收revc、发send)
复制代码

九、什么是粘包? socket 中形成粘包的缘由是什么? 哪些状况会发生粘包现象?

粘包:数据粘在一块儿,主要由于:接收方不知道消息之间的界限,不知道一次性提取多少字节的数据形成的
数据量比较小,时间间隔比较短,就合并成了一个包,这是底层的一个优化算法(Nagle算法)
什么状况会发生:
一、发送端须要等缓冲区满才发送出去,形成粘包(发送数据时间间隔很短,数据了很小,会合到一块儿,产生粘包)

二、接收方不及时接收缓冲区的包,形成多个包接收(客户端发送了一段数据,服务端只收了一小部分,
服务端下次再收的时候仍是从缓冲区拿上次遗留的数据,产生粘包)
 

十、IO多路复用的做用?

# IO多路复用分为时间上的复用和空间上的复用,
# 空间上的复用是指将内存分为几部分,每一部分放一个程序,这样同一时间内存中就有多道程序;
# 时间上的复用是指多个程序须要在一个cpu上运行,不一样的程序轮流使用cpu,
# 当某个程序运行的时间过长或者遇到I/O阻塞,操做系统会把cpu分配给下一个程序,
# 保证cpu处于高使用率,实现伪并发。

十一、什么是防火墙以及做用?

# 什么是防火墙?
防火墙是一个分离器,一个限制器,也是一个分析器,
有效地监控了内部网和Internet之间的任何活动,保证了内部网络的安全。
# 做用
防火墙可经过监测、限制、更改跨越防火墙的数据流,
尽量地对外部屏蔽网络内部的信息、结构和运行情况,以此来实现网络的安全保护。

十二、select、poll、epoll 模型的区别?

复制代码
# select本质上是经过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:
    # 1.单个进程可监视的fd数量被限制
    # 2.须要维护一个用来存放大量fd的数据结构
    #   这样会使得用户空间和内核空间在传递该结构时复制开销大
    # 3.对socket进行扫描时是线性扫描

# poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,
# 它没有最大链接数的限制,缘由是它是基于链表来存储的可是一样有一个缺点:
# 大量的fd的数组被总体复制于用户态和内核地址空间之间,而无论这样的复制是否是有意义。
# epoll支持水平触发和边缘触发,最大的特色在于边缘触发,
# 它只告诉进程哪些fd刚刚变为就需态,而且只会通知一次。
复制代码

1三、简述 进程、线程、协程的区别 以及应用场景?

# 进程
进程拥有本身独立的堆和栈,既不共享堆,亦不共享栈,进程由操做系统调度。
# 线程
线程拥有本身独立的栈和共享的堆,共享堆,不共享栈,线程亦由操做系统调度
# 协程和线程的区别
协程避免了无心义的调度,由此能够提升性能;但同时协程也失去了线程使用多CPU的能力。

进程与线程的区别
(1)地址空间:线程是进程内的一个执行单位,进程内至少有一个线程,他们共享进程的地址空间,而进程有本身独立的地址空间
(2)资源拥有:进程是资源分配和拥有的单位,同一个进程内线程共享进程的资源
(3)线程是处理器调度的基本单位,但进程不是
(4)两者都可并发执行
(5)每一个独立的线程有一个程序运行的入口

协程与线程
(1)一个线程能够有多个协程,一个进程也能够单独拥有多个协程,这样Python中则能使用多核CPU
(2)线程进程都是同步机制,而协程是异步
(3)协程能保留上一次调用时的状态

1四、GIL锁是什么鬼?

# GIL
线程全局锁(Global Interpreter Lock),即Python为了保证线程安全而采起的独立线程运行的限制,说白了就是一个核只能在同一时间运行一个线程.
对于io密集型任务,python的多线程起到做用,但对于cpu密集型任务,
python的多线程几乎占不到任何优点,还有可能由于争夺资源而变慢。

解决办法就是多进程和下面的协程(协程也只是单CPU,可是能减少切换代价提高性能).

多线程用于IO密集型,如socket,爬虫,web
多进程用于计算密集型,如金融分析
  1. 每一个cpython进程内都有一个GIL
  2. GIL致使同一进程内多个进程同一时间只能有一个运行
  3. 之因此有GIL,是由于Cpython的内存管理不是线程安全的
  4. 对于计算密集型用多进程,多IO密集型用多线程

1五、Python中如何使用线程池和进程池?

进程池:就是在一个进程内控制必定个数的线程
基于concurent.future模块的进程池和线程池 (他们的同步执行和异步执行是同样的)
参考:点击查看

1六、threading.local的做用?

a.threading.local
做用:为每一个线程开辟一块空间进行数据存储。
问题:本身经过字典建立一个相似于threading.local的东西。
storage = {
   4740: {val: 0},
   4732: {val: 1},
   4731: {val: 3},
}

b.自定义Local对象
做用:为每一个线程(协程)
开辟一块空间进行数据存储。
try:
   from greenlet import getcurrent as get_ident
except Exception as e:
   from threading import get_ident
from threading import Thread
import time
class Local(object):
   def __init__(self):
      object.__setattr__(self, 'storage', {})
   def __setattr__(self, k, v):
      ident = get_ident()
      if ident in self.storage:
         self.storage[ident][k] = v
      else:
         self.storage[ident] = {k: v}
   def __getattr__(self, k):
      ident = get_ident()
      return self.storage[ident][k]
obj = Local()
def task(arg):
   obj.val = arg
   obj.xxx = arg
   print(obj.val)
for i in range(10):
   t = Thread(target=task, args=(i,))
   t.start()
show

1七、进程之间如何进行通讯?

# 进程间通信有多种方式,包括信号,管道,消息队列,信号量,共享内存,socket等

1八、什么是并发和并行?

# 并发:同一时刻只能处理一个任务,但一个时段内能够对多个任务进行交替处理(一个处理器同时处理多个任务)
# 并行:同一时刻能够处理多个任务(多个处理器或者是多核的处理器同时处理多个不一样的任务)
# 类比:并发是一我的同时吃三个馒头,而并行是三我的同时吃三个馒头。

1九、进程锁和线程锁的做用?

复制代码
线程锁: 你们都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法 / 代码块时,同一时间只有一个线程在执行,其他线程必需要等待当前线程执行完以后才能执行该代码段。可是,其他线程是能够访问该对象中的非加锁代码块的。

进程锁: 也是为了控制同一操做系统中多个进程访问一个共享资源,只是由于程序的独立性,各个进程是没法控制其余进程对资源的访问的,可是能够使用本地系统的信号量控制(操做系统基本知识)。

分布式锁: 当多个进程不在同一个系统之中时,使用分布式锁控制多个进程对资源的访问。
参考:点击查看
复制代码

20、解释什么是异步非阻塞?

'非阻塞':
    遇到IO阻塞不等待(setblooking=False),(可能会报错->捕捉异常)
        - sk=socket.socket()
        - sk.setblooking(False)
'异步':
    回调(ajax),当达到某个指定状态以后,自动调用特定函数

2一、路由器和交换机的区别?

复制代码
'交换机'
用于在同一网络内数据快速传输转发,工做在数据链路层;
经过MAC寻址,不能动态划分子网;
只能在一条网络通路中运行,不能动态分配。

'路由器'
是一个网关设备,内部局域网到公网的一个关卡;
工做在网络层;
经过IP寻址,能够划分子网;
能够在多条网络通道中运行,能够动态分配IP地址。

'简单说'
交换机就是把一根网线变成多根网线;
路由器就是把一个网络变成多个网络;
若是不上外网,只是局域网,交换机便可;
若是上外网,而且给网络划分不一样网段,就必须用路由器。
复制代码

2二、什么是域名解析?

# 在网上,全部的地址都是ip地址,但这些ip地址太难记了,因此就出现了域名(好比http://baidu.com)。
# 而域名解析就是将域名,转换为ip地址的这样一种行为。
# 例如:访问www.baidu.com,实质是把域名解析成IP。

2三、如何修改本地hosts文件?

复制代码
'hosts':
Hosts就是将一些经常使用的网址域名与其对应的IP地址创建一个关联“数据库”
能够用来屏蔽一些网站,或者指定一些网站(修改hostsFQ)
'修改'# windows:
        位置:C:\Windows\System32\drivers\etc
        也能够经过第三方软件,我用的火绒,能够直接进行编辑hosts
    # linux:
        位置:/etc/hosts
        修改:vi /etc/hosts
复制代码

2四、生产者消费者模型应用场景及优点?

# 处理数据比较消耗时间,线程独占,生产数据不须要即时的反馈等。

生产者与消费者模式是经过一个容器来解决生产者与消费者的强耦合关系,生产者与消费者之间不直接进行通信,
而是利用阻塞队列来进行通信,生产者生成数据后直接丢给阻塞队列,消费者须要数据则从阻塞队列获取,
实际应用中,生产者与消费者模式则主要解决生产者与消费者生产与消费的速率不一致的问题,达到平衡生产者与消费者的处理能力,而阻塞队列则至关于缓冲区。 应用场景:用户提交订单,订单进入引擎的阻塞队列中,由专门的线程从阻塞队列中获取数据并处理 优点: 1;解耦 假设生产者和消费者分别是两个类。若是让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。 未来若是消费者的代码发生变化,可能会影响到生产者。而若是二者都依赖于某个缓冲区,二者之间不直接依赖,耦合也就相应下降了。 2:支持并发 生产者直接调用消费者的某个方法,还有另外一个弊端。因为函数调用是同步的(或者叫阻塞的),在消费者的方法没有返回以前,生产者只能一直等着 而使用这个模型,生产者把制造出来的数据只须要放在缓冲区便可,不须要等待消费者来取 3:支持忙闲不均 缓冲区还有另外一个好处。若是制造数据的速度时快时慢,缓冲区的好处就体现出来了。 当数据制造快的时候,消费者来不及处理,未处理的数据能够暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。
 

2五、什么是cdn?

# 用户获取数据时,不须要直接从源站获取,经过CDN对于数据的分发,
# 用户能够从一个较优的服务器获取数据,从而达到快速访问,并减小源站负载压力的目的。

2六、LVS是什么及做用?

# LVS即Linux虚拟服务器,是一个虚拟的四层交换器集群系统,
# 根据目标地址和目标端口实现用户请求转发,自己不产生流量,只作用户请求转发。

2七、Nginx是什么及做用?

Nginx是一个轻量级、高性能、稳定性高、并发性好的HTTP和反向代理服务器。
参考1:点击查看
参考2:点击查看

2八、keepalived是什么及做用?

Keepalived是Linux下一个轻量级别的高可用解决方案。
高可用,其实两种不一样的含义:广义来说,是指整个系统的高可用行,狭义的来说就是之主机的冗余和接管,
参考:点击查看

2九、haproxy是什么以及做用?

HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代 理,支持虚拟主机,它是免费、快速而且可靠的一种解决方案。
HAProxy特别适用于那些负载特大的web站点,这些站点一般又须要会话保持或七层处理。HAProxy运行在当前的硬件上,
彻底能够支持数以万计的并发链接。而且它的运行模式使得它能够很简单安全的整合进您当前的架中, 
同时能够保护你的web服务器不被暴露到网络上。
参考:点击查看

30、什么是负载均衡?

负载均衡有两方面的含义:
# 首先,大量的并发访问或数据流量分担到多台节点设备上分别处理,减小用户等待响应的时间;

# 其次,单个重负载的运算分担到多台节点设备上作并行处理,每一个节点设备处理结束后,
将结果汇总,返回给用户,系统处理能力获得大幅度提升。

3一、什么是rpc及应用场景?

复制代码
RPC 的全称是 Remote Procedure Call 是一种进程间通讯方式。
它容许程序调用另外一个地址空间(一般是共享网络的另外一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。

即程序员不管是调用本地的仍是远程的,本质上编写的调用代码基本相同
(例如QQ远程操做)

参考:点击查看
复制代码

3二、简述 asynio模块的做用和应用场景。

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。
asyncio的异步操做,须要在coroutine中经过yield from完成。

参考:点击查看

3三、简述 gevent模块的做用和应用场景。

Gevent 是一个第三方库,能够轻松经过gevent实现并发同步或异步编程,
在gevent中用到的主要模式是Greenlet, 它是以C扩展模块形式接入Python的轻量级协程。 
Greenlet所有运行在主程序操做系统进程的内部,但它们被协做式地调度。  

参考:点击查看

3四、twisted框架的使用和应用?

Twisted是一个事件驱动型的网络模型。
时间驱动模型编程是一种范式,这里程序的执行流由外部决定。
特色是:包含一个事件循环,当外部事件发生时,使用回调机制来触发相应的处理。

参考:点击查看

第三部分 数据库和缓存(46题)

一、列举常见的关系型数据库和非关系型都有那些?

'关系型'# sqllite、db二、oracle、access、SQLserver、MySQL
    # 注意:sql语句通用,须要有表结构
'非关系型'# mongodb、redis、memcache
    # 非关系型数据库是key-value存储的,没有表结构。

二、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)
复制代码

三、简述数据三大范式?

复制代码
# 数据库的三大特性:
'实体':表
'属性':表中的数据(字段)
'关系':表与表之间的关系
----------------------------------------------------
# 数据库设计三大范式:
'第一范式(1NF)'
    数据表中的每一列(每一个字段),必须是不可拆分的最小单元
    也就是确保每一列的原子性。
'第二范式(2NF)'
    知足第一范式后(1NF),要求表中的全部列,都必须依赖于主键,
    而不能有任何一列 与主键没有关系,也就是说一个表只描述一件事。
'第三范式(3NF)'
    必须先知足第二范式(2NF)
    要求:表中每一列只与主键直接相关而不是间接相关(表中每一列只能依赖于主键)
复制代码

四、什么是事务?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 手动关闭事务'
复制代码

五、数据库五大约束

'数据库五大约束'
    1.primary KEY:设置主键约束;
    2.UNIQUE:设置惟一性约束,不能有重复值;
    3.DEFAULT 默认值约束    
    4.NOT NULL:设置非空约束,该字段不能为空;
    5.FOREIGN key :设置外键约束。

六、简述数据库设计中一对多和多对多的应用场景?

# 一对一关系示例:
  一个学生对应一个学生档案材料,或者每一个人都有惟一的身份证编号。
# 一对多关系示例:(下拉单选)
  一个学生只属于一个班,可是一个班级有多名学生。
# 多对多关系示例:(下拉多选)
  一个学生能够选择多门课,一门课也有多名学生。

七、如何基于数据库实现商城商品计数器?

参考:点击查看

八、常见SQL(必备)

详见:点击查看

九、简述触发器、函数、视图、存储过程?

复制代码
'触发器':
    对数据库某个表进行【增、删、改】先后,自定义的一些SQL操做
'函数':
    在SQL语句中使用的函数 #例如:select sleep(2)
    聚合函数:max、sam、min、avg
    时间格式化:date_format
    字符串拼接:concat
    自定制函数:(触发函数经过 select)
'视图':
    对某些表进行SQL查询,将结果实时显示出来(是虚拟表),只能查询不能更新
'存储过程':
    将提早定义好的SQL语句保存到数据库中并命名;之后在代码中调用时直接经过名称便可
参数类型:
  in    只将参数传进去
  out   只拿结果
  inout 既能够传,能够取

函数与存储过程区别:
本质上没区别。只是函数有如:只能返回一个变量的限制。而存储过程能够返回多个。而函数是能够嵌入在sql中使用的,能够在select中调用,而存储过程不行。
 
  
复制代码

十、MySQL索引种类

复制代码
'主键索引(单列)':
    primary key
    加速查找+约束:不能重复、不能为空
'普通索引(单列)':
    加速查找
'惟一索引(单列)':
    unique
    加速查找+约束:不能重复
'联合索引(多列)':
    查询时根据多列进行查询(最左前缀)
'联合惟一索引(多列)':
    遵循最左前缀规则(命中索引)
# 其余词语
    1、索引合并:利用多个单列索引查询
    二、覆盖索引:在索引表中就能将想要的数据查询到
复制代码

十一、索引在什么状况下遵循最左前缀的规则?

复制代码
你能够认为联合索引是闯关游戏的设计
例如你这个联合索引是state/city/zipCode
那么state就是第一关 city是第二关, zipCode就是第三关
你必须匹配了第一关,才能匹配第二关,匹配了第一关和第二关,才能匹配第三关
你不能直接到第二关的
索引的格式就是第一层是state,第二层才是city

参考:点击查看
复制代码

十二、主键和外键的区别?

复制代码
'主键'
    惟一标识一条记录
    用来保证数据的完整性
    主键只能有一个
'外键'
    表的外键是另外一个表的主键,外键能够有重复的,能够是空值
    用来和其余表创建联系用的
    一个表能够有多个外键
'索引'
    该字段没有重复值,但能够有一个空值
    提升查询速度
    一个表能够有多个惟一索引
复制代码

1三、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() #随机数
复制代码

1四、列举 建立索引可是没法命中索引的8种状况。

复制代码
#使用'like ‘%xx’'
    select * from tb1 where name like '%cn';
#使用'函数'
    select * from tb1 where reverse(name)='zgc';
#使用'or'
    select * from tb1 where nid=1 or  email='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 * from tb1 where name=666#含有'!= '
    select * from tb1 where name != 'zgc';
    特别的:若是是主键,仍是会走索引
            # select * from tb1 where nid != 123;
#含有'>'
    select * from tb1 where name > 'zgc';
    特别的:若是是主键或者索引是整数类型,则仍是会走索引
            # select * from tb1 where nid > 123;
            # select * from tb1 where name > 123;
#含有'order by'
    select email from tb1 order by name desc;
    当根据索引排序时,选择的映射若是不是索引,则不走索引
    特别的:若是对主键排序,则仍是走索引:
            # select * from tb1 order by nid desc;

#组合索引最左前缀
    若是组合索引为:(name,email)
    name and email #使用索引
    name           #使用索引
    email          #不使用索引
复制代码

1五、如何开启慢日志查询?

'能够经过修改配置文件开启'
slow_query_log=ON   #是否开启慢日志记录
long_query_time=2   #时间限制,超过此时间,则记录
slow_query_log_file=/usr/slow.log  #日志文件
long_queries_not_using_indexes=ON  #是否记录使用索引的搜索

1六、数据库导入导出命令(结构+数据)?

#导出:
 mysqldump -h 服务器 -u用户名 -p密码 数据库名 > 备份文件.sql
#导入: 一、mysqldump -uroot -p 数据库名称 < 路径 二、进入数据库; source + 要导入数据库文件路径

1七、数据库优化方案?

复制代码
1、建立数据表时把固定长度的放在前面
二、将固定数据放入内存:choice字段(django中用到,1,2,3对应相应内容)
3、char不可变,varchar可变
4、联合索引遵循最左前缀(从最左侧开始检索)
五、避免使用 select *
6、读写分离:
    #利用数据库的主从分离:主,用于删除、修改、更新;从,用于查
    #实现:两台服务器同步数据
    \原生SQL:select * from db.tb
    \ORM:model.User.object.all().using('default')
    \路由:db router
7、分库
    # 当数据库中的表太多,将某些表分到不一样数据库,例如:1W张表时
    # 代价:连表查询跨数据库,代码变多
8、分表
    # 水平分表:将某些列拆分到另外一张表,例如:博客+博客详情
    # 垂直分表:将某些历史信息,分到另一张表中,例如:支付宝帐单
9、加缓存
    # 利用redis、memcache(经常使用数据放到缓存里,提升取数据速度)
    # 缓存不够可能会形成雪崩现象
10、若是只想获取一条数据
    select * from tb where name = 'zgc' limit 1;
复制代码

1八、char和varchar的区别?

复制代码
#char类型:定长不可变
存入字符长度大于设置长度时报错;
存入字符串长度小于设置长度时,用空格填充以达到设置字符串长度;
简单粗暴,浪费空间,存取速度快。
#varchar类型:可变
存储数据真实内容,不使用空格填充;
会在真实数据前加1-2Bytes的前缀,用来表示真实数据的bytes字节数;
边长、精准、节省空间、存取速度慢。
复制代码

1九、简述MySQL的执行计划?

# explain + SQL语句
# SQL在数据库中执行时的表现状况,一般用于SQL性能分析,优化等场景。
 'explain select * from rbac_userinfo where id=1;'
查看有没有命中索引,让数据库帮看看运行速度快不快
explain select * from table;
 
  

 
  

当type为all时,是为全表索引

 

20、在对name作了惟一索引前提下,简述如下区别:
 

select * from tb where name = ‘小明’
select * from tb where name = ‘小明’ limit 1
-------------------------------------------------------------
没作惟一索引的话,前者查询会全表扫描,效率低些
limit 1,只要找到对应一条数据,就不继续往下扫描.
然而 name 字段添加惟一索引了,加不加limit 1,意义都不大;

2一、1000w条数据,使用limit offset 分页时,为何越日后翻越慢?如何解决?

复制代码
# 例如:
#limit 100000,20; 从第十万条开始日后取二十条,
#limit 20 offset 100000; limit后面是取20条数据,offset后面是从第10W条数据开始读
由于当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会很是缓慢
--------------------------------------------------------------------------
'优化一'
先查看主键,再分页:
select * from tb where id in (select id from tb where limit 10 offset 30)
--------------------------------------------------------------------------
'优化二'
记录当前页,数据、ID、最大值和最小值(用于where查询)
在翻页时,根据条件进行筛选,筛选完毕后,再根据 limit offset 查询
select * from(select * from tb where id > 2222) as B limit 10 offset 0;
\若是用户本身修改页码,也可能致使变慢,此时能够对 url 页码进行加密,例如rest framework
--------------------------------------------------------------------------
'优化三'
能够按照当前业务需求,看是否能够设置只容许看前200页;
通常状况下,没人会咔咔看个几十上百页的;
复制代码

2二、什么是索引合并?

# 索引合并访问方法能够在查询中对一个表使用多个索引,对它们同时扫描,而且合并结果。
# 此访问方法合并来自单个表的索引扫描; 它不会将扫描合并到多个表中。

2三、什么是覆盖索引?

# 解释一:
  就是select的数据列只用从索引中就可以取得,没必要从数据表中读取,换句话说查询列要被所使用的索引覆盖。
# 解释二:
  索引是高效找到行的一个方法,当能经过检索索引就能够读取想要的数据,那就不须要再到数据表中读取行了。
  若是一个索引包含了(或覆盖了)知足查询语句中字段与条件的数据就叫作覆盖索引。
# 注意:MySQL只能使用B-Tree索引作覆盖索引

2四、简述数据库读写分离?

#利用数据库的主从分离:主,用于删除、修改、更新;从,用于查
#实现:两台服务器同步数据(减轻服务器的压力)
       原生SQL: select * from db.tb
       ORM:model.User.object.all().using('default')
       路由:db router

2五、简述数据库分库分表?(水平、垂直)

# 一、分库
    当数据库中的表太多,将某些表分到不一样数据库,例如:1W张表时
    代价:连表查询跨数据库,代码变多
# 二、分表
    水平分表:将某些列拆分到另外一张表,例如:博客+博客详情
    垂直分表:将某些历史信息,分到另一张表中,例如:支付宝帐单

2六、redis和memcached比较?

复制代码
# 1.存储容量:
    memcached超过内存比例会抹掉前面的数据,而redis会存储在磁盘
# 2.支持数据类型:
    memcached只支持string;
    redis支持更多;如:hash、list、集合、有序集合
# 3.持久化:
    redis支持数据持久化,能够将内存中的数据保持在磁盘中,memcached无
# 4.主从:
    即master-slave模式的数据备份(主从)。
# 5.特性
    Redis在不少方面具有数据库的特征,或者说就是一个数据库系统
    Memcached只是简单的K/V缓存
复制代码

2七、redis中数据库默认是多少个db 及做用?

#redis默认有16个db,db0~db15(能够经过配置文件支持更多,无上限)
#而且每一个数据库的数据是隔离的不能共享
#能够随时使用SELECT命令更换数据库:redis> SELECT 1
# 注意:
      多个数据库之间并非彻底隔离的
      好比FLUSHALL命令能够清空一个Redis实例中全部数据库中的数据。

2八、python操做redis的模块?

参考:点击查看

2九、若是redis中的某个列表中的数据量很是大,若是实现循环显示每个值?

复制代码
# 经过scan_iter分片取,减小内存压力
scan_iter(match=None, count=None)增量式迭代获取redis里匹配的的值
# match,匹配指定key
# count,每次分片最少获取个数
    r = redis.Redis(connection_pool=pool)
    for key in r.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服务器把备份文件数据导入到数据库中.
复制代码

3一、redis中的sentinel的做用?

# 帮助咱们自动在主从之间进行切换(哨兵)
# 检测主从中 主是否挂掉,且超过一半的sentinel检测到挂了以后才进行进行切换。
# 若是主修复好了,再次启动时候,会变成从。

3二、如何实现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技术团队。
复制代码

3三、redis中默认有多少个哈希槽?

#redis中默认有 16384 个哈希槽。

3四、简述redis的有哪几种持久化策略及比较?

#RDB:每隔一段时间对redis进行一次持久化。
     - 缺点:数据不完整
     - 优势:速度快
#AOF:把全部命令保存起来,若是想从新生成到redis,那么就要把命令从新执行一次。
     - 缺点:速度慢,文件比较大
     - 优势:数据完整

3五、列举redis支持的过时策略。

复制代码
# 数据集(server.db[i].expires)
a、voltile-lru:    #从已设置过时时间的数据集中,挑选最近频率最少数据淘汰
b、volatile-ttl:   #从已设置过时时间的数据集中,挑选将要过时的数据淘汰
c、volatile-random:#从已设置过时时间的数据集中,任意选择数据淘汰
d、allkeys-lru:       #从数据集中,挑选最近最少使用的数据淘汰
e、allkeys-random:    #从数据集中,任意选择数据淘汰
f、no-enviction(驱逐):#禁止驱逐数据
复制代码

3六、MySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中都是热点数据? 

# 限定Redis占用的内存,根据自身数据淘汰策略,淘汰冷数据,把热数据加载到内存。
# 计算一下 20W 数据大约占用的内存,而后设置一下Redis内存限制便可。

3七、写代码,基于redis的列表实现 先进先出、后进先出队列、优先级队列。???????????????????

Redis能作消息队列得益于他list对象blpop/brpop接口以及Pub/Sub(发布/订阅)的某些接口。他们都是阻塞版的,因此Redis实现消息队列有两种方式:
1、经过数据结构list来实现
2、经过pub/sub来实现

3八、如何基于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,用它作缓存、作计算,还作任务队列,压力太大,很差。
复制代码

3九、如何基于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 服务.

4一、什么是twemproxy及做用?

复制代码
# 什么是Twemproxy 
是Twtter开源的一个 Redis 和 Memcache 代理服务器,
主要用于管理 Redis 和 Memcached 集群,减小与Cache服务器直接链接的数量。
他的后端是多台REDIS或memcached因此也能够被称为分布式中间件。
# 做用
    经过代理的方式减小缓存服务器的链接数。
    自动在多台缓存服务器间共享数据。
    经过配置的方式禁用失败的结点。
    运行在多个实例上,客户端能够链接到首个可用的代理服务器。
    支持请求的流式与批处理,于是可以下降来回的消耗。
复制代码

4二、写代码实现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是否支持事务
复制代码

4三、redis中的watch的命令的做用?

# 用于监视一个或多个key
# 若是在事务执行以前这个/些key被其余命令改动,那么事务将被打断

4四、基于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()
数据库的锁 
复制代码

4五、简述redis分布式锁和redlock的实现机制。

复制代码
# redis分布式锁?
# 不是单机操做,又多了一/多台机器
# redis内部是单进程、单线程,是数据安全的(只有本身的线程在操做数据)
----------------------------------------------------------------
#A、B、C,三个实例(主)
一、来了一个'隔壁老王'要操做,且不想让别人操做,so,加锁;
    加锁:'隔壁老王'本身生成一个随机字符串,设置到A、B、C里(xxx=666)
二、来了一个'邻居老李'要操做A、B、C,一读发现里面有字符串,擦,被加锁了,不能操做了,等着吧~
三、'隔壁老王'解决完问题,不用锁了,把A、B、C里的key:'xxx'删掉;完成解锁
四、'邻居老李'如今能够访问,能够加锁了
# 问题:
一、若是'隔壁老王'加锁后忽然挂了,就没人解锁,就死锁了,其余人干看着无法用咋办?
二、若是'隔壁老王'去给A、B、C加锁的过程当中,刚加到A,'邻居老李'就去操做C了,加锁成功or失败?
三、若是'隔壁老王'去给A、B、C加锁时,C忽然挂了,此次加锁是成功仍是失败?
四、若是'隔壁老王'去给A、B、C加锁时,超时时间为5秒,加一个锁耗时3秒,这次加锁能成功吗?
# 解决
一、安全起见,让'隔壁老王'加锁时设置超时时间,超时的话就会自动解锁(删除key:'xxx')
二、加锁程度达到(1/2)+1个就表示加锁成功,即便没有给所有实例加锁;
三、加锁程度达到(1/2)+1个就表示加锁成功,即便没有给所有实例加锁;
4、不能成功,锁还没加完就过时,没有意义了,应该合理设置过时时间
# 注意
    使用须要安装redlock-py
----------------------------------------------------------------
from redlock import Redlock
dlm = Redlock(
    [
        {"host": "localhost", "port": 6379, "db": 0},
        {"host": "localhost", "port": 6379, "db": 0},
        {"host": "localhost", "port": 6379, "db": 0},
    ]
)
# 加锁,acquire
my_lock = dlm.lock("my_resource_name",10000)
if  my_lock:
    # 进行操做
    # 解锁,release
    dlm.unlock(my_lock)
else:
    print('获取锁失败')
#经过sever.eval(self.unlock_script)执行一个lua脚本,用来删除加锁时的key
复制代码

4六、什么是一致性哈希?Python中是否有相应模块?

# 一致性哈希
一致性hash算法(DHT)能够经过减小影响范围的方式,解决增减服务器致使的数据散列问题,从而解决了分布式环境下负载均衡问题;
若是存在热点数据,能够经过增添节点的方式,对热点区间进行划分,将压力分配至其余服务器,从新达到负载均衡的状态。
# 模块:hash_ring

4七、如何高效的找到redis中全部以zhugc开头的key?

复制代码
redis 有一个keys命令。
# 语法:KEYS pattern
# 说明:返回与指定模式相匹配的所用的keys。
该命令所支持的匹配模式以下:
1、?:用于匹配单个字符。例如,h?llo能够匹配hello、hallo和hxllo等;
二、*:用于匹配零个或者多个字符。例如,h*llo能够匹配hllo和heeeello等;
二、[]:能够用来指定模式的选择区间。例如h[ae]llo能够匹配hello和hallo,可是不能匹配hillo。同时,能够使用“/”符号来转义特殊的字符
# 注意
KEYS 的速度很是快,但若是数据太大,内存可能会崩掉,
若是须要从一个数据集中查找特定的key,最好仍是用Redis的集合结构(set)来代替。
复制代码

4八、悲观锁和乐观锁的区别?

# 悲观锁
    从数据开始更改时就将数据锁住,直到更改完成才释放;
    会形成访问数据库时间较长,并发性很差,特别是长事务。
# 乐观锁
    直到修改完成,准备提交修改到数据库时才会锁住数据,完成更改后释放;
    相对悲观锁,在现实中使用较多。

第四部分 前端、框架和其余(155题)

1.谈谈你对http协议的认识。

复制代码
复制代码
  浏览器本质,socket客户端遵循Http协议
  HTTP协议本质:经过\r\n分割的规范+ 请求响应以后断开连接   ==  >  无状态、 短链接
具体:
  Http协议是创建在tcp之上的,是一种规范,它规范定了发送的数据的数据格式,
然而这个数据格式是经过\r\n 进行分割的,请求头与请求体也是经过2个\r\n分割的,响应的时候,
响应头与响应体也是经过\r\n分割,而且还规定已请求已响应就会断开连接   
即--->  短链接、无状态
复制代码
复制代码

 

2.谈谈你对websocket协议的认识。

复制代码
复制代码
websocket是给浏览器新建的一套(相似与http)协议,协议规定:(\r\n分割)浏览器和服务器链接以后不断开,
    以此完成:服务端向客户端主动推送消息。

websocket协议额外作的一些操做
握手  ---->  链接钱进行校验
加密  ----> payload_len=127/126/<=125   --> mask key 

复制代码
本质
建立一个链接后不断开的socket
当链接成功以后:
    客户端(浏览器)会自动向服务端发送消息,包含: Sec-WebSocket-Key: iyRe1KMHi4S4QXzcoboMmw==
    服务端接收以后,会对于该数据进行加密:base64(sha1(swk + magic_string))
    构造响应头:
            HTTP/1.1 101 Switching Protocols\r\n
            Upgrade:websocket\r\n
            Connection: Upgrade\r\n
            Sec-WebSocket-Accept: 加密后的值\r\n
            WebSocket-Location: ws://127.0.0.1:8002\r\n\r\n        
    发给客户端(浏览器)
创建:双工通道,接下来就能够进行收发数据
    发送数据是加密,解密,根据payload_len的值进行处理
        payload_len <= 125
        payload_len == 126
        payload_len == 127
    获取内容:
        mask_key
        数据
        根据mask_key和数据进行位运算,就能够把值解析出来。
复制代码
复制代码
复制代码
复制代码

 3.什么是magic string ?

 客户端向服务端发送消息时,会有一个'sec-websocket-key'和'magic string'的随机字符串(魔法字符串)
# 服务端接收到消息后会把他们链接成一个新的key串,进行编码、加密,确保信息的安全性

4.如何建立响应式布局?

复制代码
复制代码
响应式布局是经过@media实现的
@media (min-width:768px){
     .pg-header{
           background-color:green;
      }      
}
@media   (min-width:992px){
     .pg-header{
            background-color:pink;
     }
}    

代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <style>
        body{ margin: 0; } .pg-header{ background-color: red; height: 48px; } @media (min-width: 768px) { .pg-header{ background-color: aqua; } } @media (min-width: 992px) { .pg-header{ background-color: blueviolet; } } </style> </head> <body> <div class="pg-header"></div> </body> </html>
复制代码
复制代码

5.你曾经使用过哪些前端框架?

jQuery
- BootStrap
- Vue.js(与vue齐名的前端框架React和Angular)

6.什么是ajax请求?并使用jQuery和XMLHttpRequest对象实现一个ajax请求。

基于原生AJAX - Demo
基于jQueryAjax - Demo

http://www.cnblogs.com/wupeiqi/articles/5703697.html

7.如何在前端实现轮训?

复制代码
复制代码
 轮询:经过定时器让程序每隔n秒执行一次操做。

复制代码
复制代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h1>请选出最帅的男人</h1>
    <ul>
        {% for k,v in gg.items() %}
            <li>ID:{{ k }}, 姓名:{{ v.name }} ,票数:{{ v.count }}</li> {% endfor %} </ul> <script> setInterval(function () { location.reload(); },2000) </script> </body> </html>
复制代码
复制代码
复制代码
复制代码

8.如何在前端实现长轮训?

复制代码
复制代码
客户端向服务器发送请求,服务器接到请求后hang住链接,等待30秒,30s事后再从新发起请求,
直到有新消息才返回响应信息并关闭链接,客户端处理完响应信息后再向服务器发送新的请求。
利用queue对象实现请求夯住
  每一个请求进来都要生成一个q对象
  若是有人投票 给全部的q对象put数据
  拿数据请求从本身的q对象get数据
复制代码
复制代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
</head>
<body>
    <h1>请选出最帅的男人</h1>
    <ul>
        {% for k,v in gg.items() %}
            <li style="cursor: pointer" id="user_{{ k }}" ondblclick="vote({{ k }});">ID:{{ k }}, 姓名:{{ v.name }} ,票数:<span>{{ v.count }}</span></li> {% endfor %} </ul> <script src="/static/jquery-3.3.1.min.js"></script> <script> $(function () { get_new_count(); }); function get_new_count() { $.ajax({ url: '/get_new_count', type:'GET', dataType:'JSON', success:function (arg) { if (arg.status){ // 更新票数 var gid = "#user_" + arg.data.gid; $(gid).find('span').text(arg.data.count); }else{ // 10s内没有人投票  } get_new_count(); } }) } function vote(gid) { $.ajax({ url: '/vote', type:'POST', data:{gid:gid}, dataType:"JSON", success:function (arg) { } }) } </script> </body> </html>
复制代码
复制代码
复制代码
复制代码

9.vuex的做用?

复制代码
复制代码
多组件之间共享:vuex

补充luffyvue
1:router-link / router-view
2:双向绑定,用户绑定v-model
3:循环展现课程:v-for
4:路由系统,添加动态参数
5:cookie操做:vue-cookies
6:多组件之间共享:vuex
7:发送ajax请求:axios (js模块)
复制代码
复制代码

10.vue中的路由的拦截器的做用?

 vue-resource的interceptors拦截器的做用正是解决此需求的妙方。
在每次http的请求响应以后,若是设置了拦截器以下,会优先执行拦截器函数,获取响应体,而后才会决定是否把response返回给then进行接收

11.axios的做用?

发送ajax请求:axios (js模块)

12.列举vue的常见指令。

复制代码
复制代码
 一、v-if指令:判断指令,根据表达式值得真假来插入或删除相应的值。
  二、v-show指令:条件渲染指令,不管返回的布尔值是true仍是false,元素都会存在在html中,只是false的元素会隐藏在html中,并不会删除.
  三、v-else指令:配合v-if或v-else使用。
  四、v-for指令:循环指令,至关于遍历。
  五、v-bind:给DOM绑定元素属性。
  六、v-on指令:监听DOM事件。
复制代码
复制代码

13.简述jsonp及实现原理?

JSONP
jsonp是json用来跨域的一个东西。原理是经过script标签的跨域特性来绕过同源策略。
JSONP的简单实现模式,或者说是JSONP的原型:建立一个回调函数,而后在远程服务上调用这个函数而且将JSON 数据形式做为参数传递,
完成回调。 

14.什么是cors ?

复制代码
复制代码
CORS
浏览器将CORS请求分红两类:简单请求和赋复杂请求

简单请求(同时知足如下两大条件)
(1)请求方法是如下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出如下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type  :只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不一样时知足上面两个条件,就属于非简单请求
复制代码
复制代码

15.列举Http请求中常见的请求方式?

复制代码
复制代码
GET、POST、
PUT、patch(修改数据) HEAD(相似于get请求,只不过返回的响应中没有具体的内容,用于获取报头) DELETE

传值代码f
Request.QueryString方法针对控件id
Request.Form方法针对控件名称name
复制代码
复制代码

16.列举Http请求中的状态码?

复制代码
复制代码
分类:
1**  信息,服务器收到请求,须要请求者继续执行操做
2**  成功,操做被成功接收并处理
3** 重定向,须要进一步的操做以完成请求
4** 客户端错误,请求包含语法错误或没法完成请求
5** 服务器错误,服务器在处理请求的过程当中发生了错误

常见的状态码
200 -请求成功
202 -已接受请求,还没有处理
204 -请求成功,且不需返回内容 301 - 资源(网页等)被永久转移到其余url
400 - 请求的语义或是参数有错
403 - 服务器拒绝请求 404 - 请求资源(网页)不存在
500 - 内部服务器错误
502 - 网关错误,通常是服务器压力过大致使链接超时
503 - 因为超载或系统维护,服务器暂时的没法处理客户端的请求。
复制代码
复制代码

17.列举Http请求中常见的请求头?

- user-agent
- host
- referer
- cookie 
- content-type 

18.看图写结果(js):

 李杰

看图写结果(js):

 武沛奇

看图写结果:(js)

 老男孩

看图写结果:(js)


 undefined

看图写结果:(js)

  武沛奇

看图写结果:(js)

 Alex

19.django、flask、tornado框架的比较?

复制代码
复制代码
对于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使用werkzeug wsgi 还有一个区别就是他们的请求管理不太同样:django是经过将请求封装成request对象,再经过参数传递,而flask是经过上下文管理机制

Tornado

# 是一个轻量级的Web框架,异步非阻塞+内置WebSocket功能。

'目标':经过一个线程处理N个并发请求(处理IO)。

'内部组件

    #内部本身实现socket

    #路由系统

    #视图

  #模板

   #cookie

    #csrf

复制代码
复制代码

20.什么是wsgi?

复制代码
复制代码
是web服务网关接口,是一套协议。
是经过如下模块实现了wsgi协议:
    - wsgiref
    - werkzurg
    - uwsgi   关于部署
以上模块本质:编写socket服务端,用于监听请求,当有请求到来,则将请求数据进行封装,而后交给web框架处理。
复制代码
复制代码

21.django请求的生命周期?

用户请求进来先走到  wsgi   而后将请求交给  jango的中间件   穿过django中间件(方法是process_request)  
接着就是 路由匹配 路由匹配成功以后就执行相应的 视图函数
在视图函数中能够调用orm作数据库操做 再从模板路径 将模板拿到 而后在后台进行模板渲染
模板渲染完成以后就变成一个字符串 再把这个字符串通过全部中间件(方法:process_response) 和wsgi 返回给用户

22.列举django的内置组件?

复制代码
复制代码
form 组件
- 对用户请求的数据进行校验
- 生成HTML标签

PS:
- form对象是一个可迭代对象。
- 问题:choice的数据若是从数据库获取可能会形成数据没法实时更新
        - 重写构造方法,在构造方法中从新去数据库获取值。
        - ModelChoiceField字段
            from django.forms import Form
            from django.forms import fields
            from django.forms.models import ModelChoiceField
            class UserForm(Form):
                name = fields.CharField(label='用户名',max_length=32)
                email = fields.EmailField(label='邮箱')
                ut_id = ModelChoiceField(queryset=models.UserType.objects.all())    
            
            依赖:
                class UserType(models.Model):
                    title = models.CharField(max_length=32)

                    def __str__(self):
                        return self.title
复制代码
复制代码
复制代码
复制代码
信号、
django的信号其实就是django内部为开发者预留的一些自定制功能的钩子。
只要在某个信号中注册了函数,那么django内部执行的过程当中就会自动触发注册在信号中的函数。
如: 
pre_init # django的modal执行其构造方法前,自动触发
post_init # django的modal执行其构造方法后,自动触发
pre_save # django的modal对象保存前,自动触发
post_save # django的modal对象保存后,自动触发
场景:
在数据库某些表中添加数据时,能够进行日志记录。


CSRF、
目标:防止用户直接向服务端发起POST请求。
对全部的post请求作验证/ 将jango生成的一串字符串发送给咱们,一种是从请求体发过来,一种是放在隐藏的标签里面用的是process_view 
方案:先发送GET请求时,将token保存到:cookie、Form表单中(隐藏的input标签),
之后再发送请求时只要携带过来便可。


ContentType
contenttype是django的一个组件(app),
为咱们找到django程序中全部app中的全部表并添加到记录中。
能够使用他再加上表中的两个字段实现:一张表和N张表建立FK关系。 - 字段:表名称 - 字段:数据行ID
应用:路飞表结构优惠券和专题课和学位课关联。
复制代码
复制代码
中间件
对全部的请求进行批量处理,在视图函数执行先后进行自定义操做。
应用:用户登陆校验
问题:为甚么不使用装饰器?
若是不使用中间件,就须要给每一个视图函数添加装饰器,太繁琐
权限组件:
用户登陆后,将权限放到session中,而后再每次请求进来在中间件里,根据当前的url去session中匹配,
判断当前用户是否有权限访问当前url,有权限就继续访问,没有就返回, (检查的东西就能够放到中间件中进行统一处理)在process_request方法里面作的,  咱们的中间件是放在session后面,由于中间件须要到session里面取数据
复制代码
复制代码
session
cookie与session区别
(a)cookie是保存在浏览器端的键值对,而session是保存的服务器端的键值对,可是依赖cookie。
(也能够不依赖cookie,能够放在url,或请求头可是cookie比较方便) (b)以登陆为例,cookie为经过登陆成功后,设置明文的键值对,并将键值对发送客户端存,明文信息可能存在泄漏,不安全;
  session则是生成随机字符串,发给用户,并写到浏览器的cookie中,同时服务器本身也会保存一份。 (c)在登陆验证时,cookie:根据浏览器发送请求时附带的cookie的键值对进行判断,若是存在,则验证经过;
  session:在请求用户的cookie中获取随机字符串,根据随机字符串在session中获取其对应的值进行验证
复制代码
复制代码
cors跨域(场景:先后端分离时,本地测试开发时使用)
若是网站之间存在跨域,域名不一样,端口不一样会致使出现跨域,但凡出现跨域,浏览器就会出现同源策略的限制
解决:在咱们的服务端给咱们响应数据,加上响应头---> 在中间件加的
复制代码
复制代码
 
  
缓存/   
经常使用的数据放在缓存里面,就不用走视图函数,请求进来经过全部的process_request,会到缓存里面查数据,有就直接拿,
        没有就走视图函数
      关键点:1:执行完全部的process_request才去缓存取数据
          2:执行完全部的process_response才将数据放到缓存

关于缓存问题
1:为何放在最后一个process_request才去缓存 由于须要验证完用户的请求,才能返回数据 2:何时将数据放到缓存中 第一次走中间件,缓存没有数据,会走视图函数,取数据库里面取数据, 当走完process_response,才将数据放到缓存里,由于,走process_response的时候可能给咱们的响应加处理

复制代码
复制代码
为何使用缓存
将经常使用且不太频繁修改的数据放入缓存。
之后用户再来访问,先去缓存查看是否存在,若是有就返回
不然,去数据库中获取并返回给用户(再加入到缓存,以便下次访问)

23.列举django中间件的5个方法?以及django中间件的应用场景?

process_request(self,request)  先走request 经过路由匹配返回
process_view(self, request, callback, callback_args, callback_kwargs) 再返回执行view
process_template_response(self,request,response)   当视图函数的返回值
process_exception(self, request, exception)  当视图函数的返回值对象中有render方法时,该方法才会被调用
process_response(self, request, response)

执行流程

24.简述什么是FBV和CBV?

复制代码
复制代码
FBV 基于函数
# FBV 写法
# urls.py
 url(r'^login/$',views.login, name="login"),

# views.py
def login(request):
    if request.method == "POST":
        print(request.POST)

    return render(request,"login.html")

# HTML
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>登陆页面</title>
</head>
<body>
<form action="{% url 'login' %}" method="post" enctype="multipart/form-data">
    <input type="text" name="user2">
    <input type="file" name="file">
    <input type="submit" value="提交">


</form>
</body>
</html> CBV 基于类 # urls.py url(r'^login/$',views.Login.as_view(), name="login"), # views.py from django.views import View class Login(View): # 类首字母大写 def get(self,request): return render(request,"login.html") def post(self,request): print(request.POST) return HttpResponse("OK") 加装饰器 ================================= class IndexView(View): # 若是是crsf相关,必须放在此处 def dispach(self,request): # 经过反射执行post/get @method_decoretor(装饰器函数) def get(self,request): pass def post(self,request): pass 路由:IndexView.as_view()
复制代码
复制代码

25.FBV与CBV的区别

- 没什么区别,由于他们的本质都是函数。CBV的.as_view()返回的view函数,view函数中调用类的dispatch方法,
在dispatch方法中经过反射执行get/post/delete/put等方法。D

非要说区别的话:
- CBV比较简洁,GET/POST等业务功能分别放在不一样get/post函数中。FBV本身作判断进行区分。

26.django的request对象是在何时建立的?

当请求一个页面时, Django会创建一个包含请求元数据的 HttpRequest 对象. 
当Django 加载对应的视图时, HttpRequest对象将做为视图函数的第一个参数.
每一个视图会返回一个HttpResponse对象.

27.如何给CBV的程序添加装饰器?

复制代码
复制代码
添加装饰器
方式一:
from django.views import View
from django.utils.decorators import method_decorator  ---> 须要引入memethod_decorator

def auth(func):
    def inner(*args,**kwargs):
        return func(*args,**kwargs)
    return inner

class UserView(View):
    @method_decorator(auth)
    def get(self,request,*args,**kwargs):
        return HttpResponse('...')    

方式二:
- csrf的装饰器要加到dispath前面
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect   ---> 须要引入 csrf_exempt


class UserView(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return HttpResponse('...')

或者:
from django.views import View
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect

@method_decorator(csrf_exempt,name='dispatch')  --->  指定名字
class UserView(View):
    def dispatch(self, request, *args, **kwargs):
        return HttpResponse('...')
复制代码
复制代码

28.列举django orm 中全部的方法(QuerySet对象的全部方法)

复制代码
复制代码
返回QuerySet对象的方法有:
      all()
      filter()
      exclude()
      order_by()
      reverse()
      distinct()
  特殊的QuerySet:
      values()       返回一个可迭代的字典序列
      values_list() 返回一个可迭代的元组序列
  返回具体对象的:
      get()
      first()
      last()
  返回布尔值的方法有:
      exists()
  返回数字的方法有:
      count() 
复制代码
复制代码

29.only和defer的区别?

复制代码
复制代码
 def defer(self, *fields):
    models.UserInfo.objects.defer('username','id')
    或
    models.UserInfo.objects.filter(...).defer('username','id')
    #映射中排除某列数据

 def only(self, *fields):
    #仅取某个表中的数据
     models.UserInfo.objects.only('username','id')
     或
     models.UserInfo.objects.filter(...).only('username','id')
复制代码
复制代码

30.select_related和prefetch_related的区别?

复制代码
复制代码
# 他俩都用于连表查询,减小SQL查询次数
\select_related
select_related主要针一对一和多对一关系进行优化,经过多表join关联查询,一次性得到全部数据,
存放在内存中,但若是关联的表太多,会严重影响数据库性能。
def index(request): obj = Book.objects.all().select_related("publisher") return render(request, "index.html", locals()) \prefetch_related prefetch_related是经过分表,先获取各个表的数据,存放在内存中,而后经过Python处理他们之间的关联。 def index(request): obj = Book.objects.all().prefetch_related("publisher") return render(request, "index.html", locals())
复制代码
复制代码

 

复制代码
复制代码
def select_related(self, *fields)
     性能相关:表之间进行join连表操做,一次性获取关联的数据。
     model.tb.objects.all().select_related()
     model.tb.objects.all().select_related('外键字段') model.tb.objects.all().select_related('外键字段__外键字段') def prefetch_related(self, *lookups) 性能相关:多表连表操做时速度会慢,使用其执行屡次SQL查询在Python代码中实现连表操做。 # 获取全部用户表 # 获取用户类型表where id in (用户表中的查到的全部用户ID) models.UserInfo.objects.prefetch_related('外键字段') from django.db.models import Count, Case, When, IntegerField Article.objects.annotate( numviews=Count(Case( When(readership__what_time__lt=treshold, then=1), output_field=CharField(), )) ) students = Student.objects.all().annotate(num_excused_absences=models.Sum( models.Case( models.When(absence__type='Excused', then=1), default=0, output_field=models.IntegerField() )))
复制代码
复制代码
复制代码
复制代码
# 1次SQL
# select * from userinfo
objs = UserInfo.obejcts.all()
for item in objs: print(item.name) # n+1次SQL # select * from userinfo objs = UserInfo.obejcts.all() for item in objs: # select * from usertype where id = item.id print(item.name,item.ut.title) select_related() # 1次SQL # select * from userinfo inner join usertype on userinfo.ut_id = usertype.id objs = UserInfo.obejcts.all().select_related('ut') 连表查询 for item in objs: print(item.name,item.ut.title) .prefetch_related() # select * from userinfo where id <= 8 # 计算:[1,2] # select * from usertype where id in [1,2] objs = UserInfo.obejcts.filter(id__lte=8).prefetch_related('ut') for obj in objs: print(obj.name,obj.ut.title)
复制代码
复制代码

31.filter和exclude的区别?

复制代码
复制代码
  def filter(self, *args, **kwargs)
      # 条件查询(符合条件)
       # 查出符合条件
      # 条件能够是:参数,字典,Q

  def exclude(self, *args, **kwargs) # 条件查询(排除条件) # 排除不想要的 # 条件能够是:参数,字典,Q
复制代码
复制代码

32.列举django orm中三种能写sql语句的方法。

复制代码
复制代码
原生SQL --->  connection
from django.db import connection, connections
cursor = connection.cursor()  # cursor = connections['default'].cursor()
cursor.execute("""SELECT * from auth_user where id = %s""", [1]) row = cursor.fetchone() # fetchall()/fetchmany(..) 
靠近原生SQL-->extra\raw extra - extra def extra(self, select=None, where=None, params=None, tables=None, order_by=None, select_params=None) # 构造额外的查询条件或者映射,如:子查询 Entry.objects.extra(select={'new_id': "select col from sometable where othercol > %s"}, select_params=(1,)) Entry.objects.extra(where=['headline=%s'], params=['Lennon']) Entry.objects.extra(where=["foo='a' OR bar = 'a'", "baz = 'a'"]) Entry.objects.extra(select={'new_id': "select id from tb where id > %s"}, s elect_params=(1,), order_by=['-nid']) - raw def raw(self, raw_query, params=None, translations=None, using=None): # 执行原生SQL models.UserInfo.objects.raw('select * from userinfo') # 若是SQL是其余表时,必须将名字设置为当前UserInfo对象的主键列名 models.UserInfo.objects.raw('select id as nid,name as title from 其余表') # 为原生SQL设置参数 models.UserInfo.objects.raw('select id as nid from userinfo where nid>%s', params=[12,]) # 将获取的到列名转换为指定列名 name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'} Person.objects.raw('SELECT * FROM some_other_table', translations=name_map) # 指定数据库 models.UserInfo.objects.raw('select * from userinfo', using="default")
复制代码
复制代码

33.django orm 中如何设置读写分离?

复制代码
复制代码
 方式一:手动使用queryset的using方法
from django.shortcuts import render,HttpResponse from app01 import models def index(request): models.UserType.objects.using('db1').create(title='普通用户')   # 手动指定去某个数据库取数据 result = models.UserType.objects.all().using('db1') print(result) return HttpResponse('...') 方式二:写配置文件 class Router1:   # 指定到某个数据库取数据 def db_for_read(self, model, **hints): """ Attempts to read auth models go to auth_db. """ if model._meta.model_name == 'usertype': return 'db1' else: return 'default'    # 指定到某个数据库存数据 def db_for_write(self, model, **hints): """ Attempts to write auth models go to auth_db. """ return 'default' 再写到配置 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }, 'db1': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } DATABASE_ROUTERS = ['db_router.Router1',]
复制代码
复制代码

34.F和Q的做用?

复制代码
复制代码
  F:主要用来获取原数据进行计算。
  Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操做。
  修改操做也能够使用F函数,好比将每件商品的价格都在原价格的基础上增长10
from django.db.models import F
from app01.models import Goods
 
Goods.objects.update(price=F("price")+10)  # 对于goods表中每件商品的价格都在原价格的基础上增长10元
F查询专门对对象中某列值的操做,不可以使用__双下划线!
Q:用来进行复杂查询
    Q查询能够组合使用 “&”, “|” 操做符,当一个操做符是用于两个Q的对象,它产生一个新的Q对象,
  Q对象能够用 “~” 操做符放在前面表示否认,也可容许否认与不否认形式的组合。
  Q对象能够与关键字参数查询一块儿使用,不过必定要把Q对象放在关键字参数查询的前面。
Q(条件1) | Q(条件2) 或 Q(条件1) & Q(条件2) 且 Q(条件1) & ~Q(条件2) 非
复制代码
复制代码

35.values和values_list的区别?

def values(self, *fields):
    # 获取每行数据为字典格式

def values_list(self, *fields, **kwargs): # 获取每行数据为元祖

36.如何使用django orm批量建立数据?

复制代码
复制代码
def bulk_create(self, objs, batch_size=None):
    # 批量插入
    # batch_size表示一次插入的个数
    objs = [ models.DDD(name='r11'), models.DDD(name='r22') ] models.DDD.objects.bulk_create(objs, 10)
复制代码
复制代码

37.django的Form和ModeForm的做用?

复制代码
复制代码
 - 做用:
      - 对用户请求数据格式进行校验 - 自动生成HTML标签 - 区别: - Form,字段须要本身手写。 class Form(Form): xx = fields.CharField(.) xx = fields.CharField(.) xx = fields.CharField(.) xx = fields.CharField(.) - ModelForm,能够经过Meta进行定义 class MForm(ModelForm): class Meta: fields = "__all__" model = UserInfo - 应用:只要是客户端向服务端发送表单数据时,均可以进行使用,如:用户登陆注册
复制代码
复制代码

38.django的Form组件中,若是字段中包含choices参数,请使用两种方式实现数据源实时更新。

复制代码
复制代码
 方式一:重写构造方法,在构造方法中从新去数据库获取值
  class UserForm(Form): name = fields.CharField(label='用户名',max_length=32) email = fields.EmailField(label='邮箱') ut_id = fields.ChoiceField( # choices=[(1,'普通用户'),(2,'IP用户')] choices=[] ) def __init__(self,*args,**kwargs): super(UserForm,self).__init__(*args,**kwargs) self.fields['ut_id'].choices = models.UserType.objects.all().values_list('id','title') 
方式二: ModelChoiceField字段 from django.forms import Form from django.forms import fields from django.forms.models import ModelChoiceField class UserForm(Form): name = fields.CharField(label='用户名',max_length=32) email = fields.EmailField(label='邮箱') ut_id = ModelChoiceField(queryset=models.UserType.objects.all()) 依赖: class UserType(models.Model): title = models.CharField(max_length=32) def __str__(self): return self.title
复制代码
复制代码

39.django的Model中的ForeignKey字段中的on_delete参数有什么做用?

复制代码
复制代码
在django2.0后,定义外键和一对一关系的时候须要加on_delete选项,此参数为了不两个表里的数据不一致问题,否则会报错:

TypeError: __init__() missing 1 required positional argument: 'on_delete' 举例说明: user=models.OneToOneField(User) owner=models.ForeignKey(UserProfile) 须要改为: user=models.OneToOneField(User,on_delete=models.CASCADE) --在老版本这个参数(models.CASCADE)是默认值 owner=models.ForeignKey(UserProfile,on_delete=models.CASCADE) --在老版本这个参数(models.CASCADE)是默认值 参数说明: on_delete有CASCADE、PROTECT、SET_NULL、SET_DEFAULT、SET()五个可选择的值 CASCADE:此值设置,是级联删除。 PROTECT:此值设置,是会报完整性错误。 SET_NULL:此值设置,会把外键设置为null,前提是容许为null。 SET_DEFAULT:此值设置,会把设置为外键的默认值。 SET():此值设置,会调用外面的值,能够是一个函数。 通常状况下使用CASCADE就能够了。
复制代码
复制代码

40.django中csrf的实现机制?

复制代码
复制代码
目的:防止用户直接向服务端发起POST请求

- 用户先发送GET获取csrf token: Form表单中一个隐藏的标签 + token - 发起POST请求时,须要携带以前发送给用户的csrf token; - 在中间件的process_view方法中进行校验。 在html中添加{%csrf_token%}标签
复制代码
复制代码

41.django如何实现websocket?

django中能够经过channel实现websocket

42.基于django使用ajax发送post请求时,均可以使用哪一种方法携带csrf token?

复制代码
复制代码
//方式一给每一个ajax都加上上请求头
    function Do1(){
        $.ajax({
            url:"/index/", data:{id:1}, type:'POST',        data:{csrfmiddlewaretoken:'{{ csrf_token }}',name:'alex'} success:function(data){ console.log(data); } }); }  方式二:须要先下载jQuery-cookie,才能去cookie中获取token function Do1(){ $.ajax({ url:"/index/", data:{id:1}, type:'POST', headers:{ 'X-CSRFToken':$.cookie('csrftoken') // 去cookie中获取 }, success:function(data){ console.log(data); } }); } 方式三:搞个函数ajaxSetup,当有多的ajax请求,即会执行这个函数 $.ajaxSetup({ beforeSend:function (xhr,settings) { xhr.setRequestHeader("X-CSRFToken",$.cookie('csrftoken')) } }); 函数版本 <body> <input type="button" onclick="Do1();" value="Do it"/> <input type="button" onclick="Do2();" value="Do it"/> <input type="button" onclick="Do3();" value="Do it"/> <script src="/static/jquery-3.3.1.min.js"></script> <script src="/static/jquery.cookie.js"></script> <script> $.ajaxSetup({ beforeSend: function(xhr, settings) { xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken')); } }); function Do1(){ $.ajax({ url:"/index/", data:{id:1}, type:'POST', success:function(data){ console.log(data); } }); } function Do2(){ $.ajax({ url:"/index/", data:{id:1}, type:'POST', success:function(data){ console.log(data); } }); } function Do3(){ $.ajax({ url:"/index/", data:{id:1}, type:'POST', success:function(data){ console.log(data); } }); } </script> </body>
复制代码
复制代码

43.django中如何实现orm表中添加数据时建立一条日志记录。

 给信号注册函数

复制代码
复制代码
使用django的信号机制,能够在添加、删除数据先后设置日志记录
pre_init  # Django中的model对象执行其构造方法前,自动触发
post_init  # Django中的model对象执行其构造方法后,自动触发
pre_save  # Django中的model对象保存前,自动触发
post_save  # Django中的model对象保存后,自动触发
pre_delete  # Django中的model对象删除前,自动触发
post_delete  # Django中的model对象删除后,自动触发
复制代码
复制代码

44.django缓存如何设置?

复制代码
复制代码
jango中提供了6种缓存方式:
  开发调试(不加缓存)
  内存
  文件
  数据库
  Memcache缓存(python-memcached模块)   Memcache缓存(pylibmc模块) 安装第三方组件支持redis:   django-redis组件 设置缓存 # 全站缓存(中间件) MIDDLEWARE_CLASSES = ( ‘django.middleware.cache.UpdateCacheMiddleware’, #第一 'django.middleware.common.CommonMiddleware', ‘django.middleware.cache.FetchFromCacheMiddleware’, #最后 ) # 视图缓存 from django.views.decorators.cache import cache_page import time @cache_page(15) #超时时间为15秒 def index(request): t=time.time() #获取当前时间 return render(request,"index.html",locals()) # 模板缓存 {% load cache %} <h3 style="color: green">不缓存:-----{{ t }}</h3> {% cache 2 'name' %} # 存的key <h3>缓存:-----:{{ t }}</h3> {% endcache %}
复制代码
复制代码

45.django的缓存能使用redis吗?若是能够的话,如何配置?

复制代码
复制代码
  pip install django-redis  
  apt-get install redis-serv 在setting添加配置文件 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", # 缓存类型 "LOCATION": "127.0.0.1:6379", # ip端口 "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", # "CONNECTION_POOL_KWARGS": {"max_connections": 100} # 链接池最大链接数 # "PASSWORD": "密码",  } } } 使用 from django.shortcuts import render,HttpResponse from django_redis import get_redis_connection def index(request): # 根据名字去链接池中获取链接 conn = get_redis_connection("default") conn.hset('n1','k1','v1') # 存数据 return HttpResponse('...')
复制代码
复制代码

46.django路由系统中name的做用?

复制代码
复制代码
反向解析路由字符串

路由系统中name的做用:反向解析
url(r'^home', views.home, name='home')
在模板中使用:url 'home' %}
在视图中使用:reverse(“home”)

复制代码
复制代码

47.django的模板中filter和simple_tag的区别?

复制代码
复制代码
filter : 相似管道,只能接受两个参数第一个参数是|前的数据

simple_tag : 相似函数

一、模板继承:extends 'layouts.html' %}
二、自定义方法
    'filter':只能传递两个参数,能够在if、for语句中使用
    'simple_tag':能够无线传参,不能在if for中使用
    'inclusion_tags':能够使用模板和后端数据
三、防xss攻击: '|safe''mark_safe'

 
  
复制代码
复制代码

48.django-debug-toolbar的做用?

1、查看访问的速度、数据库的行为、cache命中等信息。 
2、尤为在Mysql访问等的分析上大有用处(sql查询速度)

49.django中如何实现单元测试?

对于每个测试方法都会将setUp()和tearDown()方法执行一遍
会单独新建一个测试数据库来进行数据库的操做方面的测试,默认在测试完成后销毁。
在测试方法中对数据库进行增删操做,最后都会被清除。也就是说,在test_add中插入的数据,在test_add测试结束后插入的数据会被清除。
django单元测试时为了模拟生产环境,会修改settings中的变量,例如, 把DEBUG变量修改成True, 把ALLOWED_HOSTS修改成[*]。

50.解释orm中 db first 和 code first的含义?

db first: 先建立数据库,再更新表模型
code first:先写表模型,再更新数据库

https://www.cnblogs.com/jassin-du/p/8988897.html

51.django中如何根据数据库表生成model中的类?

1、修改seting文件,在setting里面设置要链接的数据库类型和名称、地址
2、运行下面代码能够自动生成models模型文件 - python manage.py inspectdb 3、建立一个app执行下下面代码: - python manage.py inspectdb > app/models.py 

52.使用orm和原生sql的优缺点?

复制代码
复制代码
SQL:
# 优势:
执行速度快 # 缺点: 编写复杂,开发效率不高 --------------------------------------------------------------------------- ORM: # 优势: 让用户再也不写SQL语句,提升开发效率 能够很方便地引入数据缓存之类的附加功能 # 缺点: 在处理多表联查、where条件复杂查询时,ORM的语法会变得复杂。 没有原生SQL速度快
复制代码
复制代码

53.简述MVC和MTV

MVC:model、view(模块)、controller(视图)
MTV:model、tempalte、view 

54.django的contenttype组件的做用?

contenttype是django的一个组件(app),它能够将django下全部app下的表记录下来
能够使用他再加上表中的两个字段,实现一张表和N张表动态建立FK关系。
   - 字段:表名称 - 字段:数据行ID 应用:路飞表结构优惠券和专题课和学位课关联

55.谈谈你对restfull 规范的认识?

复制代码
复制代码
restful其实就是一套编写接口的'协议',规定如何编写以及如何设置返回值、状态码等信息。
# 最显著的特色:
# 用restful: 
 给用户一个url,根据method不一样在后端作不一样的处理 好比:post建立数据、get获取数据、put和patch修改数据、delete删除数据。 # 不用restful: 给调用者不少url,每一个url表明一个功能,好比:add_user/delte_user/edit_user/ # 固然,还有协议其余的,好比: '版本'来控制让程序有多个版本共存的状况,版本能够放在 url、请求头(accept/自定义)、GET参数 '状态码'200/300/400/500 'url中尽可能使用名词'restful也能够称为“面向资源编程” 'api标示' api.luffycity.com www.luffycity.com/api/
复制代码
复制代码

 

56.接口的幂等性是什么意思?

复制代码
复制代码
'一个接口经过1次相同的访问,再对该接口进行N次相同的访问时,对资源不造影响就认为接口具备幂等性。'
    GET,  #第一次获取结果、第二次也是获取结果对资源都不会形成影响,幂等。
    POST, #第一次新增数据,第二次也会再次新增,非幂等。
    PUT,  #第一次更新数据,第二次不会再次更新,幂等。
    PATCH,#第一次更新数据,第二次不会再次更新,非幂等。
    DELTE,#第一次删除数据,第二次不在再删除,幂等。
复制代码
复制代码

 

57.什么是RPC?

'远程过程调用协议'
是一种经过网络从远程计算机程序上请求服务,而不须要了解底层网络技术的协议。
进化的顺序: 现有的RPC,而后有的RESTful规范

58.Http和Https的区别?

复制代码
复制代码
#Http: 80端口
#https: 443端口
# http信息是明文传输,https则是具备安全性的ssl加密传输协议。
#- 自定义证书 
    - 服务端:建立一对证书
    - 客户端:必须携带证书 #- 购买证书 - 服务端: 建立一对证书,。。。。 - 客户端: 去机构获取证书,数据加密后发给我们的服务单 - 证书机构:公钥给改机构
复制代码
复制代码

 

59.为何要使用django rest framework框架?

复制代码
复制代码
# 在编写接口时能够不使用django rest framework框架,
# 不使用:也能够作,能够用django的CBV来实现,开发者编写的代码会更多一些。
# 使用:内部帮助咱们提供了不少方便的组件,咱们经过配置就能够完成相应操做,如:
    '序列化'能够作用户请求数据校验+queryset对象的序列化称为json
    '解析器'获取用户请求数据request.data,会自动根据content-type请求头的不能对数据进行解析 '分页'将从数据库获取到的数据在页面进行分页显示。 # 还有其余组件: '认证'、'权限'、'访问频率控制 
复制代码
复制代码

 

60.django rest framework框架中都有那些组件?

复制代码
复制代码
#- 路由,自动帮助开发者快速为一个视图建立4个url
        www.oldboyedu.com/api/v1/student/$
        www.oldboyedu.com/api/v1/student(?P<format>\w+)$ www.oldboyedu.com/api/v1/student/(?P<pk>\d+)/$ www.oldboyedu.com/api/v1/student/(?P<pk>\d+)(?P<format>\w+)$ #- 版本处理 - 问题:版本均可以放在那里? - url - GET - 请求头 #- 认证 - 问题:认证流程? #- 权限 - 权限是否能够放在中间件中?以及为何? #- 访问频率的控制  匿名用户能够真正的防止?没法作到真正的访问频率控制,只能把小白拒之门外。 若是要封IP,使用防火墙来作。 登陆用户能够经过用户名做为惟一标示进行控制,若是有人注册不少帐号,则没法防止。 #- 视图 #- 解析器 ,根据Content-Type请求头对请求体中的数据格式进行处理。request.data #- 分页 #- 序列化 - 序列化 - source - 定义方法 - 请求数据格式校验 #- 渲染器 
复制代码
复制代码

 

61.django rest framework框架中的视图均可以继承哪些类

复制代码
复制代码
a. 继承APIView(最原始)但定制性比较强
    这个类属于rest framework中的顶层类,内部帮助咱们实现了只是基本功能:认证、权限、频率控制,
但凡是数据库、分页等操做都须要手动去完成,比较原始。
    class GenericAPIView(APIView) def post(...): pass b.继承GenericViewSet(ViewSetMixin,generics.GenericAPIView)   首先他的路由就发生变化 若是继承它以后,路由中的as_view须要填写对应关系   在内部也帮助咱们提供了一些方便的方法:   get_queryset   get_object   get_serializer   get_serializer_class   get_serializer_context   filter_queryset 注意:要设置queryset字段,不然会抛出断言的异常。 代码 只提供增长功能 只继承GenericViewSet class TestView(GenericViewSet):   serialazer_class = xxx   def creat(self,*args,**kwargs):     pass # 获取数据并对数据  c. 继承 modelviewset --> 快速快发     -ModelViewSet(增删改查全有+数据库操做)     -mixins.CreateModelMixin(只有增),GenericViewSet     -mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet   对数据库和分页等操做不用咱们在编写,只须要继承相关类便可。    示例:只提供增长功能 class TestView(mixins.CreateModelMixin,GenericViewSet):     serializer_class = XXXXXXX ***   modelviewset --> 快速开发,复杂点的genericview、apiview
复制代码
复制代码

 

62.简述 django rest framework框架的认证流程。

复制代码
复制代码
- 如何编写?写类并实现authenticators
  请求进来认证须要编写一个类,类里面有一个authenticators方法,咱们能够自定义这个方法,能够定制3类返回值。
  成功返回元组,返回none为匿名用户,抛出异常为认证失败。

源码流程:请求进来先走dispatch方法,而后封装的request对象会执行user方法,由user触发authenticators认证流程
- 方法中能够定义三种返回值: - (user,auth),认证成功 - None , 匿名用户 - 异常 ,认证失败 - 流程: - dispatch - 再去request中进行认证处理
复制代码
复制代码

 

63.django rest framework如何实现的用户访问频率控制? 

复制代码
复制代码
# 对匿名用户,根据用户IP或代理IP做为标识进行记录,为每一个用户在redis中建一个列表
    {
        throttle_1.1.1.1:[1526868876.497521,152686885.497521...], throttle_1.1.1.2:[1526868876.497521,152686885.497521...], throttle_1.1.1.3:[1526868876.497521,152686885.497521...], } 每一个用户再来访问时,需先去记录中剔除过时记录,再根据列表的长度判断是否能够继续访问。 '如何封IP':在防火墙中进行设置 -------------------------------------------------------------------------- # 对注册用户,根据用户名或邮箱进行判断。  { throttle_xxxx1:[1526868876.497521,152686885.497521...], throttle_xxxx2:[1526868876.497521,152686885.497521...], throttle_xxxx3:[1526868876.497521,152686885.497521...], } 每一个用户再来访问时,需先去记录中剔除过时记录,再根据列表的长度判断是否能够继续访问。 \如1分钟:40次,列表长度限制在40,超过40则不可访问
复制代码
复制代码

 

64.Flask框架的优点?

Flask自由、灵活,可扩展性强,透明可控,第三方库的选择面广,
开发时能够结合最流行最强大的Python库,

 

65.Flask框架依赖组件

# 依赖jinja2模板引擎
# 依赖werkzurg协议

 

66.Flask蓝图的做用

# blueprint把实现不一样功能的module分开.也就是把一个大的App分割成各自实现不一样功能的module.
# 在一个blueprint中能够调用另外一个blueprint的视图函数, 但要加相应的blueprint名.

 

67.列举使用的Flask第三方组件?

复制代码
复制代码
# Flask组件
    flask-session  session放在redis
    flask-SQLAlchemy 如django里的ORM操做 flask-migrate 数据库迁移 flask-script 自定义命令 blinker 信号-触发信号 # 第三方组件  Wtforms 快速建立前端标签、文本校验 dbutile 建立数据库链接池 gevnet-websocket 实现websocket # 自定义Flask组件  自定义auth认证 参考flask-login组件
复制代码
复制代码

 

68.简述Flask上下文管理流程?

复制代码
复制代码
# a、简单来讲,falsk上下文管理能够分为三个阶段:
  一、'请求进来时':将请求相关的数据放入上下问管理中
  二、'在视图函数中':要去上下文管理中取值   三、'请求响应':要将上下文管理中的数据清除 # b、详细点来讲:   一、'请求刚进来':         将request,session封装在RequestContext类中         app,g封装在AppContext类中         并经过LocalStack将requestcontext和appcontext放入Local类中   二、'视图函数中':         经过localproxy--->偏函数--->localstack--->local取值   三、'请求响应时':         先执行save.session()再各自执行pop(),将local中的数据清除
复制代码
复制代码

 

69.Flask中的g的做用?

# g是贯穿于一次请求的全局变量,当请求进来将g和current_app封装为一个APPContext类,
# 再经过LocalStack将Appcontext放入Local中,取值时经过偏函数在LocalStack、local中取值;
# 响应时将local中的g数据删除:

 

Flask中上下文管理主要涉及到了那些相关的类?并描述类主要做用?

RequestContext  #封装进来的请求(赋值给ctx)
AppContext      #封装app_ctx
LocalStack      #将local对象中的数据维护成一个栈(先进后出)
Local           #保存请求上下文对象和app上下文对象

 

为何要Flask把Local对象中的的值stack 维护成一个列表?

# 由于经过维护成列表,能够实现一个栈的数据结构,进栈出栈时只取一个数据,巧妙的简化了问题。
# 还有,在多app应用时,能够实现数据隔离;列表里不会加数据,而是会生成一个新的列表
# local是一个字典,字典里key(stack)是惟一标识,value是一个列表

 

Flask中多app应用是怎么完成?

复制代码
复制代码
请求进来时,能够根据URL的不一样,交给不一样的APP处理。蓝图也能够实现。
    #app1 = Flask('app01')
    #app2 = Flask('app02')
    #@app1.route('/index')
    #@app2.route('/index2')
源码中在DispatcherMiddleware类里调用app2.__call__, 原理其实就是URL分割,而后将请求分发给指定的app。 以后app也按单app的流程走。就是从app.__call__走。
复制代码
复制代码

 

在Flask中实现WebSocket须要什么组件?

 gevent-websocket

 

wtforms组件的做用?

#快速建立前端标签、文本校验;如django的ModelForm

 

Flask框架默认session处理机制?

复制代码
复制代码
# 前提:
    不熟的话:记不太清了,应该是……分两个阶段吧   
# 建立:
 当请求刚进来的时候,会将request和session封装成一个RequestContext()对象, 接下来把这个对象经过LocalStack()放入内部的一个Local()对象中;    由于刚开始 Local 的ctx中session是空的;    因此,接着执行open_session,将cookie 里面的值拿过来,从新赋值到ctx中 (Local实现对数据隔离,相似threading.local) # 销毁:  最后返回时执行 save_session() 将ctx 中的session读出来进行序列化,写到cookie 而后给用户,接着把 ctx pop掉
复制代码
复制代码

 

解释Flask框架中的Local对象和threading.local对象的区别?

复制代码
复制代码
# a.threading.local
做用:为每一个线程开辟一块空间进行数据存储(数据隔离)。

问题:本身经过字典建立一个相似于threading.local的东西。
storage = { 4740: {val: 0}, 4732: {val: 1}, 4731: {val: 3}, } # b.自定义Local对象 做用:为每一个线程(协程)开辟一块空间进行数据存储(数据隔离)。 class Local(object): def __init__(self): object.__setattr__(self, 'storage', {}) def __setattr__(self, k, v): ident = get_ident() if ident in self.storage: self.storage[ident][k] = v else: self.storage[ident] = {k: v} def __getattr__(self, k): ident = get_ident() return self.storage[ident][k] obj = Local() def task(arg): obj.val = arg obj.xxx = arg print(obj.val) for i in range(10): t = Thread(target=task, args=(i,)) t.start()
复制代码
复制代码

 

Flask中 blinker 是什么?

复制代码
复制代码
# 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在其中添加数据时,自动触发

复制代码
复制代码

 

SQLAlchemy中的 session和scoped_session 的区别?

复制代码
复制代码
# Session:
因为没法提供线程共享功能,开发时要给每一个线程都建立本身的session
打印sesion可知他是sqlalchemy.orm.session.Session的对象
# scoped_session:
为每一个线程都建立一个session,实现支持线程安全 在整个程序运行的过程中,只存在惟一的一个session对象。 建立方式: 经过本地线程Threading.Local() # session=scoped_session(Session) 建立惟一标识的方法(参考flask请求源码)
复制代码
复制代码

 

SQLAlchemy如何执行原生SQL?

# 使用execute方法直接操做SQL语句(导入create_engin、sessionmaker)
engine=create_engine('mysql://root:*****@127.0.0.1/database?charset=utf8')
DB_Session = sessionmaker(bind=engine) session = DB_Session() session.execute('alter table mytablename drop column mycolumn ;')

 

ORM的实现原理?

# ORM的实现基于一下三点
映射类:描述数据库表结构,
映射文件:指定数据库表和映射类之间的关系
数据库配置文件:指定与数据库链接时须要的链接信息(数据库、登陆用户名、密码or链接字符串)

 

DBUtils模块的做用?

复制代码
复制代码
# 数据库链接池
使用模式:
1、为每一个线程建立一个链接,链接不可控,须要控制线程数 2、建立指定数量的链接在链接池,当线程访问的时候去取,不够了线程排队,直到有人释放(推荐) --------------------------------------------------------------------------- 两种写法: 1、用静态方法装饰器,经过直接执行类的方法来链接使用数据库 2、经过实例化对象,经过对象来调用方法执行语句 https://www.cnblogs.com/ArmoredTitan/p/Flask.html
复制代码
复制代码

如下SQLAlchemy的字段是否正确?若是不正确请更正:

fromdatetime importdatetime

fromsqlalchemy.ext.declarative

importdeclarative_base

fromsqlalchemy importColumn, 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())

复制代码
复制代码
from datetime import datetime
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy import Column, Integer, String, DateTime Base = declarative_base() class UserInfo(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 后面不该该加括号,加了的话,字段不会实时更新。
复制代码
复制代码

 

SQLAchemy中如何为表设置引擎和字符编码?

sqlalchemy设置编码字符集,必定要在数据库访问的URL上增长'charset=utf8'
不然数据库的链接就不是'utf8'的编码格式 eng=create_engine('mysql://root:root@localhost:3306/test2?charset=utf8',echo=True)
复制代码
复制代码
1. 设置引擎编码方式为utf8。

    engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/sqldb01?charset=utf8") 2. 设置数据库表编码方式为utf8 class UserType(Base): __tablename__ = 'usertype' id = Column(Integer, primary_key=True) caption = Column(String(50), default='管理员') # 添加配置设置编码 __table_args__ = { 'mysql_charset':'utf8' } 这样生成的SQL语句就自动设置数据表编码为utf8了,__table_args__还可设置存储引擎、外键约束等等信息。
复制代码
复制代码

 

SQLAchemy中如何设置联合惟一索引?

经过'UniqueConstraint'字段来设置联合惟一索引
__table_args=(UniqueConstraint('h_id','username',name='_h_username_uc')) #h_id和username组成联合惟一约束

 

简述Tornado框架的特色。

异步非阻塞+websocket

 

简述Tornado框架中Future对象的做用?

复制代码
复制代码
# 实现异步非阻塞
视图函数yield一个futrue对象,futrue对象默认:
    self._done = False ,请求未完成 self._result = None ,请求完成后返回值,用于传递给回调函数使用。 tornado就会一直去检测futrue对象的_done是否已经变成True。 若是IO请求执行完毕,自动会调用future的set_result方法: self._result = result self._done = True 参考:http://www.cnblogs.com/wupeiqi/p/6536518.html(自定义异步非阻塞web框架)
复制代码
复制代码

 

Tornado框架中如何编写WebSocket程序?

复制代码
复制代码
Tornado在websocket模块中提供了一个WebSocketHandler类。
这个类提供了和已链接的客户端通讯的WebSocket事件和方法的钩子。
当一个新的WebSocket链接打开时,open方法被调用,
而on_message和on_close方法,分别在链接、接收到新的消息和客户端关闭时被调用。

此外,WebSocketHandler类还提供了write_message方法用于向客户端发送消息,close方法用于关闭链接。
复制代码
复制代码

 

Tornado中静态文件是如何处理的?
如: <link href="{{static_url("commons.css")}}" rel="stylesheet" />

复制代码
复制代码
# settings.py
settings = {
    "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'文件
复制代码
复制代码

 

Tornado操做MySQL使用的模块?

torndb
torndb是基于mysqldb的再封装,因此使用时要先安装myqldb

 

Tornado操做redis使用的模块?

tornado-redis

 

简述Tornado框架的适用场景?

web聊天室,在线投票

 

git常见命令做用:

复制代码
复制代码
# git init
    初始化,当前所在的文件夹能够被管理且之后版本相关的数据都会存储到.git文件中
# git status
 查看当前文件夹以及子目录中文件是否发生变化: 内容修改/新增文件/删除,已经变化的文件会变成红色,已经add的文件会变成绿色 # git add .  给发生变化的文件(贴上一个标签)或 将发生变化的文件放到某个地方, 只写一个句点符就表明把git status中红色的文件所有打上标签 # git commit -m  新增用户登陆认证功能以及xxx功能将“绿色”文件添加到版本中 # git log  查看全部版本提交记录,能够获取版本号 # git reset --hard 版本号  将最新的版本回退到更早的版本 # git reflog  回退到以前版本后悔了,再更新到最新或者最新以前的版本 # git reset --hard 版本 回退
复制代码
复制代码

 

简述如下git中stash命令做用以及相关其余命令。

复制代码
复制代码
'git stash':将当前工做区全部修改过的内容存储到“某个地方”,将工做区还原到当前版本未修改过的状态
'git stash list':查看“某个地方”存储的全部记录 'git stash clear':清空“某个地方” 'git stash pop':将第一个记录从“某个地方”从新拿到工做区(可能有冲突) 'git stash apply':编号, 将指定编号记录从“某个地方”从新拿到工做区(可能有冲突) 'git stash drop':编号,删除指定编号的记录
复制代码
复制代码

 

git 中 merge 和 rebase命令 的区别。

复制代码
复制代码
merge:
会将不一样分支的提交合并成一个新的节点,以前的提交分开显示,
注重历史信息、能够看出每一个分支信息,基于时间点,遇到冲突,手动解决,再次提交
rebase:
将两个分支的提交结果融合成线性,不会产生新的节点;
注重开发过程,遇到冲突,手动解决,继续操做
复制代码
复制代码

 

公司如何基于git作的协同开发?

复制代码
复制代码
1、大家公司的代码review分支怎么作?谁来作?
答:组长建立review分支,咱们小功能开发完以后,合并到review分支交给老大(小组长)来看,
1.1、你组长不开发代码吗? 他开发代码,可是它只开发核心的东西,任务比较少。 或者抽出时间,咱们一块儿作这个事情 2、大家公司协同开发是怎么协同开发的? 每一个人都有本身的分支,阶段性代码完成以后,合并到review,而后交给老大看 -------------------------------------------------------------------------- # 大体工做流程 公司: 下载代码 git clone https://gitee.com/wupeiqi/xianglong.git 或建立目录 cd 目录 git init git remote add origin https://gitee.com/wupeiqi/xianglong.git git pull origin maste 建立dev分支 git checkout dev git pull origin dev 继续写代码 git add . git commit -m '提交记录' git push origin dev 回家: 拉代码: git pull origin dev 继续写: 继续写代码 git add . git commit -m '提交记录' git push origin dev 
复制代码
复制代码

 

如何基于git实现代码review?

https://blog.csdn.net/june_y/article/details/50817993

 

git如何实现v1.0 、v2.0 等版本的管理?

在命令行中,使用“git tag –a tagname –m “comment”能够快速建立一个标签。
须要注意,命令行建立的标签只存在本地Git库中,还须要使用Git push –tags指令发布到服务器的Git库中

 

什么是gitlab

gitlab是公司本身搭建的项目代码托管平台

 

github和gitlab的区别?

1、gitHub是一个面向开源及私有软件项目的托管平台
(建立私有的话,须要购买,最低级的付费为每个月7刀,支持5个私有项目)
二、gitlab是公司本身搭建的项目托管平台

 

如何为github上牛逼的开源项目贡献代码?

复制代码
复制代码
1、fork须要协做项目
二、克隆/关联fork的项目到本地 3、新建分支(branch)并检出(checkout)新分支 4、在新分支上完成代码开发 5、开发完成后将你的代码合并到master分支 6、添加原做者的仓库地址做为一个新的仓库地址 7、合并原做者的master分支到你本身的master分支,用于和做者仓库代码同步 8、push你的本地仓库到GitHub 9、在Github上提交 pull requests 十、等待管理员(你须要贡献的开源项目管理员)处理
复制代码
复制代码

 

git中 .gitignore文件的做用

通常来讲每一个Git项目中都须要一个“.gitignore”文件,
这个文件的做用就是告诉Git哪些文件不须要添加到版本管理中。

实际项目中,不少文件都是不须要版本管理的,好比Python的.pyc文件和一些包含密码的配置文件等等。

 

什么是敏捷开发?

'敏捷开发':是一种以人为核心、迭代、按部就班的开发方式。

它并非一门技术,而是一种开发方式,也就是一种软件开发的流程。
它会指导咱们用规定的环节去一步一步完成项目的开发。
由于它采用的是迭代式开发,因此这种开发方式的主要驱动核心是人

 

简述 jenkins 工具的做用?

'Jenkins'是一个可扩展的持续集成引擎。

主要用于:
   持续、自动地构建/测试软件项目。 监控一些定时执行的任务。

 

公司如何实现代码发布?

 

简述 RabbitMQ、Kafka、ZeroMQ的区别?

https://blog.csdn.net/zhailihua/article/details/7899006

 

RabbitMQ如何在消费者获取任务后未处理完前就挂掉时,保证数据不丢失?

复制代码
复制代码
为了预防消息丢失,rabbitmq提供了ack
即工做进程在收到消息并处理后,发送ack给rabbitmq,告知rabbitmq这时候能够把该消息从队列中删除了。
若是工做进程挂掉 了,rabbitmq没有收到ack,那么会把该消息 从新分发给其余工做进程。
不须要设置timeout,即便该任务须要很长时间也能够处理。

ack默认是开启的,工做进程显示指定了no_ack=True
复制代码
复制代码

 

RabbitMQ如何对消息作持久化?

复制代码
复制代码
一、建立队列和发送消息时将设置durable=Ture,若是在接收到消息尚未存储时,消息也有可能丢失,就必须配置publisher confirm
    channel.queue_declare(queue='task_queue', durable=True) 2、返回一个ack,进程收到消息并处理完任务后,发给rabbitmq一个ack表示任务已经完成,能够删除该任务 3、镜像队列:将queue镜像到cluster中其余的节点之上。 在该实现下,若是集群中的一个节点失效了,queue能自动地切换到镜像中的另外一个节点以保证服务的可用性
复制代码
复制代码

 

RabbitMQ如何控制消息被消费的顺序?

默认消息队列里的数据是按照顺序被消费者拿走,
例如:消费者1 去队列中获取奇数序列的任务,消费者2去队列中获取偶数序列的任务。

channel.basic_qos(prefetch_count=1) 表示谁来谁取,再也不按照奇偶数排列(同时也保证了公平的消费分发)

 

如下RabbitMQ的exchange type分别表明什么意思?如:fanout、direct、topic。

复制代码
复制代码
amqp协议中的核心思想就是生产者和消费者隔离,生产者从不直接将消息发送给队列。
生产者一般不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。
先由Exchange来接收,而后Exchange按照特定的策略转发到Queue进行存储。
同理,消费者也是如此。Exchange 就相似于一个交换机,转发各个消息分发到相应的队列中。
-------------------------------------------------- type=fanout 相似发布者订阅者模式,会为每个订阅者建立一个队列,而发布者发布消息时,会将消息放置在全部相关队列中 type=direct 队列绑定关键字,发送者将数据根据关键字发送到消息exchange,exchange根据 关键字 断定应该将数据发送至指定队列。 type=topic 队列绑定几个模糊的关键字,以后发送者将数据发送到exchange,exchange将传入”路由值“和 ”关键字“进行匹配,匹配成功,
则将数据发送到指定队列。 --------------------------------------------------- 发送者路由值 队列中 old.boy.python old.* -- 不匹配 *表示匹配一个 old.boy.python old.# -- 匹配 #表示匹配0个或多个
复制代码
复制代码

 

简述 celery 是什么以及应用场景?

# Celery是由Python开发的一个简单、灵活、可靠的处理大量任务的分发系统,
# 它不只支持实时处理也支持任务调度。
# http://www.cnblogs.com/wupeiqi/articles/8796552.html

 

简述celery运行机制。

 

 

celery如何实现定时任务?

复制代码
复制代码
# celery实现定时任务
启用Celery的定时任务须要设置CELERYBEAT_SCHEDULE 。 
CELERYBEAT_SCHEDULE='djcelery.schedulers.DatabaseScheduler'#定时任务
'建立定时任务'
# 经过配置CELERYBEAT_SCHEDULE:
#每30秒调用task.add
from datetime import timedelta CELERYBEAT_SCHEDULE = { 'add-every-30-seconds': { 'task': 'tasks.add', 'schedule': timedelta(seconds=30), 'args': (16, 16) }, }
复制代码
复制代码

 

简述 celery多任务结构目录

复制代码
复制代码
pro_cel
    ├── celery_tasks     # celery相关文件夹
    │   ├── celery.py    # celery链接和配置相关文件
    │   └── tasks.py     #  全部任务函数
    ├── check_result.py  # 检查结果
    └── send_task.py     # 触发任务
复制代码
复制代码

 

celery中装饰器 @app.task 和 @shared_task的区别?

# 通常状况使用的是从celeryapp中引入的app做为的装饰器:@app.task
# django那种在app中定义的task则须要使用@shared_task

 

简述 requests模块的做用及基本使用?

复制代码
复制代码
# 做用:
使用requests能够模拟浏览器的请求
# 经常使用参数:
 url、headers、cookies、data json、params、proxy # 经常使用返回值:  content iter_content text encoding="utf-8" cookie.get_dict() 
复制代码
复制代码

 

简述 beautifulsoup模块的做用及基本使用?

# BeautifulSoup
用于从HTML或XML文件中提取、过滤想要的数据形式
#经常使用方法
解析:html.parser 或者 lxml(须要下载安装) find、find_all、text、attrs、get 

 

简述 seleninu模块的做用及基本使用?

Selenium是一个用于Web应用程序测试的工具,
他的测试直接运行在浏览器上,模拟真实用户,按照代码作出点击、输入、打开等操做

爬虫中使用他是为了解决requests没法解决javascript动态问题

 

scrapy框架中各组件的工做流程?

复制代码
复制代码
#一、生成初始的Requests来爬取第一个URLS,而且标识一个回调函数
第一个请求定义在start_requests()方法内默认从start_urls列表中得到url地址来生成Request请求,
默认的回调函数是parse方法。回调函数在下载完成返回response时自动触发
#二、在回调函数中,解析response而且返回值
返回值能够4种: a、包含解析数据的字典 b、Item对象 c、新的Request对象(新的Requests也须要指定一个回调函数) d、或者是可迭代对象(包含Items或Request) #三、在回调函数中解析页面内容 一般使用Scrapy自带的Selectors,但很明显你也能够使用Beutifulsoup,lxml或其余你爱用啥用啥。 #四、最后,针对返回的Items对象将会被持久化到数据库  经过Item Pipeline组件存到数据库 或者导出到不一样的文件(经过Feed exports) http://www.cnblogs.com/wupeiqi/articles/6229292.html
复制代码
复制代码

 

在scrapy框架中如何设置代理(两种方法)?

复制代码
复制代码
方式一:内置添加代理功能
# -*- coding: utf-8 -*-
import os import scrapy from scrapy.http import Request class ChoutiSpider(scrapy.Spider): name = 'chouti' allowed_domains = ['chouti.com'] start_urls = ['https://dig.chouti.com/'] def start_requests(self): os.environ['HTTP_PROXY'] = "http://192.168.11.11" for url in self.start_urls: yield Request(url=url,callback=self.parse) def parse(self, response): print(response) 方式二:自定义下载中间件 import random import base64 import six def to_bytes(text, encoding=None, errors='strict'): """Return the binary representation of `text`. If `text` is already a bytes object, return it as-is.""" if isinstance(text, bytes): return text if not isinstance(text, six.string_types): raise TypeError('to_bytes must receive a unicode, str or bytes ' 'object, got %s' % type(text).__name__) if encoding is None: encoding = 'utf-8' return text.encode(encoding, errors) class MyProxyDownloaderMiddleware(object): def process_request(self, request, spider): proxy_list = [ {'ip_port': '111.11.228.75:80', 'user_pass': 'xxx:123'}, {'ip_port': '120.198.243.22:80', 'user_pass': ''}, {'ip_port': '111.8.60.9:8123', 'user_pass': ''}, {'ip_port': '101.71.27.120:80', 'user_pass': ''}, {'ip_port': '122.96.59.104:80', 'user_pass': ''}, {'ip_port': '122.224.249.122:8088', 'user_pass': ''}, ] proxy = random.choice(proxy_list) if proxy['user_pass'] is not None: request.meta['proxy'] = to_bytes("http://%s" % proxy['ip_port']) encoded_user_pass = base64.encodestring(to_bytes(proxy['user_pass'])) request.headers['Proxy-Authorization'] = to_bytes('Basic ' + encoded_user_pass) else: request.meta['proxy'] = to_bytes("http://%s" % proxy['ip_port']) 配置: DOWNLOADER_MIDDLEWARES = { # 'xiaohan.middlewares.MyProxyDownloaderMiddleware': 543, }
复制代码
复制代码

 

scrapy框架中如何实现大文件的下载?

复制代码
复制代码
from twisted.web.client import Agent, getPage, ResponseDone, PotentialDataLoss
from twisted.internet import defer, reactor, protocol from twisted.web._newclient import Response from io import BytesIO class _ResponseReader(protocol.Protocol): def __init__(self, finished, txresponse, file_name): self._finished = finished self._txresponse = txresponse self._bytes_received = 0 self.f = open(file_name, mode='wb') def dataReceived(self, bodyBytes): self._bytes_received += len(bodyBytes) # 一点一点的下载  self.f.write(bodyBytes) self.f.flush() def connectionLost(self, reason): if self._finished.called: return if reason.check(ResponseDone): # 下载完成 self._finished.callback((self._txresponse, 'success')) elif reason.check(PotentialDataLoss): # 下载部分 self._finished.callback((self._txresponse, 'partial')) else: # 下载异常  self._finished.errback(reason) self.f.close()
复制代码
复制代码

 

scrapy中如何实现限速?

http://scrapy-chs.readthedocs.io/zh_CN/1.0/topics/autothrottle.html

 

scrapy中如何实现暂停爬虫?

复制代码
复制代码
# 有些状况下,例如爬取大的站点,咱们但愿能暂停爬取,以后再恢复运行。
# Scrapy经过以下工具支持这个功能:
一个把调度请求保存在磁盘的调度器
一个把访问请求保存在磁盘的副本过滤器[duplicates filter]
一个能持续保持爬虫状态(键/值对)的扩展 Job 路径 要启用持久化支持,你只须要经过 JOBDIR 设置 job directory 选项。 这个路径将会存储全部的请求数据来保持一个单独任务的状态(例如:一次spider爬取(a spider run))。 必需要注意的是,这个目录不容许被不一样的spider 共享,甚至是同一个spider的不一样jobs/runs也不行。 也就是说,这个目录就是存储一个 单独 job的状态信息。
复制代码
复制代码

 

scrapy中如何进行自定制命令

复制代码
复制代码
在spiders同级建立任意目录,如:commands
在其中建立'crawlall.py'文件(此处文件名就是自定义的命令) from scrapy.commands import ScrapyCommand from scrapy.utils.project import get_project_settings class Command(ScrapyCommand): requires_project = True def syntax(self): return '[options]' def short_desc(self): return 'Runs all of the spiders' def run(self, args, opts): spider_list = self.crawler_process.spiders.list() for name in spider_list: self.crawler_process.crawl(name, **opts.__dict__) self.crawler_process.start() 在'settings.py'中添加配置'COMMANDS_MODULE = '项目名称.目录名称'' 在项目目录执行命令:'scrapy crawlall' 
复制代码
复制代码

scrapy中如何实现的记录爬虫的深度?

复制代码
复制代码
'DepthMiddleware'是一个用于追踪每一个Request在被爬取的网站的深度的中间件。 
其能够用来限制爬取深度的最大深度或相似的事情。
'DepthMiddleware'能够经过下列设置进行配置(更多内容请参考设置文档): 'DEPTH_LIMIT':爬取所容许的最大深度,若是为0,则没有限制。 'DEPTH_STATS':是否收集爬取状态。 'DEPTH_PRIORITY':是否根据其深度对requet安排优先
复制代码
复制代码

scrapy中的pipelines工做原理?

Scrapy 提供了 pipeline 模块来执行保存数据的操做。
在建立的 Scrapy 项目中自动建立了一个 pipeline.py 文件,同时建立了一个默认的 Pipeline 类。
咱们能够根据须要自定义 Pipeline 类,而后在 settings.py 文件中进行配置便可

scrapy的pipelines如何丢弃一个item对象?

经过raise DropItem()方法

简述scrapy中爬虫中间件和下载中间件的做用?1

http://www.cnblogs.com/wupeiqi/articles/6229292.html

scrapy-redis组件的做用?

实现了分布式爬虫,url去重、调度器、数据持久化
'scheduler'调度器 'dupefilter'URL去重规则(被调度器使用) 'pipeline'数据持久化

scrapy-redis组件中如何实现的任务的去重?

复制代码
复制代码

a. 内部进行配置,链接Redis
b.去重规则经过redis的集合完成,集合的Key为:
   key defaults.DUPEFILTER_KEY {'timestamp'int(time.time())}
   默认配置:
      DUPEFILTER_KEY 'dupefilter:%(timestamp)s'
c.去重规则中将url转换成惟一标示,而后在redis中检查是否已经在集合中存在
   from scrapy.utils import request
   from scrapy.http import Request
   req Request(url='http://www.cnblogs.com/wupeiqi.html')
   result request.request_fingerprint(req)
   print(result)  # 8ea4fd67887449313ccc12e5b6b92510cc53675c

复制代码
复制代码
复制代码
复制代码
scrapy和scrapy-redis的去重规则(源码)
1. scrapy中去重规则是如何实现? class RFPDupeFilter(BaseDupeFilter): """Request Fingerprint duplicates filter""" def __init__(self, path=None, debug=False): self.fingerprints = set() @classmethod def from_settings(cls, settings): debug = settings.getbool('DUPEFILTER_DEBUG') return cls(job_dir(settings), debug) def request_seen(self, request): # 将request对象转换成惟一标识。 fp = self.request_fingerprint(request) # 判断在集合中是否存在,若是存在则返回True,表示已经访问过。 if fp in self.fingerprints: return True # 以前未访问过,将url添加到访问记录中。  self.fingerprints.add(fp) def request_fingerprint(self, request): return request_fingerprint(request) 2. scrapy-redis中去重规则是如何实现? class RFPDupeFilter(BaseDupeFilter): """Redis-based request duplicates filter. This class can also be used with default Scrapy's scheduler. """ logger = logger def __init__(self, server, key, debug=False): # self.server = redis链接 self.server = server # self.key = dupefilter:123912873234 self.key = key @classmethod def from_settings(cls, settings): # 读取配置,链接redis server = get_redis_from_settings(settings) # key = dupefilter:123912873234 key = defaults.DUPEFILTER_KEY % {'timestamp': int(time.time())} debug = settings.getbool('DUPEFILTER_DEBUG') return cls(server, key=key, debug=debug) @classmethod def from_crawler(cls, crawler): return cls.from_settings(crawler.settings) def request_seen(self, request): fp = self.request_fingerprint(request) # This returns the number of values added, zero if already exists. # self.server=redis链接 # 添加到redis集合中:1,添加工程;0,已经存在 added = self.server.sadd(self.key, fp) return added == 0 def request_fingerprint(self, request): return request_fingerprint(request) def close(self, reason=''): self.clear() def clear(self): """Clears fingerprints data.""" self.server.delete(self.key)
复制代码
复制代码

scrapy-redis的调度器如何实现任务的深度优先和广度优先?

  https://www.cnblogs.com/pupilheart/articles/9851936.html

  https://www.cnblogs.com/pupilheart/articles/9851964.html

 分布式爬虫的更新中。。。

简述 vitualenv 及应用场景?

'vitualenv'是一个独立的python虚拟环境
如:
   当前项目依赖的是一个版本,可是另外一个项目依赖的是另外一个版本,这样就会形成依赖冲突,
   而virtualenv就是解决这种状况的,virtualenv经过建立一个虚拟化的python运行环境,
   将咱们所需的依赖安装进去的,不一样项目之间相互不干扰

简述 pipreqs 及应用场景?

能够经过对项目目录扫描,自动发现使用了那些类库,而且自动生成依赖清单。

pipreqs ./ 生成requirements.txt

在Python中使用过什么代码检查工具?

1)PyFlakes:静态检查Python代码逻辑错误的工具。
2)Pep8: 静态检查PEP8编码风格的工具。 3)NedBatchelder’s McCabe script:静态分析Python代码复杂度的工具。 Python代码分析工具:PyChecker、Pylint

简述 saltstack、ansible、fabric、puppet工具的做用?

 

 

B Tree和B+ Tree的区别?

1.B树中同一键值不会出现屡次,而且有可能出如今叶结点,也有可能出如今非叶结点中。
  而B+树的键必定会出如今叶结点中,并有可能在非叶结点中重复出现,以维持B+树的平衡。 2.由于B树键位置不定,且在整个树结构中只出现一次,

请列举常见排序并经过代码实现任意三种。

冒泡/选择/插入/快排

https://www.cnblogs.com/Liqiongyu/p/5911613.html

http://www.cnblogs.com/feixuelove1009/p/6143539.html

 请列举常见查找并经过代码实现任意三种。

请列举你熟悉的设计模式

工厂模式/单例模式等

有没有刷过leetcode?

leetcode是个题库,里面有多很编程题目,能够在线编译运行。

https://leetcode-cn.com/problemset/all/

列举熟悉的的Linux命令。

复制代码
复制代码
1建立目录
mkdir /data cd / mkdir data 2:查看目录 ls ls -l 显示详细信息
复制代码
复制代码

公司线上服务器是什么系统?

Linux/Centos

解释 PV、UV 的含义?

PV访问量(Page View),即页面访问量,每打开一次页面PV计数+1,刷新页面也是。
UV访问数(Unique Visitor)指独立访客访问数,一台电脑终端为一个访客。

解释 QPS的含义?

'QPS(Query Per Second)'
每秒查询率,是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准

uwsgi和wsgi的区别?

wsgi是一种通用的接口标准或者接口协议,实现了python web程序与服务器之间交互的通用性。

uwsgi:同WSGI同样是一种通讯协议
uwsgi协议是一个'uWSGI服务器'自有的协议,它用于定义传输信息的类型, 'uWSGI'是实现了uwsgi和WSGI两种协议的Web服务器,负责响应python的web请求。

supervisor的做用?

复制代码
复制代码
# Supervisor:
是一款基于Python的进程管理工具,能够很方便的管理服务器上部署的应用程序。
是C/S模型的程序,其服务端是supervisord服务,客户端是supervisorctl命令 # 主要功能: 1 启动、重启、关闭包括但不限于python进程。 2 查看进程的运行状态。 3 批量维护多个进程。
复制代码
复制代码

什么是反向代理?

正向代理代理客户端(客户端找哟个代理去访问服务器,服务器不知道你的真实IP)
反向代理代理服务器(服务器找一个代理给你响应,你不知道服务器的真实IP)

简述SSH的整个过程。

SSH 为 'Secure Shell' 的缩写,是创建在应用层基础上的安全协议。
SSH 是目前较可靠,为远程登陆会话和其余网络服务提供的安全性协议。
利用 SSH 协议能够有效防止远程管理过程当中的信息泄露问题。

有问题都去那些找解决方案?

起初是百度,发现搜到的答案不精准,净广告
转战谷歌,但墙了;捣鼓怎么FQ

还会去知乎、stackoverfloow、必应、思否(segmentfault)

是否有关注什么技术类的公众号?

python之禅(主要专一Python相关知识,做者:刘志军)
码农翻身(主要是Java的,但不光是java,涵盖面很广,做者:刘欣)
实验楼(在线练项目)
and so on

最近在研究什么新技术?

Numpy
pandas(金融量化分析、聚宽)
百度AI
图灵API
智能玩具

是否了解过领域驱动模型

Domain-Driven Design

二进制与十进制之间的转换

一、十进制 与 二进制之间的转换
    (1)、十进制转换为二进制,分为整数部分和小数部分

整数部分

复制代码
复制代码
方法:除2取余法,即每次将整数部分除以2,余数为该位权上的数,而商继续除以2,余数又为上一个位权上的数。
这个步骤一直持续下去,直到商为0为止,最后读数时候,从最后一个余数读起,一直到最前面的一个余数。下面举例:

例:将十进制的168转换为二进制
得出结果 将十进制的168转换为二进制,(10101000)2
168 / 2 = 84 -- 0 84 / 2 = 42 -- 0 42 / 2 = 21 -- 0 21 / 2 = 10 -- 1 10 / 2 = 5 -- 0 5 / 2 = 2 -- 1 2 / 2 = 1 -- 0 1 / 2 = 0 -- 1 二进制(从后往前读): 10101000
复制代码
复制代码

小数部分

方法:乘2取整法,即将小数部分乘以2,而后取整数部分,剩下的小数部分继续乘以2,而后取整数部分,
剩下的小数部分又乘以2,一直取到小数部分为零为止。若是永远不能为零,就同十进制数的四舍五入同样,
按照要求保留多少位小数时,就根据后面一位是0仍是1,取舍,若是是零,舍掉,若是是1,向入一位。
换句话说就是0舍1入。读数要从前面的整数读到后面的整数
小数部分

二进制转换为十进制 (不分整数和小数部分)

方法:按权相加法,即将二进制每位上的数乘以权,而后相加之和便是十进制数。

复制代码
复制代码
例:将二进制数101.101转换为十进制数。 
得出结果:(101.101)2=(5.625)10 在作二进制转换成十进制须要注意的是 1)要知道二进制每位的权值 2)要能求出每位的值 101.101 转换为十进制 整数部分:2^2 + 2^0 = 5 小数部分:2^(-1) + 2^(-3) = 1/2 + 1/8 = 0.5 + 0.125 = 0.625 十进制: 2^2 + 2^0 + 2^(-1) + 2^(-3) = 5.625
复制代码
复制代码
相关文章
相关标签/搜索