到底该不该发未完成的包

这大概是两个星期之前发生的事情了,这个星期一直很忙,于是没记下,再拖就一个月了,决定今天,现在,记下这个教训。

经验总结,关于该不该发未完成的包:

如果提交对象是非技术型客户,不能发,因为没有任何意义;

如果提交对象是技术客户,谨慎考虑,尽量不要发。如果实在有原因要发,要在邮件写清楚,并且注意把握可能发生的风险。

发未完成的包都会因为误解、沟通丢失等带来各种各样的问题,决定发的人要为此负责。

早点给code请个医生

有这么一个场景:

一位穿白大褂的医生脸色凝重地走进ICU(重症监护室),对躺在病床上的70岁老人的家属说:太太,CT显示您先生大脑里有一恶性肿瘤,不过这个恶心肿瘤现在是可以通过手术来完全移除的。
太太:那好啊,什么时候安排手术?
医生:不过。。您先生岁数太大,身体机能无法承受手术中的创伤。虽然手术可以完全移除肿瘤,但是只怕先生挺不到手术结束了。
太太:那怎么办?
医生:那就保守疗法,将就活着呗,直到自然死亡。虽然会有痛苦和随时死亡的风险,但是比在马上的手术中死亡要好。
太太:……

与此同时。。。

一位穿着衬衫的高级软件工程师脸色凝重地走进办公室,对底下的工程师说:你的代码在项目结束前的Code Review(代码评审)中发现一个严重的性能瓶颈风险,现在体现不出来,但是在客户那边数据到达一个数量级就会体现出来了。。还好我已经有解决方案了。
工程师:那好啊,现在开始改?
高级工程师:现在来不及了,项目已经接近尾声。这个项目必须在明天提交客户上线,现在做出如此多的变动风险太大。
工程师:那怎么办?
高级工程师:先发给客户呗,在Release notes里面写清楚风险。随后我们开始做软件更新,然后再发个Patch过去。不过这段时间成本客户是不会给钱的,而且客户满意度会因为这个patch下降。
工程师:……

上面的两个场景有一个共同的尴尬:有一个解决问题的方案,但是因为时间(或者岁数)的关系来不及执行下去。
引发这种尴尬的核心原因是:发现问题太晚,总是在deadline前后发现。

最近的一次项目尝试使用上面的方案,客户在电话里面说非常满意软件质量。

于是,就出现下面一个场景:

一位穿白大褂的医生表情轻松地走入了病房,对一个躺在病床上的小伙子说:CT显示你的大脑里面有一颗良性的肿瘤,现在用手术可以轻松解决。但是如果现在不做手术,你70岁的时候可能要在ICU(重症监护室)里面度过了。
小伙子:谢谢医生,现在可以手术吗?
医生:嗯,马上!

与此同时。。。

一位穿衬衫的高级软件工程师表情轻松地走入办公室,对一个正在埋头写代码的工程师说:刚才我花了半个小时做了个Code Review Sprint,发现你的代码里面有一处性能瓶颈风险。现在如果不改的话,那么将对以后的代码造成严重的影响,最后到客户那边的大数据负载下会不堪重负。
工程师:谢谢,您辛苦了,现在我可以将改动Commit进去吗?
高级工程师:嗯,马上!

今日事,今日毕

一个人如果没有目标,就会迷失,就会拖沓,就会慢下来。

这句话用在大方面可以上升到职业或人生规划,小方面则可以具象到每天的工作。

对于一个每天都必须要有产出的团队,我们的风格是“敏捷”,我们的目标是把事情搞定。(Get Things Done)

技术是死的,人是活的

 

上一周的工作对我很有启发,本来想在周会上分享给大家的,可是后来谈我们的新年目标“敏捷”去了,由于时间关系也没有再多谈一周感悟了。

简单的说这周工作中的思考来自于和团队成员的几次争论,我是站在实用的观点,对方站在技术的层面,总结出来有三点:

1. 不要让技术指导业务

Comments: 从本例中,思考的方式比结果更重要,思考的方式不对即使结果对了,这样的成功也是无法复制的,而且会对未来的设计更大的架构带来隐患。

Comments: 设计方案是给人看的,除非是遇到技术瓶颈不得已用非常猥琐的办法做之外,尽量用符合人之常情的做法,因为技术本身就是对业务的抽象实现。

2. 设计模式不如实用模式

Comments:马谡:书上说的居高临下,势如破竹,我要在山上扎寨。王平:丞相嘱咐过,万万不可啊,人家围山切断水源放火烧山,后果不堪设想。应该依山傍水,当道扎营。请主将三思。马谡:滚。。书中自有黄金屋,书上再找不到比这更好的设计模式了。。。魏军大喜果然围山并放火,蜀军大败,痛失街亭。诸葛亮不得不挥泪斩马谡,战略上退回汉中。

3. 最难的是承认错误

Comments: Engineer protect his idea and the code which has been written, I respect his idea and his code, but I respect the right logic more.

嗯,技术是死的,人是活的。

一些基于大系统更新bug的经验

 

 

在最近的一段时间,工作上经常会扮演团队管理者的角色。随着新人慢慢适应了新环境,接下来要让他们真正成长的重任落到了我的肩上,当然,这也是我成长的过程,也是团队成长的过程。

上个星期接到了一个任务,我们开发的一个最大的系统在经过了上线的考验后,又来了一批共8个的需求更新。我想了想,决定让新人来做这次更新:如果让熟手做可以很快做完,但是新人又会少一次成长的机会;新人一上手就这样大的项目更新是有风险的,于是为了控制风险:新人写代码,熟手来看他们更新的代码并负责测试。这样在有效控制风险的同时,新人也得到了锻炼。

还是以案例来说,以下几个案例很有趣值得人思考:

1. 不注重用户行为的一致性(consistency)

2. 只看自己要更新的需求描述。

3. 不抓住本质核心

其实在修复bug的时候,特别是针对这样的特大系统,思考力变得重要,开发人员不要仅局限于某一块任务,也不要上手就开始写代码,多思考可以让人尽快抓住bug核心,从而用最少的代码解决最正确的问题。

在这整个作业流程当中,特别是第三个案例,在我们会议室交流了两个小时的时间里面,发现了大量的沟通问题:往往两个人对话,听别人讲的那个人往往看似听到了,其实什么也没听。在沟通中不会听是致命的,这些沟通方面的问题暴露,大大坚定了我下一步抓沟通的决心。

由密码引发的“专业性”思考

 

 在十月SOHO期间,办公室的同事和我就密码的问题MSN了一段讨论,这段讨论引发了对软件工程师“专业性”的思考。

技术人员通常有荣耀感,会坚持自己的技术观点不动摇。这一点挺好,但是如果做出了一个错误的判断仍然将一句真理作为支撑自己的后台的时候,有管理角色的人就应该想办法让技术人员心服口服地改变自己把持的观点。所以焦点就在于如何反驳“密文更加Professional”这句看似的真理。

不管是软件工程师,还是其他职业,专业性是显示其职业成熟度的一个重要指标。随着经验的积累,面对同一个事情所显示的专业性具体表现也会跟着改变。是为记。

真的是最后期限吗?

在项目制软件开发中,工程师和项目主管的主要压力来自于最后期限(deadline)。

有人或许说主要压力是来自于技术难点,但是事实上没有解决不了的问题,要么将技术难点攻克,要么绕过技术难点用其他的解决方案。问题在于解决技术难点需要时间,而这会让本不太多的项目时间更进一步逼近最后期限,而“按时交付”是评价一个项目成败的关键因素,所以压力由此而生。

华山不再论剑

在商业软件开发中,胜出的往往不是最好的技术和算法,而是最能够满足客户需求的技术和算法。 ---- 题记

古有华山论剑,最早出自于金庸老先生的武侠小说《射雕英雄传》,各大武功门派好手聚集华山,一绝高下,争锋天下第一。

整个的协助工作做下来,觉得最浪费时间的还是当初的华山论剑。因为技术人员都有脾气,都试图去证明自己的想法是最好的,所以有两个这样的人谁也不服谁的时候,时间的浪费就产生了。他们聚焦于最优化的技术解决方案,而往往忽略了客户其实最想要的不是最好的,而是能够解决他问题的方案。不是说最优化的方案不好,而是要除了技术本身以外,多从项目本身或者商业本身的原因去想想。技术人员当然不可能想这么多,也正是因为这点,项目中的管理人员,决策者不可或缺。

真希望有那么一天,华山不再论剑。少林寺的走进社区教老头老太强身健体,峨眉山派的作为女子防身咨询公司解决了大量单身女性的防骚扰问题。。。。。那样的话,比在华山上比个天下第一有用得多。

软件开发中的角色扮演

商业软件开发并不是只有一个编程的人,而是可以分为不同的角色。

不同的软件公司因为规模大小性质各不相同,所以围绕软件的角色也各不相同。这就好比在重点学校里面分级很明确,每科有个老师,每个年级每个班级都有各自的老师,也有主任书记校长支持角色。而在电影《一个都不能少》级别的学校里面,往往一个老师兼职从语文教到体育,年级从一年级到六年级。类似的说,一个大型的软件外包企业,外资企业,往往分工明确细致,每个人像螺丝钉一样在一起工作,让整个大机器得以运转。而在一个小型创业企业里面,往往一个人从接触客户,到开发产品到交付产品一条龙走完,整个产品周期就一个人,甚至几个产品周期就一个人。

所以解释角色要针对性。远的不说,就拿我们的项目组来举例。我们项目组可以说一共有5种角色,开发(DEV),测试(QA),质量监督(SQA),技术主管(Tech-Lead),开发经理(SDM)。

边际效用递减

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

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

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

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

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