大厂 Python常见面试20题(整理版)

1.python的数据结构?
整数(int)
浮点(float)
字符串(str)
布尔(bool)
列表(list)
元组(tuple)
字典(dict)
集合(set)
2.python中列表和元组的区别?
列表:list是可变类型,数据可以动态变化
元组:tuple是不可变类型,数据大小固定
3.什么是生产器、迭代器?二者有何区别?
迭代器:
作用:简化循环的代码并可以节约内存
是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退
迭代器有两个基本的方法:iter() 和 next()。
生成器:
作用:节约大量内存 使用了 yield 的函数被称为生成器、生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器 原理:在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。
4.什么是闭包?什么是装饰器?装饰器作用是?
闭包是指Python中将组成函数的语言和这些语言的执行环境打包到一起所得到的对象
装饰器是一种增加函数或类功能的简单方法,它可以快速给不同的函数或类插入相同的功能。语法:“@装饰器名”加在函数之前.
5.什么是匿名函数?好处?
匿名函数:使用lambda创建的函数,所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。
好处:
1、使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。 2、对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。 3、使用lambda在某些时候让代码更容易理解。 应用场景:经常与一些内置函数相结合使用,比如说map()、filter()、sorted()、reduce()等
表达式格式:lambda 参数列表: lambda体。
6.用过类吗?知道继承吗?请写一个例子,用到继承
7. 深拷贝与浅拷贝
浅拷贝,改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;改变原始对象中为不可变类型的元素的值,不会响拷贝对象。
深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。经过深拷贝后,原始对象和拷贝对象所有的可变元素地址都没有相同的了
8、列举8个常用模块都有那些?
os模块:提供了不少与操作系统相关联的函数.
sys模块:通用工具脚本经常调用命令行参数.
re模块:为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理,正则表达式提供了简洁、优化的解决方案:
random模块:提供了生成随机数的工具。
json模块:提供Python解析json数据的方法,和python格式相互转化的方法
time模块:python中用于处理时间的模块
logging模块:python中关于日志处理的模块
xml模块:python爬虫中用于定位html标签的模块
9.python的垃圾回收机制(了解)
python采用的是引用计数机制为主,标记-清除和分代收集(隔代回收、分代回收)两种机制为辅的策略
计数机制:
Python的GC模块主要运用了引用计数来跟踪和回收垃圾。在引用计数的基础上,还可以通过“标记-清除”解决容器对象可能产生的循环引用的问题。通过分代回收以空间换取时间进一步提高垃圾回收的效率。
标记-清除:
标记-清除的出现打破了循环引用,也就是它只关注那些可能会产生循环引用的对象 缺点:该机制所带来的额外操作和需要回收的内存块成正比。
隔代回收原理:将系统中的所有内存块根据其存活时间划分为不同的集合,每一个集合就成为一个“代”,垃圾收集的频率随着“代”的存活时间的增大而减小。也就是说,活得越长的对象,就越不可能是垃圾,就应该减少对它的垃圾收集频率。那么如何来衡量这个存活时间:通常是利用几次垃圾收集动作来衡量,如果一个对象经过的垃圾收集次数越多,可以得出:该对象存活时间就越长。
10.列表和数组的区别?
列表(List):存储不同类型的元素,并且可以随意增加、删除或修改其中的元素 大小不是固定的
数组(Array):是一种固定大小的数据结构,它只能存储相同类型的元素,其内存空间是连续的、预先分配好的所以数组的访问速度比列表快得多。
11.append()和extend()的区别?
append
方法可以将一个元素添加到列表的末尾。 方法可以将另一个列表中的所有元素添加到当前列表末尾。extend
举个例子:
<<<a = [1, 2, 3]
<<<b = [4, 5, 6]
<<<a.append(b)
<<<print(a)
[1, 2, 3, [4, 5, 6]]
<<<a = [1, 2, 3]
<<<a.extend(b)
<<<print(a)
[1, 2, 3, 4, 5, 6]
12.== 和 is 区别?
在Python中,“==”和“is”是两个不同的操作符,用于比较对象之间的相等性。
"=="操作符用于比较两个对象的值是否相等。它会通过比较对象的内容来判断它们是否相等。例如:
a = [1, 2, 3]
b = [1, 2, 3]
print(a == b) # 输出: True
上述代码中,尽管a和b是两个不同的对象,但它们的值是相等的,所以使用“==”操作符进行比较会返回True。
而"is"操作符则用于比较两个对象是否是同一个对象(在内存中的同一位置)。它会检查两个对象的身份标识是否相同。例如:
a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # 输出: False
上述代码中,尽管a和b的值相等,但它们是两个不同的对象,所以使用“is”操作符进行比较会返回False。
需要注意的是,在Python中,小整数对象[-5, 256]在解释器启动时会被提前创建,并且会被重复使用。因此,对于这个范围内的整数对象,使用“is”操作符进行比较可能会返回True。例如:
a = 10
b = 10
print(a is b) # 输出: True`
但对于大整数对象或其他类型的对象,使用“is”操作符进行比较通常会返回False。因此,在一般情况下,我们应该使用"=="操作符来比较对象的值是否相等。
13.break,continue,pass区别?
break、continue和pass是Python中的三种控制语句,它们的作用不同。
break语句用于跳出循环,即在循环体中遇到break语句时,立即退出循环,不再执行循环体中剩余的语句,继续执行循环后面的语句。
continue语句用于跳过本次循环,即在循环体中遇到continue语句时,立即跳过本次循环,继续执行下一次循环。
pass语句用于占位,即在程序中需要一个语句,但暂时不需要执行任何操作时,可以使用pass语句占位,使程序不会出错。
14.局部变量和全局变量区别?
局部变量和全局变量是Python中的两种不同的变量作用域。
局部变量是在函数内部定义的变量,其作用范围仅限于函数内部。当函数执行结束后,局部变量会被销毁,无法在函数外部访问。
全局变量是在函数外部定义的变量,其作用范围可以是整个程序。全局变量可以在程序的任何地方访问和修改。
在函数内部,如果要修改全局变量的值,需要使用关键字global进行声明。否则,如果在函数内部直接对全局变量进行赋值操作,将会创建一个新的局部变量,并不会修改全局变量的值。`
总结来说,局部变量只在定义它们的函数内部可见,而全局变量在整个程序中都可见。
16.xrange和range区别?
xrange用法和range完全一样,不同的是range生成的是一个list对象,而xrange生成的是一个生成器。
在处理很大的数字序列的时候,xrange会比range性能高很多,因为不用一上来就开辟很大的内存空间。
17.什么是装饰器?
给已有函数增加额外功能的函数,它本质上就是一个闭包函数。
装饰器的功能特点:不修改已有函数的源代码;不修改已有函数的调用方式;给已有函数增加额外的功能。
18.什么是GIL?
GIL是python的全局解释器锁,同一进程中假如有多个线程运行,一个线程在运行python程序的时候会霸占python解释器(加了一把锁即GIL),使该进程内的其他线程无法运行,等该线程运行完后其他线程才能运行。如果线程运行过程中遇到耗时操作,则解释器锁解开,使其他线程运行。所以在多线程中,线程的运行仍是有先后顺序的,并不是同时进行。
多进程中因为每个进程都能被系统分配资源,相当于每个进程有了一个python解释器,所以多进程可以实现多个进程的同时运行,缺点是进程系统资源开销大。
19.元组可以作为字典的key嘛?
首先一个对象能不能作为字典的key, 就取决于其有没有__hash__方法。 所以除了容器对象(list/dict/set)和内部包含容器对象的tuple 是不可作为字典的key, 其他的对象都可以。
20.Python 中的多线程和多进程有什么区别?如何实现多线程或多进程?
多线程是在同一个进程中运行多个线程,每个线程都可以执行不同的任务。多进程是在不同的进程中运行多个进程,每个进程都有自己的内存空间和系统资源。在 Python 中,可以使用 threading 模块实现多线程,使用 multiprocessing 模块实现多进程。