python面试总结3(性能分析优化,GIl常考题)
python性能分析和优化,GIL常考题
什么是Cpython GIL
- Cpython解释器的内存管理并不是线程安全的
- 保护多线程情况下对python对象访问
- Cpython使用简单的锁机制避免多个线程同时执行字节码
GIL的影响
限制了程序的多核执行
- 同一个时间只能有一个线程执行字节码
- CPU密集程序难以利用多核优势
- IO期间会释放GIL,对IO密集程序影响不大
如何规避GIL影响和IO密集程序
- CPU密集可以使用多进程+进程池
- IO密集使用多线程/协程
- Cpython扩展
为什么有了GIl还要关注线程安全
python中什么操作才是原子的?一步到位执行完
- 一个操作如果是一个字节码指令可以完成就是原子的
- 原子的是可以保证线程安全的
- 使用dis操作来分析字节码
原子操作
import dis
def update_list(l):
l[0] = 1 #原子操作,不用担心线程安全问题
dis.dis(update_list)
"""
6 0 LOAD_CONST 1 (1)
3 LOAD_FAST 0 (L)
6 LOAD_CONST 2 (0)
9 STORE_SUBSCR # 但字节码操作 线程安全
10 LOAD_CONST 0 (None)
13 RETURN_VALUE
"""
非原子操作不是线程安全的
def incr_list(l):
l[0] += 1 #危险!!! 不是原子操作
dis.dis(incr_list)
"""
21 0 LOAD_FAST 0(l)
3 LOAD_CONST 1 (0)
6 DUP_TOPX 2
9 BINARY_SUBSCR
10 LOAD_CONST 2 (1)
13 INPLACE_ADD # 需要多个字节码操作,有可能在线程中切到其他线程
"""
import threading
lock = threading.Lock() # 加锁,保证线程安全
# 加锁操作对性能有一定影响
n = [0]
def foo():
with lock:
n[0] = n[0] + 1
n[0] = n[0] + 1
threads = []
for i in range(5000);
t = threading.Thread(target=foo)
threads.append(t)
for t in threads:
t.start()
print(n)
如何剖析程序性能
使用各种profile工具(内置或第三方)
- 二八定律,大部分时间耗时在少量代码上
- 内置的profile/cprofile等工具
- 使用pyflame(uber开源)的火焰图工具
服务端性能优化措施
web应用一般语言不会成为瓶颈
- 数据结构与算法优化
- 数据库层: 索引优化,满查询消除,批量操作减少IO,NoSql
- 网络IO:批量操作,pipeline操作 减少IO
- 缓存: 使用内存数据库 redis/memcached
- 异步; asyncio , celery
- 并发: gevent/多线程
python生成器与协程
Generator
- 生成器就是可以生成值的函数
- 当一个函数里有了yield关键字就成了生成器
- 生成器可以挂起执行并且保持当前执行的状态
# 生成器
def simple_gen():
yield 'hello'
yield 'world'
gen = simple_gen()
print(type(gen)) # 'generator' object
print(next(gen)) # 'hello'
print(next(gen)) # 'world'
基于生成器的协程(python2)
python3之前没有原生协程,只有基于生成器的协程
- pep 342增强生成器功能
- 生成器可以通过yield暂停执行和产出数据
- 同时支持send()向生成器发送数据和throw()向生成器抛出异常
def coro():
hello = yield 'hello' # yield关键字在=右边作为表达式, 可以被sengd的值
yield hello
c = cor0()
#输出 ' hello' ,这里调用next产出一个值 'hello',之后函数暂停
print(next(c))
# 再次调用send发送值, 此时hello变量赋值为'world', 然后yield产出hello变量的值 'world'
print(c.send('world'))
# 之后协程结束,后续再send值会抛出异常StopIteration
python3原生协程
python3.5引入async/await支持原生协程(natice copoutine)
import asyncio
import datetime
import random
async def display_date(num, loop):
end_time = loop.time(0) + 50.0
while True:
print('Loop: {} Time: {}').format(num, datetime.datetime.now())
if (loop.time() + 1.0) >= end_time:
break
await asyncio.sleep(random.randint(0, 5))
loop = asyncio.get_event_loop()
asyncio.ensure_future(display_date(1, loop))
asyncio.ensure_future(display_date(2, loop))
loop.run_forever()
python 单元测试
什么是单元测试
- 针对程序模式进行正确性检验
- 一个函数, 一个类进行验证
- 自底向上保证程序正确性
为什么要写单元测试
三无代码不可取(无文档,无注释,无单测)
- 保证代码逻辑的正确性(甚至有些采用测试驱动开发TDD)
- 单测影响设计,易测的代码往往是高内聚低耦合的
- 回归测试,防止改一处整个服务不可用
单元测试相关的库
- nose/pytest 较为常用
- mock 模块用来模拟替换网络请求等
- coverage 统计测试覆盖率
def test():
"""
如何设计测试用例:(等价类划分)
- 正常功能测试
- 边界值 (比如最大最小,最左最右值)
- 异常值 (比如None, 空值,非法值)
"""
assert binary_search([0,1,2,3,4,5],1) == 1
assert binary_search([0,1,2,3,4,5],6) == -1
python深拷贝与浅拷贝
- 什么是深拷贝?什么是浅拷贝?
- python中如何实现深拷贝?
- 思考: python中如何正确初始化一个二维数组?
python面试总结3(性能分析优化,GIl常考题)的更多相关文章
- python 数据较大 性能分析
前提:若有一个几百M的文件需要解析,某个函数需要运行很多次(几千次),需要考虑性能问题 性能分析模块:cProfile 使用方法:cProfile.run("func()"),其中 ...
- python pstats ,profile 性能分析
#! /usr/bin/env python # encoding=utf8 import pstats import profile def func1(): for i in range(1000 ...
- 如何进行python性能分析?
在分析python代码性能瓶颈,但又不想修改源代码的时候,ipython shell以及第三方库提供了很多扩展工具,可以不用在代码里面加上统计性能的装饰器,也能很方便直观的分析代码性能.下面以我自己实 ...
- Python面试知识点小结
一.Python基础 1.Python语言特性: 动态型(运行期确定类型,静态型是编译型确定类型),强类型(不发生隐式转换,弱类型,如PHP,JavaScript就会发生隐患式转换) 2.Python ...
- 面试中常用排序算法的python实现和性能分析
这篇是关于排序的,把常见的排序算法和面试中经常提到的一些问题整理了一下.这里面大概有3个需要提到的问题: 虽然专业是数学,但是自己还是比较讨厌繁琐的公式,所以基本上文章所有的逻辑,我都尽可能的用大白话 ...
- Python 优化第一步: 性能分析实践 使用cporfile+gprof2dot可视化
拿来主义: python -m cProfile -o profile.pstats to_profile.py gprof2dot -f pstats profile.pstats |dot -Tp ...
- Python性能分析与优化PDF高清完整版免费下载|百度云盘
百度云盘|Python性能分析与优化PDF高清完整版免费下载 提取码:ubjt 内容简介 全面掌握Python代码性能分析和优化方法,消除性能瓶颈,迅速改善程序性能! 对于Python程序员来说,仅仅 ...
- 常用排序算法的python实现和性能分析
常用排序算法的python实现和性能分析 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试 ...
- 【Python】常用排序算法的python实现和性能分析
作者:waterxi 原文链接 背景 一年一度的换工作高峰又到了,HR大概每天都塞几份简历过来,基本上一天安排两个面试的话,当天就只能加班干活了.趁着面试别人的机会,自己也把一些基础算法和一些面试题整 ...
随机推荐
- Qt QtXml读取xml文件内容
Qt QtXml读取xml文件内容 xml文件内容 <?xml version="1.0" encoding="UTF-8"?> <YG_RT ...
- latex怎样生成table字样和caption换行的表格
\begin{table} \caption{\newline The results of running algorithm parallel using MapReduce.} \hline ...
- lint-staged那些事儿
一.工具选型 [预提交工具](https://www.npmtrends.com/lint-staged-vs-pre-commit-vs-pretty-quick) 1.lint-staged 检查 ...
- LeetCode:接雨水【42】
LeetCode:接雨水[42] 题目描述 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 上面是由数组 [0,1,0,2,1,0,1,3,2,1, ...
- pytest+allure测试框架搭建
https://blog.csdn.net/wust_lh/article/details/86685912 https://www.jianshu.com/p/9673b2aeb0d3 定制化展示数 ...
- JAVA windows环境配置,jdk的安装配置
一.需要的文件与下载1.jdk:jdk下载:二.安装与配置1.jdk安装与路径选择 双击安装,然后一直下一步,直至完成. 这是个人的自定义的安装目录路径(安装路径可在安装的时候自行选择,) 2.jdk ...
- 在ensp上STP配置和选路规则
原理概述 这次我们模拟的实验内容 搭建实验拓扑 搭建完拓扑之后,我们在交换机上启动STP服务,将交换机的STP模式改为普通生成树STP 配置完成之后我们来看一下S1生成树的状态(大约30秒之后,因为生 ...
- PHP设计模式 - 桥接模式
将抽象部分与它的实现部分分离,使他们都可以独立的变抽象与它的实现分离,即抽象类和它的派生类用来实现自己的对象 桥接与适配器模式的关系(适配器模式上面已讲解): 桥接属于聚合关系,两者关联 但不继承 适 ...
- 为什么Apache Kafka如此受欢迎
1.目标 今天,在这个Kafka教程中,我们将学习所有Kafka功能,如可扩展性,可靠性,耐用性,这些都说明了Kafka如此受欢迎的原因.我们将详细讨论Kafka的每个功能.但在那之前让我们明白什么是 ...
- python中将已有链接的视频进行下载
使用python爬取视频网站时,会得到一系列的视频链接,比如MP4文件.得到视频文件之后需要对视频进行下载,本文写出下载视频文件的函数. 首先导入requests库,安装库使用pip install ...