1、Python与其他语言(如Java/C++)的核心区别是什么?
Python是动态类型的解释型语言,语法简洁,支持多种编程范式(面向对象、函数式、过程式)。与Java相比, Python无需编译且语法更简洁;与C++相比,Python开发效率高但运行速度较慢,且通过解释器执行而非直接编译为机器码。
2、列表和元组的核心区别是什么?
列表可变 ,用[]定义 ,适用于动态数据集合(如增删元素);
元组不可变 ,用()定义 ,适用于固定数据(如字典键或配置项) ,且内存占用更小。
3、在异常处理中 ,else和finally块分别何时执行?举例说明其适用场景。
else在无异常时执行(如资源初始化成功后的操作);
finally无论是否异常均执行(如释放文件锁)。
4、解释 Python 中的三元表达式
与 C++不同, 在 Python 中我们不需要使用?符号 ,而是使用 如下语法:
[on true] if [expression]else [on false]
如果 [expression] 为真, 则 [on true] 部分被执行 。如果表示为假则 [on false] 部分被执行
5、Python的可变类型和不可变类型?
(1)不可变类型 :指一旦创建 ,其值就不能被修改的类型。 当对不可变类型的数据进行操作时 ,实际上是创建了一个新的对象。Python 中常见的不可变类型有:数字(Number):包括整数(int)、浮点数(float)、复数( complex);
(2) 可变类型:指在创建后,其值可以被修改的类型。对可变类型的数据进行操作时,是在原对象上进行修改 ,不会创建新的对象。 Python 中常见的可变类型有 :列表、字典、集合
6、解释装饰器的作用及典型应用场景
装饰器用于在不修改原函数代码的情况下扩展功能(如日志记录、性能统计、权限校验)。通过闭包实现,接收函数作为参数并返回增强后的函数。例如缓存装饰器可优化递归性能。
7、__new__和__init__的区别是什么?
__new__是类方法 ,负责创建实例并返回;
__init__是实例方法 ,负责初始化实例属性。重写__new__常用于单例模式或不可变对象定制。
8、深拷贝与浅拷贝的区别是什么?
浅拷贝( copy.copy)仅复制对象外层引用,若对象包含可变元素(如嵌套列表),修改拷贝对象会影响原对象。深拷贝( copy.deepcopy)递归复制所有层级元素 ,完全独立于原对象。
9、什么是闭包? Python中如何实现?
闭包是嵌套函数捕获外层作用域变量的机制。例如计数器函数可通过闭包保留计数状态 ,而无需全局变量。
在Python中,迭代器(Iterator)是— 个可以迭代访问序列元素的对象。迭代器对象实现了两个方 法:__iter__()和__next__()。__iter__()方 法返回迭代器对象本身 ,__next__()方 法返回下— 个元素。
迭代器常用于遍历序列、集合、字典等容器类型数据。它的优点是可以惰性计算(lazy evaluation) ,即只有在需要时才会计算 ,避免了一次性加载所有数据的开销, 同时也可以节省内存空间。
在Python中 ,使用 迭代器通常有以下场景:
(1)遍历大 量数据集合: 当需要处理大 量的数据集合时 ,使用 迭代器可以避免— 次性加载所有数据,节省内存空间。
(2)实现自定义迭代器: 当需要遍历自定义数据结构时 ,可以通过实现迭代器对象的__iter__()和__next__()方法实现自定义迭代器;
(3)实现惰性计算:当需要进行惰性计算时 ,可以使用迭代器来实现,例如通过filter()、map()等高阶函数返回一个迭代器对象来进行惰性计算。
下面 是— 个使用 迭代器遍历列表的例子 :
my_list = [1, 2, 3, 4, 5]
my_iterator = iter (my_list)
while True:
try:
item = next (my_iterator)
print (item)
except StopIteration:
break
10、Python生成器是什么?什么场景用到生成器?举一个例子?
在Python中 ,生 成器( Generator)是— 种特殊的迭代器 ,它使用生 成器函数来生 成序列中的元素 ,而 不是在内存中— 次性生 成所有元素。
生成器函数是使用 yield关键字定义的函数 ,每次调用 生 成器函数时 ,它会返回— 个迭代器对象,调用 next()方 法时, 它会从上次暂停的位置继续执行 ,直到遇到下— 个yield语句 ,然后返回— 个值 ,并再次暂停。 因此, 生 成器可以惰性地生 成序列中的元素 ,并在需要时逐个生 成元素 ,避免了— 次性生 成所有元素所带来的内存消耗。
使用 生 成器的场景包括:
(1) 生 成大 量的数据集合: 当需要生 成大 量数据时 ,使用生 成器可以避免— 次性占用大 量内存空间;
(2)实现自 定义的迭代器 :当需要自 定义迭代器对象时 ,可以使用 生 成器函数来实现 ,避免了繁琐的迭代器对象的定义;
(3)实现惰性计算:当需要进行 惰性计算时 ,可以使用 生 成器来实现 ,例如通过filter()、map()等高 阶函数返回— 个生 成器对象来进行 惰性计算。
下面 是— 个使用生 成器函数生 成斐波那契数列的例子 :
def fibonacci (n) :
a, b = 0, 1
for i in range (n):
yield a
a, b = b, a + b
fib = fibonacci (10)
for num in fib:
print (num)
在这个例子 中,我们定义了— 个生 成器函数fibonacci(),它的参数n表示需要生 成的斐波那契数列的长 度。在函数中 ,我们使用 yield语句返回斐波那契数列中的每— 个元素 ,这样每次调用 next()函数时, 它会返回下—个元素 ,并在下次调用 时从上次暂停的位置继续执行 。最后 ,我们使用for循环遍历生 成器对象 ,并打印出每个元素。
11、Python多线程与多进程的区别
在UNIX平台上,当某个进程终结之后,该进程需要被其父 进程调用 wait,否则进程成为僵尸 进程 (Zombie)。所以 ,有必要对每个Process对象调用join()方 法 (实际上等同于wait)。对于多线程来说, 由于只有— 个进程 ,所以不存在此必要性。
多进程应该避免共享资源。在多线程中,我们可以比 较容易地共享资源,比 如使用 全局变量或者传 递参数。在多进程情况下, 由于每个进程有自 己 独立 的内存空间 ,以上方 法并不合适。此时我们可 以通过共享内存和Manager的方 法来共享资源。但这样做提高 了程序的复杂度 ,并因为同步的需要 而 降低了程序的效率
12、装饰器的实质是什么?
或者说为什么装饰器要写2层嵌套函数,里 层函数完全就已经实现了装饰的功能为什么不直接用里 层函数名作为装饰器名称?
答 :装饰器是要把原来的函数装饰成新的函数 ,并且返回这个函数本身的高阶函数
13、Python下多线程的限制以及多进程中传递参数的方式
python多线程有个全局解释器锁(global interpreter lock) ,这个锁的意思是任—时间只能有— 个线程使用 解释器 ,跟单cpu跑多个程序— 个意思, 大 家都是轮着用 的 ,这叫“并发”,不是“并行 ”。
多进程间共享数据 ,可以使用 multiprocessing.Value 和 multiprocessing.Array
14、Python是如何进行内存管理的?
Python引用 了— 个内存池(memory pool)机制 ,即Pymalloc机制(malloc:n.分配内存) ,用 于管理对小 块内存的申请和释放内存池( memory pool) 的概念:
当创建大 量消耗小 内存的对象时 ,频繁调用 new/malloc会导致大 量的内存碎片 ,致使效率降低。 内存池的概念就是预先在内存中申请— 定数量的 ,大小 相等 的内存块留作备用 ,当有新的内存需求时 ,就先从内存池中分配内存给这个需求 ,不够了之后再申请新的内存。这样做最显著的优势就是能够减少内存碎片 ,提升效率。
内存池的实现方 式有很多 ,性能和适用 范围也不— 样。 python中的内存管理机制——Pymalloc:
python中的内存管理机制都有两套实现,— 套是针对小 对象,就是大小 小 于256bits时,pymalloc会在内存池中申请内存空间; 当大 于256bits ,则会直接执行 new/malloc的行 为来申请内存空间。
关于释放内存方面 ,当— 个对象的引用 计数变为0时 ,python就会调用 它的析构函数。在析构时,也采用了内存池机制 ,从内存池来的内存会被归还到内存池中, 以避免频繁地释放动作。
15、Python里面如何拷贝—个对象?
标准库中的copy模块提供了两个方 法来实现拷贝 . — 个方 法是copy,它返回和参数包含内容— 样的对象,使用deepcopy方法,对象中的属性也被复制
16、Python里面search()和match()的区别?
match()函数只检测re是不是在string的开始位置匹配, search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回 ,如果不是开始位置匹配成功的话, match()就返回none。
17、lambda表达式格式以及应用场景?
lambda函数就是可以接受任意多个参数(包括可选参数)并且返回单个表达式值得函数。
语法:
lambda [arg1 [,arg2, argn]]:expression
应用 :
1) lambda函数比 较轻便, 即用 即仍 ,适合完成只在— 处使用 的简单功能。
2) 匿名函数, — 般用 来给filter, map这样的函数式编程服务
3)作为回调函数 ,传递给某些应用 , 比 如消息处理。
18、*args和**kwarg作用
*args代表位置参数, 它会接收任意多个参数并把这些参数作为元组传递给函数。
**kwargs代表的关键字参数 ,允许你使用 没有事先定义的参数名。位置参数— 定要放在关键字参数的前面 。
作用 :
使用 *args和**kwargs可以非 常方 便的定义函数, 同时可以加强扩展性, 以便日 后的代码维护。