程序员估算

程序员估算

快!通过56k modem线发送《战争与和平》需要多少时间?存储一百万个姓名与地址需要多少磁盘空间?1000字节

的数据块通过路由器需要多少时间?交付你的项目需要多少个月?

在某种程度上,这些都是没有意义的问题——它们都缺少信息。然而它们仍然可以得到回答,只要你习惯于进行估

算。同时,在进行估算的过程种,你将会加深对你的程序所处的世界的理解。

通过学习估算,并将此技能发展到你对事物的数量级有直觉的程度,你就能展现出一种魔法般的的能力,确定它们

的可行性。当有人说"我们将通过ISDN线路把备份发给中央站点"时,你将能够直觉地知道那是否实际。当你编码时,你

将能够知道哪些子系统需要优化,哪些可以放在一边。



Estimate to Avoid Surprises!

估算,以避免发生意外!

多准确才足够准确

在某种程度上,所有的解答都是估算。只不过有一些要比其他的更准确。所以当有人要你进行估算时,你要问自己

的第一个问题就是,你解答的问题的语境是什么?他们是需要高度的准确性,还是在考虑棒球场的大小?

● 如果你的奶奶问你何时抵达,她也许只是想知道该给你准备午餐还是晚餐。而一个困在水下、空气就块用光的潜水员

很可能对精确到秒的答案更感兴趣。

● π的值是多少?如果你想知道的是要买多少饰边,才能把一个圆形花坛围起来,那么"3"很可能就足够好了。如果你在

学校里,那么"22/7"也许就是一个好的近似值。如果你在NASA,那么也许要12个小数位。

关于估算,一件有趣的事情是,你使用的单位会对结果的解读造成影响。如果你说,某事需要130个工作日,那么

大家会期望它在相当接近的时间里完成。但是,如果你说"哦,大概要六个月",那么大家就知道它会从现在开始的五到

七个月内完成。这两个数字表示相同的时长,但"130天"却可能暗含了比你的感觉更高的精确程度。我们建议你这样度

量时间估算:
时长 报出估算的单位
1-15天 天
3-8周 周
8-30周 月
30+周 在给出估算前努力思考一下
于是,在完成了所有必要的工作之后,你确定项目将需要125个工作日(25周),你可以给出"大约六个月"的估算。

同样的概念适用于对任何数量的估算:要选择能反映你想要传达的精确度的单位。


估算来自哪里

所有的估算都以问题的模型为基础。但在我们过深地卷入建模技术之前,我们必须先提及一个基本的估算诀窍,它
总能给出好的答案:去问已经做过这件事情的人。在你一头钻进建模之前,仔细在周围找找也曾处在类似情况下的人。

看看他们的问题是怎么解决的。你不大可能找到完全相符的案例,但你会惊奇有多少次,你能够成功地借鉴他人的

经验。


理解提问内容

任何估算练习的第一步都是建立对提问内容的理解。除了上面讨论的精确度问题以外,你还需要把握问题领域的范
围。这常常隐含在问题中,但你需要养成在开始猜想之前先思考范围的习惯。常常,你选择的范围将形成你给处的解答

的一部分:"假定没有交通意外,而且汽车例还有汽油,我会在20分钟内赶到你那里。"


建立系统的模型

这是估算有趣的部分。根据你对所提问题的理解,建立粗略、就绪的思维模型骨架。如果你是在估算响应时间,你
的模型也许要涉及服务器和某种到达流量(arriving traffic)。对于一个项目,模型可以是你的组织在开发过程中所用的

步骤、以及系统的实现方式的非常粗略的图景。

建模既可以是创造性的,又可以是长期有用的。在建模的过程中,你常常会发现一些在表面上不明显的底层模式与

过程。你甚至可能会想要重新检查原来的问题:"你要求对X所需的时间进行估算。但好象X的变种Y只需一半时间就能

完成,而你只会损失一个特性。

建模把不准确性引入了估算过程中。这是不可避免的,而且也是有益的。你是在用模型的简单性与精确性做交易。

使花在模型上的努力加倍也许只能带来精确性的轻微提高。你的经验将告诉你何时停止提炼。


把模型分解为组件

一旦拥有了模型,你可以把它分解为组件。你需要找出描述这些组件怎样交互的数学规则。有时某个组件会提供
一个值,加入到结果中。有些组件有着成倍的影响,而另一些可能会更加复杂(比如那些模拟某个节点上的到达流量的

组件)。

你将会发现,在典型情况下,每个组件都有一些参数,会对它给整个模型带来什么造成影响。在这一阶段,只要确

定每个参数就行了。


给每个参数指定值

一旦你分解出各个参数,你就可以逐一给每个参数赋值。在这个步骤中你可能会引入一些错误。诀窍是找出哪些
参数对结果的影响最大,并致力于让它们大致正确。在典型情况下,其值被直接加入结果的参数,没有被乘或除的那些

参数重要。让线路速度加倍可以让1小时内接受的数据量加倍,而增加5毫秒的传输延迟不会有显著的效果。

你应该采用一种合理的方式计算这些关键参数。对于排队的例子,你可以测量现有系统的实际事务到达率,或是找

一个类似的系统进行测量。与此类似,你可以测量现在服务1个请求所花的时间,或是使用这一节描述的技术进行估算

。事实上,你常常会发现自己以其他子估算为基础进行估算。这是最大的错误伺机溜进来的地方。


计算答案

只有在最简单的情况下估算才有单一的答案。你也许会高兴地说:"我能在15分钟内走完五个街区。"但是,当系统
变得更为复杂时,你酒会避免做出正面回答。进行多次计算,改变关键参数的值,直到你找出真正主导模型的那些参数

。电子表格有很大帮助。然后根据这参数表述你的答案。"如果系统拥有SCSI总线和64MB内存,响应时间约为四分之三

秒;如果内存是48MB,则响应时间约为一秒。"(注意,"四分之三秒"怎样给人以一种与750毫秒不同的精确感。)

在计算阶段,你可能会得到看起来很奇怪的答案。不要太快放弃它们。如果你的运算是正确的,那你对问题或模型

的理解就很可能是错的。这是非常宝贵的信息。


追踪你的估算能力

我们认为,记录你的估算,从而让你看到自己接近正确答案的程度,这是一个非常好的主意。如果总体估算涉及子
估算的计算,那么也要追踪这些子估算。你常常会发现自己估算的非常好——事实上,一段时间之后,你就会开始期待

这样的事情。

如果结果证明估算错了,不要只是耸耸肩走开。找出事情为何与你的猜想不同的原因。也许你选择了与问题的实际

情况不符的一些参数。也许你的模型是错的。不管原因是什么,花一点时间揭开所发生的事情,如果你这样做了,你的

下一次估算就会更好。


估算项目进度

在面对相当大的应用开发的各种复杂问题与反复无常的情况时,普通的估算规则可能会失效。我们发现,为项目确
定进度表的唯一途径常常是在相同的项目上获取经验。如果你实行增量开发、重复下面的步骤,这不一定就是一个悖论:

● 检查需求

● 分析风险

● 设计、实现、集成

● 向用户确认

一开始,你对需要多少次迭代,或是需要多少时间,也许只有模糊的概念。有些方法要求你把这个初始计划的一部

分定下来,但除了最微不足道的项目,这是一个错误。除非你在开发与前一个应用类似的项目,拥有同样的团队和同样

的技术,否则,你就只不过是在猜想。

于是你完成了初始功能的编码与测试,并将此标记为第一轮增量开发的结束。基于这样的经验,你可以提炼你原来

对迭代次数、以及在每次迭代中可以包含的内容的猜想。提炼会变得一次比一次好,对进度表的信心也将随之增长。


Iterate the Schedule with the Code!

通过代码对进度表进行迭代!

这也许并不会受到管理部门的欢迎,在典型情况下,他们想要的是单一的,必须遵守的数字——甚至是在项目开
始之前。你必须帮助他们了解团队、团队的生产率、还有环境将决定进度。通过使其形式化,并把改进进度表作为每次

迭代的一部分,你将给予他们你所能给予的最精确的进度估算。


在被要求进行估算时说什么

你说:"我等会儿回答你。"

如果你放慢估算的速度,并花一点时间仔细检查我们在这一节描述的步骤,你几乎总能得到更好的结果。在咖啡

机旁给出的估算将(像咖啡一样)回来纠缠你。

讨论:

有人问你:"1Mbps的通信线路和在口袋里装了4GB磁带、在两台计算机间步行的人,哪一个的带宽更高?"

你要对你的答案附加什么约束,以确保你的答复范围是正确的?你的假设下答案是什么?(比如,你可以说,

访问磁带所花时间忽略不记。)

假设:
1.磁带中含有我们需要传送的信息;
2.知道行走人的速度;
3.知道两台机器间的距离;
4.不考虑磁带读写时间;
5.在磁带上存储数据的开销与通过线路传送数据的开销相等;
结论:
4GB的磁带含有的320亿的比特信息,于是1Mbps的线路上传送相同数量的信息需要约32000秒,约9小时.如果人以9Km/h行走,那么两台机器至少要相距80km,通信线路才能胜过我们的传信人.



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jianxiong8814/archive/2007/05/06/1598214.aspx
posted @ 2011-01-06 06:23  dkcndk  阅读(306)  评论(0编辑  收藏  举报