您现在的位置是:首页 > 文章详情

面使汇总2

日期:2018-08-27点击:507


Python基础

1.为什么学习Python? 

2.通过什么途径学习的Python? 
略… 
  
3.Python和Java、PHP、C、C#、C++等其他语言的对比? 
执行过程上:Python为脚本语言,边解释边执行,而编译型语言需要编译完成后才能执行;在执行效率上脚本语言也就不如编译型语言快; 
变量使用上:Python变量无需声明, 鸭子类型;C++等为强类型,变量使用前需声明; 
… 
  
4.简述解释型和编译型编程语言? 
解释型语言在解释器下边解释边运行(动态),而编译型语言需要将源码交给编译器,经编译链接生产二进制可执行文件后,才能运行(静态)。 
  
5.Python解释器种类以及特点? 
CPython、IPython:用C语言开发,效率高,GIL,使用最广泛,IPython基于CPython,在交互方式上做了改进; 
PyPy:PyPy是另一个Python解释器,它的目标是执行速度,PyPy采用JIT技术,对Python代码进行动态编译,所以可以显著提高Python代码的执行速度。 
JPython:Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。无GIL 
IronPython:IronPython是运行在微软.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。 
  
6.位和字节的关系? 
位(bit),字节(byte), 1Byte = 8bit 
  
7.b、B、KB、MB、GB 的关系? 
略… 
  
8.请至少列举5个 PEP8 规范(越多越好)。 
具体看这里 
  
9.通过代码实现如下转换:

# 二进制转换成十进制:v = “0b1111011”

# 十进制转换成二进制:v = 18

# 八进制转换成十进制:v = “011”

# 十进制转换成八进制:v = 30

# 十六进制转换成十进制:v = “0x12”

# 十进制转换成十六进制:v = 87

 

print(int('0b1111011', 2)) # 123

print(bin(18)) # 0b10010

print(int('011', 8)) # 9

print(oct(30)) # 0o36

print(int('0x12', 16)) # 18

print(hex(87)) # 0x57

 

10.请编写一个函数实现将IP地址转换成一个整数。

# 10.3.9.12 转换规则为:

#         10            00001010

#          3            00000011

#          9            00001001

#         12            00001100

# 再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 =

 

def func(s):

    l = s.split('.')

    ret = []

    for item in l:

        item = str(bin(int(item)))[2:]

        if len(item) < 8:

            n = 8 - len(item)

            item = ''.join(['0'*n, item])

        ret.append(item)

    print(ret)

 

    temp = ''.join(ret)

    print(temp)

    print(int(temp, 2))

    return ret

 

func('10.3.9.12')

 

11.python递归的最大层数?

def foo(n):

    print(n)

    n += 1

    foo(n)

 

foo(1) # 998

 

import sys

sys.setrecursionlimit(100000)

 

def bar(n):

    print(n)

    n += 1

    bar(n)

 

bar(1) # 3222左右

 

12.求结果:

v1 = 1 or 3

v2 = 1 and 3

v3 = 3 and 1 # 短路原则

v4 = 0 and 2 and 1

v5 = 0 and 2 or 1

v6 = 0 and 2 or 1 or 4

v7 = 0 or False and 1

 

print(v1, v2, v3, v4, v5, v6, v7)

# 1 3 1 0 1 1 False

 

13.ascii、unicode、utf-8、gbk 区别? 
  
ascii 只支持英文字符 1字符1字节 
unicode 通用编码,支持大部分语言,但比较占空间 
utf-8 可变长编码,节省内存,ascii码是其子集 
gbk 支持中文字符的编码

  
14.字节码和机器码的区别? 
  
机器码是电脑CPU直接读取运行的机器指令,是电脑的CPU可直接解读的数据,运行速度最快,但是非常晦涩难懂,也比较难编写,一般从业人员接触不到; 
字节码(Bytecode)是一种包含执行程序、由一序列 op 代码/数据对 组成的二进制文件。字节码是一种中间码,它比机器码更抽象,需要直译器转译后才能成为机器码的中间代码。 
  
15.三元运算规则以及应用场景? 
  
i = A if condition else B,主要运用与结构简单的条件语句,这样可以节省代码 
  
16.列举 Python2和Python3的区别? 
 

print函数

xrange和range

raw_input和input

字符串编码: py2字符串其实是byte(默认已编码)

除法运算

延伸阅读 点这里

  
17.用一行代码实现数值交换:

    a = 1

    b = 2

    a, b = b, a

 

18.Python3和Python2中 int 和 long的区别? 
Python 2有为非浮点数准备的intlong类型。int类型的最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在Python 3里,只有一种整数类型int,大多数情况下,它很像Python 2里的长整型。由于已经不存在两种类型的整数,所以就没有必要使用特殊的语法去区别他们。延伸阅读点这里。 
  
19.xrange和range的区别? 
  
在Python 2里,有两种方法来获得一定范围内的数字:range(),它返回一个列表,还有xrange(),它返回一个迭代器。在Python 3里,range()返回迭代器,xrange()不再存在了。 
  
20.文件操作时:xreadlines和readlines的区别? 
  
在Python 2里,文件对象有一个xreadlines()方法,它返回一个迭代器,一次读取文件的一行。这在for循环中尤其有用。 
在Python 3里,xreadlines()方法不再可用了,可改为for line in a_file。 
  
21.列举布尔值为False的常见值? 
  
主要有:0,空字符串,空元组,空列表,空字典等。 
  
22.字符串、列表、元组、字典每个常用的5个方法?

str:

    find()

    replace()

    spilit()

    join()

    strip()

    ...

list:

    append()

    remove()

    pop()

    reverse()

    sort()

....

 

23.lambda表达式格式以及应用场景? 
  
格式:`lambda x: x+1 
场景:配合map、reduce等高阶函数使用,或作为列表元素排序的key。 
  
24.pass的作用? 
  
空语句,什么也不做,占坑; 
保证结构的完整性,可以以后实现。 
  
25.*arg和**kwarg作用 
  
实现了不定长传参,其中*args为可变长参数,允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple;**kw为关键字参数,允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。 
  
26.is和==的区别 
  
is对比内存地址是否一致; == 对比值是否相等。 
  
27.简述Python的深浅拷贝以及应用场景? 
  
浅拷贝指仅仅拷贝数据集合的第一层数据,深拷贝指拷贝数据集合的所有层。对于只有一层的数据集合来说深浅拷贝的意义是一样的,比如字符串,数字,还有仅仅一层的字典、列表、元祖等。 
  
对于 数字和字符串 而言,赋值、浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址。 
  
场景: 数据完整备份(隔离) 
  
28.Python垃圾回收机制? 
  
Python的GC模块主要运用了“引用计数”(reference counting)来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用的问题。通过“分代回收”(generation collection)以空间换取时间来进一步提高垃圾回收的效率。 
Python中的垃圾回收机制 
  
29.Python的可变类型和不可变类型? 
  
数值类型(int和float)、字符串str、元组tuple都是不可变类型。而列表list、字典dict、集合set是可变类型。 
  
不可变对象,变量对应内存的值不允许被改变,当变量要改变时,实际上是把原来的值复制一份后再改变,开辟一个新的地址,旧的地址上的数据被垃圾回收。 
  
30.求结果:

v = dict.fromkeys(['k1','k2'],[])

v['k1'].append(666)

print(v)  # >>> {'k1': [666], 'k2': [666]}

v['k1'] = 777

print(v)  # >>> {'k1': 777, 'k2': [666]}

 

31.求结果:

def num():

    return [lambda x:i*x for i in range(4)]

 

print([m(2) for m in num()])  # >>> [6, 6, 6, 6]

# 匿名函数m中,i只是一个变量,在匿名函数执行时才去查找,而这个时候,i已经变成3了;

# 若不想这样搞,可以让匿名函数中的i提升为函数的参数,这样在生成匿名函数时就绑定了每个i的值:

# def num():

#     return [lambda x, i=i:i*x for i in range(4)]

#

# print([m(2) for m in num()])

 

32.列举常见的内置函数? 

33.filter、map、reduce的作用? 
  
filter(function, sequence):对sequence中的item依次执行function(item),将执行结果为True的item组成一个List/String/Tuple(取决于sequence的类型)。 
  
filter(function or None, sequence) -> list, tuple, or string:入参为函数和列表/元组/字符串,返回值为item列表/元组/字符串。 
  
map(function, sequence) :对sequence中的item依次执行function(item),将执行结果function(item)组成一个List返回。 
  
map(function, sequence[, sequence, …]) -> list:入参是为函数和列表/元组/字符串,返回值为function(item)列表。 
  
reduce(function, sequence, starting_value):对sequence中的item顺序迭代调用function,如果有starting_value,还可以作为初始值调用。function接收的参数个数只能为2,先把sequence中第一个值和第二个值当参数传给function,再把function的返回值和第三个值当参数传给function,然后只返回一个结果。 
  
reduce(function, sequence[, initial]) -> value:入参是为函数和列表/元组/字符串和初始值,返回值为数值。 
  
34.一行代码实现9*9乘法表

print ("\n".join(["\t".join(["%s*%s=%s" %(x,y,x*y) for y in range(1, x+1)]) for x in range(1, 10)]))

1

35.如何安装第三方模块?以及用过哪些第三方模块? 
  
在Python中,安装第三方模块,是通过setuptools这个工具完成的。Python有两个封装了setuptools的包管理工具:easy_install和pip。目前官方推荐使用pip。 
  
36.至少列举8个常用模块都有那些? 
  
pyqt、pymql、pygame、Django、Flask、opencv-python、pillow-python、Scrappy…… 
  
37.re的match和search区别? 
  
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配,否则也返回None。 
  
38.什么是正则的贪婪匹配? 
  
重复运算符在默认条件下是贪婪的。

import re

 

pattern1 = r'\*(.+)\*'

r1 = re.findall(pattern1, r'*hello * *world!*')

print(r1)

 

pattern2 = r'\*(.+?)\*'

r2 = re.findall(pattern2, r'*hello * *world!*')

print(r2)

 

>>> ['hello * *world!']

>>> ['hello ', 'world!']

# 可见贪婪模式匹配了开始星号到结束星号间的全部内容,包括中间两个星号。

 

# (.+?)代替(.+)得到非贪婪模式,它会匹配尽可能少的内容。

 

39.求结果:

print([i % 2 for i in range(10)])

print((i % 2 for i in range(10)))

#######################################

# 一个是列表,一个是生成器:

# [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

# <generator object <genexpr> at 0x0000014F8B419410>

 

40.求结果:

print(1 or 2# 1 短路原则

print(1 and 2# 2

print(1 < (2==2))  # False

print(1 < 2 == 2# True !!!!!!

# 注意最后一个!

 

41.def func(a,b=[]) 这种写法有什么坑? 
  
将可变对象作为默认参数,若多次调用时使用默认参数,默认参数会保留上次调用时的状态! 
  
函数体内最好加上判断:if not b: b = [] 
  
42.如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ? 
  
print("1,2,3".split(',')) 
  
43.如何实现[‘1’,’2’,’3’]变成[1,2,3] ? 
  
print(list(map(lambda x:int(x), ['1', '2', '3']))) 
  
44.比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 c = [(1,),(2,),(3,) ] 的区别? 
  
a,b 均为整型列表, c为元组列表。 
  
45.如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ? 
  
print([i**2 for i in range(1,11)]) 
  
46.一行代码实现删除列表中重复的值 ? 
  
print(list(set(l))) 
  
47.如何在函数中设置一个全局变量 ?

def f():

    global x

    x = 1

 

f()

print(x)

 

  
不知道对不对,好像也可以直接用给函数加属性,是全局的:

def add(x=1):

    try:

        add.sum += x

    except AttributeError:

        add.sum = x

    return add.sum

 

print(add(3))

print(add(4))

print(add.sum)

 

48.logging模块的作用?以及应用场景? 
  
日志记录,可以更好的管理我们的日志,并且可以将标准输入输出保存到日志文件,而且利用logging模块可以部分代替debug的功能,给程序排错。 
  
场景:登录日志,错误日志等等 
  
49.请用代码简单实现stack

class Stack:

    def __init__(self):

        self.items = []

 

    def isEmpty(self):

        return not len(self.items)

 

    def push(self, item):

        self.items.append(item)

 

    def pop(self):

        return self.items.pop()

 

    def size(self):

        return len(self.items)

 

    def clear(self):

        self.items.clear()

 

50.常用字符串格式化哪几种? 
  
%s,%d,%f 
{} format格式化 
  
51.简述 生成器、迭代器、可迭代对象 以及应用场景? 
  
生成器应用场景: 
在结果集比较大的情况下,可返回生成器以节省内存。如读取文件时…. 
  
52.用Python实现一个二分查找的函数。

l = list(range(10000))

 

def binary_search(seq, target_num):

    if len(seq) > 1:

        mid = int(len(seq)/2)

        if seq[mid] == target_num:

            print('find target number: %s'%target_num)

        elif seq[mid] < target_num:

            binary_search(seq[mid+1:], target_num)

        else:

            binary_search(seq[0:mid], target_num)

    else:

        if seq[0] == target_num:

            print('find target number: %s'%target_num)

        else:

            print('There is no such number!')

 

 

binary_search(l,111)

 

53.谈谈你对闭包的理解? 
  
闭包 = 代码块 + 执行环境

函数声明的时候,会生成一个独立的作用域

同一作用域的对象可以互相访问

作用域呈层级包含状态,形成作用域链,子作用域的对象可以访问父作用域的对象,反之不能;另外子作用域会使用最近的父作用域的对象 
 

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

# os模块常用方法

 

os.remove(‘path/filename’) 删除文件

os.rename(oldname, newname) 重命名文件

os.walk() 生成目录树下的所有文件名

os.chdir('dirname') 改变目录

os.mkdir/makedirs('dirname')创建目录/多层目录

os.rmdir/removedirs('dirname') 删除目录/多层目录

os.listdir('dirname') 列出指定目录的文件

os.getcwd() 取得当前工作目录

os.chmod() 改变目录权限

os.path.basename(‘path/filename’) 去掉目录路径,返回文件名

os.path.dirname(‘path/filename’) 去掉文件名,返回目录路径

os.path.join(path1[,path2[,...]]) 将分离的各部分组合成一个路径名

os.path.split('path') 返回( dirname(), basename())元组

os.path.splitext() 返回 (filename, extension) 元组

os.path.getatime\ctime\mtime 分别返回最近访问、创建、修改时间

os.path.getsize() 返回文件大小

os.path.exists() 是否存在

os.path.isabs() 是否为绝对路径

os.path.isdir() 是否为目录

os.path.isfile() 是否为文件

 

# sys模块常用方法

sys.argv #命令行参数List,第一个元素是程序本身路径

sys.path #返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

sys.modules.keys() #返回所有已经导入的模块列表

sys.modules #返回系统导入的模块字段,key是模块名,value是模块

sys.exc_info() #获取当前正在处理的异常类,exc_typeexc_valueexc_traceback当前处理的异常详细信息

sys.exit(n) #退出程序,正常退出时exit(0)

sys.hexversion #获取Python解释程序的版本值,16进制格式如:0x020403F0

sys.version #获取Python解释程序的版本信息

sys.platform #返回操作系统平台名称

sys.maxint # 最大的Int

sys.stdout #标准输出

sys.stdout.write('aaa') #标准输出内容

sys.stdout.writelines() #无换行输出

sys.stdin #标准输入

sys.stdin.read() #输入一行

sys.stderr #错误输出

sys.exc_clear() #用来清除当前线程所出现的当前的或最近的错误信息

sys.exec_prefix #返回平台独立的python文件安装的位置

sys.byteorder #本地字节规则的指示器,big-endian平台的值是'big',little-endian平台的值是'little'

sys.copyright #记录python版权相关的东西

sys.api_version #解释器的CAPI版本

sys.version_info #'final'表示最终,也有'candidate'表示候选,表示版本级别,是否有后继的发行

sys.getdefaultencoding() #返回当前你所用的默认的字符编码格式

sys.getfilesystemencoding() #返回将Unicode文件名转换成系统文件名的编码的名字

sys.builtin_module_names #Python解释器导入的内建模块列表

sys.executable #Python解释程序路径

sys.getwindowsversion() #获取Windows的版本

sys.stdin.readline() #从标准输入读一行,sys.stdout.write(a) 屏幕输出a

sys.setdefaultencoding(name) #用来设置当前默认的字符编码(详细使用参考文档)

sys.displayhook(value) #如果value非空,这个函数会把他输出到sys.stdout(详细使用参考文档)

 

55.如何生成一个随机数? 
  
使用random模块 
  
56.如何使用python删除一个文件? 
  
os.remove('path/filename') # 删除文件 
  
57.谈谈你对面向对象的理解? 
 (看看左耳朵耗子的见解~) 
面向对象编程是种具有对象概念的程序编程范型,同时也是一种程序开发的抽象方针。它可能包含数据、属性、代码与方法。对象则指的是类的实例。它将对象作为程序的基本单元,将程序和数据封装其中,以提高软件的可重用性、灵活性和可扩展性,对象里的程序可以访问及修改对象相关联的数据。在面向对象编程里,计算机程序会被设计成彼此相关的对象。 
  
面向对象程序设计可以看作一种在程序中包含各种独立而又互相调用的对象的思想,这与传统的思想刚好相反:传统的程序设计主张将程序看作一系列函数的集合,或者直接就是一系列对计算机下达的指令。面向对象程序设计中的每一个对象都应该能够接受数据、处理数据并将数据传达给其它对象,因此它们都可以被看作一个小型的“机器”,即对象。 
  
优点:

能和真实的世界交相辉映,符合人的直觉。

面向对象和数据库模型设计类型,更多地关注对象间的模型设计。

强调于“名词”而不是“动词”,更多地关注对象和对象间的接口。

根据业务的特征形成一个个高内聚的对象,有效地分离了抽象和具体实现,增强了可重用性和可扩展性。

有大量非常优秀的设计原则和设计模式。

S.O.L.I.D(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转,是面向对象设计的五个基本原则)、IoC/DIP…… 
 

缺点:

代码都需要附着在一个类上,从一侧面上说,其鼓励了类型。

代码需要通过对象来达到抽象的效果,导致了相当厚重的“代码粘合层”。

因为太多的封装以及对状态的鼓励,导致了大量不透明并在并发下出现很多问题。 
 

58.Python面向对象中的继承有什么特点? 
  
继承更多了是为了多态,也可提升代码的复用程度。 
特点:

在继承中基类的构造(init()方法)不会被自动调用,它需要在其派生类的构造中亲自专门调用;

Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找); 
 

59.面向对象深度优先和广度优先是什么? 
  
当出现多重继承并产生菱形交叉时查找属性或方法路径顺序。 
  
60.面向对象中super的作用? 
  
super() 函数是用于调用父类(超类)的一个方法。 
super 是用来解决多重继承问题的,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。 
MRO 就是类的方法解析顺序表, 其实也就是继承父类方法时的顺序表。 
Python3.x 和 Python2.x 的一个区别是: Python 3 可以使用直接使用 super().xxx 代替 super(Class, self).xxx 
  
61.是否使用过functools中的函数?其作用是什么? 
 

@functools.wraps:使用装饰器时保留被装饰函数的签名和docstring

@functools.lru_cache(maxsize=128, typed=False):(下面给出例子)

functools.partial(func, *args, **keywords): 
用于静态Web内容的LRU缓存示例:

@lru_cache(maxsize=32)

def get_pep(num):

    'Retrieve text of a Python Enhancement Proposal'

    resource = 'http://www.python.org/dev/peps/pep-%04d/' % num

    try:

        with urllib.request.urlopen(resource) as s:

            return s.read()

    except urllib.error.HTTPError:

        return 'Not Found'

 

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:

...     pep = get_pep(n)

...     print(n, len(pep))

 

>>> get_pep.cache_info()

CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

1

 

使用缓存实现动态编程技术高效计算斐波那契数列的示例:

@lru_cache(maxsize=None)

def fib(n):

    if n < 2:

        return n

    return fib(n-1) + fib(n-2)

 

>>> [fib(n) for n in range(16)]

[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

 

>>> fib.cache_info()

CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

 

partial()用于冻结函数的某些参数和/或关键字参数,生成一个简化的签名对象。例如,用于创建一个类似int()函数的可调用对象,其中base参数默认为2:

>>> from functools import partial

>>> basetwo = partial(int, base=2)

>>> basetwo.__doc__ = 'Convert base 2 string to an int.'

>>> basetwo('10010')

18

 

62.列举面向对象中带爽下划线的特殊方法,如:__new__、__init__ 
  
__setattr__:添加/修改属性会触发它的执行 
__delattr__:删除属性的时候会触发 
__getattr__:只有在使用点调用属性且属性不存在的时候才会触发 
__getattribute__:当__getattribute____getattr__同时存在,无论属性是否存在,只会执行__getattrbute__,除非__getattribute__在执行过程中抛出异常AttributeError 
__get__: 调用一个属性时触发 
__set__: 为一个属性赋值时触发 
__delete__: 采用del删除一个属性时触发 
__setitem__,__getitem____delitem__ 
这三个方法为实例提供了类字典操作 
__next____iter__实现迭代器协议 
__enter____exit__实现上下文管理协议 
  
63.如何判断是函数还是方法? 
是否需要实例化的对象来调用 
  
64.静态方法和类方法区别? 
  
静态方法无需传入类名或对象作为第一个参数;而类方法需要传入类名作为第一个参数 
  
65.列举面向对象中的特殊成员以及应用场景

__doc__  描述类的信息

__call__ 对象后面加括号,触发执行

__dict__ 查看类或对象中的所有成员

__str__ 如果一个类中定义了__str__方法,那么在打印对象时,默认输出该方法的返回值

 

66. 1、2、3、4、5 能组成多少个互不相同且无重复的三位数

l = [1, 2, 3, 4, 5]

 

cnt = 0

for i in range(5):

    for j in range(5):

        if j == i:

            continue

        for k in range(5):

            if k != j and k != i:

                print(l[i]*100+l[j]*10+l[k])

                cnt += 1

print(cnt)  # 60

 

67.什么是反射?以及应用场景? 
  
反射主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。 
  
应用场景:实现可插拔机制;导入其他模块,利用反射查找该模块是否存在某个方法

if hasattr(f1,'get'):

    func_get=getattr(f1,'get')

    func_get()

 

import module_test as obj

 

#obj.test()

print(hasattr(obj,'test'))

getattr(obj,'test')()

 

68.metaclass作用?以及应用场景? 
  
元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为 
  
元类的实例化的结果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例),type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象 
场景:当然是定制类的行为了…. 
  
69.用尽量多的方法实现单例模式。

# 1. 使用模块:Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件;

# 当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码

#foo1.py

class Singleton:

    def foo(self):

        pass

singleton = Singleton()

 

 

#foo.py

from foo1 import singleton

 

# 2. 静态变量方法(自定义new方法)

class Singleton(object):

    def __new__(cls,a):

        if not hasattr(cls, '_instance'):

            cls._instance = object.__new__(cls)

        return cls._instance

    def __init__(self,a):

        self.a = a

    def aa(self):

        print(self.a)

 

 

a = Singleton("a")

 

# 3. 使用装饰器

def Singleton(cls):

    _instance = {}

 

    def _singleton(*args, **kargs):

        if cls not in _instance:

            _instance[cls] = cls(*args, **kargs)

        return _instance[cls]

 

    return _singleton

 

 

@Singleton

class A:

    pass

 

# 4. 使用类方法获取单例(考虑多线程)

# 这种方式实现的单例模式,使用时会有限制,以后实例化必须通过 obj = Singleton.instance()

# 如果用 obj=Singleton() ,这种方式得到的不是单例

import time

import threading

class Singleton(object):

    _instance_lock = threading.Lock()

 

    def __init__(self):

        time.sleep(1)

 

    @classmethod

    def instance(cls, *args, **kwargs):

        if not hasattr(Singleton, "_instance"):

            with Singleton._instance_lock:

                if not hasattr(Singleton, "_instance"):

                    Singleton._instance = Singleton(*args, **kwargs)

        return Singleton._instance

 

obj = Singleton.instance()

 

# 5. 基于metaclass方式实现

"""

类由type创建,创建类时,type__init__方法自动执行,

() 执行type __call__方法(类的__new__方法,类的__init__方法)

"""

 

import threading

 

 

class SingletonType(type):

    _instance_lock = threading.Lock()

 

    def __call__(cls, *args, **kwargs):

        if not hasattr(cls, "_instance"):

            with SingletonType._instance_lock:

                if not hasattr(cls, "_instance"):

                    cls._instance = super().__call__(*args, **kwargs)

        return cls._instance

 

 

class Foo(metaclass=SingletonType):

    def __init__(self, name):

        self.name = name

 

 

obj1 = Foo('name')

obj2 = Foo('name')

print(obj1 is obj2)

 

 

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

# 1. 授权

# 2. 日志

# 3. 带参数的装饰器

from functools import wraps

 

def logit(logfile='out.log'):

    def logging_decorator(func):

        @wraps(func)

        def wrapped_function(*args, **kwargs):

            log_string = func.__name__ + " was called"

            print(log_string)

            # 打开logfile,并写入内容

            with open(logfile, 'a') as opened_file:

                # 现在将日志打到指定的logfile

                opened_file.write(log_string + '\n')

            return func(*args, **kwargs)

        return wrapped_function

    return logging_decorator

@logit()

def myfunc1():

    pass

@logit(logfile='func2.log')

def myfunc2():

    pass

 

# 4. 装饰类 的装饰器:类实例化的过程,也是函数调用

from functools import wraps

 

def foo(bar):

    @wraps(bar)

    def __foo(*args,**kwargs):

        print('before')

        obj = bar(*args, **kwargs)

        print('after')

        return obj

    return __foo

@foo

class Person:

    def __init__(self, name):

        self.name = name

 

 

# 5. 类装饰器:重写__call__()方法

# Q: 这里如果被装饰的函数有参数,应该怎么写呢?

class foo:

    def __init__(self, func):

        self.func = func

 

    def __call__(self, *args, **kwargs):

        print('begin...')

        self.func(*args, **kwargs)

        print('end')

 

 

@foo    # bar = foo(bar)

def bar():

    print('in bar')

 

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

try:

    pass

except:

    pass

finally:    # 无论是否有异常,都执行

    pass

 

# 抛出异常:raise 异常类

1

2

3

4

5

6

7

8

72.什么是面向对象的mro 
  
对于你定义的每一个类,python会计算出一个方法解析顺序(MRO)列表,这个MRO列表就是一个简单的所有基类的线性顺序列表。为了实现继承,python会在MRO列表上从左到右开始查找基类,直到找到第一个匹配这个属性的类为止。 
  
1. 子类会先于父类被检查 
2. 多个父类会根据它们在列表中的顺序被检查 
3. 如果对下一个类存在两个合法的选择,选择第一个父类 
  
73.isinstance作用以及应用场景? 
判断是否是某类型的实例 
  
74. 写代码并实现:

写代码并实现:

Given an array of integers, return indices of the two numbers such that they add up to a specific target.You may assume that each input would

have exactly one solution, and you may not use the same element twice.

Example:

          Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,

           return [0, 1]

 

# 以空间换时间,使用dict保存各项和target的差值,然后查看有没有元素刚好等于该差值

 

nums = [2, 7, 11, 3, 8, 10]

target = 11

 

def solution(nums, target):

    dic = {}

    for index, num in enumerate(nums):

        if num in dic:

            return [dic[num], index]

        else:

            dic[target-num] = index

 

print(solution(nums, target))

73. json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型? 
  
支持的数据类型:

Python

JSON

dict

object

list, tuple

array

str

string

int, float

number

True

true

False

false

None

null

对于,特殊的数据类型,例如,datatime() 时间类型,json.dumps不支持该数据类型的序列化;那么就可以通过自定义处理来扩展,使用的时候,只要在json.dumps()方法中增加一个cls参数即可:

import json

from datetime import date

from datetime import datetime

 

class JsonCustomEncoder(json.JSONEncoder):

 

    def default(self, obj):

        if isinstance(obj, datetime):

            return obj.strftime(‘%Y-%m-%d %H:%M:%S‘)

        elif isinstance(obj, date):

            return obj.strftime(‘%Y-%m-%d‘)

        else:

            return json.JSONEncoder.default(self, obj)

 

# ds = json.dumps(d, cls=JsonCustomEncoder)

 

76. json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?

import json

a=json.dumps({"ddf":"你好"},ensure_ascii=False)

print(a) #{"ddf": "你好"}

 

77.什么是断言?应用场景? 
Python的assert是用来检查一个条件,如果它为真,就不做任何事。如果它为假,则会抛出AssertError并且包含错误信息。

x = 23

assert x > 0, "x is not zero or negative"

assert x%2 == 0, "x is not an even number"

 

断言应该用于: 
防御型的编程 
运行时检查程序逻辑 
检查约定 
程序常量 
检查文档 
 
一个好的使用断言的方式是检查程序的不变量。一个不变量是一些你需要依赖它为真的情况,除非一个bug导致它为假。如果有bug,最好能够尽早发现,所以我们为它进行一个测试,但是又不想减慢代码运行速度。所以就用断言,因为它能在开发时打开,在产品阶段关闭。 
  
78.有用过with statement吗?它的好处是什么? 
  
with语句会在嵌套的代码执行之后,自动关闭文件。这种做法的还有另一个优势就是,无论嵌套的代码是以何种方式结束的,它都关闭文件。如果在嵌套的代码中发生异常,它能够在外部exception handler catch异常前关闭文件。如果嵌套代码有return/continue/break语句,它同样能够关闭文件。

from contextlib import contextmanager

import os

 

@contextmanager

def working_directory(path):

    current_dir = os.getcwd()

    os.chdir(path)

    try:

        yield

    finally:

        os.chdir(current_dir)

 

 

with working_directory("../"):

    # do something within ../

    print('in', os.getcwd())

# here I am back again in the original working directory

print('out', os.getcwd())

 

79.使用代码实现查看列举目录下的所有文件。 
 

import os

 

ret = []

for root, dirs, files in os.walk(os.getcwd(), topdown=True):

    # print([os.path.join(root, file) for file in files])

    ret.extend([os.path.join(root, file) for file in files])

 

print(ret)

 

80. 简述 yield和yield from关键字。 
  
当一个函数中存在yield关键字时,它就变成了一个生成器,每次迭代求值一次,节省内存; 
yield from 意思是从一个可迭代对象中逐一取值并yield:

yield from iterable

# 与上面等价

for item in iterable:

    yield item


 

1.简述 OSI 七层协议。 
  
OSI七层模型的划分 
应用层(Application)、表示层(presentation)、会话层(session)、传输层(Transport)、网络层(Network)、数据链路层(Data Link)、物理层(Physical)。 
每一层实现各自的功能和协议,并完成与相邻接口通信,OSI的服务定义详细说明了各层所提供的服务。某一层的服务就是该层及其下各层的一种能力,它通过接口提供给更高一层。 
 
各层含义: 
  
应用层 
OSI 参考模型中最靠近用户的一层,是为计算用户提供应用接口,也为用户直接提供网络服务。常见的应用层网络服务协议有:HTTP,HTTPS,FTP,POP3,SMTP等 
表示层 
表示提供各种用于应用层数据编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。如果必要该层可提供一种标准表示形式,用于将计算机内部的多种数据格式转换成通信中采用的标准表示形式。数据压缩和加密也是表示层可提供的转换功能之一。 
  
会话层 
会话层负载建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。 

传输层 
传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,是高层用户看到的只是在两个传输实体建的一个主机到主机的、可由用户控制和设定、可靠的数据通路。通常说的TCP UDP就是在这层。端口号即是这里的“端”。 

网络层 
本层通过IP寻址来建立两点之间的连接,为源端的运输层来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的ip层。这一层就是我们经常说的IP协议层。IP协议是Internet的基础。 

数据链路层 
将比特组合成字节,再将字节组成帧,使用链路层地址(以太网mac地址)来访问介质,并进行差错检测。 
数据链路层又分为2个子层:逻辑链路控制子层(LLC)和媒体访问控制子层(MAC)。 

物理层 
实际最终信号传输是通过物理层实现的。通过物理介质传输比特流。规定电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。


2.什么是C/S和B/S架构? 
Client/Server Vs Browser/Server 
  
3.简述 三次握手、四次挥手的流程。 
 
TCP三次握手的过程如下:

客户端发送SYNseq=x)报文给服务器端,进入SYN_SEND状态;

服务端收到SYN报文,回应一个SYN(seq=y) ACK(ack=x+1)报文,进入SYN_RECV状态;

客户端收到服务端的SYN报文,客户端进入ESTABLISHED状态;然后回应一个ACK(ACK=y+1)报文,服务器端进入ESTABLISHED状态; 
 

建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的。 
(1) 某个应用进程首先调用close,称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。 
(2) 接收到这个FIN的对端执行 “被动关闭”(passive close),这个FIN由TCP确认。 
注意:FIN的接收也作为一个文件结束符(end-of-file)传递给接收端应用进程,放在已排队等候该应用进程接收的任何其他数据之后,因为,FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。 
(3) 一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。 
(4) 接收这个最终FIN的原发送端TCP(即执行主动关闭的那一端)确认这个FIN。 
  
4.什么是arp协议? 
  
要了解ARP的作用,首先要分清两个“地址”: 
(1)TCP/IP的32bit IP地址。仅知道主机的IP地址不能让内核发送数据帧给主机。 
(2)网络接口的硬件地址,它是一个48bit的值,用来标识不同的以太网或令牌环网络接口。在硬件层次上,进行数据交换必须有正确的接口地址,内核必须知道目的端的硬件地址才能发送数据。 
简言之,就是在以太网中,一台主机要把数据帧发送到同一局域网上的另一台主机时,设备驱动程序必须知道以太网地址才能发送数据。而我们只知道IP地址,这时就需要采用ARP协议将IP地址映射为以太网地址。详解请看这篇博客。 
  
5.TCP和UDP的区别? 
  
    TCP—传输控制协议,提供的是面向连接、可靠的字节流服务。当客户和服务器彼此交换数据前,必须先在双方之间建立一个TCP连接,之后才能传输数据。TCP提供超时重发,丢弃重复数据,检验数据,流量控制等功能,保证数据能从一端传到另一端。 
    UDP—用户数据报协议,是一个简单的面向数据报的运输层协议。UDP不提供可靠性,它只是把应用程序传给IP层的数据报发送出去,但是并不能保证它们能到达目的地。由于UDP在传输数据报前不用在客户和服务器之间建立一个连接,且没有超时重发等机制,故而传输速度很快 
    TCP是面向连接的,有比较高的可靠性, 一些要求比较高的服务一般使用这个协议,如FTP、Telnet、SMTP、HTTP、POP3等。而UDP是面向无连接的,使用这个协议的常见服务有DNS、SNMP、QQ等。 
  
6.什么是局域网和广域网? 
 略… 
  
7.为何基于tcp协议的通信比基于udp协议的通信更可靠? 
  
tcp:可靠 对方给了确认收到信息,才发下一个,如果没收到确认信息就重发; 
udp:不可靠 一直发数据,不需要对方回应。 
  
8.什么是socket?简述基于tcp协议的套接字通信流程。 
  
Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部。 
  
服务端先初始化Socket实例化一个类拿到对象(才能调用下面的接口),然后绑定IP端口(bind),监听(listen)就是说客户端可以来连我了,调用accept接收链接;这时客户端初始化一个socket,然后connect与服务端建立好双向链接与accept对应。客户端发送请求数据,服务端处理请求并给客户端回应数据,这样一个通信循环;最后关闭套接字,一次交互结束。 
  
9.什么是粘包? socket 中造成粘包的原因是什么? 哪些情况会发生粘包现象? 
  
接收方收到的数据是多个数据包黏在一起的内容的现象就叫粘包; 
原因:

TCP是流式传输,无消息边界,接收方不知道每个报文的长度;

TCP为提高传输效率,发送方往往要收集到足够多的数据后才发送一个TCP段。若连续几次需要send的数据都很少,通常TCP会根据优化算法把这些数据合成一个TCP段后一次发送出去,这样接收方就收到了粘包数据。 
 

10.IO多路复用的作用? 
  
IO多路复用模型(也叫异步非阻塞,但实质是同步IO,因为自己负责进行读写,也就是说这个读写过程是阻塞的)是建立在内核提供的多路分离函数select基础之上的,使用select函数可以避免同步非阻塞IO模型中轮询等待的问题; 
  
从流程上来看,使用select函数进行IO请求和同步阻塞模型没有太大的区别,甚至还多了添加监视socket,以及调用select函数的额外操作,效率更差。但是,使用select以后最大的优势是用户可以在一个线程内同时处理多个socket的IO请求。用户可以注册多个socket,然后不断地调用select读取被激活的socket,即可达到在同一个线程内同时处理多个IO请求的目的。而在同步阻塞模型中,必须通过多线程的方式才能达到这个目的。 
  
如果处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。select/epoll的优势并不是对于单个连接能处理得更快,而是在于能处理更多的连接。 
  
相对于异步IO,多路复用模式在select返回时,需要用户线程调用read操作,将数据从kernel拷贝到用户进程,而异步IO是把一切都准备好了才通知用户线程。 
  
11.什么是防火墙以及作用? 
一种信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。 
  
12.select、poll、epoll 模型的区别? 
  
详细介绍:参考这篇文章

select:

select 会修改传入的参数数组,这个对于一个需要调用很多次的函数,是非常不友好的;

select 如果任何一个sock(I/O stream)出现了数据,select 仅仅会返回,但是并不会告诉你是那个sock上有数据,于是你只能自己一个一个的找;

select 只能监视1024个链接;

select 不是线程安全的;

poll:

poll 去掉了1024个链接的限制;

poll 从设计上来说,不再修改传入数组,不过这个要看你的平台了;

poll依然是线程不安全的

epoll 

epoll 现在是线程安全的;

epoll 现在不仅告诉你sock组里面数据,还会告诉你具体哪个sock有数据,你不用自己去找了;

只有linux支持

注意:如果并发量不高,用哪个效果没差 
  
13.简述 进程、线程、协程的区别 以及应用场景?

进程: 

系统进资源分配的独单位

子进程因为某种原因崩溃,不会直接导致主程序的崩溃,可以降低主程序崩溃的概率;

-

线程: 

CPU调度和分派的基本单位

个进程内的所有线程共享全局变量,很便在多个线程间共享数据

线程执开销,但不利于资源的管理和 保护;进程正相反

协程: 

它是个比线程更轻的执单元,因为它CPU上下

协程是由用户程序自己控制调度的;

应用程序级别(而非操作系统)控制切换,开销小;

修改共享数据不需加锁;

一个协程遇到IO操作自动切换到其它协程; 
 

14.GIL锁是什么鬼? 
  
首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。>有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。 
  
GIL本质就是一把互斥锁,在一个python进程内,不仅有主线程或者由该主线程开启的其他线程,还有解释器开启的垃圾回收等解释器级别的线程,同一个进程中,所有数据都是共享的,例如:test.py定义一个函数work,在进程内所有线程都能访问到work的代码,于是我们可以开启三个线程然后target都指向该代码,能访问到意味着就是可以执行;所有线程的任务,都需要将任务的代码当做参数传给解释器的代码去执行,即所有的线程要想运行自己的任务,首先需要解决的是能够访问到解释器的代码。

  
综上:

如果多个线程的target=work,那么执行流程是——多个线程先访问到解释器的代码,即拿到执行权限,然后将target的代码交给解释器的代码去执行。 
  
解释器的代码是所有线程共享的,所以垃圾回收线程也可能访问到解释器的代码而去执行,这就导致了一个问题:对于同一个数据100,可能线程1执行x=100的同时,而垃圾回收执行的是回收100的操作,解决这种问题没有什么高明的方法,就是加锁处理。 
  
其他语言线程内部应该也有锁控制,只不过其粒度更细,不会把整个线程锁死,由于python的线程是调用c语言的pthread接口,无法控制线程内部,只好来一把大锁了。。。 
另外,GIL 与Lock是两把锁,保护的数据不一样,前者是解释器级别的(当然保护的就是解释器级别的数据,比如垃圾回收的数据),后者是保护用户自己开发的应用程序的数据,很明显GIL不负责这件事,只能用户自定义加锁处理,即Lock。 
  
15.Python中如何使用线程池和进程池?

线程池: 

from concurrent.futures import ThreadPoolExecutor

future = executor.submit(task, i)

executor.map(task,range(1,12)) #map取代了for+submit

future.submit(get_page,url).add_done_callback(parse_page) #parse_page拿到的是一个future对象obj,需要用obj.result()拿到结果

进程池: 

from concurrent.futures import ProcessPoolExecutor

方法同上:submit || map || 回调

from multiprocessing import Pool

res=p.apply_async(work,args=(i,))

  
16.threading.local的作用? 
  
在多线程环境下,每个线程都有自己的数据。一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁。 
Threading.local可以创建一个对象,每个线程都可以对他读写属性,但不会互相影响。 
  
17.进程之间如何进行通信? 
Queue、Pipe、Socket、File … 
  
18.什么是并发和并行? 
并行:同一时刻多条指令在运行; 
并发:短暂时间内多条指令交替运行; 
  
19.进程锁和线程锁的作用? 
保护数据安全,因为多线程/多进程的执行顺序是不可预知的。 
  
20.解释什么是异步非阻塞? 
一个函数调用遇到IO直接返回做其他任务(异步),等到IO都被其他人准备好了(非阻塞)就会收到通知,继续执行。 
  
21.路由器和交换机的区别? 
  
工作所在的OSI层次不一样:交换机工作在 OSI模型的数据链路层,路由器工作在OSI模型的网络层; 
数据转发所依据的对象不一样:交换机依据MAC地址,路由器依据IP地址; 
  
22.什么是域名解析? 
单的说就是把你在浏览器地址栏输入的网页地址解析成IP地址.由于IP地址是用四段数字组成,相对英文来说不好记,通过域名解析就可以不用记IP地址,直接通过输入的英文或汉字链接到网站上了。 
  
23.如何修改本地hosts文件? 
文件路径:C:\WINDOWS\system32\drivers\etc 
格式: 网络IP地址 主机名或域名 主机名别名 
  
24.生产者消费者模型应用场景及优势? 
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。 
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 
  
25.什么是cdn? 
CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。 
CDN的基本原理是广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对集中的地区或网络中,在用户访问网站时,利用全局负载技术将用户的访问指向距离最近的工作正常的缓存服务器上,由缓存服务器直接响应用户请求。 
  
26.LVS是什么及作用? 
待更新… 
  
27.Nginx是什么及作用? 
  
28.keepalived是什么及作用? 
  
29.haproxy是什么以及作用? 
  
30.什么是负载均衡? 
  
31.什么是rpc及应用场景? 
  
32.简述 asynio模块的作用和应用场景。 
  
33.简述 gevent模块的作用和应用场景。 
  
34.twisted框架的使用和应用?

 

 

 

26LVS是什么及作用?

pass

27Nginx是什么及作用?

我们可以了解到Nginx是一个http服务器。同效果的http服务器还有Apachetomcat 
作用: 
1
http服务器。Nginx是一个http服务可以独立提供http服务。可以做网页静态服务器。 
2
虚拟主机。可以实现在一台服务器虚拟出多个网站。例如个人网站使用的虚拟主机。基于端口的,不同的端口基于域名的,不同域名 
3
反向代理,负载均衡。当网站的访问量达到一定程度后,单台服务器不能满足用户的请求时,需要用多台服务器集群可以使用nginx做反向代理。并且多台服务器可以平均分担负载,不会因为某台服务器负载高宕机而某台服务器闲置的情况。

28keepalived是什么及作用?

pass

29haproxy是什么以及作用?

pass

30、什么是负载均衡?

负载均衡是高可用网络基础架构的的一个关键组成部分,有了负载均衡,我们通常可以将我们的应用服务器部署多台,然后通过负载均衡将用户的请求分发到不同的服务器用来提高网站、应用、数据库或其他服务的性能以及可靠性。

31、什么是rpc及应用场景?

pass

32、简述 asynio模块的作用和应用场景。

asyncioPython 3.4版本引入的标准库,直接内置了对异步IO的支持。 
asyncio
的编程模型就是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO

33、简述 gevent模块的作用和应用场景。

当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO 
由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成:

34twisted框架的使用和应用?

Twisted是用Python实现的基于事件驱动的网络引擎框架,Twisted支持许多常见的传输及应用层协议,包括TCPUDPSSL/TLSHTTPIMAPSSHIRC以及FTP。就像Python一样,Twisted也具有内置电池batteries-included)的特点。Twisted对于其支持的所有协议都带有客户端和服务器实现,同时附带有基于命令行的工具,使得配置和部署产品级的Twisted应用变得非常方便。


 

数据库:

 

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

关系型:Mysql / Oracle / SQL Server 
非关系型:redis / MongoDB…

 

2MySQL常见数据库引擎及比较?

MySQL数据库中的表引擎一般常用两种:MyISAMInnoDB 
区别: 
MyISAM
类型的数据文件有三个1.frm(结构)2.MYD(数据)、3.MYI(索引) 
MyISAM
类型中的表数据增 改速度快,不支持事务,没有InnoDB安全。 
InnoDB
类型的数据文件只有一个 .frm 
InnoDB
类型的表数据增 改速度没有MyISAM的快,但支持事务,相对安全。

 

3、简述数据三大范式?

1 每一列只有一个值 
2
每一行都能区分。 
3
每一个表都不包含其他表已经包含的非主关键字信息。

 

4、什么是事务?MySQL如何支持事务?

同时对一组数据进行操作的语句就成为事务 
MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

 

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

一对多 :一个学生对多门考试成绩 
多对多 :一个老师教多个学生 一个学生让好几个老师教

 

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

设置一个商品计数的列 自动递增为1

 

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

触发器:制定一个sql条件和要做的事当满足的时候自动触发并执行要做的事 
函数(存储过程):Mysql储存过程简而言之就是一组已经好的命令,需要使用的时候拿出来用就可以 
视图:将一个写好的查询语句封装起来 当调用的时看到的数据就是满足条件的数据 不用每次都写同样的代码

 

9MySQL索引种类

唯一索引

主键索引

普通索引

全文索引

 

10、索引在什么情况下遵循最左前缀的规则?

联合索引

 

11、主键和外键的区别?


 

12MySQL常见的函数?

*concat(s1,s2,…Sn) 连接s1,s2..Sn为一个字符串 
*length(str)
返回值为字符串str 的长度 
*datediff(expr,expr2)
返回起始时间和结束时间的间隔天数

 

13、列举 创建索引但是无法命中索引的8种情况。

1、如果条件中有or,即使其中有条件带索引也不会使用 
2
、对于多列索引,不是使用的第一部分(第一个),则不会使用索引 
3
like查询是以%开头 
4
、如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引5、如果mysql估计使用全表扫描要比使用索引快,则不使用索引

 

14、如何开启慢日志查询?

1.查看慢查询是否开启 
show variables like ‘slow_query%’; 
show variables like ‘long_query_time’;

2.打开慢查询 
set global slow_query_log=’ON’;

3.设置慢查询日志记录文件 
set global slow_query_log_file=’/var/lib/mysql/test-10-226-slow.log’;

4.指定慢查询事件 
set global long_query_time=1;

 

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

导出: 
mysqldump -u root -p
库名 >导出的文件.sql

导入: 
mysql -u root -p
库名

 

16、数据库优化方案?

为经常查询的字段添加索引 
减少外键关联查询

 

17charvarchar的区别?

char的长度是不可变的,而varchar的长度是可变的,也就是说,定义一个char[10]varchar[10],如果存进去的是‘csdn’,那么char所占的长度依然为10,除了字符‘csdn’外,后面跟六个空格,而varchar就立马把长度变为4

 

18、简述MySQL的执行计划?

数据库的执行计划通俗点说就是,数据库服务器在执行sql语句的时候,会准备几套方案,最后选择消耗资源最小的那个方案。就是执行计划。

 

19、在对name做了唯一索引前提下,简述以下区别:

select* from tb where name= ‘Oldboy-Wupeiqi’ —–取出所有name= Oldboy-Wupeiqi 
select* from tb where name= ‘Oldboy-Wupeiqi’ limit1 —–
只取出第一条 name=Oldboy-Wupeiqi

 

201000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?

当一个数据库表过于庞大,LIMIT offset, length中的offset值过大,则SQL查询语句会非常缓慢,增加order by,并且order by字段需要建立索引。

 

21、什么是索引合并?

1、索引合并是把几个索引的范围扫描合并成一个索引。 
2
、索引合并的时候,会对索引进行并集,交集或者先交集再并集操作,以便合并成一个索引。 
3
、这些需要合并的索引只能是一个表的。不能对多表进行索引合并。

 

22、什么是覆盖索引?

就是select的数据列只用从索引中就能够取得,不必从数据表中读取,换句话说查询列要被所使用的索引覆盖。

 

23、简述数据库读写分离?

对于数据存储层高并发问题,最先想到的可能就是读写分离,在网站访问量大并且读写不平均的情况下,将存储分为master,slave两台,所有的写都路由到master上,所有的读都路由到slave上,然后masterslave同步。如果一台salve不够,可以加多台,比如一台master3slave

 

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

分区的主要目的是将数据按照一个较粗的粒度分在不同的表中,这样可以将相关的数据存放在一起,而且如果想一次性的删除整个分区的数据也很方便。 
通过一些HASH算法或者工具实现将一张数据表垂直或者水平进行物理切分

 

25redismemcached比较?

1RedisMemcache都是将数据存放在内存中,都是内存数据库。不过memcache还可用于缓存其他东西,例如图片、视频等等;

2Redis不仅仅支持简单的k/v类型的数据,同时还提供listsethash等数据结构的存储;

3、虚拟内存–Redis当物理内存用完时,可以将一些很久没用到的value 交换到磁盘;

4、过期策略–memcacheset时就指定,例如set key1 0 0 8,即永不过期。Redis可以通过例如expire 设定,例如expire name 10

5、分布式设定memcache集群,利用magent做一主多从;redis可以做一主多从。都可以一主一从;

6、存储数据安全–memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);

7、灾难恢复–memcache挂掉后,数据不可恢复; redis数据丢失后可以通过aof恢复;

 

26redis中数据库默认是多少个db 及作用?

redis默认有十六个db

 

27python操作redis的模块?

import redis

r = redis.Redis(host='127.0.0.1', port=6379,decode_responses=True)

r.set('name', 'OK')

print(r.get('name'))

 

28、如果redis中的某个列表中的数据量非常大,如何实现循环显示每一个值?

查询取出列表的值让后使用python循环

 

29redis如何实现主从复制?以及数据同步机制?

MasterSlave互通之后,首先,Slave会发送sync同步指令,当Master收到指令后,将在后台启动存盘进程,同时收集所有来自Slave的修改数据集的指令信息,当后台进程完成之后,Master将发送对应的数据库文件到对应的Slave中,以完成一次完整的同步工作。其次Slave在接受到数据库文件之后,将其存盘并加载到内存中。最后,Master继续收集修改命令和新增的修改指令,并依次发送给Slave,其将在本次执行这些数据的修改命令,从而最终达到数据同步的实现。

 

30redis中的sentinel的作用?

Redis Sentinel Redis提供了高可用的实现。通俗来说就是你可以部署一套无需人为干预即可防灾的Redis环境。 
RS
同时为客户端提供了其他诸如监控,通知的功能。

 

31、如何实现redis集群?

官方cluster方案 
twemproxy
代理方案 
哨兵模式 
codis 
客户端分片

 

32redis中默认有多少个哈希槽?

2**14个哈希槽 16384

 

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

rdb:快照形式是直接把内存中的数据保存到一个dump文件中,定时保存,保存策略 
aof
:把所有的对redis的服务器进行修改的命令都存到一个文件里,命令的集合

 

34、列举redis支持的过期策略。

定时删除 
含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除

惰性删除 
含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null

定期删除 
含义:每隔一段时间执行一次删除(redis.conf配置文件设置hz1s刷新的频率)过期key操作

 

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

LRU(最近少用的淘汰)

redis的缓存每命中一次,就给命中的缓存增加一定ttl(过期时间)(根据具体情况来设定, 比如10分钟).一段时间后, 热数据的ttl都会较大, 不会自动失效, 而冷数据基本上过了设定的ttl就马上失效了.

 

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

先进lpush keys values 先出 rpop keys

先进lpush keys values 后出 lpop keys

 

37、如何基于redis实现消息队列?

Redis中五大数据结构之一列表,其PUSHPOP命令遵循FIFO先进先出原则。当我们需要发布消息的时候执行LPUSH(消息从左边进入队列),消息接收端执行RPOP获得消息(消息从右侧弹出)。对于列表,Redis提供了带有阻塞的命令(命令前加B)。因此,生产者lpush消息,消费者brpop(从列表中弹出最右端元素,如无元素则一直阻塞到timeout)消息,并设定超时时间timeout,可以减少redis的压力。

 

38、如何基于redis实现发布和订阅?以及发布订阅和消息队列的区别?

创建一个频道 客户端加入频道 等待频道发布订阅

 

39、什么是codis及作用?

Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (不支持的命令列表), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务.

 

40、什么是twemproxy及作用?

Twemproxy是一种代理分片机制,由Twitter开源。Twemproxy作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个Redis服务器,再原路返回。该方案很好的解决了单个Redis实例承载能力的问题。

 

41、写代码实现redis事务操作。

>multi   //开启一个事务

>set age 10 //暂存指令队列

>set age 20

>exec    //开始执行(提交事务)

>discard //清空指令队列(事务回滚)

 

42redis中的watch的命令的作用?

Redis Watch 命令用于监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

 

43、基于redis如何实现商城商品数量计数器?

指定键的值做加加操作,返回加后的结果。

 

44、简述redis分布式锁和redlock的实现机制

在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段。 
一个Client想要获得一个锁需要以下几个操作:

得到本地时间Client使用相同的key和随机数,按照顺序在每个Master实例中尝试获得锁。在获得锁的过程中,为每一个锁操作设置一个快速失败时间(如果想要获得一个10秒的锁, 那么每一个锁操作的失败时间设为5-50ms) 
这样可以避免客户端与一个已经故障的Master通信占用太长时间,通过快速失败的方式尽快的与集群中的其他节点完成锁操作。

客户端计算出与master获得锁操作过程中消耗的时间,当且仅当Client获得锁消耗的时间小于锁的存活时间,并且在一半以上的master节点中获得锁。才认为client成功的获得了锁。

如果已经获得了锁,Client执行任务的时间窗口是锁的存活时间减去获得锁消耗的时间。 
如果Client获得锁的数量不足一半以上,或获得锁的时间超时,那么认为获得锁失败。客户端需要尝试在所有的master节点中释放锁, 即使在第二步中没有成功获得该Master节点中的锁,仍要进行释放操作。

 

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

对节点和数据,都做一次哈希运算,然后比较节点和数据的哈希值,数据取和节点最相近的节点做为存放节点。这样就保证当节点增加或者减少的时候,影响的数据最少。 
hash_ring
python中做一致性哈希的模块

 

46、如何高效的找到redis中所有以oldboy开头的key

key oldboy*

 


 

前端:

 

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

HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。 
HTTP
是一个应用层协议,由请求和响应构成,是一个标准的客户端服务器模型。HTTP是一个无状态的协议。端口号为80

 

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

WebSocketHTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。

 

3、什么是magic string

有触发时机在满足条件时自动触发就是魔术方法

 

4、如何创建响应式布局?

使用媒体查询的方式,创建多个元素宽度是相对的的布局理想的响应式布局是指的对PC/移动各种终端进行响应的

 

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

Bootstrap / vue

 

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

AJAX是在不加载整个页面的情况异步下与服务器发送请求交换数据并更新部分网页的艺术

$.ajax({

    url:'user/add',

    type:'get',

    data:{id:100},

    dataType:'json',

    success:function(data){

       

        console.log(data);

    },

    error:function(){

       

        alert('ajax执行错误');

    },

    timeout:2000,

    async:true

})

 

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

特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客户端的浏览器。

 

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

ajax实现:在发送ajax后,服务器端会阻塞请求直到有数据传递或超时才会返回,客户端js响应处理函数会在处理完服务器返回的信息后在次发出请求,重新建立连接

 

9vuex的作用?

Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

 

10vue中的路由的拦截器的作用?

判断每一个页面的http请求的状态获取内容做响应的处理

 

11axios的作用?

在浏览器中发送 XMLHttpRequests 请求

node.js 中发送 http请求

支持 Promise API

拦截请求和响应

转换请求和响应数据

自动转换 JSON 数据

客户端支持保护安全免受 XSRF 攻击

 

12、列举vue的常见指令。

条件判断使用 v-if指令

循环使用 v-for 指令。

事件监听可以使用 v-on 指令:

 

13、简述jsonp及实现原理?

JSONP是用来解决跨域请求问题的 
跨域:协议 域名 端口号有一个不一样就是跨域 
实现原理: 
script
标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。

 

14、什么是cors

CORS 全称是跨域资源共享(Cross-Origin Resource Sharing),是一种 AJAX 跨域请求资源的方式,支持现代浏览器,IE支持10以上。

 

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

GET / POST

 

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

404 请求的url地址不存在 
503 访问限制有权限 
200 访问成功 
302 重定向

 

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

User-Agent:浏览器类型,如果Servlet返回的内容与浏览器类型有关则该值非常有用。

Cookie:这是最重要的请求头信息之一

Content-Type:请求类型

 

18、看图写结果:


alert(
李杰)

 

19、看图写结果:


console.log(‘
武沛齐’)

 

20、看图写结果:


console.log(‘
老男孩’)

 

21、看图写结果:


结果什么也没有 因为console.log.的时候xo还没有定义

 

22、看图写结果:


alert(”
武沛齐’)

 

23、看图写结果:


alert(”
武沛齐’)

 

24djangoflasktornado框架的比较?

DjangoPython 界最全能的 web 开发框架,battery-include 各种功能完备,可维护性和开发速度一级棒。常有人说 Django 慢,其实主要慢在 Django ORM 与数据库的交互上,所以是否选用 Django,取决于项目对数据库交互的要求以及各种优化。而对于 Django 的同步特性导致吞吐量小的问题,其实可以通过 Celery 等解决,倒不是一个根本问题。Django 的项目代表:InstagramGuardian

Tornado:天生异步,性能强悍是 Tornado 的名片,然而 Tornado 相比 Django 是较为原始的框架,诸多内容需要自己去处理。当然,随着项目越来越大,框架能够提供的功能占比越来越小,更多的内容需要团队自己去实现,而大项目往往需要性能的保证,这时候 Tornado 就是比较好的选择。Tornado项目代表:知乎。

Flask:微框架的典范,号称 Python 代码写得最好的项目之一。Flask 的灵活性,也是双刃剑:能用好 Flask 的,可以做成 Pinterest,用不好就是灾难(显然对任何框架都是这样)。Flask 虽然是微框架,但是也可以做成规模化的 Flask。加上 Flask 可以自由选择自己的数据库交互组件(通常是 Flask-SQLAlchemy),而且加上 celery +redis 等异步特性以后,Flask 的性能相对 Tornado 也不逞多让,也许Flask 的灵活性可能是某些团队更需要的。

 

25、什么是wsgi

WSGIWeb Server Gateway InterfaceWeb 服务器网关接口)则是Python语言中1所定义的Web服务器和Web应用程序之间或框架之间的通用接口标准。

WSGI就是一座桥梁,桥梁的一端称为服务端或网关端,另一端称为应用端或者框架端,WSGI的作用就是在协议之间进行转化。WSGIWeb组件分成了三类:Web 服务器(WSGI Server)、Web中间件(WSGI Middleware)与Web应用程序(WSGI Application)。

Web Server接收HTTP请求,封装一系列环境变量,按照WSGI接口标准调用注册的WSGI Application,最后将响应返回给客户端。

 

26django请求的生命周期?

前端请求—>nginx—>uwsgi.—>中间件—>url路由—->view试图—>orm—->拿到数据返回给view—->试图将数据渲染到模版中拿到字符串—->中间件—>uwsgi—->nginx—->前端渲染

 

27、列举django的内置组件?

url viewmodeltemplate、中间件

 

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

process_request(self,request)

process_view(self, request, callback, callback_args, callback_kwargs)

process_exception(self, request, exception)

process_response(self, request, response)

 

29、简述什么是FBVCBV

django中请求处理方式有2种:FBV CBV 
FBV
function base views 就是在视图里使用函数处理请求。 
CBV(class base views)
就是在视图里使用类处理请求 类需要继承view

 

30djangorequest对象是在什么时候创建的?

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

 

31、如何给CBV的程序添加装饰器?

  from django.views import View

  from django.utils.decorators import method_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('...')

 

32、列举django orm 中所有的方法(QuerySet对象的所有方法)

返回Query Set对象的方法有: 
* all() 
* filter() 
* exclude() 
* order_by() 
* reverse() 
* dictinct()

特殊的QuerySet: 
* values()
返回一个可迭代的字典序列 
* values_list()
返回一个可迭代的元祖序列

返回具体对象的: 
* get() 
* first() 
* last()

返回布尔值的方法有: 
* existe()

返回数学的方法有: 
* count( )

 

33onlydefer的区别?

defer : 映射中排除某列数据

only : 仅取某个列中的数据

 

34select_relatedprefetch_related的区别?

select_related通过多表join关联查询,一次性获得所有数据,通过降低数据库查询次数来提升性能,但关联表不能太多,因为join操作本来就比较消耗性能

prefetch_related()的解决方法是,分别查询每个表,然后用Python处理他们之间的关系! 
都是为了减少SQL查询的数量

 

35filterexclude的区别?

filter是查询满足条件的数据 
exclude
是查询不满足添加的数据

 

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

 

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

 class Router1:

      def allow_migrate(self, db, app_label, model_name=None, **hints):

          """

          All non-auth models end up in this pool.

          """

          if db=='db1' and app_label == 'app02':

              return True

          elif db == 'default' and app_label == 'app01':

              return True

          else:

              return False

 

         

 

      def db_for_read(self, model, **hints):

          """

          Attempts to read auth models go to auth_db.

          """

          if model._meta.app_label == 'app01':

              return 'default'

          else:

              return 'db1'

 

      def db_for_write(self, model, **hints):

          """

          Attempts to write auth models go to auth_db.

          """

          if model._meta.app_label == 'app01':

              return 'default'

          else:

              return 'db1'

 

38FQ的作用?

F:操作数据表中的某列值,F( )允许Django在未实际链接数据的情况下具有对数据库字段的值的引用,不用获取对象放在内存中再对字段进行操作,直接执行原生产sql语句操作。

通常情况下我们在更新数据时需要先从数据库里将原数据取出后方在内存里,然后编辑某些属性,最后提交

Q:对对象进行复杂查询,并支持&and,|or),~not)操作符。

 

39valuesvalues_list的区别?

values方法可以获取number字段的字典列表。

values_list可以获取number的元组列表。

values_list方法加个参数flat=True可以获取number的值列表。

 

40、如何使用django orm批量创建数据?

  def bulk_create(self, objs, batch_size=None):

       

       

        objs = [

            models.DDD(name='r11'),

            models.DDD(name='r22')

        ]

        models.DDD.objects.bulk_create(objs, 10)

 

41djangoFormModeForm的作用?

- 作用:

      - 对用户请求数据格式进行校验

      - 自动生成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                           

  - 应用:只要是客户端向服务端发送表单数据时,都可以进行使用,如:用户登录注册

 

42djangoForm组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新。

方式一:重写构造方法,在构造方法中重新去数据库获取值

  class UserForm(Form):

      name = fields.CharField(label='用户名',max_length=32)

      email = fields.EmailField(label='邮箱')

      ut_id = fields.ChoiceField(

         

          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

 

43djangoModel中的ForeignKey字段中的on_delete参数有什么作用?

on_deleteCASCADEPROTECTSET_NULLSET_DEFAULTSET()五个可选择的值

CASCADE:此值设置,是级联删除。

 

PROTECT:此值设置,是会报完整性错误。

 

SET_NULL:此值设置,会把外键设置为null,前提是允许为null。

 

SET_DEFAULT:此值设置,会把设置为外键的默认值。

 

SET():此值设置,会调用外面的值,可以是一个函数。

 

44djangocsrf的实现机制?

Django预防CSRF攻击的方法是在用户提交的表单中加入一个csrftoken的隐含值,这个值和服务器中保存的csrftoken的值相同,这样做的原理如下:

1、在用户访问django的可信站点时,django反馈给用户的表单中有一个隐含字段csrftoken,这个值是在服务器端随机生成的,每一次提交表单都会生成不同的值

2、当用户提交django的表单时,服务器校验这个表单的csrftoken是否和自己保存的一致,来判断用户的合法性

3、当用户被csrf攻击从其他站点发送精心编制的攻击请求时,由于其他站点不可能知道隐藏的csrftoken字段的信息这样在服务器端就会校验失败,攻击被成功防御

具体配置如下:

template中添加{%csrf_token%}标签

 

45django如何实现websocket

利用dwebsocketDjango中使用Websocket 
https://www.cnblogs.com/huguodong/p/6611602.html

 

46、基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token

https://www.cnblogs.com/wxp5257/p/7834090.html

 

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

在settings.py中添加:

LOGGING = {

    'disable_existing_loggers': False,

    'version': 1,

    'handlers': {

        'console': {

           

            'class': 'logging.StreamHandler',

            'level': 'DEBUG',

        },

    },

    'loggers': {

        '': {

           

           

           

            'handlers': ['console'],

            'level': 'DEBUG',

            'propagate': False,

                                

        },

        'django.db': {

           

            'handlers': ['console'],

            'level': 'DEBUG',

            'propagate': False,

        },

    },

}

 

48django缓存如何设置?

  三种粒度缓存

   1 中间件级别

       'django.middleware.cache.UpdateCacheMiddleware',

       'django.middleware.cache.FetchFromCacheMiddleware',

        CACHE_MIDDLEWARE_SECONDS=10

 

   2 视图级别

 

      from django.views.decorators.cache import cache_page

      @cache_page(15)

      def index(request):

          import time

          t=time.time()

          return render(request,"index.html",locals())

 

 

   3 局部缓存

      {% load cache %}

          ...

          ...

      {% cache 15 "time_cache" %}

      <h3>缓存时间:{{ t }}</h3>

      {% endcache %}

 

49django的缓存能使用redis吗?如果可以的话,如何配置?

  pip install django-redis 

  apt-get install redis-server

 

  然后在settings.py 里面添加CACHES = {

  'default': {

  'BACKEND': 'redis_cache.cache.RedisCache',

  'LOCATION': '127.0.0.1:6379',

  "OPTIONS": {

  "CLIENT_CLASS": "redis_cache.client.DefaultClient",

  },

  }

 

50django路由系统中name的作用?

name 可以用于在 templates, models, views ……中得到对应的网址,相当于给网址取了个小名,只要这个名字不变,网址变了也能通过名字获取到。

 

51django的模板中filtersimple_tag的区别?

simple_tag 
-参数任意,但是不能作为if条件判断的条件 
filter 
-参数最多只能有两个,但是可以作为if条件判断的条件。

 

52django-debug-toolbar的作用?

django_debug_toolbar django的第三方工具包,给django扩展了调试功能。 
包括查看执行的sql语句,db查询次数,requestheaders,调试概览等。 
https://blog.csdn.net/weixin_39198406/article/details/78821677

 

53django中如何实现单元测试?

https://www.jianshu.com/p/34267dd79ad6

 

54、解释orm db first code first的含义?

datebase first就是代表数据库优先,那么前提就是先创建数据库。 
model first
就是代表model优先,那么前提也就是先创建model,然后根据model自动建立数据库。

 

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

Django附带一个名为inspectdb的实用程序,可以通过检查现有的数据库来创建Model(模型)

 

56、使用orm和原生sql的优缺点?

ORM框架:

对象关系映射,通过创建一个类,这个类与数据库的表相对应!类的对象代指数据库中的一行数据。

简述ORM原理:

让用户不再写SQL语句,而是通过类以及对象的方式,和其内部提供的方法,进行数据库操作!把用户输入的类或对象转换成SQL语句,转换之后通过pymysql执行完成数据库的操作。

ORM的优缺点:

优点: 
*
提高开发效率,降低开发成本 
*
使开发更加对象化 
*
可移植 
*
可以很方便地引入数据缓存之类的附加功能

缺点: 
*
在处理多表联查、where条件复杂之类的查询时,ORM的语法会变得复杂。就需要写入原生SQL

 

57、简述MVCMTV

MTVMVC

MVC 模型 视图 控制器 
MTV
模型 模板 视图

 

58djangocontenttype组件的作用?

django内置的ContentType组件就是帮我们做连表操作 
如果一个表与其他表有多个外键关系,我们可以通过ContentType来解决这种关联 
http://www.cnblogs.com/iyouyue/p/8810464.html

 

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

restful其实就是一套编写接口的协议,协议规定如何编写以及如何设置返回值、状态码等信息。 

最显著的特点: 
restful:
给用户一个url,根据method不同在后端做不同的处理,比如:post 创建数据、get获取数据、putpatch修改数据、delete删除数据。 
no rest:
给调用者很多url,每个url代表一个功能,比如:add_user/delte_user/edit_user/

当然,还有协议其他的,比如: 

版本,来控制让程序有多个版本共存的情况,版本可以放在 url、请求头(accept/自定义)、GET参数

状态码,200/300/400/500

url中尽量使用名词,restful也可以称为面向资源编程

api标示: 
api.YueNet.com 
www.YueNet.com/api/

 

60、接口的幂等性是什么意思?

一个接口通过首先进行1次访问,然后对该接口进行N次相同访问的时候,对访问对象不造成影响,那么就认为接口具有幂等性。 
比如: 
* GET
第一次获取数据、第二次也是获取结果,幂等。 
* POST
第一次新增数据,第二次也会再次新增,非幂等。 
* PUT
第一次更新数据,第二次不会再次更新,幂等。 
* PATCH
,第一次更新数据,第二次可能再次更新,非幂等。 
* DELTE
,第一次删除数据,第二次不会再次删除,幂等。

 

61、什么是RPC

RPCRemote Procedure Call远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCPUDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。

 

62. HttpHttps的区别?

超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。

为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS,为了数据传输的安全,HTTPSHTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

 

63、为什么要使用django rest framework框架?

1.客户端-服务端分离 
优点:提高用户界面的便携性,通过简化服务器提高可伸缩性…. 
2.无状态(Stateless):从客户端的每个请求要包含服务器所需要的所有信息 
优点:提高可见性(可以单独考虑每个请求),提高了可靠性(更容易从局部故障中修复),提高可扩展性(降低了服务器资源使用) 
3.缓存(Cachable):服务器返回信息必须被标记是否可以缓存,如果缓存,客户端可能会重用之前的信息发送请求 
优点:减少交互次数,减少交互的平均延迟 
4.统一接口 
优点:提高交互的可见性,鼓励单独改善组件 
5.支持按需代码(Code-On-Demand 可选) 
优点:提高可扩展性

 

64django 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

            - 定义方法

        - 请求数据格式校验

 

    - 渲染器

 

65django rest framework框架中的视图都可以继承哪些类?

a. 继承 APIView

  这个类属于rest framework中顶层类,内部帮助我们实现了只是基本功能:认证、权限、频率控制,但凡是数据库、分页等操作都需要手动去完成,比较原始。

 

 

 class GenericAPIView(APIView)

 

      def post(...):

          pass

b. 继承 GenericViewSet(ViewSetMixin, generics.GenericAPIView)

如果继承它之后,路由中的as_view需要填写对应关系 .as_view({‘get’:’list’,’post’:’create’}) 
在内部也帮助我们提供了一些方便的方法: 
- get_queryset 
- get_object 
- get_serializer

  注意:要设置queryset字段,否则会跑出断言的异常。

  # 只提供增加功能

  class TestView(GenericViewSet):

      serializer_class = XXXXXXX

 

      def create(self,*args,**kwargs):

          pass # 获取数据并对数据进行操作

c. 继承 
- ModelViewSet 
- mixins.CreateModelMixin,GenericViewSet 
- mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet

  对数据库和分页等操作不用我们在编写,只需要继承相关类即可。

 

  示例:只提供增加功能

  class TestView(mixins.CreateModelMixin,GenericViewSet):

      serializer_class = XXXXXXX

 

66、简述 django rest framework框架的认证流程。

如何编写?写类并实现authticate

方法中可以定义三种返回值: 

user,auth),认证成功

None , 匿名用户

异常 ,认证失败

流程: 

dispatch

再去request中进行认证处理

 

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

a. 基于用户IP限制访问频率

b. 基于用户IP显示访问频率(利于Django缓存)

c. view中限制请求频率

d. 匿名时用IP限制+登录时用Token限制

 

68Flask框架的优势?

一、整体设计方面

首先,两者都是非常优秀的框架。整体来讲,两者设计的哲学是区别最大的地方。Django提供一站式的解决方案,从模板、ORMSessionAuthentication等等都分配好了,连app划分都做好了,总之,为你做尽量多的事情,而且还有一个killer级的特性,就是它的admin,配合django-suit,后台就出来了,其实最初Django就是由在新闻发布公司工作的人设计的。Flask只提供了一些核心功能,非常简洁优雅。它是一个微框架,其他的由扩展提供,但它的blueprint使它也能够很方便的进行水平扩展。

二、路由设计

Django的路由设计是采用集中处理的方法,利用正则匹配。Flask也能这么做,但更多的是使用装饰器的形式,这个有优点也有缺点,优点是读源码时看到函数就知道怎么用的,缺点是一旦源码比较长,你要查路由就不太方便了,但这也促使你去思考如何更合理的安排代码。

三、应用模块化设计

Django的模块化是集成在命令里的,也就是说一开始Django的目标就是为以后玩大了做准备的。每个都是一个独立的模块,为以后的复用提供了便利。Flask通过Blueprint来提供模块化,自己对项目结构划分成不同的模块进行组织。

 

69Flask框架依赖组件?

Route(路由)

templates(模板)

Models(orm模型)

blueprint(蓝图)

Jinja2模板引擎

 

70Flask蓝图的作用?

将不同的功能模块化

构建大型应用

优化项目结构

增强可读性,易于维护(跟Djangoview功能相似)

 

71、列举使用过的Flask第三方组件?

内置
-
配置 
-
路由 
-
视图 
-
模板 
- session 
-
闪现 
-
蓝图 
-
中间件 
-
特殊装饰器 
第三方
- Flask
组件: 
- flask-session 
- flask-SQLAlchemy 
- flask-migrate 
- flask-script 
- blinker 
-
公共组件: 
- wtforms 
- dbutile 
- sqlalchemy 
-
自定义Flask组件 
- auth
,参考flask-login组件

 

72、简述Flask上下文管理流程?

每次有请求过来的时候,flask 会先创建当前线程或者进程需要处理的两个重要上下文对象,把它们保存到隔离的栈里面,这样视图函数进行处理的时候就能直接从栈上获取这些信息。

 

73Flask中的g的作用?

g 相当于一次请求的全局变量,当请求进来时将gcurrent_app封装为一个APPContext类,在通过LocalStackAppcontext放入Local中,取值时通过偏函数,LocalStackloca l中取值,响应时将local中的g数据删除

 

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

flask

requestcontext

request

securecookiesessioninterface

securecookiesession

 

75、为什么要FlaskLocal对象中的的值stack 维护成一个列表?

当是web应用时:不管是单线程还是多线程,栈中只有一个数据 
-
服务端单线程: 

111:{stack: [ctx, ]} 

-
服务端多线程: 

111:{stack: [ctx, ]} 
112:{stack: [ctx, ]} 
}

 

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

请求进来时,可以根据URL的不同,交给不同的APP处理

 

77、在Flask中实现WebSocket需要什么组件?

Flask-SocketIO

Flask-SocketsFlask框架的一个扩展,通过它,Flask应用程序可以使用WebSocket

 

78wtforms组件的作用?

WTForms是一个支持多个web框架的form组件,主要用于对用户请求数据进行验证。 
https://www.cnblogs.com/big-handsome-guy/p/8552079.html

 

79Flask框架默认session处理机制?

Flask的默认session利用了WerkzeugSecureCookie,把信息做序列化(pickle)后编码(base64),放到cookie里了。

过期时间是通过cookie的过期时间实现的。

为了防止cookie内容被篡改,session会自动打上一个叫sessionhash串,这个串是经过session内容、SECRET_KEY计算出来的,看得出,这种设计虽然不能保证session里的内容不泄露,但至少防止了不被篡改。

 

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

a. threading.local 
作用:为每个线程开辟一块空间进行数据存储。 
b.
自定义Local对象 
作用:为每个线程(协程)开辟一块空间进行数据存储。 
https://www.jianshu.com/p/3f38b777a621

 

81Flask blinker 是什么?

Flask框架中的信号基于blinker,可以让开发者在flask请求过程中 定制一些用户行为执行。 
在请求前后,模板渲染前后,上下文前后,异常 的时候

 

82SQLAlchemy中的 sessionscoped_session 的区别?

使用scoped_session的目的主要是为了线程安全。 
scoped_session
类似单例模式,当我们调用使用的时候,会先在Registry里找找之前是否已经创建session了。 
要是有,就把这个session返回。 
要是没有,就创建新的session,注册到Registry中以便下次返回给调用者。 
这样就实现了这样一个目的:在同一个线程中,call scoped_session 的时候,返回的是同一个对象

 

83SQLAlchemy如何执行原生SQL

  from sqlalchemy import create_engine

  from sqlalchemy.orm import 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 ;')

 

84ORM的实现原理?

概念: 对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。

详细介绍: 让我们从O/R开始。字母O起源于对象”(Object),R则来自于关系”(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。

当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。 
ORM
解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。

ORM技术特点: 
*
提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。 
* ORM
提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。

 

85DBUtils模块的作用?

使用DBUtils模块

两种使用模式: 
1. 为每个线程创建一个连接,连接不可控,需要控制线程数 
1. 创建指定数量的连接在连接池,当线程访问的时候去取,如果不够了线程排队,直到有人释放。平时建议使用这种!

 

86、以下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())

ctime字段中的参数应该为default=datetime.now, now后面不应该加括号.如果加了,字段不会随时更新

 

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

sqlalchemy设置编码字符集一定要在数据库访问的URL上增加charset=utf8,否则数据库的连接就不是utf8的编码格式 
eng = create_engine(‘mysql://root:root@localhost:
3306/test2?charset=utf8’,echo=True)

 

88. SQLAlchemy中如何设置联合唯一索引?

UniqueConstraint 设置联合唯一索引

 

89、简述Tornado框架的特点。

Tornado的独特之处在于其所有开发工具能够使用在应用开发的任意阶段以及任何档次的硬件资源上。而且,完整集的Tornado工具可以使开发人员完全不用考虑与目标连接的策略或目标存储区大小。

Tornado 结构的专门设计为开发人员和第三方工具厂商提供了一个开放环境。已有部分应用程序接口可以利用并附带参考书目,内容从开发环境接口到连接实现。Tornado包括强大的开发和调试工具,尤其适用于面对大量问题的嵌入式开发人员。这些工具包括CC++源码级别的调试器,目标和工具管理,系统目标跟踪,内存使用分析和自动配置. 另外,所有工具能很方便地同时运行,很容易增加和交互式开发。

 

90、简述Tornado框架中Future对象的作用?

http://python.jobbole.com/87310/

 

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

https://www.cnblogs.com/aguncn/p/5665916.html

 

92Tornado中静态文件是如何处理的?如:

处理方法:

static_path = os.path.join(os.paht.dirname(file), “static”) #这里增加设置了静态路径 
另外一个修改就是在实例化 tornado.web.Application() 的时候,在参数中,出了有静态路径参数 static_path ,还有一个参数设置 debug=True

 

93Tornado操作MySQL使用的模块?

torndb是一个轻量级的基于MySQLdb封装的一个模块,从tornado3.0版本以后,其已经作为一个独立模块发行了。torndb依赖于MySQLdb模块,因此,在使用torndb模块时,要保证系统中已经有MySQLdb模块。

 

94Tornado操作redis使用的模块?

tornado-redis

 

95、简述Tornado框架的适用场景?

Tornado是使用Python编写的一个强大的、可扩展的Web服务器。它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中。

我们现在所知道的Tornado是基于Bret Taylor和其他人员为FriendFeed所开发的网络服务框架,当FriendFeedFacebook收购后得以开源。不同于那些最多只能达到10,000个并发连接的传统网络服务器,Tornado在设计之初就考虑到了性能因素,旨在解决C10K问题,这样的设计使得其成为一个拥有非常高性能的框架。此外,它还拥有处理安全性、用户验证、社交网络以及与外部服务(如数据库和网站API)进行异步交互的工具。

iReader

 


 

爬虫阶段:

 

96. git常见命令作用

某个文件夹中的内容进行版本管理:

进入文件夹,右键git bash

git init 初始化,当前所在的文件夹可以被管理且以后版本相关的数据都会存储到.git文件中

git status 查看当前文件夹以及子目录中文件是否发生变化:内容修改/新增文件/删除,已经变化的文件会变成红色,已经add的文件会变成绿色

git add . 给发生变化的文件(贴上一个标签)或 将发生变化的文件放到某个地方,只写一个句点符就代表把git status中红色的文件全部打上标签

git commit -m ‘新增用户登录认证功能以及xxx功能绿色文件添加到版本中

git log 查看所有版本提交记录,可以获取版本号

git reset –hard 版本号 将最新的版本回退到更早的版本

git reflog 回退到之前版本后悔了,再更新到最新或者最新之前的版本

git reset –hard 版本 回退

 

97. 简述以下gitstash命令作用以及相关其他命令。

stash用于将工作区发生变化的所有文件获取临时存储在某个地方,将工作区还原当前版本未操作前的状态;stash还可以将临时存储在某个地方的文件再次拿回到工作区。

git stash 将当前工作区所有修改过的内容存储到某个地方,将工作区还原到当前版本未修改过的状态

git stash list 查看某个地方存储的所有记录

git stash clear 清空某个地方

git stash pop 将第一个记录从某个地方重新拿到工作区(可能有冲突)

git stash apply 编号, 将指定编号记录从某个地方重新拿到工作区(可能有冲突)

git stash drop 编号,删除指定编号的记录

 

98. git merge rebase命令 的区别。

采用mergerebase后,git log的区别,merge命令不会保留merge的分支的commit

 

99. 公司如何基于git做的协同开发?

https://www.cnblogs.com/abelsu/p/5138136.html

 

100、如何基于git实现代码review

利用github/gitlab自带的在线Diff展示功能做。 
https://blog.csdn.net/maray/article/details/50206927

 

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

https://blog.csdn.net/zhazhaji/article/details/75258426

 

102. 什么是gitlab

GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务。安装方法是参考GitLabGitHub上的Wiki页面。

 

103githubgitlab的区别?

先说一下相同点,二者都是基于webGit仓库,在很大程度上GitLab是仿照GitHub来做的,它们都提供了分享开源项目的平台,为开发团队提供了存储、分享、发布和合作开发项目的中心化云存储的场所。

GitHub作为开源代码库及版本控制系统,拥有超过900万的开发者用户,目前仍然是最火的开源项目托管系统。GitHub同时提供公共仓库和私有仓库,但如果要使用私有仓库,是需要付费的。

GitLab解决了这个问题,你可以在上面创建私人的免费仓库。

GitLab让开发团队对他们的代码仓库拥有更多的控制,相比于GitHub,它有不少的特色:

允许免费设置仓库权限;允许用户选择分享一个project的部分代码;允许用户设置project的获取权限,进一步的提升安全性;可以设置获取到团队整体的改进进度;通过innersourcing让不在权限范围内的人访问不到该资源。

从代码私有性方面来看,有时公司并不希望员工获取到全部的代码,这个时候GitLab无疑是更好的选择。但对于开源项目而言,GitHub依然是代码托管的首选。

 

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

对一个开源项目有足够了解的情况下,如果你发现问题或者更好的解决方案的话,可以开个issue先。

一般情况下维护这个项目的人或者其他使用这个项目的人会参与讨论的,然后基于这些讨论你可以发一些pull requests

如果你的方案得到很多人赞同的话,项目维护人员会把他们merge,你也就成了这个项目的contributor了。

当然很多情况下,你开的这个issue已经有人提过了,或者说是你自己误解了,但是相信在和其他开发人员交流的过程中,你也能学到许多。

 

105git .gitignore文件的作用?

一般来说每个Git项目中都需要一个“.gitignore”文件,这个文件的作用就是告诉Git哪些文件不需要添加到版本管理中。

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

 

106. 什么是敏捷开发?

敏捷开发以用户的需求进化为核心,采用迭代、循序渐进的方法进行软件开发。在敏捷开发中,软件项目在构建初期被切分成多个子项目,各个子项目的成果都经过测试,具备可视、可集成和可运行使用的特征。换言之,就是把一个大项目分为多个相互联系,但也可独立运行的小项目,并分别完成,在此过程中软件一直处于可使用状态。


 

119、简述 requests模块的作用及基本使用?

使用requests可以模拟浏览器发送的请求

发送get请求:requests.get()

发送post请求:requests.post()

读取请求返回内容:requests.text()

保存cookie:requests.cookie()

 

120、简述 beautifulsoup模块的作用及基本使用?

查找xml/html文本中查找指定信息的三方库 
*
获取title信息 soup.title 
*
获取title的属性 soup.title.attrs 
https://blog.csdn.net/qq_37275405/article/details/80953517

 

121、简述 seleninu模块的作用及基本使用?

selenium最初是一个自动化测试工具,而爬虫中使用它主要是为了解决requests无法直接执行JavaScript代码的问题

selenium本质是通过驱动浏览器,完全模拟浏览器的操作,比如跳转、输入、点击、下拉等,来拿到网页渲染之后的结果,可支持多种浏览器

 

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

Scrapy Engine(引擎): 负责SpiderItemPipelineDownloaderScheduler中间的通讯,信号、数据传递等。

Scheduler(调度器): 它负责接受引擎发送过来的Request请求,并按照一定的方式进行整理排列,入队,当引擎需要时,交还给引擎。

Downloader(下载器):负责下载Scrapy Engine(引擎)发送的所有Requests请求,并将其获取到的Responses交还给Scrapy Engine(引擎),由引擎交给Spider来处理,

Spider(爬虫):它负责处理所有Responses,从中分析提取数据,获取Item字段需要的数据,并将需要跟进的URL提交给引擎,再次进入Scheduler(调度器)

Item Pipeline(管道):它负责处理Spider中获取到的Item,并进行进行后期处理(详细分析、过滤、存储等)的地方.

Downloader Middlewares(下载中间件):你可以当作是一个可以自定义扩展下载功能的组件。

Spider MiddlewaresSpider中间件):你可以理解为是一个可以自定扩展和操作引擎和Spider中间通信的功能组件(比如进入SpiderResponses;和从Spider出去的Requests

 

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

from scrapy.downloadermiddlewares.httpproxy import HttpProxyMiddleware 
from urllib.request import getproxies

 

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

FilesPipeline

ImagesPipeline

 

125scrapy中如何实现限速?

修改setting文件的AUTOTHROTTLE_START_DELAY 打开后默认限速为5

 

126scrapy中如何实现暂定爬虫?

cmdcd 进入项目 
然后在项目目录下创建 记录文件:remain/001 
然后输入:scrapy crawl zhihu -s JOBDIR=remain/001 
回车运行就行了 
ctrl+c 暂停 
继续运行只要再次输入:scrapy crawl zhihu -s JOBDIR=remain/001就行了 
需要重新爬取就换个文件 002就行了

 

127scrapy中如何进行自定制命令?

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

 

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

class scrapy.contrib.spidermiddleware.depth.DepthMiddleware 
DepthMiddleware
是一个用于追踪每个Request在被爬取的网站的深度的中间件。 其可以用来限制爬取深度的最大深度或类似的事情。

DepthMiddleware 可以通过下列设置进行配置(更多内容请参考设置文档):

DEPTH_LIMIT - 爬取所允许的最大深度,如果为0,则没有限制。 
DEPTH_STATS -
是否收集爬取状态。 
DEPTH_PRIORITY -
是否根据其深度对requet安排优先级

 

129scrapy中的pipelines工作原理?

Scrapy 提供了 pipeline 模块来执行保存数据的操作。在创建的 Scrapy 项目中自动创建了一个 pipeline.py 文件,同时创建了一个默认的 Pipeline 类。我们可以根据需要自定义 Pipeline 类,然后在 settings.py 文件中进行配置即可

 

130scrapypipelines如何丢弃一个item对象?

pipelines的时候不执行持久化保存就会什么也不执行也就是丢弃

 

131、简述scrapy中爬虫中间件和下载中间件的作用?

下载器中间件(Downloader Middlewares) 
位于Scrapy引擎和下载器之间的框架,主要是处理Scrapy引擎与下载器之间的请求及响应。 
爬虫中间件(Spider Middlewares) 
介于Scrapy引擎和爬虫之间的框架,主要工作是处理蜘蛛的响应输入和请求输出。

 

132scrapy-redis组件的作用?

scheduler - 调度器 
dupefilter - URL
去重规则(被调度器使用) 
pipeline -
数据持久化

 

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

定义去重规则(被调度器调用并应用)

  a. 内部会使用以下配置进行连接Redis

 

      # REDIS_HOST = 'localhost'                            # 主机名

      # REDIS_PORT = 6379                                   # 端口

      # REDIS_URL = 'redis://user:pass@hostname:9001'       # 连接URL(优先于以上配置)

      # REDIS_PARAMS  = {}                                  # Redis连接参数             默认:REDIS_PARAMS = {'socket_timeout': 30,'socket_connect_timeout': 30,'retry_on_timeout': True,'encoding': REDIS_ENCODING,}

      # REDIS_PARAMS['redis_cls'] = 'myproject.RedisClient' # 指定连接RedisPython模块  默认:redis.StrictRedis

      # REDIS_ENCODING = "utf-8"                            # redis编码类型             默认:'utf-8'

 

  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

 

 

      PS:

          - URL参数位置不同时,计算结果一致;

          - 默认请求头不在计算范围,include_headers可以设置指定请求头

          示例:

              from scrapy.utils import request

              from scrapy.http import Request

 

              req = Request(url='http://www.baidu.com?name=8&id=1',callback=lambda x:print(x),cookies={'k1':'vvvvv'})

              result = request.request_fingerprint(req,include_headers=['cookies',])

 

              print(result)

 

              req = Request(url='http://www.baidu.com?id=1&name=8',callback=lambda x:print(x),cookies={'k1':666})

 

              result = request.request_fingerprint(req,include_headers=['cookies',])

 

              print(result)

 

!#Ensure all spiders share same duplicates filter through redis.

!#DUPEFILTER_CLASS = “scrapy_redis.dupefilter.RFPDupeFilter”

 

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

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

 

 

原文链接:https://yq.aliyun.com/articles/629656
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章