python面试题
Python 基础
1.什么是闭包
函数a中定义函数b,函数b使用函数a的变量就叫闭包
def a(): a1 = 1 a2 = 2 def b(): b1 = a1 + a2 return b1 return b
2.简述生成器, 迭代器, 可迭代对象
生成器
函数内部有yield关键字
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
生成器的编写方法和函数定义类似, 只是把return改为yield 生成器中可以有多个yield, 当生成器遇到yield时, 会暂停运行生成器, 返回yield后面的值.当再次调用的时候,会从刚才暂停的地方继续运行,直到下一个yield. 生成器自身又构成一个迭代器, 每次迭代时使用一个yield返回的值 应用场景 range/xrange - py2: range(10000) 会立即创建 / xrange(10000) 生成器 - py3: range(10000) 生成器 redis获取值 def hscan_iter(self, name, match=None, count=None): """ Make an iterator using the HSCAN command so that the client doesn't need to remember the cursor position. ``match`` allows for filtering the keys by pattern ``count`` allows for hint the minimum number of returns """ cursor = '0' while cursor != 0: # 去redis中获取数据:12 # cursor,下一次取的位置 # data:本地获取的12条数数据 cursor, data = self.hscan(name, cursor=cursor,match=match, count=count) for item in data.items(): yield item
迭代器
类的内部实现__iter__和__next__方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。 在for循环中,Python将自动调用工厂函数iter()获得迭代器,自动调用next()获取元素,还完成了检查StopIteration异常的工作。 自己实现迭代器, 只需要在类的__iter__方法中返回一个对象,这个对象拥有一个next()方法,这个方法能在恰当的时候抛出StopIteration异常即可。 class test: def __init__(self, input_list): self.list = input_list self.i = 0 def __iter__(self): return self def __next__(self): if self.i == len(self.list): self.i = 0 raise StopIteration self.i += 1 return self.list[self.i - 1] 使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。 但是需要自己实现迭代器的时候不多,即使需要,使用生成器会更轻松。
可迭代对象
一个类的内部实现__iter__方法且返回一个迭代器
可以使用for...in...语句进行循环的对象,比如字符串、列表、元组、字典以及迭代器、生成器都是可迭代对象。
总结
1.迭代器一定是迭代对象,迭代对象不一定是迭代器
2.生成器一定是迭代器,迭代器不一定是生成器
3.使用for...in...来遍历迭代对象是最常用的方式
3.什么是异步IO?
遇到IO不等待
网络相关
1.http协议是什么?
中文名叫 超文本传输协议 基于TCP来传递数据, 请求响应之后断开连接(无状态, 短链接)
本质就是定义了传输数据的格式
客户端发送一个HTTP请求到服务器的请求消息格式:
请求行(request line) 请求头(header) 空行 请求体 四个部分组成
2.访问一次网页经历了什么过程?
输入url - DNS解析 - 发起TCP请求 - 建立TCP连接后, 浏览器向服务器发送HTTP请求 - (负载均衡) - 服务端响应HTTP, 将请求的数据返回 - 浏览器释放TCP连接 - 浏览器渲染
图示:
3.tcp三次握手和四次挥手
******** 三次握手 ************** 第一次 客户端向服务端发起一次建立连接的请求,并产生一个 SYN(同步序列号) 第二次 服务端收到请求,确认客户端的SYN, 然后自己也发送一个SYN 第三次 客户端收到服务器发的SYN, 向服务器发送一个确认包,发送完毕之后建立TCP连接 ******** 四次挥手 ************** 第一次 客户端向服务端发起断开连接的请求 第二次 服务端向客户端确认请求 第三次 服务端断开客户端连接,发送一个断开连接请求 第四次 客户端向服务端缺点断开请求
4.cookie和session是什么
由于HTTP是一次响应一次请求. 为了保持会话有了cookie和session
cookie保存在浏览器
session保存在服务端
并发相关
1.简述进程,线程和协程
# 进程
进程就是正在运行的程序,拥有自己独立内存空间
# 线程
线程是操作系统进行运算调度的最小单位, 共享堆, 不共享栈
被包含在进程中, 是进程中实际运作的单位,一个进程中最少又一个线程运行
# 协程
协程是人为定义的,使用协程避免无意义的调度,由此可以提高性能
一个线程中可以有多个协程, 一个进程也可以单独拥有多个协程
进程线程都是同步机制, 协程是异步
2.python中怎么使用协程
通过yield关键字
使用greenlet/ gevent 模块
详细参考 https://blog.csdn.net/andybegin/article/details/77884645 https://www.cnblogs.com/gide/p/6187080.html
3.进程之间怎么传递数据
通过队列
from multiprocessing import Process, Queue
通过过管道
from multiprocessing import Process, Pipe
数据库相关
1.redis数据类型
string(字符串) hash(哈希) list(列表) set(集合) zset(有序集合)
2.关系型数据库分表要素
不分表会变慢查找速度
框架相关
其他
1.手写一下二分排序
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
def foo(find, lis): lis = sorted(lis) min = 0 max = len(lis) while(min<max): mid = int((max+min)/2) if lis[mid] == find: print('od') return mid elif lis[mid] > find: max = mid else: min = mid return None