- *args, **kwargs 是什么意思?
args: 可变位置参数。 *kwargs: 可变关键字参数。
- 谈一谈 Python 中的装饰器
Python中的装饰器其实也是一种函数, 它可以在不修改原函数代码情况下扩展原函数功能。装饰器函数与普通函数不同之处就在于装饰器函数返回了一个函数对象,装饰器利用了闭包的原理来实现。主要用于日志插入,权限管理等等。
- Python 的垃圾回收机制以及内存管理
垃圾回收机制: Python的垃圾回收机制以引用计数为主, 标记清除、分代回收为辅。
引用计数指:Python在内部维护了针对每一个对象的引用计数, 当一个对象创建或者被引用时,其引用计数将加1,当一个对象被销毁或作用域失效时, 其引用计数将减1。只有对象的引用计数为0时,这个对象将会被回收。
引用计数的优点:简单、具有实时性。
缺点:对象循环引用时将永远不会被销毁。对于对象循环引用的状况Python使用标记清除来解决,Python在内部实现了一个循环检测器, 不停的检测对象是否存在循环引用,如果两个对象互相循环引用并且不包含其他第三者对象时, 其将会被收回。在Python参考手册中有写道: 当一个对象无法获取时, 那么这个对象有可能被当成垃圾销毁了。Python将所有对象分成了三代, 对象存活时间越长就越晚被回收, 反之则越早被回收。
内存管理: Python使用了内存池机制来管理内存,其内存以金字塔的形式对内存功能进行划分,-1、-2层主要用于对操作系统进行操作, 0层中是C的malloc,、free等等内存分配和释放函数。1、2层是一个内存池, 当对象小于265K时将直接由这片内存池进行分配内存,否则将调用第0层中的C函数来分配内存,当小于265K的对象被销毁时, 其内存也不会被销毁, 只是返回给了内存池以便二次利用。2层是对Python对象进行操作。
- Python 多线程是什么?
Python中多线程由于有GIL的影响, 导致在任意时间内只有一个线程在运行,所以Python的多线程在处理计算密集型任务上效果反而不如单线程, 只有在处理IO密集型任务上多线程才能发挥实力,在等待IO过程中Python C源码会释放GIL, 最终会导致线程在等待IO过程中会被暂停去执行其他的线程。python中GIL主要是由于历史原因导致Cpython虚拟机中的GIL难以移除,同时GIL的存在保证了多线程之间数据完整性以及状态同步。
- 说明 os、sys 模块不同,并列举常用的模块方法
os: 提供了对使用操作系统函数的高度封装
sys: 提供由解释器访问或者维护的变量以及与解释器交互的一些函数
os模块只负责程序与操作系统交互, 提供了访问操作系统底层的接口封装。 sys模块负责程序与解释器交互, 提供了一系列的函数用于操控Python运行的环境设置。
os模块常用方法: os.getcwd() # 获取当前运行路径 os.remove() # 删除指定的文件 os.walk() # 生成指定目录下的文件夹以及文件 os.makedirs() # 生成多成目录 os.mkdir() # 生成目录 os.rmdir() # 删除指定目录 os.removedir() # 删除多层目录 os.listdir() # 列出指定目录下所有的文件夹以及文件 os.path.join() # 将分离的各部分组合成一个路径名 os.path.getsize() # 获取指定文件大小 os.path.exists() # 查看指定目录或者文件是否存在 os.path.isabs() # 查看指定目录是否为绝对路径 ... sys模块常用方法: sys.argv# 命令行参数列表 sys.exit() # 退出程序并返回指定的整数 sys.maxunicode # 最大的Unicode值 sys.modules # 系统导入的模块名称 sys.path # python搜索模块时的路径 sys.stdout # 标准输出 sys.stdin # 标准输入 sys.stderr # 错误输出 …
- 什么是 lambda 表达式?它有什么好处?
lambda也是函数的一种, 在处理一些简单的操作时可以使用该表达式, 其好处是不用为一些实现简单功能的函数命名,毕竟编程只有两个难点: 缓存失效, 命名。
- Python 里面如何拷贝一个对象?
Python中拷贝分为深拷贝、浅拷贝。浅拷贝只拷贝父级对象, 不会拷贝对象内部的子对象,使用copy模块中的copy。深拷贝则会完全拷贝父对象以及子对象, 使用copy模块中的deepcopy。
- new 和 init 的区别。
new负责构建一个类对象并将其返回,init则负责初始化一些变量,不返回任何对象。在实例化一个类时, new方法将会先被运行, 其次才运行init方法。
- Python 中协程?
Python中协程最初使用yield来实现, 当程序运行到yield语句时就会将控制权交出来去执行其他的函数, 在Python3之前只能通过原生yield、greenlet以及Gevent第三方库来实现协程, 在Python3 之后引入了yield from, yield from 用于重构生成器。在Python3.5之后引用了async和await, 其作为yield from, yield的完美替身来实现协程。
- Python 的异常机制?
Python中异常也是一个对象, 所有的异常的基类都是Exception。捕获异常使用try...except....语法,如果要try与except之间的代码出现了错误并且我们将其异常类型捕获了那么代码将会跳转代except中去执行。还可以使用raise 去手动的触发一个错误,也可以使用assert来触发异常, 只不过assert经常用来在测试中, 并且assert对程序的性能有着极大影响,只有内置的debug为True时assert才会执行。
- Python 旧式类(经典类)和新式类的区别?
经典类与新式类的区别是:继承搜索的顺序发生了改变,经典类多继承搜索顺序是深度优先, 按照从左至右的查找,并且将每一个父类的基类都查找一遍。新式类则是, 先从左至右的查找, 然后再向每一个父类的基类进行查找。(都是从左至右的顺序查找, 经典类查找一个父类时同时向上查找,新式类则是先查找所有的父类然后再向上查找)
- classmethod, staticmethod, property 是什么?有什么作用?
lassmethod,staticmethod,property都是装饰器, 他们都作用在类的方法上。
classmethod:使得被装饰的方法成为一个类方法既不需要实例化类就可以直接调用的方法,第一个参数为cls。
staticmethod: 使得被装饰的方法成为一个静态函数既与普通的函数无区别。 property: 将一个方法变成一个属性来使用。
13 Python 中的绑定方法和未绑定方法是什么?
绑定方法:绑定了实例化的方法既第一个参数是self
未绑定方法:没有绑定实例化的方法既类方法、静态方法
- Python 上下文管理器是什么?
Python中上下文管理器使用with来调用主要用于数据库连接,文件操作, 网络操作。 其作用是: 如果在进行一些打开资源操作时出现了异常,上下文管理器将会自动的执行一些资源清理操作。在进入上下文管理器时, Python会先调用对象的enter方法, 该方法返回一个对象用于进行一些操作,如果在进行一些操作时发生了异常Python则调用exit该对象接受三个参数第一个参数异常类,第二个参数异常提示字符串, 第三个参数traceback对象。
- functools 的 wraps 是做什么的?
wraps是一个装饰器功能是: 由于被装饰的函数传入到装饰器中时已经不是原函数了, 而是一个新的函数, 并且丢失一些原函数的属性, 为了不影响函数的使用, 可以使用wraps来抵消这种副作用。
- 请说一说 ORM 实现原理
ORM使用了Python的属性描述符协议实现,通过另外一个类来描述类变量的属性类型, 再给这个属性进行赋值时(对应数据库中的字段名称)会调用set方法,访问属性则会调用get方法删除则调用delete方法。
- 请说一说迭代器和生成器区别?
生成器时一种特殊的迭代器, 生成器自动实现了迭代器协议, 不需要手动的实现iter以及next方法,生成器在迭代的过程中可以改变当前的迭代值, 而普通的迭代器改变当前值时往往会发生错。迭代器必须实现iter以及next方法。
- 描述一下 type() 的作用
当type只传入一个参数时将返回该参数的类型,如果传入了三个参数则返回一个类对象,同时Python中的所有类的基类都是type
- Python 中列表与元组的异同?
相同: 列表和元组都是容器并且是可迭代对象,二者可以包含任意类型的对象。
不同:列表是可变的, 元组是不可变。
- Python 中的列表是如何实现的?
Python中的列表使用了分离式技术实现的动态顺序表。
- Python 中列表的索引查询的时间复杂度是多少?
O(1)
- Python 字典的实现原理?
Python的字典使用了哈希表来储存key、value,当添加一个数据时首先会把key通过哈希函数转换成一个数字, 然后将该数字对存放value的数组长度取余并将取余结果当做数组的下标, 将value存放在该取余结果为下标的数组中。数据查询时将key转换为对应的数组下标,并定位到数组的位置获取value。
- 什么是 pickling 和 unpickling?
Pickle模块读入任何Python对象,将它们转换成字符串,然后使用dump函数将其转储到一个文件中——这个过程叫做pickling,反之从存储的字符串文件中提取原始Python对象的过程,叫做unpickling。
- 有哪些工具可以帮助 debug 或做静态分析?
debug工具:pdb。静态分析工具:pep8 / pycodestyle,Pyflakes,Pylint,flake8,Pysa,pytype,pyright,Pyre等
- Python 中的作用域?
在Python中,一个对象的作用于总是由代码被赋值的地方所决定的。当遇见一个变量时Python会按照: 本地作用域→ 当前作用域被嵌入的本地作用域→ 全局/模块作用域→ 内置作用域顺序搜索。
- Python 的参数传递是值传递还是引用传递?
可变对象使用引用传递, 不可变对象使用值传递
- 写一个函数,输入一个字符串,返回倒序排列的结果
def reverse(text):
return text[::-1]
- Python 中 is 和 == 的区别
is比较的是对象在内存的地址, ==比较的对象中的值
- 什么是 Python 的闭包?
内层函数引用了其外部作用域的变量,然后返回内层函数的情况,称为闭包,创建一个闭包必须满足以下几点:
- 必须有一个内嵌函数
- 内嵌函数必须引用外部函数中的变量,外层空间中被引用的变量叫做层函数的环境变量
- 外部函数的返回值必须是内嵌函数
- 环境变量和内层非全局函数一起构成了闭包
- Python 的自省?
type(),dir(),getattr(),hasattr(),isinstance()
- Python 并发的解决方案。
Twisted是一个事件驱动型的网络引擎,不同于单线程和多线程模式,这种模式不需要过多去关心线程锁的问题,当遇到高并发问题时候,采用twisted会很好解决数据共享的问题。
Tornado既是一个web server,也是web framework。就是说这个web框架有自己内置的web server,在写web时候可以用到它的高性能网络库,甚至有公司拿这个来做游戏的服务器,可以用它处理高并发问题。 Gevent是基于协程的Python网络库,基于libev的快速事件循环,基于greenlet的轻量级执行单元,API的概念和Python标准库一致。
sanic基于uvloop和httptools实现高并发异步网络框架。