论程序员的时间分配问题

论程序员的时间分配问题

 

 

 

内容摘要:在面对一个任务时,程序员往往不能正确、合理地时间安排,结果是延误项目进度,或程序质量低劣达不到要求,或导致返工增加成本。本文论述了程序员如何合理地安排时间,按照过程模型将任务分成几个阶段,每个阶段合理地分配时间,并考虑各种风险因素,强调程序员和项目经理等成员之间的沟通,将计划留有余地。

 

0 问题提出

 

在实际工作中,我们经常发现:某程序员接到一个任务,任务单上写明了任务的内容、时间要求,甚至还包括质量要求。这个程序员要不到时间交不了活,给项目经理若干理由,比如很忙,造成任务延期或者加班,最后造成整个项目的延期;要么交来的结果出乎了管理者的预料,根本就不是管理者所要的,不得不返工重来,浪费时间和精力;或者按时交了结果,功能也基本上是对的,但质量很差,在后面的系统测试中发现了大量的缺陷,修复起来很困难,有些甚至不能与系统其它部分集成[6]

出现这些问题的根本原因是,程序员没有很好地分配自己的时间。在长期的软件开发管理实践中,我们发现,程序员最关心的是自己对编程方法的掌握,轻视设计、评审、测试和总结等重要环节,这样一来,他们提交的产品是不合格的产品,甚或是半成品[6]

本文将讨论程序员如何将一个任务划分成若干小任务,然后对这些小任务合理分配时间。本文针对的是个体的行为,不是项目的行为;讨论的内容是当一个程序员个体接到一个任务后如何分解任务从而更合理地安排时间,而不是讨论软件生命周期模型问题;目的是交流如何合理安排程序员(个体)自己的时间,而不是讨论整个项目的进度安排。

文章分四个部分:第一部分介绍程序开发任务的分解,第二部分比较详细地描述各阶段任务;第三部分举例说明合理的和不合理的时间安排;第四部分介绍进度风险和计划余地;第五部分强调程序员要经常和项目经理沟通,以及时调整计划。

 

1        任务分解

 

一个软件模块的开发任务分下来之后,应该能分成几个阶段来完成:计划、可行性分析、设计和设计评审、编码和代码评审、编译、测试、交付、回顾与总结。下图是过程示意图[4]


 

 

计划

可行性分析

设计

编码

设计评审

代码评审

测试

回顾与总结

交付

编译

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


1 过程示意图

 

计划阶段的任务是将分配到的要完成的任务划分成若干子任务,并按照时间排出进度;可行性分析是分析本任务是否能够在你的能力范围、时间范围内完成;设计阶段的主要任务是将你所分到的任务划分成几个程序子模块,并说明这些子模块之间的关系;设计评审是对设计的重新审视,发现问题并修改设计,直到设计满意为止;编码即用给定的程序设计语言编写程序;代码评审是按照一定的技术检查程序的正确性,检查代码中是否有遗漏和考虑不周的地方;编译阶段的主要任务是将代码用指定的编译器进行编译,发现编译错误并进行改正;测试主要指单元测试、几个子程序模块之间的集成测试,和其它系统模块之间的集成测试等等;交付阶段的主要任务是按照项目经理的要求或单位的相关规定,提交你的程序和相关文档;回顾与总结阶段分析这个任务的完成情况,有没有学到新知识和新经验,以利于下次任务更好更快地完成;如果尝试量化管理个人活动,还需要在每个阶段记录量化数据,并在这个阶段做数据分析工作[4]

 

2        各阶段任务描述和时间分配原则

 

2.1 计划

计划是程序员接到一个任务后第一件要做的事情。首先要做工作量估计,根据自己的技能和知识面,估计每项任务完成的难度和所需要的时间,其中可能还存在一些不确定的因素需要在后续的工作中验证或校正,对于那些因为技术不熟悉、没有把握完成的工作,要安排专门时间来探讨,不能因为自己不熟悉,拖延时间进度。

根据以上的分析,安排出进度。做进度安排要注意以下几个原则:

1、  认真审题。面临的任务究竟是什么?很多时候,任务的内容和要求并不是很显然的。在审题时,不妨和项目经理做一次确认。

2、  留有余地。各种可能的突发事件,或者事先估计不充分等原因,都有可能造成进度滞后,因此在做计划时要留出缓冲时间,比如整个估计时间的20%留做缓冲,一旦上述情况发生,还有时间进行补救。因此工作量估算要尽量精确,对困难要估计充分。

3、  在脑海里装着整体计划。你所承担的任务是项目的一部分,项目经理对你提出的进度要求是整个计划的一部分,不能由于你个人的任务进度缓慢耽误了整体的时间进度。如果你的任务在关键路径上,要想方设法加快完成你那部分任务。

4、  及时沟通。估计能顺利完成的话,要向项目经理确认,让经理了解你的任务执行情况;如果估计不能按时完成的话,要及时和项目经理沟通,及早调整你的计划,以免耽误整个项目进度。也许和你的开发任务相对应的需求写得不够清晰明了,这时候,你要和项目经理或其它熟悉需求的人们沟通,直到彻底弄清楚需求为止。

因为程序员可能还面临着多个任务同时进行的情况,这时要给多个不同任务做优先级排序,决定先做什么、后做什么。

在实施PSP的团队中,每个程序员还应将估计的工作量、进度、任务规模大小填入相应的表格中[4]

 

2.2 可行性分析

可行性分析包括理解本任务究竟是一项什么样的任务,反问自己以下问题:

我真的理解了分配任务的人的意图吗?有时候负责任务分配的人也没有完全写清楚,或者没有写具体,这时候要和分给你任务的人进行沟通;

这个任务可能涉及到哪些技术?哪些是自己已经有把握的,哪些还没有掌握?

分配给你的时间和其它资源是否充足?

该任务和周围的同事所承担的任务是个什么样的关系?

该任务和已有系统的其它模块之间是什么关系?

还有什么没有考虑到的?

这些问题看起来是很“显然”的,其实未必。等这些问题都有了明确答案,你需要优化调整上一步的计划,才能进行下面的工作,如设计等。

 

2.3 设计和设计评审

接下来,程序员要定义如何设计和构造这个产品。没有设计、或者设计不好,可能导致很严重的问题。设计工作的目标是计划和组织将要编写的程序代码。它把模块分成更小的几个小模块,定义各模块之间的关系[2]。这中间,可能涉及到程序流程设计,数据结构设计、类和接口设计等等。设计阶段一定要给文档书写分配充足的时间。

没有正确与不正确的设计方案,只有相对好和不好的设计方案[2]。一个有经验的设计者能充分考虑到设计方案对未来产品的稳定性、可扩展性、可靠性、性能等的影响。建议经验不足的程序员,在初次设计程序时,请求项目经理或有经验的程序员帮你做检查。

在初步设计做出来后,要做必要的评审,目的是找出设计方案中错误的地方、不符合标准的地方和遗漏的地方,以不断优化设计方案。

 

2.4 编码和代码评审

编码是对设计的实现,是用确定的编程语言(如CC++Java)等编写程序,实现本任务所要求的各项功能。编码本身并不是本文所讨论的重点,因为程序员们已经给予了足够的关注;本文所关注的重点是编码的评审工作。程序员,特别是初级的程序员最为关心的自己所编写的程序是否能通过编译,只要编译通过,基本功能实现、能够演示,他们就有了足够的成就感,以为任务已经完成。其实,产品质量问题往往出在这个阶段,程序通过了编译器的检查,没有发现错误,而实际上存在很多问题,以下只是很多类似问题的一小部分而已:

l  变量申明了,但未经赋值就被引用;

l  不同类型的变量之间进行运算,导致数据精度下降甚至出现错误;

l  除数可能为0

l  下标超出了数组的边界;

l  一个打开的文件未被关闭;

l  一段占用的内存未被释放。

因此,代码评审是非常必要的,事实证明,代码评审阶段能发现很多产品质量问题,是一种很有效、很经济的查错方法。有很多现成的评审技术可供参考。评审可以是自己完成,也可以由同行完成,还可以小组的名义完成[3]

 

2.5 编译

这个阶段的主要任务是将代码用指定的编译器进行编译,生成相应的可直接执行(或可解释执行的)二进制代码或可供调用的代码库。在这期间,可能发现编译错误,要逐个修正直到程序通过编译。

编译是检查程序错误的一个手段,但是程序的错误远不止编译错误,这是程序员容易疏忽的问题,特别是新手程序员,只要程序通过编译了,就以为程序编码的工作已经完成。即使是有经验的程序员,很多时候也不愿意把时间花在检查其它的程序错误上。上面提到的代码评审,以及将要提到的测试环节,都是为了检查程序其它错误而设置的步骤。

 

2.6 测试

在完成编码任务的时候,一定要进行测试。没有验证,就不能交付。

代码评审是一种静态的查错方法,而这里的测试是一种动态的查错方法。测试是把程序运行起来,看它的表现是否有问题,是否符合需求[3]

这里的测试主要是单元测试,即最底层的模块测试,例如一个方法(类中的一个方法)或一个函数的测试。除了单元测试之外,还应包括此次任务之内的各模块之间的接口测试,也叫集成测试;还应包括和其他人承担的模块之间的集成测试、和已有系统中的模块间的集成测试。

l  发现了各子模块实现中的错误并予以改正;

l  子模块性能达到了规格说明书的要求;

l  和其他人新开发的模块一起能正确工作;

l  和系统中已有的模块一起能正确工作。

当以上条件都可以满足的时候,你就可以考虑交付你的产品。

 

2.7 交付

交付不只是简单的代码提交。在提交代码的同时,还应提交该代码对应的程序设计文档、测试用例和测试程序、程序的调用方法。

程序设计文档可以是程序流程图,也可以是设计文字说明,还可以是程序中的注释行。好的编程实践要求一定数量的注释行,用来说明这一段程序的编程思路,提高程序的可读性,以便于以后维护。

在有代码版本控制的团队中,每检进(Check in)一次代码,都须说明代码变更的位置和原因。这一点对于代码追踪和维护,是非常有帮助的。

如果实施了PSP,在提交产品的同时,还应提交PSP必须要求的表格[4]

 

2.8 回顾和总结

对于分配的任务,你的工作似乎已经完成了。但是,一个好的程序员在每完成一个模块之后,会认真总结和回顾:在这一轮开发任务中,各个阶段有没有犯错误的地方,犯错误的原因是什么,今后如何避免?工作量估算和进度估计是否准确,估计值和实际值得之间有多大差距?有什么样的心得可以供别人和自己今后参考,少走弯路?程序中还有什么样的问题有待解决和优化?等等。

如实施PSP,对个体工作进行量化管理,还有填写相应的表格,如实际的完成时间、任务规模和缺陷数量等[4]

 

2.9 时间安排原则

首先,个人计划要服从整体计划,如无特殊原因,要想方设法、克服困难在规定的时间内完成你个人的任务。

第二,上述各阶段都要分配一定的时间,不要企图跳过任何一个阶段。

第三,有时,多个阶段的任务可以同时进行,分配一个总的时间。例如代码编写和代码审查阶段可穿插进行,写好了一个代码片段,就可以立即进行评审,可不必等到所有代码都完成之后再做统一评审。再比如,可以将计划和可行性分析这两个阶段合并成一个,只分配一个时间。

第四,各个阶段时间分配的比例没有一定标准,要根据项目自身情况确定各阶段的时间长短。如关键系统,测试时间相对较长;如果系统是基于构件的设计,编码时间相对较短。

第五,充分考虑任务的风险因素,充分估计任务的难度,计划一定要留有余地。

第六,一定要经常性和周围的同事(特别是项目经理)沟通,及时动态地调整计划,以保证整体计划不因为你个人计划而延迟。

 

3 进度安排对比

下面通过几个例子说明,什么是合理的计划安排,什么是不合理的计划安排,以及其中的原因。

 

3.1 不合理的进度安排

现状令人担忧,很多程序员不是按照上述阶段安排时间,而是省却了很多过程,将进度安排成如下图这样。图中第一列是任务名称,第二列和之后的各列表示任务完成的时间长短,黑方框越长表示所花的时间越多。

设计

 

 

 

编码

 

 

 

编译

 

 

 

2 不合理的时间进度安排

不难看出,程序员将绝大部分精力用于他们自己认为重要的编程阶段,轻视了设计、忽略了测试。更有甚者,有些程序员还省去了设计阶段,一上来就编程。这样一来,看起来省去了很多时间,但实际上,因为程序没有充分测试,问题百出,程序质量得不到保证;事前没有很好审题,返工现象严重,耽误了整体进度;程序没有经过设计,结构紊乱,不易维护;没有总结和回顾,不利于程序员进步,也不利于后续的工作的改进。

 

3.2 较合理的进度安排

根据以上介绍,我们对一个分配来的软件开发任务作出如下时间进度安排,如图2所示。

设计

 

 

 

 

 

 

 

设计评审

 

 

 

 

 

 

 

编码

 

 

 

 

 

 

 

代码评审

 

 

 

 

 

 

 

测试

 

 

 

 

 

 

 

编译

 

 

 

 

 

 

 

提交

 

 

 

 

 

 

 

3 比较合理的时间进度安排

 

程序员在这个时间进度安排上,对承担的程序模块做了设计、设计评审,加上了代码审查、测试和提交阶段,相比图2所示的进度安排有了很大长进,但仍然把绝大部分时间安排在编码阶段。

 

3.3 优化后的进度安排

下图所示的进度安排中,程序员做了任务计划和可行性分析,在事后也做了回顾和总结。在测试上增加了较多时间,反映了程序员有比较好的质量意识。这是一个比较符合规范的进度安排。

 

计划

 

 

 

 

 

 

 

 

 

 

可行性分析

 

 

 

 

 

 

 

 

 

 

设计

 

 

 

 

 

 

 

 

 

 

设计评审

 

 

 

 

 

 

 

 

 

 

编码

 

 

 

 

 

 

 

 

 

 

代码评审

 

 

 

 

 

 

 

 

 

 

测试

 

 

 

 

 

 

 

 

 

 

编译

 

 

 

 

 

 

 

 

 

 

提交

 

 

 

 

 

 

 

 

 

 

回顾和总结

 

 

 

 

 

 

 

 

 

 

4 优化后的时间进度安排

 

4 风险管理和计划余地

         任何任务都面临着一定的风险,程序员的工作也不例外。例如事先没有考虑周全的地方到时候需要另外的时间去弥补,又例如,项目整体上有变化,导致程序员个体的任务有所变化、进度需要做相应调整。

因此风险管理是必要的,也因为这个原因,计划要留有充分余地。

        

         4.1 风险管理

风险管理,首先要识别风险,其次是判断风险出现的可能性大小,再次是估计风险一旦不能规避,所造成的损失有多大,最后是风险化解措施[3]

对于程序员来说,一个任务面临的风险是很多的。例如,由于程序员不熟悉其中涉及的某项技术,需要花时间去学习,学习时间多长并不明确,这就是一个风险。这个风险出现的可能性大小要根据自己的知识背景、学习能力、工作状态来确定,例如50%的可能性。如果风险造成的损失以10为最大,0为最小,那么此风险造成的进度损失估计是6。还例如,由于程序员担任多个任务,其它任务对本任务的干扰也可能是一个风险,出现的可能性是30%,造成的损失是7。可能性和损失的积越大,其风险的重要性越大,一般来说,程序员要关心最重要的几个风险,例如前3个最重要的风险。

除了上述的两个例子之外,程序员还可能面临如下风险:临时出差、生病、休假、设备不及时到位、临时增加或改变工作、新人加入导致重新分工、同行其他人员离职、过程革新部署等等。

        

4.1留有余地

         正因为存在以上各种不确定因素,所以我们在做计划时一定要留有余地。

余地的大小视风险的多少和重要程度而定。通常,软件工程师会留20%的余地,以应对各种可能出现的冲击。下图是一个留有余地的进度安排。

 

计划

 

 

 

 

 

 

 

 

 

 

 

可行性分析

 

 

 

 

 

 

 

 

 

 

 

设计

 

 

 

 

 

 

 

 

 

 

 

设计评审

 

 

 

 

 

 

 

 

 

 

 

编码

 

 

 

 

 

 

 

 

 

 

 

代码评审

 

 

 

 

 

 

 

 

 

 

 

测试

 

 

 

 

 

 

 

 

 

 

 

编译

 

 

 

 

 

 

 

 

 

 

 

提交

 

 

 

 

 

 

 

 

 

 

 

回顾和总结

 

 

 

 

 

 

 

 

 

 

 

预留

 

 

 

 

 

 

 

 

 

 

 

4 优化后的时间进度安排

 

        

5 及时反馈和沟通

项目经理不是神,他给你的进度不可能天衣无缝,正好合适;项目经理是人,只不过比你更有经验,他给制定的时间进度可能太紧张,也可能太过宽松。

经过以上安排之后,如果你认为时间太紧,就必须立即向项目经理汇报,申请延长时间;如果进度太宽松,就要求安排其它任务。在任务执行过程中,要视各子任务的执行情况,协助项目经理,动态调整计划。这是一个职业化的软件工程师必备的美德[1][5][6]

最不愿意看到的情况是,自己明明知道任务不可能完成,却不报告,等待最后耽误了整个项目的进度;或者无视整个项目的进度而我行我素。

 

6 结论

在接到任务前期,认真审题,保证交付物符合项目经理和需求说明书的要求,而不至于让人大吃一惊,返工重来;将自己承担的开发任务放到整个项目的大背景中考虑,认真安排进度,充分考虑各种风险因素,最大限度地满足项目的进度要求;和各方面(特别是项目经理)保持经常性的沟通,保证项目计划及时动态地调整,使项目进展在控制之中;认真进行设计、评审和测试,保证产品质量。

 

 

参考文献:

 

[1] IEEE/ACM:《Software Engineering Code of Ethics and Professional Practice》,Science and Engineering Ethics2001

[2] Summivalue:《Software Engineering, 机械工业出版社,2005

[3] Ron Patton: Software Testing, 机械工业出版社,2007

[4] Watts S. Humphrey: Introduction to the Personal Software Process, Addison-Wesley2000

[5] 陈尚义:《做职业化的软件工程师》,《程序员》,2008年第7

[6] 陈尚义:《软件工程师的十个不职业行为》,《程序员》,2009年第9

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值