python是一个解释强类型语言
python的优缺点
- 胶水语言,轮子多,应用广泛
- 语言灵活,生产力高
- 性能问题,代码维护问题,python2、3兼容问题
什么是鸭子类型
- 关注点是对象的行为,而不是类型(duck typing)
什么是monkey patch
- 所谓的monkey patch 就是运行时替换
- 比如gevent库需要修改socket
- from gevent import monkey;monkey.patch_select()
什么是自省?
- 使用id,type,isinstance() 判断一个对象的类型
python2与python3相关问题
python2与3的差异
- print 在2里面是一个关键字,在3中是一个函数
- 编码问题: python3中没有unicode对象,默认str就是unicode,python2有两种 一种是str(byte)和unicode
- 除法问题: python3除号返回浮点数
python3的改进
- 类型注解(type hint) 帮助IDE实现类型检查
- 优化的super()方便直接调用父类函数
- python2 super(A,self):python2需要2个参数
- python3 super() : 可以直接调用
- 高级解包操作 a,b,*c = range(10)
- 限定关键字参数
- def he(a,b,*,c):return a,b,c
- python3 重新跑出异常不会丢失栈信息
- 一切返回迭代器 range zip map dict.values etc.are all, iterators
python3新增特性
- yield from 链接子生成器
- asyncio内置库,async/await 原生协程支持异步编程
- 新的内置库:enum,mock,asyncio,ipaddress,concurrent.futures等
python3改进
- 生成的pyc文件统一放到pycache
- 一些内置库的修改,urllib,selector等
兼容2/3的工具
- six模块
- 2to3等工具转换代码
- __future__
python函数常考题
python的参数传递
- python的参数传递方式,既不是引用传递也不是值传递,他是对象引用传递
python如何传递参数
- 一个混淆的问题
- 传递值还是引用呢,都不是,唯一支持的参数传递是共享传参
- 共享传参:函数形参获得实参中各个引用的副本
python的可变和不可变对象
- 不可变对象:
- bool,int,float,tuple,str,frozenset
- 可变对象
- list、set、dict
- 默认参数只计算一次
*args 和 **kwargs是什么
- 用来处理可变参数
- *args 被打包成tuple
- **kwargs 被打包成dict
python的异常
什么时候需要捕获处理异常,看python内置异常的类型
- 网络请求(超时,链接错误等)
- 资源访问(权限问题,资源不存在)
- 代码逻辑(越界访问,keyError等)
如何自定义自己的异常,为什么需要定义自己的异常
- 继承Exception实现自定义异常()
- 给异常加上一些附加信息
- 处理一些业务相关的特定异常(raise MyException)

python性能分析与优化,GIL常见考题
GIL锁带来的缺点?
- 限制了程序的多核执行
- 同一个时间只能有一个线程执行字节码
- CPU密集程序难以利用多核优势
- IO期间会释放GIL,对IO密集程序影响不大
如何规避GIL影响
- 区分CPU和IO密集程序
- CPU密集可以使用多进程+进程池
- IO密集使用多线程、协程
- cython扩展
为什么有了GIL还要关注线程安全
- python中什么操作才是原子的,一步到位执行完的
- 一个操作如果是一个字节码指令可以完成的,这就是原子的
- 原子操作是可以保证线程安全的
- 使用dis操作来分析字节码

如何剖析程序性能
- 使用各种profile工具(内置或第三方)
- 二八定律,大部分时间好事在少量代码之上
- 内置的profile、cprofile等工具
- 使用pyflame(uber开源)的火焰图工具
服务端性能优化措施
- web应用一般语言不会成为瓶颈
- 数据结构与算法优化
- 数据库层:索引优化,慢查询消除,批量操作减少IO,NoSql
- 网络IO:批量操作,pipline操作 减少IO
- 缓存:使用内存数据库redis、memcached
- 异步: asyncio,celery
- 并发:gevent、多线程
什么是生成器
- 生成器就是可以生成值的函数
- 当一个函数里有了yield关键字就成了生成器
- 生成器可以挂起来执行并且保持当前执行的状态
基于生成器的协程
- python3之前没有原生的协程,只有基于生成器的协程
- 生成器可以通过yield暂停执行和产出数据
- 同时支持send()向生成器发送数据和throw()向生成器抛出异常

协成的注意点
- 协成需要使用send(None)或者next(coroutine)来预激才能启动
- 在yield处协成会暂停执行
- 单独的yield value会产出值给调用方
- 可以通过coroutine.send(value) 来给协成发送值,发送的值或赋值给yield表达式左边的值
- 协程执行完成后没有遇到下一个yield语句会抛出Stoplteration
- python3.5引入async、await支持原生协成(native coroutine)
python 单元测试
unit Testing
- 针对程序模块进行正确性检验
- 一个函数,一个类进行验证
- 自底向上保证程序的正确性
三无代码不可取(无文档,无注释,无单测)
- 保证代码逻辑的正确性,(甚至有些采用测试驱动开发(TDD))
- 单测影响设计,易测的代码往往是高内聚低耦合的
- 回归测试,防止改一处整个服务不可用
单元测试相关库
- nose/pytest 较为常用
- mock 模块用来模拟网络请求等
- coverage 统计测试覆盖率