Python 面试题
点击这里关注GitHub,期待您的参与!
-
什么是 Python?使用 Python 有什么优缺点?
Python是一种计算机程序设计语言。是一种动态的、面向对象的脚本语言。
- 好处:
- 简单易学。
- 代码开源,自由度高,高度可定制化。
- 可移植性强。
- 丰富的库,开发效率高。
- 可扩展性和可嵌入性,被称作胶水语言。
- 面向对象、模块、线程、异常处理和自动内存管理。
- 代码简洁规范,可读性强。
- 好处:
-
Python是如何被解释的?
Python 是一种解释性语言,它的源代码可以直接运行,Python 解释器会将源代码转换成中间语言,之后再翻译成机器码再执行。
-
__new__
和__init__
区别?__new__
是一个静态方法,__init__
是一个实例方法。__new__
返回一个创建的实例,__init__
什么都不返回。__new__
返回一个 cls 的实例时后面的__init__
才能被调用。
当创建一个新实例时调用__new__
,初始化一个实例时调用__init__
。
-
什么是深浅拷贝?
- 浅拷贝只是增加了一个指针指向一个存在的地址。
- 深拷贝是增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存。
- 采用浅拷贝的情况,释放内存,会释放同一内存,深拷贝就不会出现释放同一内存的错误。
-
什么叫做 RabbitMQ?作用是什么?有何特点?
- 概念:
- RabbitMQ(Rabbit Message Queue):表示服务器由 Erlang 语言编写,支持多种客户端的应用,利用在应用程序对应用程序的通信的一种方法。是一种消息队列机制。
- 作用:
- 分布式系统中存储转发消息。
- 管理应用界面。
- 保证解耦、冗余(存储)、扩展性、可恢复性、顺序保证、缓冲和异步通信。
- 特点:
- 可靠性,持久化、传输确认、发布确认。
- 灵活的路由,多个交换器可以绑定。
- 扩展性,可以组成集群。
- 高可用性,队列镜像。
- 多种协议,AMPQ、STOMP、MQTT。
- 多语言客户端,支持所有常用语言。
- 管理界面。
- 插件机制。
- 概念:
-
什么是装饰器?
装饰器其实是一个闭包函数,为其他函数添加附加功能,不修改被修改的源代码和不修改被修饰的方式,装饰器的返回值也是一个函数对象。比如:插入日志、性能测试、事物处理、缓存、权限验证等,有了装饰器,就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
-
什么是闭包?闭包有何特点?
- 闭包(Closure):
- 词法闭包(Lexical Closure)的简称,是引用了自由变量的函数。这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外。所以,闭包是由函数和与其相关的引用环境组合而成的实体。
- 特点:
- 必须有一个内嵌函数。
- 内嵌函数必须引用外部函数的变量(该函数包含对外作用域而不是全局作用域名字的引用)。
- 外部函数的返回值必须是内嵌函数。
- 闭包(Closure):
-
什么是迭代器与生成器?有何关系?
- 迭代器:可以被 next() 函数调用并不断返回下一个值的对象称为迭代器(Iterator)。
- 生成器:在 Python 中的一种一边循环一边计算的机制,称为生成器(Generator)。
注意:生成器也是迭代器,调动 next 把函数变成迭代器。
- 关系:
- 迭代可迭代对象对应
__iter__
(方法)和迭代器对应__next__
(方法)的一个过程。 - 生成器:包括含有 yield 这个关键字,生成器也是迭代器,调动 next 把函数变成迭代器。
- 迭代可迭代对象对应
-
解释 classmethod、staticmethod 和 property。
- classmethod:又叫类方法,将类的函数转换成类方法,函数上装饰 @classmethod 会将函数的自动传值参数改成 cls。
- staticmethod:又叫静态方法,将被装饰的函数从类中分离出来,该函数不能访问类的属性,简单说可以将该函数理解为一个独立的函数,不允许使用 self。
- property:又叫属性方法,通过 property 装饰器控制类的属性的绑定与获取,一般就是给某个属性增加一个验证类型等功能。
-
试解释多 GIL、进程、线程、多进程、多线程和协程。
- GIL(Global Interpret Lock):全局解释器锁,是锁在 CPython 解释器上,导致同一时刻,同一进程只能有一个线程被执行。
- 进程:是资源管理单位,进行是相互独立的,实现并发和并发。
- 线程:是最小的执行单位,线程的出现为了降低上下文切换的消耗,提供系统的并发性。
- 多进程:多进程模块 multiprocessing 来实现,CPU 密集型,IO 计算型可以用多进程。
- 多线程:多线程模块 threading 来实现,IO 密集型,多线程可以提高效率。
- 协程:依赖于 geenlet,对于多线程应用。CPU 通过切片的方式来切换线程间的执行,遇到 IO 操作自动切换,线程切换时需要耗时,而协成好处没有切换的消耗,没有锁定概念。
-
什么叫做 IO 多路复用/异步非阻塞?
- IO 多路复用:通过一种机制,可以监听多个描述符 select/poll/epoll。
- select:连接数受限,查找配对速度慢,数据由内核拷贝到用户态。
- poll:改善了连接数,但是还是查找配对速度慢,数据由内核拷贝到用户态。
- epoll:epoll 是 linux下 多路复用 IO 接口,是 select/poll 的增强版,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。
- 异步非阻塞:异步体现在回调上,回调就是有消息返回时告知一声儿进程进行处理。非阻塞就是不等待,不需要进程等待下去,继续执行其他操作,不管其他进程的状态。
- IO 多路复用:通过一种机制,可以监听多个描述符 select/poll/epoll。
-
什么是 PEP8 规范?具体有何内容?
- PEP8 规范是 Python 创始人 Guido 根据 Python 特性,为了增加代码可读性,维护代码编码风格一致性,减少代码模糊与冲突而规定的规范。
- 内容:
- 每一级缩进使用4个空格。
- 所有行限制的最大字符数为79。
- 顶层函数和类的定义,前后用两个空行隔开。
- 注释规范。
- 文件命名规范。
- ···
-
简述 range 和 xrange 的区别?
都在循环时使用,xrange 内存性能更好,xrange 用法与 range 完全相同,range 生成一个生成 list 对象,xrange 生成生成器。
-
简述 with 的上下文机制原理。
with expression [as variable]: with-block
上面表示的是 with 语句的书写常见书写方式。其中 expression 是一个上下文管理器,其实现了
__enter__
和__exit__
两个函数。当我们调用一个 with 语句时,执行过程如下:- 首先生成一个上下文管理器 expression。
- 然后执行
expression.__enter__()
。如果指定了 [as variable] 说明符,将__enter__()
的返回值赋给 variable。 - 执行 with-block 语句块。上例中执行读取文件。
- 执行
expression.__exit__()
,在__exit__()
函数中可以进行资源清理工作。
-
经典类和新式类有何区别?
- 经典类遵循深度优先,存在 Python2 中。
- 新式类遵循广度优先,存在 Python3 中。
-
有没有一个工具可以帮助查找 Python 的 bug 和进行静态的代码分析?
有。PyChecker 是一个 Python 代码的静态分析工具,它可以帮助查找 Python 代码的 bug,会对代码的复杂度和格式提出警告,Pylint 是另外一个工具可以进行 codingstandard 检查。
-
Python 是如何进行内存管理的?
-
对象引用计数:
- 引用计数增加的情况:
- 来保持追踪内存中的对象,所有对象都用引用计数,一个对象分配一个新名称。
- 将其放入一个容器中(列表,字典,元祖)。
- 引用计数减少的情况:
- 使用 del 语句对对象别名显示的销毁。
- 引用超出作用域或被重新赋值。
- sys.getrefcount() 函数可以获得对象的当前引用计数。
- 引用计数增加的情况:
-
标记-清除机制
-
分代技术
-
-
什么是 pickling 和 unpickling?
这是来自 Pickle 模块的两个方法,读入任何 Python 对象,用 pickling 将它们转换成序列化字符串,反之从存储的序列化字符串文件中提取原始 Python 对象的过程,叫做 unpickling。
-
列表、元祖和字典之间的区别是什么?
- 列表:list,是处理一组有序项目的数据结构,可以在一个列表中存储一个序列的项目,不可哈希。
- 元祖:tuple,元祖和列表十分相似,不过元祖是不可变的。即你不能修改元祖,可哈希。
- 字典:dict,是一种存储键值对的数据结构,可以通过键来取值,不可哈希。
-
参数按值传递和引用传递是怎么实现的?
Python 中的一切都是类,所有的变量都是一个对象的引用。引用的值是由函数确定的,因此无法被改变,但是如果一个对象是可以被修改的,你可以改动对象。