Python面试综合-Python相关
Python特性
设计哲学 | Python3 版本变化 | 与其它语言对比(比如C++) |
---|---|---|
优雅 | 动态解释性脚本语言 | |
明确 | int、long | 开发维护成本低 |
简单 | byte、str | 丰富的生态圈 |
... | 函数新特性 | 跨平台 |
... |
GIL
Global Interpreter Lock:
- 出现原因
- 运行机制--一个进程同一时刻只有一个线程在运行(非并行)
- 只在Cpython解释器中存在
GIL释放时机:
- 线程开始IO操作时
- 计算任务,解释器每隔100opcode或者15ms
Python的多线程和单线程效率测试:
- Python的多线程只对IO密集型任务产生正面效果,而当其中至少有一个CPU密集型任务时,多线程效率将急剧下降
如何避免GIL消极影响:
- 多进程、协程
- 其它解释器,但会带来新的问题
Python解释器相关
内存管理
对象存储--万物皆对象:
- 整数和较小字符串
- 容器对象
垃圾回收机制
对象回收:
- 引用计数
- 分代回收:gc.get_threshold(),gc.set_threshold(700, 10,10)
循环引用解决办法:
- 手动回收:gc.collect()
- 弱引用: weakref.ref
示例面试(1)
问题:
扫描二维码关注公众号,回复:
6634177 查看本文章
- 什么情况下使用Python语言开发比较好?
- 你对Python怎么看?
- 为什么要用Python?
- ...
回答思路1:
- 时间线:
- 1991年,第一个稳定的Python版本;
- 2000年,Python2.7稳定版本发布;
- 2008年,Python3发布;
- 2020年,Python2不再维护;
- 空间线:
- Python设计哲学;
- Python2、3特性;
- 和其它语言(如C++)对比;
- 语言选型考虑因素;
思路串联1:
设计哲学(Python本质特性)->如何选型(正面回答,取其精华) -> 埋下一个问题引子
示例答案1:
Python自1991年Rossum编写发布出第一个版本以来,便一直遵循着其设计哲学”简单、明确、优雅“,设计哲学的根本出发点就决定了Python这门语言的编程开发的易用性和工作高效性,同样的业务需求实现,可能传统编程语言C++程序猿需要1周工期,而Python程序猿很有可能三天不到就能完成,而且潜在隐藏的问题会少很多,因为Python本身目前有非常庞大的开源第三方库,同时封装了很多复杂的语言底层操作如内存分配与释放,指针的相关操作等;
在具体的项目实践过程中,开发语言的选型需要考虑到几个方面:项目业务本身的特点适合哪种语言、公司历史的技术栈和人员技术储备倾向于哪种语言、选型的语言当前领域内的生态体系和发展前景(比如是否不在维护);如果项目非计算密集型项目,其中对于算法性能等要求不是非常非常高,相对而言是业务功能和流程逻辑较为复杂,此时Python语言就天然具备很大的优势,碰到其中少部分算法等计算性能瓶颈的地方可以用c++等语言重写,然后Python调用,这样可以兼顾Python开发低成本和C++高性能两方面的有点;
具体选用Python后,新项目推荐使用python3,2008年Python3发布后,十几年来Python3生态圈三方库已经非常完备和齐全,而官方已宣布Python2在2020年将不再维护,另外Python3本身性能也相较Python2有一定的提升;
回答思路2:
- 时间线:
- 截止2014年,哈佛、麻省理工、伯克利、卡内基等美国顶尖高校将Python作为教学语言;
- 2018年开始,Python雄踞各大年度最佳编程语言排行榜榜首(IEEE, TIOBE);
- 空间线:
- Python特性:动态、解释、脚本、跨平台...
- 解释器:cpython,jpython,ipython,jit
- Python2,3特性
思路串联2:
Python特性(解释、动态、脚本)-> 当前发展-> 解释器及性能优化 -> 埋下一个问题引子
示例答案2:
Python语言和C++, Java等其他编译型语言不一样,它是一种动态解释型脚本语言,代码在执行时会一行一行的解释成CPU能理解的机器码。同时它又是跨平台的,可以允许在windows,linux,mac等系统上,同样的程序逻辑,可能C语言需要1000行代码,java有100行,而Python实现可能只需要20行,这极大程度上提升了企业的项目开发效率。
记得之前看到一篇报道说,到2014年为止,哈佛、麻省理工、伯克利等顶尖高校都已经使用Python作为教学语言,而最近这一两年来Python也多次被各大机构评为年度最佳编程语言。对于企业项目后台开发而言,不是说一定需要使用Python开发,但至少应该是一个首选考虑项,当然Python本身从根本上来说性能是比不上C/C++这些编译型语言,但现在语言本身的性能差距在实际开发的过程中,相对业务功能合理性设计、代码编写架构质量等等,语言底层本身造成的性能损失越来越可以忽略不计;针对于一些特定的功能模块,Python当前也出现了pypy,JIT等大幅提高Python程序运行效率的相关技术,能够满足大多数功能需求业务场景。
具体选用Python后,新项目推荐使用python3,2008年Python3发布后,十几年来Python3生态圈三方库已经非常完备和齐全,而官方已宣布Python2在2020年将不再维护,另外Python3本身性能也相较Python2有一定的提升;
回答思路3:
- 空间线:
- 语言的本质
- Python行业发展(人工智能、云计算、大数据...)
- Python开源生态圈
- Python2,3特性
思路串联3:
语言进化 -> 语言本质 ->Python当前发展(应用产业及开源生态圈)-> 留下一个问题引子(此思路不说Python缺陷,留下两个下一问题引子)
示例答案3:
恩...这个问题我是这么看的,上世纪60年Unix诞生时,贝尔实验室是使用的B语言,解决了面向机器的汇编语言极其复杂问题,然后到72年,面向过程的C语言出现,再到95年Java诞生,面向对象的思想极大的提升了程序猿的开发效率。2000年第一个稳定的Python2版本,20年来其简单高效的特质大大降低了研发人员的学习和开发成本;
编程语言的本质是人与机器沟通的工具,将人类希望机器做的事翻译成机器本身能够理解的指令;语言发展进化的历史也已经表明,越符合人类自身思维逻辑及习惯的编程语言将越受到大众欢迎。目前从云端、客户端,到物联网终端,python应用无处不在,同时也是人工智能首先的编程语言(Python在在人工智能上的优势至今无人能够撼动)。Python当前也已经具备了非常完备丰富的开源三方生态圈(比如web框架tornado,sanic, 运维监控zabbix,游戏引擎firefly等等不胜枚举)。对于大多数企业新后台项目开发,个人倾向于推荐Python作为首选语言。
具体选用Python后,新项目推荐使用python3,2008年Python3发布后,十几年来Python3生态圈三方库已经非常完备和齐全,而官方已宣布Python2在2020年将不再维护,另外Python3本身性能也相较Python2有一定的提升;
进程、线程、协程、并行、并发
进程
进程:
- 资源分配和调度的基本单位
- 一个运行的程序
- 独立的内存空间
- 父子进程:fork时复制逻辑地址 物理地址=基址+逻辑地址
- copy on write
适用场景:CPU密集型任务
缺陷:
- 创建和切换代价高
- 进程间通信效率相对较低
- 资源消耗大
线程
线程:
- 系统运算调度的最小单位
- 依赖进程存在:主线程、内核线程、用户线程
- 资源共享
适用场景:CPU密集型任务
缺陷:
- 频繁线程切换代价高
- 线程安全(GIL)
如果某些资源不独享会导致线程运行错误,则该资源就由每个线程独享,而其他资源都由进程里面的所有线程共享。
线程共享资源 | 线程独享资源 |
---|---|
地址空间 | 程序计数器 |
全局变量 | 寄存器 |
打开的文件 | 栈 |
子进程 | 状态字 |
闹铃 | |
信号及信号服务程序 | |
记账信息 |
寄存器---》cache---》内存---》外存(硬盘)---》外设
协程
- 产生背景:先于线程产生,但不符合当时自顶向下的程序设计思想,不流行
- 微线程:轻量级线程,协程的调度完全由用户控制
- 运作机制:协程调度切换时,将寄存器上下文和栈保存到其他地方,在切回来的时候,恢复先前保存的寄存器上下文和栈,直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量,所以上下文的切换非常快
适用场景:多进程+协程
优势:
- 省去大量线程切换开销
- 单线程运行,无需加锁
并行、并发
Parallel(并行):同一时刻执行多个任务,并行库multiprocessing
Concurrency(并发):在同一时间间隔内多个任务都在运行,但是并不会在同一时刻同时运行,存在交替执行的情况,并发库threading
程序需要执行较多的读写、请求和回复任务的需要大量的 IO 操作,IO 密集型操作使用并发更好。CPU 运算量大的程序程序,使用并行会更好。