今天我们以两道可能看起来有点“惨无人道”的题目开始

1.一个长方体的卡车车厢能装下多少个高尔夫球?

2.密西西比河一天流出多少水?

第一个题目据说是Google的“产品经理”职位面试题,大家可能已经在网络上有过了解;第二个问题来自《编程珠玑》一书。

很容易看出,这两道题的难点在于很难得出一个准确的答案。如果大家将思路放在寻找一个具体而精确的答案上的话,就落入了陷阱,因为这两道题要讨论的是另外一个主题:粗略估算

所谓粗略估算,是指在已知的有限信息下,对一些似乎是算不出来的量,作出合理的猜测,通常用来作量纲分析。

我们先看看这两道题的答案是什么:

  1. 假设卡车车厢的容积(长×宽×高)=10m×2m×3m=60m³,一个高尔夫球的半径大约为10cm,根据球体体积=4/3πr³,高尔夫球体积约为0.004m³(其它小数位,我们可以忽略,因为球体之间会存在缝隙),如是可得:卡车车厢可容纳60/0.004=15000个

  2. 猜测出河的出口大约1英里宽和20英尺深,猜测河水的流速是每小时5英里,换算成天就是120英里。由体积公式可得:1英里×1/250英里×120英里/天 = 0.5英里³/天。

在以上的答案中,体现了粗略估算的两个关键点:公式与猜测。公式,是进行估算的整体模型,而猜测,是对缺失信息的补充。这两者,一方面取决于我们的知识,比如知识告可以告诉我们,球体体积的计算公式是4/3πr³,另一方面取决我们的经验。但归根结底,经验更为重要。因为估算要应对的情况更多是信息的缺乏,所以需要更多的利用我们的经验(包括生活经验,工程经验等)来进行猜测,以补充缺失的信息,在平时更善于捕获和总结经验所得的人,或在某方面有更多历练的人,在某方面的估算上也就更有优势,比如一个有过性能调优经验的程序员,他在程序的性能估算上就会更加擅长。

在科学界还有另外一个更“学术”的名称叫费米估算(或费米问题),它的命名来自物理学家恩里科·费米,费米以他通过非常少量或不精确的数据来得到比较好的估计的能力而被广泛熟知。一个例子就是他在主要领导的曼哈顿计划(美/英/加三国联合的原子弹制造计划)中估算核爆炸的”爆炸力相当量“。1945年7月16日晚,原子弹在内华达州的沙漠引爆成功时,费米在原子弹试爆现场附近,突然跃起向空中撒了一把碎纸片,爆炸后气浪将纸片急速地卷走,他紧追纸片跑了几步,并根据纸片飞出的距离估算了核爆炸的”爆炸力相当量“,费米计算出的爆炸威力相当于一万吨TNT炸药,非常接近现在所接受的二万吨的数值,之间的误差少于一个数量级。

费米还善于提出各种估算的问题,比如他提出的一个经典的费米问题:在芝加哥有多少钢琴调琴师?

这个问题的一个经典答案是建立在一系列的猜测上的:

首先,建立我们估算的模型:需求=供给。即需要被调整的钢琴数等于钢琴师可以调整的钢琴数。我们需要估算出一年中芝加哥有多少钢琴需要被调整以及一个钢琴师一年大概能调多少台钢琴,由此,我们作出以下一系列假设:

  1. 芝加哥的居民数大约为5,000,000人

  2. 平均一个家庭有2个人,在20个家庭中有一个家庭需要定期调钢琴

  3. 定期调琴的周期为1年,每个调琴师大约要2小时来完成一次调琴

  4. 每个调琴师每天工作8小时,一周5天,一年50周(为便于快速计算,将尾数去掉也是进行粗略估算的一个基本技巧)。

通过这些假设我们可以计算出芝加哥每年需要调整的钢琴数量为:

(5,000,000 人) / (2 人/家) × (1 架钢琴/20 家) × (1 架钢琴调整/1年) = 125,000架

类似地计算出平均每个调琴师:

(50 周/年)×(5 天/周)×(8 小时/天)/(1 架钢琴/2小时) = 1000 架钢琴每年/1调琴师

进一步计算即得出答案:

125000架钢琴 /( 1000架钢琴每年/1调琴师) = 125 个调琴师

最后,我们在附上两个可用于粗略估算的小经验法则,以便大家更好的进行类似的估算:

“72法则”

“72法则”主要用于指数级增长情况的估算

比如以r%的年利率投资一笔钱y年,如果r*y=72,那么你的投资差不多会翻倍。具体来看:以6%投资1000美元12年,可得到2012美元,以年利率8%投资1000美元9年,可得到1999美元。

“72法则”对程序员估计一个时间复杂度是指数级的程序性能来说也非常有用,当n每增加1,运行时间就是增加12%时,那由“72法则”可得当n每增加6,运行时间就加倍了,或者n每增加60,运行时间增加为原来的1000倍。

Little定律

对于一个有输入和输出的系统,*系统中物体的平均数量等于物体离开系统的平均速率和每个物体在系统中停留的平均时间的乘积

比如假设酒窖里有150箱酒,每年喝掉25箱并存入25箱,那么每箱酒的保存时间是多长呢?Little定律告诉我们:用150箱/25箱/年=6年

再如:某个酒吧可以容纳约60人,每个人在里面逗留的时间大约是3小时,那进入该酒吧的速率大概就是每小时20人。也就意味着当你排队进入酒吧时,前面有20人排队,那你还需要等待大概一小时才可以进入酒吧。