第三话按照原计划是要写写平常心的,因为飞跃计划要交作业,所以就改为写自己对项目管理的一些经验总结,刚好前一段时间那些年我们一起追过的女孩很是流行,这一话的名字就叫做那些年我们一起做过的项目。
我的第一个项目是在2005年,那是一家市场占有率前三的本地化翻译公司,公司的信息部门只有两个人:老大和我,我们一起开发公司内部的协同办公系统。要解决的问题很简单:由于公司发展迅速,以前单纯依靠纸质单据和邮件分派和追踪任务已经越来越让项目经理和财务不堪重负,迫切需要将这些工作给自动化。系统的技术架构也很简单: jsp+javabean+mysql。没有专门的开发计划,基本开发流程是这样的:每周一我们访谈一个业务部门经理,了解他的需求,周中开发,开发中有任何问题都可以直接找业务经理,周五的时候系统上测试环境,再和业务经理坐到一起看一下是否满足了他的需求。系统就一直这样不紧不慢的开发着,老板办公室就在我们身后,一有时间老板就会和我们一起使用该系统。整个开发过程只有一个细节让我印象深刻,就是对任务估算工作量时,不管我估算多少,老大都会给我乘以3,一次要给业务表单增加一个字段,老大问我需要多长时间,我说不就是增加数据库字段吗10分钟,结果老大给了我半天时间,老大说,增加字段确实只需要几分钟,但打开编辑器需要时间吧,集中注意力需要时间吧,改完了启动系统测试需要时间吧,测试完了和业务经理确认需求需要时间吧,我们估算的是完成整个事情的时间而不仅仅是编码的时间。
这个项目完成时获得了公司上下的一致好评,从公司老板到业务经理,每个人都非常满意,而让我感到唯一遗憾的却是身为IT人员竟然从来都没有加过班。
回想起来,这个项目之所以成功固然是因为技术简单和系统不复杂(我们甚至都不需要 SVN,完全依靠脚本同步代码),但最重要的还是持续交付和持续的用户反馈,老板和业务经理每周都能看到新功能的上线,这增强了他们的信心,同时反馈几乎每天都在进行,并且他们很快都能看到这是否是他们想要的。
第二个项目在2006年,这一年我换工作了,因为当时我认为不加班的程序员不是好程序员。新公司在上地,是一家做协同办公业务平台的公司,最开始去的是项目部,一开始很为业务平台这个概念着迷,因为当写程序时最先不是写代码而是用代码生成器生成代码,并且生成完的代码马上可以运行!第一个项目是丰田公司的销售管理系统,我们创新的使用了当时最热的Ajax技术,我们完全是用技术热情加上周末时间完成对原有功能的 Ajax增强,这个项目获得了用户极高的评价,因为当大多数web系统还在使用点击 /刷新的方式进行交互时,我们却可以直接拖拽完成操作了。如果在当时,我会认为是技术的创新让项目获得了成功,但是现在,我会用渐进式增强这个词,即只有在完成用户所需要的核心功能(什么叫核心功能,即缺少这个功能系统不能工作)后才开始对系统用户体验、性能进行渐进式优化。
第三个项目是在公司的平台部,这里部门经理正准备对原有的业务平台进行重写,原先业务平台的技术框架是:jsp+struts+ojb+sqlserver,新的技术框架定义为: ajax+freemarker+webwork+spring+hibernate。这让我兴奋,因为新的技术框架几乎是当时最流行的技术。加部门经理共有三个开发人员(所以沟通一直不是问题),老大使用project来管理项目,每个人负责一个模块,估算以周为单位,最初计划是 5个月交付,功能直接就是老平台的翻版换的只是技术实现,但是 5个月后进行测试和项目试用时却发现了大量缺陷,最后几乎用了半年时间才将缺陷收敛,产品发布计划延期半年。回顾这个项目,需求没有进行详细的分解和评审导致实现与需求不一致 似乎是项目延期最重要的问题,然而更深的思考却是我们需不需因为技术原因开始新产品的开发,在不影响用户使用的情况下对原业务平台进行渐进式增强是否更加合适。即我们在启动项目时更多关注的应该是用户价值(只有有用户价值用户才会买单公司才有收益)。
第四个项目是我负责的,这个项目几乎是上一个项目的翻版,重写公司的工作流产品:支持更多的工作流模式,更易集成的api和管理界面,唯一不同的是这个项目采用了很多敏捷里的实践:持续集成、单元测试、站会、迭代,但这些实践均不影响这个项目最终的失败。同样是该不该重写这个项目的问题,在公司资金链紧张、时间要求紧、新产品相比竞品没有突出特性的情况下,这个项目从一开始就决定了失败。如果没有特别充足的理由就不要重写产品,这几乎成为我目前最重要的一条原则,尤其要从公司全局的角度看待产品不能局限在技术。现在,只要谁一说到要重写产品,而给出的仅仅是技术原因,我就会两股加紧,冷汗直流。在对项目完全负责的情况下,我另一点深刻感受就是人的重要性,对团队中的每个人员,作为leader 你都需要知道他的需求是什么,没有人愿意做机器人,在一次对某一技术方案简单粗暴拍板后,一个核心技术人员流失了,这成了压垮这个项目的最后一根稻草。
08年底去了一家新公司,新公司采用敏捷实践。第一个项目很成功,几乎是敏捷项目的一个成功范例,需求分析、迭代、持续集成、结对、客户 showcase、持续交付,项目甚至提前半个月完成。唯一美中不足的是项目二期时新团队由于一期文档很少带来了很多困扰。突出的感受是:团队人员有了角色、有了分工也就有了流程。现在,到了一个新的部门或中心,第一件事情往往就是梳理项目开发流程,定义出每个人的角色,职责不清是互相埋怨之源。
第二个项目是咨询项目,略去不表。第三个项目是分布式团队,一部分团队在国外,一部分团队在国内,最开始一切顺利,但在上线前一个月遇到了严重的性能问题,陷入了一片混乱当中,所有人都不知道我们离上线还有多远,还有哪些工作需要完成,优先级都是什么,项目经理甚至自己都失去对整个项目的把控,她不知道项目上线究竟需要满足什么条件,于是一次次在等待国外团队优化后的测试结果,于是一次次的测试结果不满意,于是项目在一次次的下周二上线的空头承诺中成了整个公司的笑柄。这个项目回顾起来就是团队遇到挫折时放弃了计划,迭代没有了,故事墙没有了,所有人都在等待,而项目经理为了不让开发人员被公司收回还不得不想一些优先级不高的任务给团队完成装着我们很忙。教训就是,任何情况下都不能放弃计划,计划是项目之本。其他包括团队能不分布式就不要分布式,如果必须分布式那么一定要从架构开发任务上进行隔离,尽量减少两个团队之间的交互(很多项目经理进入到部门之后推进项目制,其实也是同样的原则,团队大了就要拆解,产品代码多了也要模块化,尽量减少团队之间、模块之间的交互,做到能够各自独立演进和发布)。尽早进行实际环境的测试,越早越好。测试越早进行越好,测试环境越贴近产品环境越好,这一原则什么时候强调都不过分(我们上线前的测试才发现严重的性能问题)。
第三个项目是幸运的,因为他们有钱,能够等待,在多等待了大半年后系统终于上线。而第四个项目就没有这么走运了,这个项目是一个在线 saas CRM系统的重写,而且有着强时间约束(如果半年不能交付,将错过该系统客户每年做预算的窗口期),看吧,又是重写,又是时间约束,这几乎总预示着它厄运难逃。表面上看项目是在一次中期的架构重写中崩溃了,重写耗去了团队太多的时间,而由于对未知领域知识的不正确估算(需要学习)再次令项目雪上加霜,项目目标又不能变化,要在六个月后上线,但更深层的原因还是项目开始之前没有决策正确,真的要重写产品吗?老产品确实界面很丑、一些功能没有,但这些不能渐进式增强进行吗,一定要重新开始吗?重写使用新团队,他们对该业务领域并没有经验,过去系统遇到的坑他们不清楚,他们的计划因为少考虑了一些情况是否显得过于乐观?这个项目的其他问题包括项目计划一直没有发生变化,尽管所有人都认为在规定日期到来之前不可能交付,但这个日期却没有发生变化。最后不得不说这是一个技术强大的团队,一切都做到了自动化,甚至部署产品环境也是一键完成,但是这些在项目目标失败的情况下显得黯然失色。而客户贷款做这个项目则让很多团队成员良心不安。
来到腾讯,来到soso,最重要的收获是对运维有了新的认识,以前曾经认为devops就是自动化部署,全功能团队,现在发现它关乎架构:一条搜索的badcase是否能够很快找出错误的原因?是抓取失败,是索引时丢失,还是相关性排序不好?关乎监控和报警,我们能否很快从监控中定位出原因?关乎组织结构,前台开发,后台架构,基础架构,运维测试团队都是分离的,如何协作才能使团队合作的成本最低而整体利益最大化?
回顾往事,保尔柯察金说:如何才能不虚度光阴,只有为共产主义奋斗终身;柯景腾说:唯有沈佳宜让我怀念;而我想说的是:
- 做任何项目之前一定要想清楚为什么要做这个项目,一定要想清楚这个项目的价值是对用户和公司的(尤其需要跳出站到一个比较高的层次看项目),一定要想清楚项目的约束(时间约束、人员约束),不仅是项目开始之前要想,过程中要不断回顾;;
- 项目任何时候都必须有计划,对所有干系人透明;
- 项目一定是持续交付和持续反馈的,不允许黑盒出现;
- 测试和运维一定要尽早介入;
- 从每个团队成员的角度出发关注所有人的利益实现共赢。