边际效用递减

这段时间在工作中,QA经常给我发一些bug,这些bug确实也是bug,但是是那种“需要花费很多工作量才能达到一点效果”的bug。对于此类bug,我的态度是,
1.作为enhancement,我会在后期有时间的时候fix掉;
2.如果在软件开发正式开发过程中,我会将精力更集中在开发功能上;
3.如果在软件打包的那天,拒绝fix;
4.特殊情况除外。

在软件的早期版本包中,相当于部分功能开发完成的提交,这个期间软件产品的已有功能不可能达到完美的程度。尽管我们工程师经常有完美的意识,但是在deadline的有限时间内,我们要做的就是把基本的功能做好,然后才去fix这些bug。如果时间有很多空闲,就不在此讨论范围之类,而大多数的情况是,按照流程下午2:00打包,但是如果早上发现了此类bug,fix这些bug需要大量的工作量,但是又只能达到一点效果。这时候如果开始编码fix这个包,那么很有可能下午规定时间内不能打包,于是内部开始delay。流程被打破之后,如果为了修复这个小bug引起了其他的回归bug(regression bug),那么其他的DEV又要去修复。修复完了之后QA再做full test……如此下去,包最后一定打好了,但是所有team内人都搞得身心俱疲。

最后包发到客户那里,客户可能只会关心这次提交的主要功能,至于这个enhancement的功能,客户也许完全不在意,因为他知道这不是终极版本。而且即使这个enhancement没有,也不会影响主要的数据和用户体验。

于是我们在做完主要功能后,承担着压力和风险,在软件提交日花了大量额外时间做的一个小的enhancement,客户可能完全忽略,甚至连测都有可能没测到。换句话说,之前花费的大量精力没有对客户满意度有大的提升,甚至没有提升

这让我想到了那个烧饼的故事,一个大汉饿了N天,有一天终于可以吃烧饼了。开始吃烧饼,第一个觉得味道太美了,简直是世界最美味的食物,第二个也很好的味道,第三个也是,到了第14个以后,望着第15个烧饼,只打饱嗝,抱怨说,这个烧饼太难吃了。其实第15个烧饼和第一个烧饼是一样的。

200多年前,Bernoulli提出的期望效用理论(expected utility theory)可以解释这种现象。期望效用理论认为,人们应该选择的是期望效用最大的那个选项,而不是期望值最大的那个。说白话一点,效用有时候是一种感觉(feeling),如果我们能够让别人有这种感觉就很好了,而不在于给别人的东西有多大价值。就像上面的烧饼,第一个和第15个一样,但是第一个给人“感觉”就很好,所以让人满意度也很好。同样的1000块钱,用于给总监加工资和给普通员工加工资完全效果不一样。

同样,给客户发包的时候,客户的满意度不在于你在这段代码里面你花了多少努力,而在于你完成的功能给他的感觉。当他看到你写的主要功能都完成之后,就像吃了14个烧饼,然后他可能就不在乎你那一点enhancement了,你那一点enhancement不会给他太大的满足感,如果你为这个enhancement花了甚至多于主要功能的努力的话,那么就显得有点stupid了。特别是在打包日把自己和团队其他成员感到身心惧疲,就更不划算了。

所以如果我们掌握了这一点,在和客户交流的过程中,就更可能会聪明的提高客户满意度以及内部软件团队管理了。


管理成本与收益

周五又开周会了,气氛很凝重,主要是对近期发生的事情检讨,然后分析到底什么原因出现了这样的事情。

主要是因为两个项目,一个项目的事故在于用一个项目文件覆盖另外一个项目文件的时候,被覆盖的项目文件属性不会变。这一点很不make sense,而那个属性直接影响到手机同步数据的问题,所以自然到客户那边会感觉出了一个很大的事故。第二个项目的事故在于客户要求在每级数据库下加一个key字段,但是这边DEV在加的过程中,只注意到名称,没有注意到类型,导致某个key字段居然用image类型保存。

于是在会上每个人发表了自己的观点,总结起来主要就一点:心理麻痹。简单的说,在一个人在面对一个熟练工作的时候往往放松警惕,发展到最后事情有时候就不会考虑很全面,做事情的时候就不会足够的严谨。开发人员对自己放松了,很容易在产品中表现出来。第二个项目事故就是一个很好的例子,还是一个低级的失误,实在有些让人汗颜。

至于第一个事故,我的感觉还是过于自信。因为这个项目客户的一套API,IDE,客户端很特殊,网上找不到资料,而官方资料提供有限,所以很多机制,原理我们并不了解很透彻,在这种摸着石头过河的情况下,尽量还是少“想当然”一点,多检查几遍。说到检查,团队内部准备加入一个新的机制,就是放入一个Check list。每次最后软件打包的之前,由QA对照着Check list从上到下检查一遍,保证所有主要功能点覆盖而不遗漏。如果有这样的机制在的话,那么第一个项目事故就应该能够很快的检查出来,从而能够轻松定位到那个属性。

这样说来Check list就很重要了,因为任何管理手段都有成本,我们就应该在成本和收益之间找到平衡。Check list最好是要不遗漏,不重复。找出一条最短路径覆盖所有点,保证检查的效率。因为每次软件打包都有可能甚至对某些项目来说极有可能是在时间非常紧急的情况下发生的,能不能保证Check list的执行力是每个人应该思考的问题。根据我们目前项目组的情况,团队成员状态有所下滑,客户满意度有下降趋势,Check list的引入是非常有必要的。至于制定人的角色,可能QA更好些,第一是因为QA日常空闲时间比DEV要多,第二是因为写测试用例的QA写Check list驾轻路熟,第三是因为Check list主要是模拟客户行为找出比较大的问题或者低级错误的问题(以代替客户发现这些问题),而“模拟客户行为”QA更在行。

而团队成员有的也提出,搞一个“大家来找碴”的游戏,每次发给客户的邮件先发给我们大家,让大家帮助找错误。其实我是非常赞同这样的想法,第一保证质量,第二比较有趣味。但同时我也很担心这个游戏的成本和执行力。

个人方面,每个人每天都有自己的任务,都有自己最重要最紧急的事情,如果我在处理这些事情的过程中,有人邀请我做“大家来找碴”,我想我是不会做的,因为这种找碴本身很耗脑力和体力,除非我闲的时候我会看,否则我不会回复。机制方面,因为回复意味着你对你double check的结果负责,说到负责,“大家来找碴”最大的一个缺点是没有责任人,这是非常影响执行力的,“大家来找碴”其实就是一个mini的FTR,不过跟正式的FTR不同的是正式的会指定责任人,而这不会。没有责任人,那么发信的人就不知道等多长时间会回复,那么就不是很清楚是没有人看还是看了没有错误。团队方面,沟通的成本进一步增加,一天本来就有很多的邮件,客户的,leader的,同事的,如果还有与你无关的项目的邮件过来让你检查语法错误,我想每个人更会焦头烂额。

SQA也提出定期做一个全面的测试,但是开发主管也明显考虑到这个措施的成本以及收益之间的关系。

成本与收益,应该是软件项目始终要考虑的东西。

生活依然继续

生活依然继续。平淡是主旋律,偶尔来的变化则是点缀。

新项目一个接一个来,刚刚分析完需求,准备开工的时候,客户一个邮件过来说等等。接着在莫名其妙中修复老项目的bug,接着又莫名其妙的接到一个邮件说新项目来了。此新项目不同于彼新项目。很好,“这个世界果然在飞速变化”,不知道会不会激起我对变化的嗜血性,游戏很精彩。

关于English,我承认我在不断的学习中。以前说过我想把TOEFL 10000这本书的所有单词例句往博客上面抄 [详情],其实我没有食言,我是不断的在公司把那本书往电脑里面写,我不知道写完之后效果怎么样,但是有一种坚持也不错,哪怕只是小小的抄书。在All hands meeting上,我提出公司英文环境的逐渐缺失需要引起重视和采取必要的措施,结果是我偶然的一段中文对话被突然出现的SQA抓到现行,于是无奈地往存钱罐里面放入一元血汗钱。当然这只是一个花絮,平常这段时间办公期间我们团队对话语言和MSN语言基本被英文覆盖,则是铁的事实。

星期六又去踢足球了,这次是真的踢足球,手指受伤的困扰让我从守门员暂时转战到后卫,后卫感觉也还不错,一开始累得上气不接下气,过了一段时间就逐渐适应了这种奔跑强度,于是精彩解围和头球助攻纷纷在我身上上演。

上个星期聚会了两次,都是光谷帮的高中同学。说实话,跟他们在一起是最放松的时候,哪怕不说话也可以。不过毕竟是在不同的环境里面生活,想法也都不尽相同。在国有研究院里面读研究生的某位兄弟一直说我很迷茫,我不敢说我不迷茫,但绝没有他说的那种程度。也许受到环境熏陶,他无法理解什么叫”Genius of the AND”,我也不想强制价值观输出,这样挺好,如果什么价值观都相同的在一起就太没意思了,前提是彼此互相尊重对方价值观。有这样的朋友,我感到很满足。(如果你看到这段文字,下个星期的聚会不要找我纠结此类问题,我拒绝^_^)

寝室有电脑了,于是每天下班回家,就和美国的六个人一起享受《Friends》的快乐时光,真想和他们那样,不过貌似在中国,不太允许。大环境不太允许,我个人应该没问题。

今天国际劳动妇女节,祝天下女生生活甜蜜幸福。

生活依然继续,发现我很喜欢点缀,喜欢新鲜的东西,不喜欢按部就班。如果没有点缀,那就由我来创造点缀。

Cool~~

软件包中的调试代码

上周一的一次Deliverable出事故了,一个DEV因为同时负责几个项目导致慌乱将某个软件包中的debug信息忘记去掉,发到客户那里被客户发现,在一个主要功能点上打开界面居然弹出4个Message box(DEV常用的调试方法),导致那个美国客户花容失色(想象的)。

背景是这样的,那天这个DEV本人接到了很多任务,而且都是跨项目的,他一共负责两个项目。其中有一个项目便要当天打包发给客户,于是他急急忙忙fix了一个bug后,便打包发出去了,然后马不停蹄的做下一个项目的debug工作。因为我们的项目的特殊性,调试是要用message box的,这位仁兄调试完了之后忘了把messagebox()的代码删掉,也没有自己测试一遍就打包发过去了。Tech-lead基于对这个DEV(确实技术很牛)的信任,看完邮件后直接发给客户,于是第一段的情况出现了。

我们的项目从技术上看是这样的。
1. 面向过程。
2. 工程文件只有一个xml文件。
3. 一个比记事本稍微好点的IDE。
4. 调试无法IDE跟踪,只能弹Message box显示变量信息。

多次事实证明,一个人在慌乱的时候或者心理状态不佳的时候,代码质量也不佳 [详见此] 。智商不高的客户怎么也不能理解在一个主要功能点出现类似于“0”,”f1″诸如此类的信息是怎么回事,于是自然愤怒。还好最后在我们的SDM和Tech-Lead的公关下解决了客户的不满。

说到这里我们的经验是什么:
1. 做任何事情不能慌乱。
2. 如果头脑迷糊,可以暂停工作,用冷水洗脸,清醒后继续。
3. 如果同时有多个项目在身,要一个一个的做,项目项目之间不能随意切换,否则大脑容易迷糊。
4. 不要在主版本上面调试,任何调试要在自己的版本上面调,调好后再merge到主版本上。这样从源头上阻止了调试代码的嵌入。
5. 任何debug完成之后,DEV不要过于自信而不测试,因为大脑不像电脑永远可以保持活力和“全面的思考”。
6. 在最后的软件版本完成之后打包之前,QA要做个全面的测试,至少smoke testing(冒烟测试)要覆盖所有的主功能点
7. 在重要的包发出去之前,如果有必要的话在Tech-lead这里做一个“随机点击测试”。

经过这几层过滤下来,在软件包中含有调试代码的几率将大大减少。