图 1:本文封面,一条典型的费米因子链。
面试里有一类让人当场卡壳的题:「一颗 CPU 每秒大约执行多少条指令」「一座城市有多少部电梯」。这个系列另有一篇真题解析专门拆解 CPU 指令那道题的硬件背景,本篇换个视角:把这类题背后的通用方法论——费米估算法——讲透。学会这套拆解套路,任何「算不出」的问题都能拆成一串「敢猜」的小因子。先说明,本文示例中的公开量级数据只做定性量级判断,不追求精确数字。
费米估算的四步套路。
第一步,界定问题。先别急着算,问清口径:估什么对象、什么单位、什么范围。「一座城市有多少部电梯」——是行政区还是建成区?只算载人电梯还是含货梯?口径不同结果差几个数量级,主动澄清口径本身就是加分项。第二步,拆因子。把目标量写成一条乘法链,让每个因子都落在常识可及的范围内。第三步,取数量级。每个因子按 1、3、10 的档位取整——一个因子你觉得在 2 到 5 之间,取 3;在 10 到 30 之间,取 10。取整到档位之后,整条链心算就能完成。第四步,交叉验证。换一条不同的拆法再算一遍,两个结果量级一致就可以交卷;差出一个数量级以上,回头检查哪个因子的估计最可疑。
拆因子为什么有效:误差被关进了笼子。
直接拍一个大总量,误差是没有约束的——让你直接猜「全国一年喝掉多少杯咖啡」,差出百倍都不奇怪。但拆成「人口 × 喝咖啡的人口比例 × 每人每年杯数」之后,每个因子都是生活常识范围内的小量,单因子估值很少偏离真实值几倍以上;而且乘法链里有的因子偏高、有的偏低,高估与低估在乘积中会部分抵消。用一段蒙特卡洛模拟把这句话量化(Node.js 22.15.0,node fermi.js):真实总量设为 10⁹,一种方式是直接估总量、误差按 ±100 倍随机,另一种拆成 5 个因子、每个因子误差按 ±3 倍随机,各跑 20 万次:
const N = 200000, trueTotal = 1e9;
function direct() {
return trueTotal * 100 ** (Math.random() * 2 - 1); // 总量误差 ±100 倍
}
function chain(nFactors) {
const trueFactor = trueTotal ** (1 / nFactors);
let est = 1;
for (let k = 0; k < nFactors; k++) {
est *= trueFactor * 3 ** (Math.random() * 2 - 1); // 每因子误差 ±3 倍
}
return est;
}
function report(name, fn) {
let sum = 0, over10 = 0;
for (let i = 0; i < N; i++) {
const d = Math.abs(Math.log10(fn() / trueTotal));
sum += d;
if (d > 1) over10++;
}
console.log(`${name}: 平均偏差 ${(sum / N).toFixed(2)} 个数量级, 偏差超过10倍的比例 ${(100 * over10 / N).toFixed(1)}%`);
}
report('直接估总量(±100倍)', direct);
report('拆5个因子(各±3倍)', () => chain(5));
实测输出:
直接估总量(±100倍): 平均偏差 1.00 个数量级, 偏差超过10倍的比例 50.1%
拆5个因子(各±3倍): 平均偏差 0.50 个数量级, 偏差超过10倍的比例 10.6%
拆因子后平均偏差减半,偏差超过 10 倍的比例从约 50% 降到约 11%。这就是方法论的数学底气:它不是让你猜得更准,而是让误差的上限可控。
一道完整的示例:一座城市有多少部电梯。
界定口径:一座千万人口量级的特大城市,只算运行中的载人电梯。拆因子:人口取 10⁷ 量级;人均电梯占有率——住宅、写字楼、商场、医院加起来,粗略按每百人一部取 10⁻²。乘起来约 10⁵ 部。交叉验证:换一条拆法,按楼宇算——全市高层楼宇按 10⁴ 栋量级估,每栋平均电梯数按 10¹ 量级估,同样落在 10⁵ 量级。两条路径指向同一个数量级,答案就可信了。再次强调,这里的人口、楼宇数都是定性量级,面试要的不是精确值,是这条可辩护的拆解过程。
图 2:四步套路、电梯示例与误差相消原理。
面试现场的答题姿态。
遇到估算题最忌讳两种反应:直接报一个数,或者说「这没法算」。正确的姿态是把思考过程外化:先复述并澄清口径,再写下因子链,每个因子报出自己的档位取整和理由——「这个因子我取 10,理由是……」,让面试官能逐因子追问和修正。算完主动做交叉验证,最后坦白误差边界:「真实值大概率在 10⁴ 到 10⁶ 之间,我更倾向 10⁵」。这套流程展示的是结构化思考能力,恰恰是估算题真正要考察的东西。日常工程里它同样好用:容量规划估 QPS、给服务定内存预算、评估一次迁移的数据量,都是同一条因子链思维。你被问过最刁钻的估算题是什么?当时拆成了哪几个因子?欢迎分享。