PS:附上我的博客地址,答案中略的部分我的博客都有,直接原标题搜索即可。
https://www.cnblogs.com/Roc-Atlantis/
第一部分 Python基础篇(80题)
为什么学习Python?
Omit
通过什么途径学习的Python?
Omit
Python和Java、PHP、C、C#、C++等其他语言的对比?
Omit
简述解释型和编译型编程语言?
编译型语言:在运行程序之前将源代码翻译成目标代码(机器语言),
运行时不需要重新翻译,直接使用翻译的结果,程序执行效率高,依赖编译器运行(比如vs),
跨平台性差。比如c,c++等。
解释型语言:源代码一边翻译成机器语言一遍执行,效率较低,
但是灵活性较高,依赖解释器运行(比如py),修改方便,跨平台性好。如python,java,PHP等。
Python解释器种类以及特点?
cpython pypy jpython
位和字节的关系?
一个字节占8个bit位
b、B、KB、MB、GB 的关系?
1024关系 自行梳理
请至少列举5个 PEP8 规范(越多越好)。
我的博客直接搜索PEP8规范
通过代码实现如下转换:
# 二进制转换成十进制:v = “0b1111011”
# int("1111011",2) # 123
# 十进制转换成二进制:v = 18
# print(bin(18))
# 八进制转换成十进制:v = “011”
# int("011",8) # 9
# 十进制转换成八进制:v = 30
# print(oct(30))
# 十六进制转换成十进制:v = “0x12”
# int("12",16) # 18
# 十进制转换成十六进制:v = 87
# print(hex(87))
请编写一个函数实现将IP地址转换成一个整数。
如 10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果:00001010 00000011 00001001 00001100 = ?
def ip_to_int(s):
L = '0b'+''.join([bin(int(i)) for i in s.split('.')]).replace('0b','')
print(int(L,2))
if __name__ == '__main__':
s = "10.3.9.12"
ip_to_int(s)
python递归的最大层数?
import sys
print(sys.getrecursionlimit())
默认最大是1000层
求结果:
v1 = 1 or 3
v2 = 1 and 3
v3 = 0 and 2 and 1
v4 = 0 and 2 or 1
v5 = 0 and 2 or 1 or 4
v6 = 0 or Flase and 1
# 1
# 3
# 0
# 1
# 1
# False
ascii、unicode、utf-8、gbk 区别?
ascii:不能表示中文,英文用一个字节表示
unicode:中文和英文都用2个字节表示
utf-8:英文用一个自己表示,中文用3个
gbk:英文用1个字节表示,中文用2个字节表示
字节码和机器码的区别?
机器码是电脑CPU直接读取运行的机器指令,运行速度最快,
但是非常晦涩难懂,也比较难编写,一般从业人员接触不到。
字节码是一种中间状态(中间码)的二进制代码(文件)。需要直译器转译后才能成为机器码。
三元运算规则以及应用场景?
应用场景:简单的if else语句
a = 3 if x>10 else 12 如果if条件成立就输出前面的结果,如果不成立就输出后面的结果
列举 Python2和Python3的区别?
python2默认ascii,python3默认utf-8
博客搜索python2和python3的区别
用一行代码实现数值交换:
a = 1
b = 2
a = 1
b = 2
# a,b = 2,1
# print(a,b)
# c = a
# a = b
# b = c
# print(a,b)
# a,b = (2,1)
# print(a,b)
Python3和Python2中 int 和 long的区别?
python2中需要自己根据数值大小去判断该用int还是long
python3中取消了long类型数据,会自动判断
xrange和range的区别?
xrange(1,5)是python2里的生成器,可作为list对象得到一个列表
在python3,xrange相当于改了个名字,改成了range,也是一个生成器对象。
文件操作时:xreadlines和readlines的区别?
readlines() 读取文件所有内容,按行为单位放到一个列表中,返回list类型。
xreadlines()官方解释 >> Returns a generator to loop over every single line in the file
xreadlines只在python2里有
返回一个生成器,来循环操作文件的每一行。循环使用时和readlines基本一样,但是直接打印就不同
列举布尔值为False的常见值?
0,None,"",False
字符串、列表、元组、字典、集合每个常用的5个方法?
字符串:title(),join(),replace(),strip(),split(),eval()
元组:count(),index(),sorted(tuple)
列表:insert(),extend(),append(),pop(),remove(),sort()
字典:get(),items(),values(),keys(),clear(),copy(),pop(),setdefault()
集合:add(),deference(),discard(),remove(),pop(),symmetric_difference(),union(),intersection_update
lambda表达式格式以及应用场景?
lambda 变量名:变量表达式
通常和高阶函数连用 map reduce等
pass的作用?
空函数常用
表示直接跳过继续向下运行
*args和**kwargs作用
*args 表示接受溢出的位置参数,并以元组的形式返回给args
**kwargs 表示接受溢出的关键字参数,并以字典的形式返回给kwargs
is和==的区别
is判断id是否相等
== 判断值是否相等
为什么有时候值相同但是不同的两个地址,is判断却为True?
因为python有个缓存机制,一定范围内的整数不会独自再分配一个内存空间,他们共享一个内存空间.
简述Python的深浅拷贝以及应用场景?
深拷贝:拷贝后的对象的值不会再随着被拷贝对象值的改变而改变
浅拷贝:拷贝后的对象得值会随着被拷贝对象值的改变而改变.
浅拷贝的对象如果有多层可变类型,浅拷贝只拷贝第一层,深拷贝是递归拷贝,拷贝到迭代结束.
Python垃圾回收机制?
python每次定义一个变量都会带一个引用计数,每调用一次变量值,引用计数都会加1.
每次引用被删除,引用计数减1.当引用计数为0,变量值就会被当成垃圾回收.
Python的可变类型和不可变类型?
可变类型:列表,集合,字典
不可变类型:元组,字符串,整型
求结果:
v = dict.fromkeys(['k1','k2'],[])
#value的内存空间是公用的,所有的键都指向同一个value [].
v[‘k1’].append(666)
print(v)
v[‘k1’] = 777
print(v)
求结果:
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
列举常见的内置函数?
map() reduce() abs() filter() len()
filter、map、reduce的作用?
filter:符合条件的元素会筛选留下来
map:作用于每一个可迭代对象的元素
reduce:python3里使用reduce需要调用functools
from functools import reduce
# res = reduce(lambda x,y: (x+y)*2, [1,2,3,4,5])
# print(res)
# ((((((1+2)*2) + 3)*2+4)*2)+5)*2 = 98
一行代码实现9*9乘法表
"\n".join("\t".join(["%s*%s=%s" % (y, x, x*y) for y in range(1, x + 1)]) for x in range(1, 10))
如何安装第三方模块?以及用过哪些第三方模块?
通常用两种方法安装第三方模块:
一:直接用pip安装
二:在第三方库下载安装包,在cmd命令直接安装下载好的包
常用的第三方模块:
requests,turtle,pymysql,gevent,mulitprocessing,threading,bs4
至少列举8个常用模块都有那些?
random,time,turtle,requests,math,re,os,pickle,json,logging,sys,subprocess,pymysql,hashlib
re的match和search区别?
re模块中match(pattern,string[,flags]),检查string的开头是否与pattern匹配。
re模块中research(pattern,string[,flags]),在string搜索pattern的第一个匹配值。
什么是正则的贪婪匹配?
.*从.前面的字符开始匹配,一直到*后面字符是整个字符串最后一个符合条件的才会结束。
补充下非贪婪匹配:.*? 匹配到最近的一个符合条件的字符就会停下来。
求结果:
a. [ i % 2 for i in range(10) ]
b. ( i % 2 for i in range(10) )
a [0,1,0,1,0,1,0,1,0,1]
b 生成器表达式
求结果:
a. 1 or 2
b. 1 and 2
c. 1 < (2==2)
d. 1 < 2 == 2
a 1
b 2
c False
d True
def func(a,b=[]) 这种写法有什么坑?
会造成重复赋值,形参名不要写成变量的形式。
如何实现 “1,2,3” 变成 [‘1’,’2’,’3’] ?
a = "1,2,3"
print(a.split(","))
如何实现[‘1’,’2’,’3’]变成[1,2,3] ?
a = ["1","2","3"]
for i in range(len(a)):
a[i] = int(a[i])
print(a)
比较: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的区别?
b = [(1),(2),(3) ] 和a = [1,2,3]没区别,最多写的形式不一样
b = [(1,),(2,),(3,)] 这个因为多了个小括号里的逗号,列表里相当于嵌套了元组,
打印出来结果和前面两个是不一样的
如何用一行代码生成[1,4,9,16,25,36,49,64,81,100] ?
[i**2 for i in range(1,11)]
一行代码实现删除列表中重复的值 ?
字典key值的唯一性
print(dict.fromkeys(l).keys())
集合去重
print(set([1,2,3,4,1,2])
如何在函数中设置一个全局变量 ?
加入globals 申明下面的变量为全局变量
logging模块的作用?以及应用场景?(待补充--通常会忘记补充)
日志模块。
应用场景:需要生成日志在屏幕或者需要日志记录。
请用代码简答实现stack 。(实现堆栈--先进先出和先进后出)
一.用到append(i)和insert(0,i) ==for循环出结果
二.线程queue中的q = queue.Queue()-先进先出和q = queue.LifoQueue() --先进后出
常用字符串格式化哪几种?
"%s"%i
"{}-{}".format(1,2)
f"" python3新增,不太了解
简述 生成器、迭代器、可迭代对象 以及应用场景?
可迭代对象:有__iter__方法的都是可迭代对象
迭代器:本身就是由可迭代对象经过__iter__方法转换成迭代器对象,本身有__iter__和__next__方法。
生成器:生成器本身就是个迭代器,生成器构造有个yield函数,相当于自定义迭代器。
用Python实现一个二分查找的函数。
num = [1,3,4,5,6,8,22,33,55,778,990]
def search(search_number,num):
if len(num) == 0:return
mid = len(num) // 2
mid_nums = num[len(num)//2]
if search_number > mid_nums:
num = num[mid + 1:]
search(search_number,num)
elif search_number < mid_nums:
num = num[:mid]
search(search_number, num)
else:
print("find it")
search(363,num)
谈谈你对闭包的理解?
闭包就是调用函数会得到一个返回值,返回值是函数的内存地址。加括号即可调用。
闭指的是该函数是一个内部函数
包指的是该函数对外部作用域(非全局作用域)名字的引用。
os和sys模块的作用?
os:这个模块提供了一种方便的使用操作系统函数的方法。
sys:这个模块可供访问由解释器使用或维护的变量和与解释器进行交互的函数。
总结:os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口;sys模块负责程序
与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
如何生成一个随机数?
调用random模块
random.randint(1,3)
random.randrange(1,3)
random.random()
如何使用python删除一个文件?
import os
os.remove(文件路径)
谈谈你对面向对象的理解?
核心是对象。对象是特征与技能的结合体,类就是一系列对象相似的特征与技能的结合体。
面向对象编程
Python面向对象中的继承有什么特点?
继承:子类会遗传父类的属性 继承是类与类之间的关系
继承的特点:
1、在继承中基类的构造(__init__()方法)不会被自动调用,
它需要在其派生类的构造中亲自专门调用。有别于C#
2、在调用基类的方法时,需要加上基类的类名前缀,且需要带上self参数变量。
区别于在类中调用普通函数时并不需要带上self参数
3、Python总是首先查找对应类型的方法,如果它不能在派生类中找到对应的方法,
它才开始到基类中逐个查找。(先在本类中查找调用的方法,找不到才去基类中找)
面向对象深度优先和广度优先是什么?
自己理解:深度优先就是在查找方式上遍历到最后的节点,和递归类似,有明确的结束条件。
广度优先就是不优先查找最后的节点,到最后才去查找。
新式类:广度查找优先,经典类:深度查找优先
网上:
深度优先:
将一个子节点的所有内容全部遍历完毕之后再去遍历其他节点实现的 (递归实现)
广度优先:
广度优先的算法的实现是通过 分层次的进行遍历 先遍历第一层,然后第二层,第三层 (队列实现)
深度优先遍历的算法是通过递归的方式一只只遍历某一个节点从而进行的,
而广度优先遍历算法则是把上一个层次的所有节点归入队列全部遍历完毕再进行下面的遍历的
面向对象中super的作用?(具体参考博客)
要理解super的原理,就要先了解mro。mro是method resolution order的缩写,表示了类继承体系中的成员
解析顺序。在python中,每个类都有一个mro的类方法。
可以看到mro方法返回的是一个祖先类的列表。Leaf的每个祖先都在其中出现一次,
这也是super在父类中查找成员的顺序。
通过mro,python巧妙地将多继承的图结构,转变为list的顺序结构。super在继承体系中向上的查找过程,
变成了在mro中向右的线性查找过程,任何类都只会被处理一次。
通过这个方法,python解决了多继承中的2大难题:
1. 查找顺序问题。从Leaf的mro顺序可以看出,如果Leaf类通过super来访问父类成员,
那么Medium1的成员会在Medium2之前被首先访问到。
如果Medium1和Medium2都没有找到,最后再到Base中查找。
2. 钻石继承的多次初始化问题。在mro的list中,Base类只出现了一次。事实上任何类都只会在mro list中
出现一次。这就确保了super向上调用的过程中,任何祖先类的方法都只会被执行一次。
是否使用过functools中的函数?其作用是什么?
搜索我博客:functools模块中的函数
列举面向对象中带双下划线的特殊方法,如:__new__、__init__
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
下面是查看对象属性的一些方法
__name__
__main__
__doc__
__file__
__metaclass__
__dict__
如何判断是函数还是方法?
函数:
函数是封装了一些独立的功能,可以直接调用,
python内置了许多函数,同时可以自建函数来使用。
方法:
方法和函数类似,同样封装了独立的功能,但是方法是
需要通过对象来调用的,表示针对这个对象要做的操作,使用时采用点方法。
静态方法和类方法区别?
静态方法是类和对象都可以调用,调用的时候必须传入对应的参数
类方法:类调用直接把调用的类当作参数传入,对象调用类方法还是会自动传入类。
列举面向对象中的特殊成员以及应用场景
__new__
__init__
__str__
__call__
__del__
__iter__
__next__
__getitem__ 、 __setitem__ 、__delitem__ 用于索引操作,如字典。分别表示获取、设置、删除数据
1、2、3、4、5 能组成多少个互不相同且无重复的三位数
count = 0
for i in range(1,6):
for m in range(1,6):
for n in range(1,6):
if i != m and m != n and i!=n:
print(100*i + 10*m + n)
count+=1
print(count)
什么是反射?以及应用场景?
反射就是通过字符串来操作类和对象的属性
hasattr(obj,attrib) 判断对象是否存在这个属性,存在就返回True
getattr(obj,attrib,None) 判断属性对象是否可以访问,如果可以
就返回数据属性的值或者函数属性的内存地址。如果不能,就返会None。
setattr(obj,attrib,属性值) 修改对象的属性值,如果没有该属性则添加属性到名称空间
delattr(obj,attrib) 删除对象名称空间里的属性值,删除类的属性值,数据属性和函数属性都可以删除
metaclass(元类)作用?以及应用场景?
元类负责控制类的产生过程。
分为type元类创建类和自定义元类创建类。具体看我博客。
用尽量多的方法实现单例模式。
三种:一:直接在类中通过if判断来确定__instance是否为None,如果是给他赋值,不是直接返回self.__instance
二.通过在类上加装饰器的方法实现。装饰器里的wrapper就是Mysql,调用wrapper相当于通过Mysql往里面传值
,如果不传值args和kwargs长度为0,可以以此为关键进行判断。
三.自定义元类中通过传入参数的长度来判断是否传参,没传参直接返回self.__instance,传参则产生新对象
装饰器的写法以及应用场景。
单层装饰器和多层装饰器
为了节省代码量,避免代码冗余,装饰器出现解决了这些问题。
无参装饰器外面包着一层,有参装饰器外面包着两层。通常写成语法糖的形式,放在被装饰的对象上面。
装饰器是为了不违背开放封闭原则的前提下,为被装饰对象添加功能。
异常处理写法以及如何主动抛出异常(应用场景)
异常处理:try..except..else..finally
主动抛出:raise Typeerror("抛出的异常说明")
什么是面向对象的mro
mro是子类查找父类的顺序,mro列表里的类不会重复并且只会被查找一次,且按照继承的顺序来。
isinstance作用以及应用场景?
isinstance(obj,class) 判断对象obj是不是由class生成的对象。
什么是语句,什么是表达式?
写代码并实现:
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]
l = [2,7,11,15]
target = 9
for i in l:
for m in l:
if i != m and i+m == target:
print(i,m)
json序列化时,可以处理的数据类型有哪些?如何定制支持datetime类型?
json不可以处理的数据类型:元组,集合,自定义类和类的对象。
datetime类型???
json序列化时,默认遇到中文会转换成unicode,如果想要保留中文怎么办?
Str=json.dumps(jsonData,ensure_ascii=False,indent=2)
加上ensure_ascii=False即可。 indent是用来设置排版格式。
什么是断言?应用场景?
详情见我博客,自己解释不清,也不懂assert到底怎么用。
有用过with statement(with 声明)吗?它的好处是什么?
>>>with open('text.txt')as my_file:
...whileTrue:
...line=my_file.readline()
...if not line:
...break
...print(line)
#with语句使用所谓的上下文管理器对代码块进行包装,允许上下文管理器实现一些设置和清理操作。
#例如:文件可以作为上下文管理器使用,它们可以关闭自身作为清理的一部分。
#NOTE:在PYTHON2.5中,需要使用from__future__importwith_statement进行with语句的导入
使用代码实现查看列举目录下的所有文件。
import os
for file in os.listdir(r'\address'):
print(file)
简述 yield和yield from关键字。
看我博客 看我博客 。
第二部分 网络编程和并发(34题)
简述 OSI 七层协议。
物理层:主要是基于电器特性发送高低电压(电信号),高电压对应数字1,低电压对应数字0
数据链路层: 功能:定义了电信号分组的方式 以太网协议
网络层:网络层功能:引入一套新的地址用来区分不同的广播域/子网,这套地址即网络地址
规定网络地址的协议叫做ip协议,它定义的地址称为ip地址
传输层:传输层功能:建立端口到端口的通信
应用层:必须有不同协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。
什么是C/S和B/S架构?
客户端与服务端通信
浏览器客户端与服务端通信
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),
调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),
如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器
端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
简述 三次握手、四次挥手的流程。
第一次握手:
客户端发送一个TCP的SYN标志位置1的包指明客户打算连接的服务器的端口,
以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
第二次握手:
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,
将确认序号(Acknowledgement Number)设置为客户的I S N加1以.即X+1。
第三次握手.
客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器
发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写ISN的+1
连接终止协议(四次分手)
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据
发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,
一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1) TCP客户端发送一个FIN,用来关闭客户到服务器的数据传送(报文段4)。
(2) 服务器收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。
和SYN一样,一个FIN将占用一个序号。
(3) 服务器关闭客户端的连接,发送一个FIN给客户端(报文段6)。
(4) 客户段发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
什么是arp协议?
ARP协议
ARP 地址解析协议,就是 把 IP->MAC(你听过ARP欺骗的)
arp协议由来:计算机通信基本靠吼,即广播的方式,所有上层的包到最后都要封装上以太网头,
然后通过以太网协议发送,在谈及以太网协议时候,我门了解到
通信是基于mac的广播方式实现,计算机在发包时,获取自身的mac是容易的,如何获取目标主机的mac,
就需要通过arp协议。
一:首先通过ip地址和子网掩码区分出自己所处的子网
二:分析172.16.10.10/24与172.16.10.11/24处于同一网络
(如果不是同一网络,那么下表中目标ip为172.16.10.1,通过arp获取的是网关的mac)
三:这个包会以广播的方式在发送端所处的自网内传输,所有主机接收后拆开包,
发现目标ip为自己的,就响应,返回自己的mac
最前面的”以太网标头”,设置发出方(本机)的MAC地址和接收方(DHCP服务器)的MAC地址。
前者就是本机网卡的MAC地址,后者这时不知道,
就填入一个广播地址:FF-FF-FF-FF-FF-FF
arp协议功能:广播的方式发送数据包,获取目标主机的mac地址。
TCP和UDP的区别?
TCP协议每一次传输都要发送请求和确认传输信号,安全可靠,速度较慢。
UDP协议直接传输,不需要经过请求,速度会很快,但容易造成数据包的丢失。
什么是局域网和广域网?
广域网:作用范围大,一般可以从几十公里至几万公里。
一个国家或国际间建立的网络都是广域网。在广域网内,用于通信的传输装置和传输介质可由电信部门提供。
局域网(LAN):为了完整地给出LAN的定义,必须使用两种方式:一种是功能性定义,另一种是技术性定义。
前一种将LAN定义为一组台式计算机和其它设备,在物理地址上彼此相隔不远,以允许用户相互通信
和共享诸如打印机和存储设备之类的计算资源的方式互连在一起的系统。这种定义适用于办公环境下
的LAN、工厂和研究机构中使用的LAN。
就LAN的技术性定义而言,它定义为由特定类型的传输媒体(如电缆、光缆和无线媒体)和网络适配器
(亦称为网卡)互连在一起的计算机,并受网络操作系统监控的网络系统。
为何基于tcp协议的通信比基于udp协议的通信更可靠?
tcp协议设立了接受确认和重传机制。每一次信息传输都和三次握手一样,使得每一个信息都能保证到达,很可靠。
udp是尽力传送,没有确认和重传机制,udp只是将信息发送出去,对方收不收到也不进行应答
什么是socket?简述基于tcp协议的套接字通信流程。
socket是套接字。
先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),
调用accept阻塞,等待客户端连接。在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),
如果连接成功,这时客户端与服务器端的连接就建立了。客户端发送数据请求,服务器端接收请求并处理请求,
然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。
什么是粘包?socket中造成粘包的原因是什么? 哪些情况会发生粘包现象?
产生粘包的原因:第一点:客户端向服务端发起命令请求,服务端接受命令请求,并返回对应的信息,
如果信息过大,客户端一次接受不了,那么下一次请求依然返回
上一个命令的内容,就出现了粘包的情况。
第二点:发送端需要等缓冲区满才发送出去,造成粘包(发送数据时间间隔很短,数据了很小,
会合到一起,产生粘包)
所谓粘包问题主要还是因为接收方不知道消息之间的界限,不知道一次性提取多少字节的数据所造成的。
发送端为了将多个发往接收端的包,更有效的发到对方,使用了优化方法(Nagle算法),将多次间隔较小且数据量
小的数据,合并成一个大的数据块,然后进行封包。这样做,虽然节省了时间,但是发出的包却粘在了一起,
造成粘包现象。
IO多路复用的作用?
IO复用机制可以同时监控多个描述符,当某个描述符就绪(读或写就绪),则立即通知相应程序进行读或写操作。
但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说
这个读写过程是阻塞的。
I/O多路复用的优势并不是对于单个连接能处理的更快,而是在于可以在单个线程/进程中处理更多的连接。
与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,
也不必维护这些进程/线程,从而大大减小了系统的开销。
什么是防火墙以及作用?
防火墙见我博客
select、poll、epoll 模型的区别?
见我的博客
简述 进程、线程、协程的区别 以及应用场景?
看我的博客
GIL锁是什么鬼?
全局解释器锁
当程序在运行某段代码遇到GIL锁,此时会变成串行,需要一个线程执行完该段代码下一个执行才可以进去。
Python中如何使用线程池和进程池?
# 进程池
from concurrent.futures import ProcessPoolExecutor
import time,os
def func1(name):
print("%s is %s"%(name,os.getpid())) # 打印了进程id
time.sleep(1)
if __name__ == "__main__":
p = ProcessPoolExecutor(4) # 指定进程池最大进程个数
for i in range(10):
obj = p.submit("omit %s"%i,i) 提交任务
# 线程池
rom concurrent.futures import ThreadPoolExecutor
import time,os,random
def func2(name):
print("%s is %s"%(name,os.getpid())) # 打印了进程id
time.sleep(random.randint(1,3))
if __name__ == "__main__":
p = ThreadPoolExecutor(4) # 指定线程池最大线程个数,不包含控制线程
for i in range(10):
obj = p.submit("omit %s"%i,i) # 提交任务
threading.local的作用?
一旦在主线程实例化了一个local,它会一直活在主线程中,并且又主线程启动的子线程调用这个local实例时,
它的值将会保存在相应的子线程中。
1.local_data具有全局访问权,主线程,子线程都能访问它。
2.但是 local_data的值却是线程隔离的,值只与各当前线程有关。
ThreadLocal 最常用的地方:
为每个线程绑定一个资源(数据库连接,HTTP请求,用户身份信息等),
这样一个线程的所有调用到的处理函数都可以非常方便地访问这些资源。
进程之间如何进行通信?
通过管道或者队列来通信。一般用的队列,因为队列是管道加锁,不用自己再加锁。
导入multiprocessing模块中的Queue,生成Queue对象,调用put方法把值放到队列里,get从队列里取值,
每取一个值也同时删除队列中的该值。
什么是并发和并行?
并发是伪并行,通过遇到IO切换来实现类似并行的效果。
并行多核才能实现,多个进程同时工作。
进程锁和线程锁的作用?
线程锁:大家都不陌生,主要用来给方法、代码块加锁。当某个方法或者代码块使用锁时,那么
在同一时刻至多仅有有一个线程在执行该段代码。当有多个线程访问同一对象的加锁方法/代码块时,
同一时间只有一个线程在执行,其余线程必须要等待当前线程执行完之后才能执行该代码段。但是,
其余线程是可以访问该对象中的非加锁代码块的。
进程锁:也是为了控制同一操作系统中多个进程访问一个共享资源,只是因为程序的独立性,
各个进程是无法控制其他进程对资源的访问的,但是可以使用本地系统的信号量控制(操作系统基本知识)。
解释什么是异步非阻塞?
见我博客
路由器和交换机的区别?
一、工作所在的OSI层次不一样(根本区别,导致接下来的区别)
交换机工作在 OSI模型的数据链路层,所以工作原理比较简单;
路由器工作在OSI模型的网络层,具备更多的网络协议信息,所以可以做出更好的数据转发策略。
二、数据转发所依据的对象也不一样。
交换机工作在数据链路层,所以交换机转发数据依靠的是每个物理地址(MAC地址),MAC地址一般
是设备生产商在设备出厂时固定在设备中的,不能进行更改。
路由器工作在网络层,所以其交换数据依靠网络地址(IP地址),而IP地址是由网络管理员自己分配
或者系统自动获取的。
三、是否可以分割广播域
由交换机连接的所有端口仍然属于同一个广播域,所以极有可能会产生数据拥堵;
连接到路由器上的所有端口不在属于同一个广播域,所以不会产生类似的数据拥堵问题
什么是域名解析?
域名解析是把域名指向网站空间IP,让人们通过注册的域名可以方便地访问到网站一种服务。
域名解析也叫域名指向、服务器设置、域名配置以及反向IP登记等等。说得简单点就是将好记的域名解析成IP,
服务由DNS服务器完成,是把域名解析到一个IP地址,然后在此IP地址的主机上将一个子目录与域名绑定。
如果是需要建站,除了注册域名,还需要向虚拟主机提供商申请空间,如果空间是国内的还需要备份,
国外的空间则不需要。
如何修改本地hosts文件?
1.在菜单栏找到记事本
2.右键记事本 >>使用管理员权限打开
3.单击文件按钮>>下拉菜单点击打开文件>>C:\Windows\System32\drivers\etc 这个路径
4.如果到这步来了找不到hosts文件这是我们点击文本文档下拉框选择 “所有文件”
5.输入127.0.0.1 或你指向的IP就行了,ctrl + s 就OK
hosts记录规则非常简单,只需要将你的记录以 “IP + 空格 + 域名” 的格式填写即可。
生产者消费者模型应用场景及优势?
生产者与消费者模式是通过一个容器来解决生产者与消费者的强耦合关系,生产者与消费者之间不直接进行通讯,
而是利用阻塞队列来进行通讯,生产者生成数据后直接丢给阻塞队列,消费者需要数据则从阻塞队列获取,实际应
用中,生产者与消费者模式则主要解决生产者与消费者生产与消费的速率不一致的问题,达到平衡生产者与消费者
的处理能力,而阻塞队列则相当于缓冲区。
# 应用场景
由一个线程生成订单,并将其放入队列中.由多个线程去处理
# 优势
平衡生产者与消费者的处理能力
简述 gevent模块的作用和应用场景。
Gevent 是一个第三方库,可以轻松通过gevent实现并发同步或异步编程,在gevent中用到的主要模式是Greenlet,
它是以C扩展模块形式接入Python的轻量级协程。 Greenlet全部运行在主程序操作系统进程的内部,但它们被
协作式地调度。
什么是cdn?
CDN的全称是Content Delivery Network,即内容分发网络。
其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快、更稳定。
通过在网络各处放置节点服务器所构成的在现有的互联网基础之上的一层智能虚拟网络,CDN系统能够实时地根
据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近
的服务节点上。
其目的是使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
第三部分 数据库和缓存(46题)
列举常见的关系型数据库和非关系型都有那些?
关系型 : MySQL,SQL Server ,Oracle , Sybase, DB2
非关系型 : Redis, MongodDB
MySQL常见数据库引擎及比较?
ISAM:ISAM是一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到数据库被查询的次数
要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个
主要不足之处在于,它不支持事务处理,也不能够容错:如果你的硬盘崩溃了,那么数据文件就无法恢复了。
如果你正在把ISAM用在关键任务应用程序里,那就必须经常备份你所有的实时数据,通过其复制特性,
MYSQL能够支持这样的备份应用程序。
MyISAM:MyISAM是MySQL的ISAM扩展格式和缺省的数据库引擎。除了提供ISAM里所没有的索引
和字段管理的大量功能,MyISAM还使用一种表格锁定的机制,来优化多个并发的读写操作,
其代价是你需要经常运行OPTIMIZE TABLE命令,来恢复被更新机制所浪费的空间。MyISAM还有一些有用的扩展
,例如用来修复数据库文件的MyISAMCHK工具和用来恢复浪费空间的 MyISAMPACK工具。MYISAM强调了快速读取操作
,这可能就是为什么MySQL受到了WEB开发如此青睐的主要原因:在WEB开发中你所进行的大量数据操作都是读取操作。所以,大多数虚拟主机提供商和INTERNET平台提供商只允许使用MYISAM格式。MyISAM格式的一个重要缺陷就是不能在表损坏后恢复数据。
InnoDB:InnoDB数据库引擎都是造就MySQL灵活性的技术的直接产品,这项技术就是MYSQL+API。在使用MYSQL
的时候,你所面对的每一个挑战几乎都源于ISAM和MyISAM数据库引擎不支持事务处理(transaction process)
也不支持外来键。尽管要比ISAM和 MyISAM引擎慢很多,但是InnoDB包括了对事务处理和外来键的支持,这两点
都是前两个引擎所没有的。如前所述,如果你的设计需要这些特性中的一者或者两者,那你就要被迫使用后两个
引擎中的一个了。
MEMORY: MEMORY是MySQL中一类特殊的存储引擎。它使用存储在内存中的内容来创建表,而且数据全部放在内存中。
这些特性与前面的两个很不同。每个基于MEMORY存储引擎的表实际对应一个磁盘文件。该文件的文件名与表名相同,
类型为frm类型。该文件中只存储表的结构。而其数据文件,都是存储在内存中,这样有利于数据的快速处理,
提高整个表的效率。值得注意的是,服务器需要有足够的内存来维持MEMORY存储引擎的表的使用。如果不需要了,
可以释放内存,甚至删除不需要的表。MEMORY默认使用哈希索引。速度比使用B型树索引快。当然如果你想用B型树
索引,可以在创建索引时指定。注意,MEMORY用到的很少,因为它是把数据存到内存中,如果内存出现异常就会
影响数据。如果重启或者关机,所有数据都会消失。因此,基于MEMORY的表的生命周期很短,一般是一次性的。
简述数据三大范式?
1.第一范式:确保每列保持原子性
2.第二范式:确保表中的每列都和主键相关
3.第三范式:确保表中每一列都和主键列直接相关,而不是间接相关.
什么是事务?MySQL如何支持事务?
事务是逻辑上的一组操作,组成这组操作的各个单元,要不全都成功要不全都失败,这个特性就是事务
事务可以包含一系列的sql语句,事务的执行具有原子性
1、原子性:
包含多条sql语句要么都执行成功,要么都执行不成功
2、回滚
简述数据库设计中一对多和多对多的应用场景?
应用场景:一对多:一个学生可以有多门课程
多对多:一个老师可以有多个学生,一个学生也可以有多个老师
如何基于数据库实现商城商品计数器?
详情见我博客
常见SQL(必备)
详见武沛齐博客:https://www.cnblogs.com/wupeiqi/articles/5729934.html
简述触发器、函数、视图、存储过程?
触发器: 在执行某种操作前后一些自定义的操作
函数: 处理参数,返回结果
视图: 把需要的数据存放在一张临时表中,简化查询
存储过程: sql语句集,简化了一些操作.与函数不同,他可以返回一个结果集(查询结果)
MySQL索引种类
1. 普通索引
这是最基本的索引,它没有任何限制,比如上文中为title字段创建的索引就是一个普通索引,
MyIASM中默认的BTREE类型的索引,也是我们大多数情况下用到的索引。
2. 唯一索引
与普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值(注意和主键不同)。
如果是组合索引,则列值的组合必须唯一,创建方法和普通索引类似。
3. 全文索引(FULLTEXT)
MySQL从3.23.23版开始支持全文索引和全文检索,FULLTEXT索引仅可用于 MyISAM 表;
他们可以从CHAR、VARCHAR或TEXT列中作为CREATE TABLE语句的一部分被创建,或是随后
使用ALTER TABLE 或CREATE INDEX被添加。对于较大的数据集,将你的资料输入一个
没有FULLTEXT索引的表中,然后创建索引,其速度比把资料输入现有FULLTEXT索引的速度更为快。
不过切记对于大容量的数据表,生成全文索引是一个非常消耗时间非常消耗硬盘空间的做法。
4. 单列索引、多列索引
多个单列索引与单个多列索引的查询效果不同,因为执行查询时,MySQL只能使用一个索引,
会从多个索引中选择一个限制最为严格的索引。
5. 组合索引(最左前缀)
平时用的SQL查询语句一般都有比较多的限制条件,所以为了进一步榨取MySQL的效率,就要考虑建立组合索引。
索引在什么情况下遵循最左前缀的规则?
联合索引的情况下遵循最左前缀的规则。
主键和外键的区别?
主键 : 该表中此列唯一,非空
外键 : 该列中的值必须是关联表中关联的数据
MySQL常见的函数?
详情见我博客
列举 创建索引但是无法命中索引的8种情况。
1.如果条件中有or,即使其中有条件带索引也不会使用(这也是为什么尽量少用or的原因)
注意:要想使用or,又想让索引生效,只能将or条件中的每个列都加上索引
2.对于多列索引,不是使用的第一部分,则不会使用索引
3.like查询是以%开头
4.如果列类型是字符串,那一定要在条件中将数据使用引号引用起来,否则不使用索引
5.如果mysql估计使用全表扫描要比使用索引快,则不使用索引
此外,查看索引的使用情况
show status like ‘Handler_read%';
大家可以注意:
handler_read_key:这个值越高越好,越高表示使用索引查询到的次数
handler_read_rnd_next:这个值越高,说明查询低效
如何开启慢日志查询?
如何查看当前慢查询日志的开启情况?
在MySQL中输入命令:
showvariables like ‘%quer%’;
主要掌握以下的几个参数:
(1)slow_query_log的值为ON为开启慢查询日志,OFF则为关闭慢查询日志。
(2)slow_query_log_file 的值是记录的慢查询日志到文件中(注意:默认名为主机名.log,
慢查询日志是否写入指定文件中,需要指定慢查询的输出日志格式为文件,相关命令为:
show variables like ‘%log_output%’;去查看输出的格式)。
(3)long_query_time 指定了慢查询的阈值,即如果执行语句的时间超过该阈值则为慢查询语句,
默认值为10秒。
(4)log_queries_not_using_indexes 如果值设置为ON,则会记录所有没有利用索引的查询(注意:如果只是将log_queries_not_using_indexes设置为ON,而将slow_query_log设置为OFF,此时该设置也不会生效,即该设置生效的前提是slow_query_log的值设置为ON),一般在性能调优的时候会暂时开启。
数据库导入导出命令(结构+数据)?
Mysqldump -h127.0.0.1 -P3306 -uroot -p密码 数据库名称>xx.sql
数据库优化方案?
详情见我博客
char和varchar的区别?
#char类型:定长,简单粗暴,浪费空间,存取速度快
#varchar类型:变长,精准,节省空间,存取速度慢
简述MySQL的执行计划?
详情见博客
在对name做了唯一索引前提下,简述以下区别:
select * from tb where name = ‘Oldboy-Wupeiqi’
select * from tb where name = ‘Oldboy-Wupeiqi’ limit 1
全局遍历与只取一条
1000w条数据,使用limit offset 分页时,为什么越往后翻越慢?如何解决?
越是向后,扫描的数据也就越多
解决方案:按照需求实现,可分为
限制浏览页数,
存储本页数据两端的主键,按主键查找后向前或向后取多少条
另外,如果数据没有缺失的话,还可以通过页数来计算主键
什么是索引合并?
使用多个主键进行查询
什么是覆盖索引?
查询内容在主键中可以直接查到
简述数据库读写分离?
建立主从关系,实现高可用,并减少主服务器的压力。
简述数据库分库分表?(水平、垂直)
水平 : 数据库字段过多
垂直 : 数据库行数太多