标签归档:谁动了我的代码

铁打的营盘流水的兵

每年的6月7月是毕业季,尽管我已身在职场,可是依然可以感受到“毕业”的分别。

有的人一路向东去了上海,有的人北上去了帝都,有的人南下去了深圳广州,有的人改行去了郑州,还有的人去了软件园长方形园区的对面那条边。

武汉,九省通衢,当之无愧。流的不仅是物,也有人。

作为那些人的朋友,我为他们的离开送上祝福。

有的人去上海为了和家人更近,有的人去帝都为了边工作边读个在职学位,有的人随女朋友一起去了南方,有的人喜欢和亲戚挨着的生活回归故里……当然,去软件园长方形对面的那个人,则道出了简单的规律:

人的自我改变,都是为了更好的发展。

离开一个稳定熟悉的地方,去到一个陌生的城市,承担一些变化的风险,为的是赚更多的钱(更有成就感),或者离家人更近(更有幸福感),或者做自己喜欢的事情(更有新鲜感)。

正常规律讲人总是趋利的,自我的革新和变化都是想给自己带来更好的可能。从个人的发展来看,在这个年龄承担一些风险并不一定是坏事。关键是要明白自己想要什么,北上广深机会多赚得钱多竞争压力大,二线城市机会不多赚钱相对少但幸福感更强。

不明白自己想要什么的人,要么随遇而安慢慢想,要么分别体验慢慢试。在如今这扁平化世界里,信息的传递不会再有任何限制,人的迁徙也变得比以前更加简单,基于互联网交付的工作让时空的限制更加少,去中心化的思维理念也让组织更难hold住个人单元。

父母那辈找一份工作干到退休的时代已经过去,现如今,职场供应商心态更加有生命力。职场供应商(员工),提供自己的工作技能或者资源,给客户(公司)创造价值带来利润,从而赚取自己的回报(薪水福利等)。

作为一个基层团队管理者,我也为同事的离职感到森森的苦恼。

换一个角度看同样的事情,面对这样的残酷世界,组织如何能够hold住员工?

团队管理者花费心血打造好的团队,每个位置都能经验娴熟的处理业务。旧去新来,留下了一个新团队又得重新开始训练磨合。管理者感到苦恼在所难免。

从美国回来的商务同事看出了我的苦恼,闲聊时他问了我一个问题。

NCAA(美国大学生篮球联赛)里为什么那些强队大体上每个赛季都是强队?

这里有个隐藏的条件,就是美国大学生正常情况下是4年毕业的,也就是说每4年球队的球员应该全部换新。特殊情况下,表现特别优秀的球员会在大学没读完时就被NBA挑走。那么为什么基本上那些强队一直都是强队呢?球队的教练到底干啥了呢?

当然,这里面肯定有马太效应。NCAA的冠军球队不管是从外界的资源名声,还是内部的招生倾向,都会更有利于这只球队下赛季依然夺冠。不过,这里强调的是管理者(球队教练)的心态以及工作方法。

既然现有的球员哪怕他再有天赋再有能力,教练也不会让他拥有所有的上场时间,而是有意地逐步将他的上场时间分配给有潜力的新人。这样,在足以保证维护本球队荣誉的前提下,教练的策略让有潜力的新人逐步变成球队的中坚力量。等现有球员毕业之时,这些新人也可以顺其自然顶替他的位置并表现得不赖了。

大道至简,商业团队也可如此。虽然做不到提前四年将新人招入团队“慢慢学”,但是知识的传承体系以及培训机制的建立和落地就显得极其重要。以便当有老员工提出来”要毕业或者被NBA选中“之时,用那一段不太长的工作交接时间内,将新人培训上岗,在岗位上再持续地对新人进行培训和锻炼将其逐步打造成能够独立工作的人。

既然道理和方法很简单,为什么管理者都会苦恼呢?经过反思,我想团队管理者的苦恼来自于:

期望建立的团队永久保持稳定,从而自己一劳永逸,而扁平化的信息世界让这一切都不现实。

NCAA教练可以为某球队服务N年,每年面对不同的球员,他都可以神工巧匠地维持着球队的荣誉和排名。那么管理者是不是也要接纳这样的世界,并且琢磨出高效可重复的培训方法,去管理和维护这些变化呢?

自然规律告诉我们,兵一定是流水的,或长或短;营盘却不一定是铁打的,需要管理者付出心力。管理也是一门实操技术,需要在新的游戏规则里不断更新不断进步。终身学习的时代,人人都不能偷懒。

人生就是睡不醒

我打开收件箱,看到了他的辞职信。

他曾经说过,

人生就是睡不醒。只有一次,不能refine.

他努力践行着他自己的名言。将近一年的时间,工作时间他保持着睡不醒的状态,而且还经常迟到。他的主管为此多次找他谈话。在我们团队迟到是要收税的,于是我们的周会零食以及一些团队活动经费名义上都要感谢他的赞助。

我不是他的主管,但却一起共事了好久。下班之后,拉他到公司外花坛边。他点燃了一根烟。

他有两个同学在某地电视台工作,闲暇之余有些电视行业的私活儿,比如写剧本,画插图,剪片子之类的,于是找到了他。他做着做着开始爱上了这些东东。于是,白天他在一个软件公司上班,下班后他开始琢磨学习着电视行业的技术,然后干到凌晨1点2点或者3点。

就这样,坚持了一年多。直到现在,他觉得可以过去和他两个同学一起干点儿事情了,于是他提出了辞职。

我默默地听完了他的故事,这才明白了一直以来他在人前睡不醒的秘密。往常团队有人离职,我都会劝留。可是听完了他的故事,我没有半点劝留的话,反而鼓励他有梦就去追。

看得出来,他是真的对电视行业产生了兴趣。按他的话说,“下班跟上班似的”。这个不是说着玩儿,坚持一年多便是最好的证明。

面试中我经常听到有人说对某某事情有兴趣,但是却又不能拿出很好的行动证明来。如何判断你对某某事物真的有兴趣?最简单的方式就是看你有没有在业余时间里不计回报的对某某事情有所投入。

你拿出了业余时间,原本可以进行你最喜欢的休闲放松活动,但是你却投入地做某件事情,这足以说明这件事情让你获得足以超过休闲放松还多的快感和激情。

能够认识到自己并找到自己的热爱,在当今社会里,弥足珍贵。

这种睡不醒,便是在追梦。

最简单的时间管理

团队有了一个新项目组,3个开发,2个测试。其中Project Owner是一个开发小伙。前段时间,我发现这个小伙每天下班尤其晚,但其他的成员正常下班,然后又听说他私下说Project Owner不好当,心想要找他谈谈了。

他告诉我,他的工作总是被频繁打断,然后不得不等到大家都下班了才开始做自己的活儿。我说,那起码你要开始学会管理你的时间了。

他的工作内容主要有两个,一个是项目主程,负责开发部分新功能和修复Bug;一个是Project Owner。所谓Project Owner,是除PM之外对项目负责的人,相当于“包工头”。所以Project Owner的工作会包括写日报,制定缺陷修复计划,和其他开发讨论解决方案,和测试讨论需求疑问,写问题列表以及其他项目“杂事”。

所以他的痛苦是,当他扮演主程身份的时候,通常被其他成员“绑架”到Project Owner身份上来做交流,等回到主程身份又重新进入全速前进的状态需要至少15到20分钟。于是,主程的活儿根本干不了了。

时间管理已经是老话题了,而且有非常多的理论。我当然不能跟他一上来做个2小时培训,于是告诉他一些最简单的原则:

首先,要掌握自己的时间,需提高自己的效率,提高效率来自专注 — 同一时间只做一件事情效率最高。

其次,频繁被打断手头的事情,并不意味着处理打断后手头事情能立马恢复全速,每次被打断回来后至少需要15分钟恢复全速前进。

怎么办?设置“时间点”!

让他跟团队成员交流,他有上面说的两个角色,为了保证项目主程能够保持高效并且一段时间连续工作,他不会随时随地突然扮演Project Owner处理大家的疑问,而是设置“检查时间点”。

具体说,每天上午从8点半上班11点半下班,中间9点晨会后,以及11点有两个“检查点”,这两个检查点他会扮演Project Owner的身份来处理大家的各种杂事,处理时间10到20分钟。然后他会安心以主程的身份开发新功能,修复缺陷。他在主程的时候请各位成员先自行处理问题,并等到下一个检查点告诉我。下午从1点半到5点半下班,一般设置1点半,3点半,5点三个检查点。

总会有成员还是延续习惯中间随时随地找他,那么他会立马简单把这个请求写在记录本上,然后说,OK,了解了,我11点去找你可以吗,我先完成手头上的工作。

于是,他作为主程的时间被保护了起来,而各种杂事好像也没有那么紧急需要立即处理,集中时间反而处理杂事效率也更高了。

临危受命 — 如果再给一次机会

这场战斗终于结束,太多的血与泪。事后,我们团队和公司上下也做了深刻的总结和反思。

PM,天职是管理好项目,所以需要对项目的一切负责。

当项目出现不可消化的问题时,需要及时地Esclation,向上抛出问题警告或者通知各个相关利益人,并积极寻找资源解决问题。切不可隐瞒问题,否则迟早变大灾难。

项目经理有义务保证项目交付成功,同时也具备了管理团队的权力。即使是跨国团队中,PM有权力对非本地团队进行指挥调度,这是再正常不过的事情。不要因为中国人的内敛而在“国际问题”上畏缩。

PM应该全力维护团队的利益。一方面反思和总结团队不足的地方,并对内做出迅速而有效的行动来改变;另一方面不能将责任全部揽入怀中,当客户出现挑衅责怪的时候,PM应该勇敢站出来做一个恶人,因为不能让团队受伤。

用数字说话,可以更好地反映项目的真实的状况,而不是“自我感觉”,感觉着东东不靠谱。

剩下的,就是用教科书般的简单办法去管理团队,保证质量,沟通合作。

……

这场发生在去年7月份的战斗,从结束至今已经有半年之久。在这半年里,我们无时不刻谨慎地对待新项目,因为那次战斗所带来的经验让我们力争不再犯已经犯过的错误。

感谢团队里面的每一个人的支持和付出,感谢开发和测试的大家伙儿在最关键的时候顶住压力在前线奋战,感谢软件开发总监和软件开发经理对这个项目的协助和指导,感谢美国的USP在客户那儿的斡旋协调,感谢美国的USP老大亲临武汉对团队的监督指导,感谢家人在背后的默默支持特别是连续好几个周末不休息,最后感谢当时的那个她在背后的支持。谢谢大家。

这个临危受命的项目已经尘封,新的项目还在开启,而人生也将继续一路前行。

2013.3.2 菠萝头

临危受命 — 黎明前的黑暗

团队继续吭哧吭哧地前进,在经历过功能更新,用户体验更新以及性能更新的阶段后,剩下的Bug让我们看到了最终Release的曙光。一阵邮件和电话会议后,双方敲定了最终Release的日期。

在最终Release之前的三天,我们突然接到一个任务,要求换一些程序UI的元素。此时此刻,我相当不建议接受这个任务,特别是在最终Release的前三天。由于程序UI的界面图片实际是存储在数据库中,新UI的界面和老UI的界面尺寸大小都不一样,所以还需要调整项目的XIB文件以及相关的代码,这些改动在最终Release三天前发生是一个相当有风险的事情。

经过一番争取,产品总监依然坚持需要改动UI,而且这个比任何都要重要,因为客户需要看到新的UI设计,相对于后台客户“看不到”的功能反而变得其次。无奈团队只好接下这个新的任务。

墨菲定律,如果说你真心想避免墨菲定律发生在你的身上,那么墨菲定律就一定会发生在你的身上。

最终Release的那天早晨,团队成员在更新SVN之后发现程序不能成功编译,提示说缺少一些文件。可是前一天的下午我们的Daily build还好好的。调来SVN Check in记录一查,发现当天中国凌晨的时候有美国团队往里面Check in代码。出错的地方就是他们新Check in的代码。

团队计划好当天的下午Release,可是上午还有很多事情需要做,时间一分一秒地过去。一方面,我们紧急联系了美国的产品总监,说明了情况,要求美国的团队立即Check in缺少的文件,使我们可以编译成功;另一方面,中国团队先注释掉必要的代码让编译通过,然后继续工作。一阵折腾,美国团队最后在中国早上的11点左右才Check in那些丢失掉的文件。团队的工作才得以继续。

有一点不能忽略,就是为什么美国团队会在最终Release之前的一天Check in一些代码,并且不知会一声其他的团队,更没有通知项目经理。按理说最终一天的任何Check in都需要通知项目经理,由项目经理综合考虑各种风险才能批准Check in,否则新Check in的代码很有可能产生严重的回归Bug。

可惜理论和实际总是有一段距离,项目经理在中国团队,理论上可以对乌克兰团队和美国团队直接管理,可实际上并非完全如此。乌克兰团队没问题,问题是美国团队直接由产品总监坐镇。产品总监来自于创业公司,本来就缺少大团队合作的经验,两三个人一起做事儿还可以,人一多心里根本没有任何流程的概念。所以很多时候,产品总监会饶过项目经理直接和美国团队说需求,然后美国团队的高级工程师们一起就干了并Check in代码。所以至此,可能中国团队和乌克兰团队都不知道这回事儿,只有当工程师更新代码的时候,才发现Check in记录,于是再反馈到项目经理这里来,项目经理再去调查Check in代码到底改变了哪些功能。美国团队高效率的背后,留给的是跨团队合作的隐患。

早上11点,经过我们的努力美国团队最终Check in那些丢失掉的文件。团队重新打好Build,QA立即去测试新Build后果然发现各种Regression bug。这些Regression bug都似曾相识,以前团队修复过,但是都有复活。很多Regression bug都会直接导致程序崩溃。于是,在这个最终Release Day的时候,程序的表现还不如前几天的了。

之前预测到的各种风险在这一天都直接变成问题,临时改变UI设计样式,前一天不经过任何确认就Check in一些新功能,这些都造成了现有程序的大量Regression bug。同时,在修复这些Regression bug之后,可能会有新的Regression bug的发生。噩梦,总是接着一个噩梦。

接近晚饭时间,大家精神高度紧张一天,我决定还是让大家稍微喘点气去吃个饭。我自己没吃饭,回家冲了个凉,以让自己疲惫的头脑更清醒点,疲惫的身体得到一些放松。躺在阳台的躺椅上,我看着夕阳,心想这段日子终将结束,最后一天还是把团队搞得灰头土脸狼狈不堪,真不知道这是不是最后一天……

闭目养神了几分钟,跳起来,穿上衣服,去了公司。

来到公司后,发现大家都站着办公区停止了工作,似乎在等着我回来。看见我来了,立马跑过来说UI的改动需要回滚,我说怎么了,他们说Bug太多了。我知道,大家在等着我的决定。现在要么回滚所有的UI改动,这几天白忙活,而且美国特别要求的任务没完成,换来的是现在的Release安全了(可能安全了,可能不会);要么坚持继续下去,修复完所有的Bug,然后交付,换来的是极大的风险导致不能交付。

在做决定之前,我还是想先看看现场到底发生了什么,而且在这危急时刻PM需要自己来判断而不是完全根据别人提供的信息来判断。我要求QA给我展示她们发现的一个个Bug,然后我和Dev一起判断这可能是什么原因引起的Bug。当我看完了所有的情况紧急的重大Bug后,我发现真正由替换UI引出的Bug不过一二,其他的Bug来自于非UI替换的组件。于是我做出决定,不要回滚UI改动,继续推进修复完所有Bug完成交付。

回过头来想,为什么当时大家都站在办公区停止了工作,为什么会认为UI的改动需要回滚。我想那个时候,大家跟我在自家阳台躺椅上的心境应该差不多。坚持了大概一个多月没休息,最后一天出了这么多乱子,使得大家士气很低落,于是开始怀疑自己的努力,并且想放弃自己的努力。我想,这个时候就需要PM站出来,勇敢地做出决定,并鼓舞大家的士气。

我召集所有人开会,告诉了大家我们看完了所有的Bug后,真正由替换UI引出的Bug只有2个,说明我们的替换UI的改动还是非常成功的。剩下的所谓的很多Bug,加起来也不过7到8个。很多都是以前修复过的问题不知道什么原因又重新打开了,换句话说,大家都肯定熟悉那块地方的代码,修复起来也不会太难。现场有这么多人,大家加把油,今天最后一天,做完就成功。

其实数据都摆在那里,需要一个人High level的说出来分析给大家听,大家才放心。我并没有“望梅止渴”,我只是在陈述事实。

最后晚上还算顺利,临近12点,基本开始进入交付流程了。我拿出钱,让大家去公司对面买些烧烤和啤酒,大家一起庆祝最后的交付。尽管最后已经快到2点了。

有人说,等下4点有球赛,干脆等下一起喝啤酒看球赛算了。呵呵,一群可爱的人。

最终还是没看球赛,大家各自在香甜的睡梦中,迎接了黎明的到来。

临危受命 — 功能,用户体验和性能

 

自从项目组成功的交付了前几个软件包之后,压力减少了许多。现在的软件看起来还是那么回事儿,而不是像几个星期前那样一堆跑不起来的玩意儿。可是我们的活儿还没完,接下来的几周主要是针对目前的版本做维护更新。

现在回顾起来,这几周的维护更新基本上是被美国产品总监驱动着前进。先后经历了功能完善,用户体验完善和性能完善阶段。

首先说功能完善阶段。一个软件最基本的功能都没能实现,当然不用谈其他的。整个软件团队分为三地,美国,乌克兰和中国。软件有四个组成部分:Server, HH, DB, Web。软件开发阶段的前期貌似没有非常明确的说明团队是按照横向分工还是纵向分工。所谓横向,就是四个组成部分一个团队专门负责一块或两块,不会有一个组成部分同时由两个团队进行维护;所谓纵向,是按照需求功能分,一个软件需求可能四个组成部分都会涉及,那么同一个团队为了完成一个需求会四个组成部分都用到。

现实的情况是乌克兰团队负责HH和Web;中国团队在开发阶段主要负责Server和Web;美国团队负责DB,HH以及Server。所以应该算是偏纵向分工。在开发阶段,中国团队的作用基本上是处理分配过来的任务或者需求,没有一个整块。其他两边的团队也各自为政。最后导致的结果是,貌似每个需求点都有开发,但是又都连接不起来。所以我们的任务是在别人70%的代码上做补充修改。经过分析,其实所谓的需求都不太难实现,只是横跨的组件非常多,而团队之间又缺乏沟通,所以导致很多事情做了但是没做完,半吊子。

好吧,开始工作了。首先,该项目并没有正规完善的功能需求说明书,于是先让QA根据界面设计测试用例,然后让QA进行测试 — 结果当然是Bug一大堆了。于是,在没有功能需求说明书的情况下,开发们可以根据Bug来有目标地进行工作了。(想想极限情况是什么,就是一行代码没写,于是功能说明书就完全以Bug列表的格式展现了)。

此刻最大的变化是,中国团队开始介入HH的开发,于是Server, HH和Web中国团队就都有横跨,这样可以极好地解决跨团队沟通效率低下的问题。这时候有人提议,干脆以后就把所有的模块都接过来得了,免得出现其他团队不好合作的情况。这个建议立即被我们的软件开发总监驳回了,因为从商业上和实际上很难一个团队把所有的模块都接了,另外奢求这样的工作模式实际上是管理低能的表现。

吭哧吭哧地前进,随着主要的功能性Bug被修复,软件也可以慢慢跑起来了。美国产品总监在点击某些按钮时发现结果也可以正常显示出来后,就开始注意用户体验了。

以前三地的团队都是做企业级应用的,和互联网应用不一样,通常企业级应用对用户体验的要求比较少,所以印象中企业级软件的界面都比较丑陋。可是我们做的是iOS,iOS有些基本的用户体验规范,这些用户体验规范由苹果官方出品为的是所有的iOS应用有着相同或相近的体验。在我看来,有些iOS基本的用户体验已经不是传统上的用户体验,而是默认的必须要的功能。

举个例子,某条规范说用户在触发一个事件后,如果结果不能立即出来,应该有某种提示进度的方式。即如果你点击一个按钮,在去下一个屏幕的之前需要等待很长的时间,那么需要设计一个提示框或者转圈指示器显示在屏幕中央,如果没有,那么用户体验是相当恶劣的。

再举些例子,有的时候一些iOS应用就是把用户体验做到极致,比如打开App store,里面介绍应用的页面通常会列出好多应用,而这里的显示逻辑是先加载基本的框架,然后再加载所有应用的文字,最后再加载所有应用的图片。想想看,如果给了一般团队做,估计是对一个应用进行框架,图片和文字的加载,就算多线程也会出现在界面上时快时慢的现象。

吭哧吭哧地前进,对用户体验类型的Bug做了一轮整体的修改,于是软件又看起来更像那么一回事儿了。美国产品总监开始考虑性能的问题。

在我们的测试过程中,发现有些环节的数据加载特别慢,于是调查代码实现,发现加载慢是因为前期设计有问题,设计地非常草率。现在看来哪怕一点点的思考力,就足以解决这些性能问题。换句话说,解决性能问题的根本不在维护阶段,而在设计阶段。设计阶段越草率,后面的维护工作就越麻烦。

所以,在设计阶段就需要开始考虑上线后预告有哪些数据,对每个功能点的开发都需要有足够的思考 — 如果这里有很大的数据量怎么办。进行过这样的思考和不进行思考就显得不一样,甚至代码的实现角度都会不一样。上面的用户体验的例子也可以放到这里作为性能的优化方案来讨论。先UI框架,然后所有的文字,然后所有的图片,就是为了对付图片下载的性能问题,所以把图片的下载放到最后,而把主要的页面框架文字放在前面。

好了,功能也完善了,用户体验也OK了,最大的性能问题也解决了,准备终极Release了吧。

临危受命 — 一次完满的Release

Release,即软件发布,俗称发包。在整个软件开发生命周期中,Release算是最扣人心弦的环节,因为这是整个周期的最后一个环节,而又往往是麻烦最多的环节。

之所以说Release扣人心弦,是因为大多数情况下,项目总是在资源有限的情况下进行的。要么是时间资源有限,要么是人力资源有限,最后为了能够保质保量通常不是以非常”优雅“的姿态,甚至以”狼狈“的姿态完成,最后惊心动魄地“刚刚好”完成任务。

另外一个原因导致Release总是让人提心吊胆是因为这个毕竟是软件开发周期最接近Deadline的环节,所以一旦项目出了一些错几乎没有什么多的机会加以改正,直接会导致项目延期。

从Release的作业内容来说,发布团队需要将一个软件的各个组件衔接起来,再加上项目上的文档,说明,七七八八的千头万绪,一点点的意外和疏漏少则提高所有人的荷尔蒙,多则需要重新来过,所以不得不让人绷紧了弦。

所以一次正常的,在各种资源有限的情况下完成Release,需要一个PM甚至一个团队倾尽全力完成。团队越大,合作起来越复杂,PM在里面倾注的心力越多。

幸运的是,我们依然可以从那些成功的Release中总结一些经验,并形成一个框架模型。不同的项目参考这个模型或许可以让自己相对“优雅”的完成项目的Release.

通常来说,Release环节的进入标志为Code Freeze,即代码冻结 — 所有人不得做代码Check in. 通常这个代码冻结的时间点由PM给出,而定这个时间的标准则是根据项目规模,复杂度决定的。比如,临危受命的这个项目,在交付日当天的下午1PM开始进入代码冻结。下午1PM是怎么定出来的呢?是有经验的项目管理人员,根据这个项目的规模大小,根据一次冒烟测试的时间做出的估算。有的大型的项目估计会在交付日提前两天开始进入代码冻结,因为需要留足够的时间进行交付测试。

交付前为什么要做代码冻结?每次代码Check in,都会改变整个代码库编译的版本。Check in要么是提交一个新功能,要么是修复缺陷,要么是改进代码,任何的代码的改动除了带来本身的价值外,都会引入回归(Regression)的风险。简单地说,任何代码改动可能会带来新的问题,轻则出现新的缺陷,重则整个包打不起来。如果现在已经进入交付测试阶段,不做代码冻结,开发者在测试阶段做的任何代码改动,都会让现在的交付测试报废 — 因为你无法确认这次代码Check in会不会引入以及引入什么样程度的缺陷,所以交付测试需要在每次改动后再重新来过一遍。为了让整个交付程序更加的顺畅而不是一遍遍重新来过,需要做代码冻结。

代码冻结后干什么?当然是打Build,就是把这套软件的各个组件进行编译然后连接成的软件包。这些软件包叫Release Candidates,即“交付候选”,这些候选包会做一轮Release testing确保没有大的问题才能真正Release出去。

Release testing的级别通常由项目经理和QA Leader做出决定,是做一轮完整测试,还是做一轮冒烟测试,亦或是最简单的Bug verification和小范围的回归测试。做此类决定的标准一般有三:1. 交付包的内容。如果这个交付包里有大量的改动,那么还是做一次完整测试好,否则一般改动就做冒烟测试。2. 本次交付的重要程度。非常重要的交付比如要直接上线那么还是需要做一轮完整测试的好。3. 留给做测试的时间。这是一个非常现实的问题,如果交付前期花费了大量时间,最后留给交付的时间不多,那么项目组不得不接受一个现实是没有足够的时间测试而只能妥协做低一级别的测试,从而背上一些交付失败风险,或者项目经理出面协商交付延后,当然这个也会对团队的信誉产生负面影响。

刚刚做完了一次Release testing,QA组发布了一个Bug列表。这些Bug需要在这个版本里面修复掉吗?如果选择修复Bug,那么不可避免地需要一个新的Release Candidates,而且附带有一轮新的Release testing,而且还会有新的Regression bug产生。在争分夺秒的交付时间线里面,每一次代码重新改动都需要仔细考量,因为上面的Release流程耗时很长,但又是必须的。

基于这些想法,所以一次Release testing,通常只会修复P1到P3的Bug,P4和P5的Bug就不用看了。当然项目经理可以对临场的情况做出决策,因为坏情况在于有时候P1到P3的某些诡异Bug修复时间会过长而影响Release,所以最后可能会缩小修复的范围到P1到P2,剩下的作为已知Bug列表报给客户并做出计划什么时候修复。当然,如果P1到P3的Bug太多而导致这次交付基本不可能,那么团队在交付期已无力回天,别怪交付了,好好复盘一下整个的开发过程吧。

最后整个的一轮轮做完,最后一个Release candidates将会作为交付的正式版本发给客户。用7z或者zip等压缩软件,将你的软件精致地打包好,传上FTP或者附件吧。最后一个环节也不要出错,确保你的软件包不会因为网络原因而上传不完整,否则刚才的一切努力在客户那边都白费。

最后的最后便是Release Email, 一般来说一封Release Email会有一个稍微正式的格式,让阅读者体验到“看,这个Release是我们静心准备的”。内容上会包括这次交付有哪些组件,交付版本号,代码SVN存放处,Build的存放处,还会包括一个Release Note的附件。Release Note里面会写这次交付具体有哪些更新;会有已知Bug列表,告诉接包方这个包里面还有哪些Bug,这些Bug计划在什么时候修复;当然还会有下一阶段的计划等等。

经历过上述这么多步骤后,终于可以说这次Release成功,大家可以回去好好睡一觉了。

临危受命 — 一切用数字说话

 

一切用数字说话

 

依稀记得在项目开始的时候,当时项目的USP将我的手机号发送邮件到一大票大佬们,我就觉得情况不妙,估计我的所有时间都真的和这个项目绑定上了。

之后,不论是内线电话,还是Skype,还是手机,还是MSN,还是邮件,我会经常被各种大佬找到,我想这便是PM经常的状态了。重复说一遍PM项目经理的职责,对项目的所有负责。所以即便你的项目组里面有成员若干,项目组外围的各种角色,不论是高管,还是客户,还是其他角色,如果有问题都会找PM项目经理 — 他们不会主动识别出来是技术问题所以应该找某某工程师。

于是,我就经常在上述渠道听到那些公司高管和总监的声音,不论是在平常工作日,还是在周末。

他们经常第一句话是:现在项目状况怎么样?

然后我会答:现在情况还不错,基本的功能我看过了都可以前后台连起来了,大家也很努力地在修复缺陷……

然后我就会被打断,高管他们会换种说法问:现在过的需求有多少个?还有多少Open的bug?上次交付邮件里面提到的已知项目缺陷的18个Bug现在还剩多少个?……

我管这样的电话叫夺命追魂Call。因为他可以发生在任何地方任何时间,可以在周末你抽出闲暇约会的时候,可以在平常吃晚饭正香的时候。让我印象最深的一次是当时我和同事在公司对门小街上的一个台湾卤肉店里面吃卤肉饭,说是台湾,其实也就是本地周边的人小本经营的店子,小店面,环境不太好。我和同事边吃边聊,突然手机响了,拿起一看,未显号码。一接听,”Hello, Kenny, how many bugs now?”……当时我听出来了是我们的副总裁,美国高级总监,USP团队老大打过来的。我连忙放下碗筷,”Sorry, please give me seconds.”走出小店。恰巧当时老板和老板娘在吵架,用本地方言很大声地互相对骂,我从他们的战火中穿过,一头钻进街对面的黑暗,用英文和他聊起来了。各种状态更新,打完电话一看,接近14分钟。

后来我悟道了,高管他们对这个项目的状况很担忧,估计在美国那边应该很多人找了他们不少的麻烦。他们会抽空大老远跑到武汉来坐镇项目组,但毕竟是少数时候,于是经常问项目状况是让他们安心。

软件开发总监也是说,其实有些时候项目经理就是个算账的,估计进度,算现在的需求数,算现在的缺陷数,配比人员后算现在的缺陷什么时候可以改完等等等等。我被总监批评,不太理性地去描述问题。就像上面那段对话,我讲的话里面有内容吗?有,就是现在项目状态总的来说是积极的;也算没有,积极到什么程度?离结束还有多久?再加上不同的人对待感性描述的理解不同,于是都要求将一切用数字描述,只有数字才能让世界各地的人知道现在具体发生了什么。

了解到这一点之后,我开始有意识地要求自己,一旦自己空下来,就去统计现在的项目状态,简单地说就是统计各种数字。比如现在的过的需求数,过的需求数除以总需求数的百分比,现在的缺陷数,有多少个P1的缺陷,有多少个P2的缺陷,这么些缺陷都什么时候才能改完等等。然后将其记下来并随身带,这样就不再惧怕任何夺命追魂Call。同时,如果预测到每天某个时间高管总会电话来,干脆就提前给他发个邮件并简明扼要的说明项目状态,这样夺命追魂Call也少了很多。

更值得一提的是,当你很清楚地并迅速地将理性的数字表达出来,这个时候感性就不知不觉地释放出来给对方信心了。

临危受命 — 对错之间的电话会议

 

对错之间的电话会议

 

在这个持续的5周时间里面,有几次交付。每次交付,我们除了提供版本包以外,还会提供一份已知缺陷列表 — 没有哪个软件是0Bug的。

在某次交付之后,美国的产品总监第二天又发了一份缺陷列表,说这个是他在这次交付里面“随手”点出来的,并且带着质问的口气问我们的开发团队为什么还会让这些缺陷留在软件里,另外我们的测试团队为什么没有将这些缺陷找出来。最后他期望在第二天早上他们的9AM也就是当晚我们的9PM好好的讨论下这些Bug。

美国产品总监的为人我已经早有所耳闻,而且经历过几次。所以当他带着强烈质问责备的语气去提出他的缺陷列表的时候,我第一时间就是去分析他的缺陷列表是不是真的如他所说的那样,而没有沉湎于他强烈问责中而不安,更没有直接和他理论“怎么可能发生这样的情况”,因为在这样临危受命的大背景以及他是我们的上司的情况下这些情绪上的对抗毫无意义甚至会让状况变得更糟糕。

我花了一早上的时间一个个看他报过来的Bug,并且和工程师一个个确认,然后从他那凌乱的缺陷列表中找到和我们的已知缺陷列表中对应的Bug。最后我将每个Bug加注了相应的评论,并且给出总结。总结用数字说话,告诉了哪些Bug已经在我们的已知缺陷列表中,哪些Bug其实是新的需求,哪些Bug是用户体验方面的Bug — 现阶段大家先完成基本功能为目标,用户体验方面稍后,哪些Bug根本就不是Bug等等。

随后这份报告发给了我们的软件开发总监A,接着他给出了他的一些评论,我根据他的评论改善了报告。最后这个报告发给了USP,他根据我们的情况也加注了他的评论,我又根据他的评论改善了报告。

就这样,几乎每个人都预测到,晚上的电话会议一定是腥风血雨,我们需要接受美国方面的严格的盘问。我们为这次电话会议做了一整天的准备。最后我小心翼翼再三查看并静心写好邮件后在电话会议之前将报告发给了美国。

晚上,气氛紧张的电话会议开始了。美国方面那个凶神恶煞的产品总监跟着我们一起过Bug,并且我们共享着桌面和Mac,可以让他现场看到我们部署好的环境。针对每一个问题,双方细细地推敲。遇到他误报的问题,他一带而过;遇到我们的问题,哪怕不是现阶段应该注意的问题, 他会严厉指责为什么没有做好。总监在会议室里面转来转去,他屏气听着我们的对话,他并不在这次电话会议上出现,所以他会按下静音间告诉我如何回答电话中那无赖的指责,然后由我来回答。

照理说我参加过很多电话会议,但是这样子各种大佬参加,维护团队甚至公司声誉级别的电话会议我才是第一次参加。会议后,我发挥地并不好,虽然我感觉和平常的电话会议我发挥的一致,可是得到了软件开发总监的批评。那天给我感触很大,夜晚天开始下雨,我和同事离开公司分开后没打伞走了回家。雨越下越大,在暴雨中行走也可以好好地反省一下。

这次电话会议虽然过程很痛苦,但是收获也颇丰:

Reputation很重要。Reputation,就是声誉、声望。人是一种很奇怪的生物,就算一群很严谨做技术的人,你会发现在他们身上发生的事情并不是各自独立的。

比如说,如果你们在讨论10件事情,如果你第一件事情就处理地很失误,或者说你马虎了,或者说你说的话明显有问题,那么你们在讨论完第一件事情后,后面的9件事情对方都会用一种质疑的心态跟你讨论 — 对方会想后面的事情很可能和你的第一件事一样也会出错。正因为此,我们需要在一个电话会议前,一次交付前,做任何一件事情之前保持严谨的作风,并且充分准备,否则你的Reputation,声誉和声望就因为某件事情全毁了。记得一个场景吗,路人甲跟路人乙说:那家奶茶店不干净,上次我看到他们里面把掉在地上的水果加到奶茶里。估计不论是路人乙,还是作为路人丙的你,都很难再去那家奶茶店了吧。

电话会议往往也是团队作战。根据上面的第一点,当遇到讨论技术细节的时候,PM可能并没有具体的工程师清楚,这样不妨让工程师去回答而不是PM直接去回答,虽然PM的英语可能比工程师好。为什么?因为这样的技术细节,如果PM答错,或者说很多无事实根据的推断,很容易造成Reputation降低。这样不妨让工程师代劳,如果工程师说错,PM可以再接话过来说事后可以再讨论。这样有利于维护己方PM的Reputation,从而PM可以在其他方面更容易地维护己方利益。

电话会议,其实是跟人打交道的。虽然是讨论技术,但是如果你是一个天使类型的技术人,很有可能你在电话会议中并不那么占有便宜。如果是跟人打交道,那么还是需要懂点丛林法则。工程师思维容易认错,说这是我的责任。没错,当然你可能负上主要责任,但是如果你直接交枪,那么对手接下来会把本来不是你的错,或者你只负有一点责任的事情往你身上推。这些虽然很“邪恶”,但确是事实。我们需要尊重事实,所以也需要聪明一些地维护自己的利益。在坦诚自己错误的同时,也要想想对方是不是也有做得不对的地方,勇敢说出来,就不会让你处于过度被动的地位。

这次电话会议让我明白,现实并不是非黑即白,同样的情况在不同话术的牵引下,结果会导致不同。如果说现实就是一个灰色空间,那么一个合格的PM,首先守住做人和做事的底线 — 即不欺骗讲诚信,然后应该在某些时候变身一个恶人,凶恶的善良人,因为你不能让你的团队和周围的人受到不必要的伤害。

临危受命 — 再论角色扮演

角色扮演

 

09年的时候,我写过一篇软件开发的角色扮演(点这里),那里主要是叙述在通常情况下每个岗位的人一般如何各司其职。接下来要说的是在这个临危受命的项目中,观察到的一些角色扮演,有的是对已知的角色补充,有的是介绍一些新角色。

1. 项目经理

项目经理是项目的直接负责人,对项目的成败直接负起责任。在项目经理的这个角色上,需要有很强的主人翁意识和自我驱动力。简单地说,你要视你的项目为你的孩子,静心打理,这个项目交给你,你就需要操所有的心。你需要很清楚地知道达到项目交付需要干些什么,你可以听从别人的建议,但是如果只跟着别人的指点自己没有主见,那么项目很有可能在你手上砸掉。

项目经理最主要的工作就是掌控对项目的进度,追踪项目的状态。思考一个问题:你说你在做一个项目,那么这个项目的状态是什么?

我在这个项目中扮演这个角色的初期,我经常会用“感性”去描述:现在比以前好多了,很多模块都可以用了……但是实际上这会让很多人迷糊,因为他们不知道你的感觉到底是个什么样的程度,你的感觉准不准。

所以需要用一些理性的数据来描述,而数据是需要填在一些框架里的,于是就会有需求列表,时间线,Bug列表,问题列表等等一系列的框架。这些框架依照现实填满了数据后,就可以提炼成一些数字。比如说,需求列表当前显示一共300条需求,完成了160条,另外30条需求还有bug,还有50条直接做废了,剩下的没有做;时间线显示开发者A进度落后了3人天的量,离交付还有5人天的工作量但是实际上还有3天了;Bug列表显示P1的Bug还有3个,P2的Bug还有5个,P3的Bug有12个,我们需要在交付前全部修复他们;问题列表显示还有5个需求是有问题的,其中的2个会影响到下一个交付……

这样就会让自己还有任何人,对这个项目的状况清楚。

然后就是一些日常管理杂事,比较琐碎,但是就好像玩游戏里面的微操一样。只有一点一滴都做好了,你的项目才不会危险。这其中包括:客户沟通,控制交付流程,需求分析,组织人员做估算,分配Bug。

突然问一个问题:如果有个技术问题一直困扰着你的技术人员,你该怎么办?不要说这是技术人员的事情,不是项目经理的事情。 — 在项目中任何事情都是项目经理的事情,所以项目经理需要对所有事负责。技术人员只是代理你做技术这一块的事情,如果这个技术问题解决不了,你可以找人求助,卷起袖子自己干,替换掉这个技术人员,告诉客户这个需求在下一次交付里面包括等等用一切你能用到的手段推动项目前进。有句俗话:人挡杀人,佛挡杀佛。描述的就是项目经理的霸气。

2. 开发

开发除了写功能外,还要的是修复Bug。这两样除了写代码外,就是需要做估算。估算,应该由开发这个功能和修复这个Bug的开发自己给出,而不是项目经理。项目经理往往之前是开发,然后加上项目的压力,往往让开发做估算的时候会抢着说“这个明天做完没问题吧”。建议的是由开发自己说需要花多少时间,如果有分歧项目经理可以和开发稍微探讨一下实现方式,总之尊重开发自己的承诺。但是开发一旦承诺,就务必做完,超出的时间需要自己花额外时间补齐,以便不会影响到其他的进度。

3. 测试

测试方面,除了写测试用例和跑测试用例外,也是需要对时间进行估算。和上面开发一样的原理,项目经理需要尊重测试给出的承诺。有稍许不一样的是,有的时候项目时间线压力大,往往在交付前留给测试的时间相对较少,测试可能测不完全,那么只好是测试了多少就算多少,尽量保证所有的功能都覆盖到,然后项目经理报Known Issue(已知错误)以及说明情况以调整客户的期望。这里的意思是,测试需要在给定的时间内最大程度的测试。

测试还可以定义Bug的优先级,这个往往直接决定交付。通常来说,一个交付里面应该不会含有P1到P3的Bug,否则交付会受到影响或者说不能交付。一般来说,P1的Bug会被修复掉,因为太明显。P2的Bug也会被基本扫光,P3的Bug可能还会剩。所以这要求测试对Bug的优先级定义要尽量准确。

测试还可以标明一条需求是过还是不过,因为一条需求可能对应一个功能点,而一个功能点又可以有多个Bug。一般来说,一个功能点有一条P1到P3的Bug就可以标这个需求是不通过的。在这样的判断标准下,测试需要保留自己的独立判断权。

4. 乌克兰同事

乌克兰的两个同事实际上也是开发者,和我们的开发者身份一样,也是做部分模块。在项目开始的时候,我们也是第一次和他们一起工作。当时有个不太正常的关系是,因为乌克兰同事所在的公司是我们所在的公司的客户,所以我们的团队成员就把他们也当“客户”。毫无疑问,这样的关系是不健康的,因为我们所做的事情一样,为什么需要像客户那样供着?不卑不亢,平等合作才是正道。他们依然是属于项目经理的管理,所以中国的项目经理需要摆正心态。

5. 美国的同事

其实美国那边也有两个开发,他们也是项目组成员,只不过他们在美国产品总监身边,所以有的时候并不太买中国项目经理的账。具体的表现并不是“项目经理让他做什么他不做”,而是他可以直接做美国产品总监分配的任务而不告诉项目经理。曾经还一度出现,乌克兰的同事突然之间在做其他的事情,然后项目经理仔细一问,乌克兰同事在做美国同事跟他商量好的东西,在Skype上面商量了就直接干了。

6. 项目总监

他给整个团队的方向定基调,是项目经理汇报的对象。在公司层面,他的压力来自于公司高层,让他紧盯这个项目,于是他会参与我们的Bug分配,参与我们的交付。但是他一般不会直接做事,而是让项目经理完成他的指令,以及指导年轻的项目经理怎么处理难缠的客户。

7. 临时加入的外援USP
帮手还是累赘,看你怎么用?他的身份决定他不会由ownership,你来驱动他做事,虽然他比你官大几级。

在项目最焦头烂额的时候,公司高层那边介绍了一个USP,就是在公司美国总部的人。介绍的理由是他了解iOS项目,可以给我们一些指导。那个USP来了之后就想要搭各种环境,以便看到App效果,而这些环境又在我们内部网络他不能直接访问,于是我们只好在美国找到一个服务器忍受龟速的网络跟他搭了一个环境。心中觉得憋屈在于,他对于客户不可见,但是我们在本来焦头烂额缺人手的时候还需要花费额外的功夫帮他做一些事情。又不知道他对于客户不可见对我们有什么积极的意义。

最后,项目的最后,他总算提出了几点iOS App的建议。

不过回想起来,他的身份决定了他在这个项目中属于顾问的角色。如果他被高层指派到项目组中提供帮助,那么项目经理不能不招待他,但是招待他的同时,项目经理需要打好算盘怎么来利用好这个钦差的角色,让他要么对客户,要么对团队有积极的帮助。否则只能损失一些招待的成本。

8. USP老大
一个老头子,多次电话会议参与讨论。沟通极其棒,他很明确自己的角色,所以当其他人说你要不要看看App长什么样子,他说他不用看,因为很多人在看,他只关心项目的进度。所以这就是他拿着我的手机号的原因,随时打电话我“现在多少Bug了”,而作为项目经理,我也就因为他养成了将项目状态放在心中的习惯,时不时去看看实际的状态然后做出调整,否则就会被他骂。

“我问你的是一个很简单的问题,很难回答吗?。。。。”