最近刷牛客网的时候,我发现一个很有意思的现象。
以前,Python面试喜欢问:
list和tuple有什么区别?
深拷贝和浅拷贝有什么区别?
而现在,越来越多的大厂开始问:
Python为什么会有GIL?
为什么dict查找这么快?
Python对象为什么要维护引用计数?
阿里巴巴、美团、字节跳动、百度、微软、Oracle、Google……不少公司的Python岗位,开始把重点放在底层原理上。
很多人不理解。
AI都能写代码了,为什么还要考这些?
恰恰相反。
AI越强,底层能力反而越值钱。
📌 今日面试题
为什么Python的列表(list)扩容不是每次只增加一个元素,而是一次扩容一大块内存?
如果你回答:
为了提高性能。
面试官一般会继续问:
为什么这样就能提高性能?
这时候,真正的考验才开始。
一个很多人忽略的细节
来看一段再普通不过的代码。
nums = []for i in range(100000): nums.append(i)
很多人觉得:
每执行一次 append(),
Python就在后面加一个元素。
实际上,并不是。
如果真这样做,会发生什么?
假设列表容量已经满了。
此时新增一个元素,
Python必须:
如果每次 append() 都这样操作,
十万个元素,
就意味着十万次内存搬家。
性能几乎无法接受。
所以,
Python选择了另一种策略。
Python的答案:提前"囤空间"
Python列表采用的是**预分配(Over-allocation)**策略。
什么意思?
假设当前只能放8个元素。
当第9个元素到来时,
它不会只申请一个位置。
而是一次性申请更多空间。
比如:
8 → 16 → 25 → 35 → 46……
(具体扩容策略会随着CPython版本调整,但核心思想始终一致。)
为什么?
一句话:
用少量内存,换大量时间。
于是,
绝大多数 append(),
都只是简单放进去。
不用频繁搬家。
所以,
Python官方文档才会说:
list.append() 的平均时间复杂度接近 O(1)。
注意。
这里依然是:
平均(Amortized O(1))。
不是绝对O(1)。
🤔 面试官最喜欢追问
既然列表这么快,为什么还要有deque?
很多人开始犹豫。
其实答案很简单。
列表:
适合尾部插入。
效率极高。
但是:
每次都要移动后面的所有元素。
时间复杂度:
O(n)。
而:
collections.deque
采用双端队列结构。
头尾插入删除,
都是:
O(1)。
所以,
没有最好的数据结构。
只有最适合场景的数据结构。
这,
也是大厂真正想考察的能力。
AI时代,一个越来越重要的能力
很多开发者都有一种错觉。
AI出现以后,
算法和底层是不是不重要了?
我反而认为:
重要性更高了。
为什么?
因为AI已经帮你解决了:
"怎么写"。
未来真正决定竞争力的,
是:
"为什么这样写。"
举个例子。
AI当然能写:
但如果:
一天处理一亿条日志。
一个接口每秒几十万次调用。
一个Agent同时管理几千个任务。
这时候,
你还会不会选择list?
什么时候该换deque?
什么时候该用set?
什么时候应该改成生成器?
这些,
AI不会替你做架构决策。
真正做决策的人,
还是工程师。
一个容易被忽略的事实
很多人喜欢刷Python八股。
今天背GC。
明天背协程。
后天背GIL。
看似学了很多。
真正写项目时,
依然不知道什么时候该用。
为什么?
因为知识点没有连起来。
其实你会发现:
Python很多设计,
都遵循同一个原则。
看似毫无关系。
其实背后,
都是工程上的权衡。
真正优秀的程序员,
学习的不是API。
而是:
设计哲学。
💡 我的观点
这些年,我越来越不建议大家死记硬背Python面试题。
因为真正的大厂,
考的已经不是:
"你背没背过?"
而是:
"你有没有自己的理解?"
AI时代,
知识越来越廉价。
思考越来越昂贵。
如果别人问:
"为什么Python列表要扩容?"
你的回答只是:
"因为快。"
那么,
AI也能回答。
但如果你能够继续分析:
那么,
你已经不是在回答一道面试题。
而是在展示自己的工程思维。
我一直认为:
未来真正稀缺的开发者,
不是写代码最快的人。
而是能够理解每一个技术决策背后原因的人。
因为,
代码会过时,框架会更新,AI会迭代。
唯独底层思维,
会一直陪伴你的职业生涯。
📚 今日知识总结
✅ Python列表采用连续内存存储,因此支持高效随机访问。
✅ append() 并非每次扩容,而是采用预分配策略,实现均摊 O(1)。
✅ insert(0) 和 pop(0) 需要移动元素,效率较低。
✅ deque 更适合频繁头尾操作。
✅ 真正的大厂面试,不只是考数据结构,更是在考工程思维。
💬 留一道Google风格的思考题
如果让你重新设计Python的list,
你还会采用连续内存吗?
还是会选择链表、跳表、B+树,或者其他结构?
为什么?
欢迎在评论区聊聊你的答案。
真正的成长,不是记住1000道面试题,而是学会追问1000个"为什么"。
🚀关注我,每天拆解一道Python大厂高频面试题。从Python语法,到CPython底层;从AI工程,到软件设计。愿我们一起,把技术学深,而不是学碎。