最近刷牛客网面经的时候。
看到一道出现频率极高的Python面试题。
问题很简单:
很多同学看到这道题。
心里第一反应都是:
这还不简单?
结果往往答完以后。
面试官继续追问:
为什么生成器更省内存?
yield到底做了什么?
生成器和迭代器是什么关系?
然后。
空气突然安静。😅
说实话。
这类问题才是大厂最喜欢问的。
因为考察的不是背诵能力。
而是对Python运行机制的理解。
先来看一个例子
很多人这样创建数据:
nums = [i for i in range(10000000)]
有没有问题?
能运行。
完全没问题。
但问题是:
这一行代码可能直接占用几百MB内存。
如果数据量再大一点。
甚至可能让程序崩掉。
而如果换成:
nums = (i for i in range(10000000))
情况就完全不同了。
为什么?
因为:
列表一次性生成全部数据。
生成器按需生成数据。
这就是本质区别。
什么叫按需生成?
举个生活中的例子。
列表像什么?
像自助餐。
所有菜全部摆在桌子上。
你一次性看到全部内容。
好处是:
拿取速度快。
坏处是:
占地方。
成本高。
生成器呢?
像现点现做。
你要一份。
厨师做一份。
你再要。
他再做。
优点是:
几乎不占库存。
缺点是:
每次都需要重新制作。
看到这里。
其实很多人已经理解了。
为什么大厂特别喜欢考生成器?
因为它背后体现的是:
工程思维
举个例子。
假设你需要处理:
如果全部读入内存。
服务器直接爆炸。
💥
而生成器的方式:
def read_log(): with open(”log.txt”) as f: for line in f: yield line
此时。
程序只会读取当前需要处理的一行。
内存占用几乎恒定。
这才是真正的工程方案。
yield 到底干了什么?
这是字节跳动非常喜欢追问的问题。
很多人会回答:
yield返回数据。
不完全对。
准确地说:
yield会暂停函数执行。
保存当前状态。
等待下一次继续运行。
例如:
def func(): print(”A”) yield 1 print(”B”) yield 2
执行:
输出:
再次执行:
输出:
注意。
函数没有重新开始。
而是从上次暂停的位置继续执行。
这才是yield最神奇的地方。
谷歌工程师特别喜欢的一种思维
很多人写程序喜欢问:
怎么实现?
而优秀工程师更喜欢问:
为什么这样设计?
生成器为什么出现?
答案其实很简单。
因为内存永远是有限的。
数据却越来越大。
早些年。
百万级数据已经很大。
今天呢?
日志系统。
AI训练数据。
用户行为数据。
动辄TB级。
甚至PB级。
如果没有生成器思想。
很多系统根本无法运行。
AI时代,生成器反而更重要了
很多人以为:
AI火了。
生成器这种老知识没用了。
恰恰相反。
越来越重要。
例如:
训练大模型时。
不会一次性把所有数据加载进内存。
而是:
分批读取。
本质上就是一种生成器思想。
包括:
背后都有类似思想。
所以你会发现:
Python基础。
从来不是基础。
而是未来技术的地基。
牛客网上一个有意思的现象
很多面试题反复出现。
比如:
为什么?
因为这些问题都指向同一个核心:
Python底层运行机制
而企业越来越看重这一点。
因为AI已经能写代码。
甚至能写得不错。
但AI无法代替工程师理解系统。
一个越来越明显的趋势
过去企业招聘:
看谁写代码快。
今天企业招聘:
看谁理解系统深。
差别很大。
写代码越来越容易。
理解代码越来越值钱。
未来三年。
真正有竞争力的人。
未必是会用AI的人。
而是:
会利用AI,同时理解底层原理的人。
我的一个观点
很多程序员成长缓慢。
并不是因为不努力。
而是学错了方向。
总在研究:
却很少思考:
当你开始研究:
你就已经从“使用Python”进入“理解Python”的阶段了。
而这一步。
恰恰决定了技术天花板。
写在最后
如果今天有人问我:
学习Python最值得投入时间的内容是什么?
我的答案不是框架。
不是八股文。
更不是背面试题。
而是:
理解那些看似简单的底层机制。
因为你会发现。
生成器也好。
迭代器也好。
协程也好。
本质上都在解决同一个问题:
如何用有限资源,处理无限增长的数据。
这不仅仅是Python的智慧。
更是整个计算机世界的智慧。🚀
点个「在看」👍
愿你下一次看到 yield 时,想到的不只是语法,而是它背后的工程哲学。