python语言基础

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 统计测试覆盖率