如何衡量每一次决策的价值
最近和朋友聊到这个话题,顺便发散一下,说说完整想法。
我首先觉得这是一个伪命题,不太可能有种方法能衡量决策的价值。决策有时效性,过了这个时间,决策的价值就发生变化,无法衡量。此外,决策也没有绝对的好或不好,往往都是各方权衡的结果。相对来说,决策的过程比较容易衡量,如果每次能按照最合理的过程来进行决策,决策本身就应该具有最大的价值。就能从侧面衡量决策本身的价值。
我认为合理的决策过程是:找到所有决策相关的人,推动大家在合适的时间达成一致。Find out stake-holders, and push them to reach a consensus at right time.
这句话非常的tricky,里面暗含很多意思。比如谁去负责push、stake-holders如何定义、right time究竟是什么时候等。
如果我是决策的最终负责人,那么负责push的人就应该是我,这个最容易回答。
要界定stake-holders就要看这个决策一旦制定该如何实施,所有在实施过程中会涉及到的关键人物都应该算作stake-holders,决策的过程应该是所有stake-holders buy in整个决策的过程。比如要决定一个feature是否应该做,首先可以假设要做,然后就可以知道需要有PM来决定feature细节、要dev决定如何实现、要team lead决定如何将这个插入项目计划之中,等等,这样就要引入相关的负责人来进行评估。此外,这个例子里面暗含一个角色,这个feature的提出者,他/她有可能是一个dev、客服甚至公司外的用户,他/她应该也以某种形式参与进来,直接参与或者由某个人(PM)代理。集齐所有stake-holders,每个人buy in这个决策的后果(该干活的干活、该承担风险的承担风险等),就可以让这个决策通过,否则,修改决策本身,继续讨论。
要确定right time非常困难,但可以有几个简单的衡量标准,比如要做出决策的各方面条件是否满足、决策本身是否依赖于某些时间相关的因素等,总的来说是一个仁者见仁的过程,需要决策的最终负责人来给出right time的预期。需要注意避免把right time看做是deadline,任何schedule都会遇到意外,而right time则不能出意外,deadline一定要早于right time,这样才能使得这个觉得真的right。此外,right time也不是ASAP(as soon as possible),过于草率的决策往往结果不会太好。
“如何做决策”是一个需要长期积累的技术活,我现在经验尚少,只有这些肤浅的认识,欢迎所有读者过来批评指导。 :)
Scrum的基础知识、常见问题和解决方法
Scrum是一种敏捷开发过程,最基础的介绍推荐看这个:An Overview of Scrum
关于Scrum运行当中常见问题及解决方法,我曾写过一个slides,在公司内部分享,现在重新整理了以后共享在这里:近距离接触Scrum
近距离接触Scrum
View more presentations from huandu.
关于Scrum,最常见的误解是Scrum master == team lead,这是不对的。Scrum master可以是任何人,不需要担当任何管理职责,在Scrum中只是一个推动者。
除了Scrum过程本身,还需要整个team共同遵守一些游戏规则。这些规则可以根据实际情况来制定,不过尽量不要超过3项,毕竟人能同时记住的事情一 般不超过4项,还得留1项给当前的工作。
例如,可以制定以下规则:
No suprise:大家都有义务保持信息通畅,及时有效的将stakeholders关心的消息传递给他们,尽量不要让任何人对结果产生suprise。对于不紧急的沟通,可以选择在daily scrum的时候将信息传递出来,尽量不打断其他人的日常工作。
Focus on one thing:很少有人能够快速的在多个任务之间切换还不影响效率,集中精力干好一件事情是提高效率的最简单的做法。要做到这一点,必须懂得如何对手头工作进行排序,最简单的就是focus on high priority work,这也就是Scrum过程中安排work item并对它们排序的意义。
无论如何,Scrum过程只是一个工具,而非目的,任何事情还是以delivery为重,流程本身执行是否合乎规范完全是次要的。
敏捷开发的几个误区
不少公司都在考虑采用敏捷开发,或者在项目开发过程中融入敏捷的思想,在这里,我列出几个常见的误区,希望能对大家有所帮助。
欢迎发表不同意见。
误区:敏捷开发 == 极限编程/Scrum/…
敏捷开发是一种方法论,只是一些基本原则的集合,并非具体流程。
极限编程、Scrum等流程是具体的实施方法,它们都声称符合敏捷开发的思想,但执行起来是否真的“敏捷”,还得看参与者究竟思想上是否真的接受敏捷开发的原理。
如果把结对编程、daily scrum当做是敏捷开发的表现,那更是本末倒置,可悲的是,不少人还真是这么认为的。
误区:敏捷开发 == 简化流程
敏捷开发不一定能简化工作流程,而且简化流程也并非提出敏捷开发的初衷。敏捷开发最重视的是拥抱变化,至于怎么拥抱,只能随机应变。实际应用中,既有流程相当简单的经典Scrum过程,也有极为冗繁、不亚于CMMI的RUP,根据应用场景不一样,项目组应该使用最适合的流程。
选择敏捷开发流程时也应带着敏捷开发的思维去选择,即快速响应项目实际的流程需求、拥抱流程应用过程中遇到的各种变化。没有银弹,也没有长期适合的项目流程,生搬硬套某个看似成熟的敏捷开发流程是大忌。
误区:敏捷开发 == 快速开始编码
敏捷开发强调迭代,鼓励开发人员用代码说话,不过绝对不鼓励没想明白就写代码。
符合敏捷开发思想的流程往往主张在一个稳定的基础之上迭代完成各种功能。如果基础都不牢固,迭代就无法进行,整个开发过程就退化成不断重写的过程,浪费开发时间。敏捷开发实际非常重视“设计”,并且对开发人员的设计水平提出了极高的要求,既要“持续重构”又不能“过度设计”,稍有不慎就会陷入反复推翻已有代码的窘境。对于内功不够的开发人员最好还是想好再写代码,设计的时候慢一点没关系,尽量少的做无用功才是最重要。
误区:传统开发能随时转变成敏捷开发
敏捷开发过于诱人,很容易让深受传统软件开发思想折磨的开发人员感觉敏捷开发就是灵丹妙药。
要想转变,首先需要从思想上正确认识敏捷开发的含义,了解它能解决什么问题、会带来什么新的问题、对现有软件/硬件资源有什么要求等。
例如在原先采用CMM的团队中,想利用敏捷开发简化冗余的文档、降低沟通成本,那么敏捷开发确实能在一定程度上缓解这些问题,但也会造成内部文档缺失、沟通不够深入的问题,在应用敏捷开发之前需要先确定适合团队的新的文档流程(代码注释能够自动/半自动的变成团队需要的文档么?),并且确定沟通的一些原则(比如,对于一些重要的沟通,是否还是用邮件来进行,不要过于“敏捷”?)。
有趣的是,有可能在回答这几个问题之后会发现,敏捷开发并不能解决项目中遇到的问题,反倒是其他方面出了问题。
举例来说。如果之前开发方法是简单的目标管理,遇到的问题是项目进度不可控、开发+测试的周期较长、不能及时响应需求变化,那么敏捷开发能解决的是快速响应需求变化,对项目进度和开发测试周期帮助不大(没有一种流程能够承诺改善项目的开发效率!),但前提是开发人员必须懂得怎样正确的去迭代开发,并且必须认识到一次迭代的结束是以完成测试为标准的。
在这个例子中可以看到,敏捷开发能带来的好处非常有局限性,如果开发人员达不到一定的层次是很难受益的。与其号召使用敏捷开发,不如想想如何增加执行力,以及找到周期偏长的根本原因(是因为设计不充分而返工?还是因为没有可以快速回归的测试用例?等等)。
体验为先
一般的想法似乎是:产品部负责体验,技术部负责实现细节,这两者虽相辅相成,但终究关注点不同。不过我觉得其实技术部也应该关注体验,这种体验是开发体验、运维体验和用户体验,至于实现细节,反倒是最后需要关注的。这样提的原因是,确实有一些技术的人一见到好的新奇的技术就像应用到项目中去(本身没什么不好),却没把体验这件事情做好(这个有点不好)。
现在来说说我对体验的理解。作为开发者,最大的目标绝不只是开发符合需求的产品。产品的开发、实施、上线、维护等过程都涉及大量不同的人,每一个相关的人对这个产品都有自己的体验,都会对这个产品在某一方面上是否好用有自己的看法。就像体验不好的产品会被用户弃用一样,过程体验不好的产品也会被开发者抛弃,只是迟早的事。
开发体验好也就是代码具有很好的观赏性、架构容易懂、代码质量高、具有可伸缩性等,它是开发过程中最需要注意的事情。
代码是开发者之间的交互工具,一个开发者写出来的代码其实就是其他人未来将用到的“界面”,它的体验直接影响到它的用户(所有与它相关的开发者,包括作者)对它的看法。开发体验不好的代码,在完成自己的当前使命之后很可能会很快被开发者厌倦,甚至废弃,如果一个组织不断在废弃旧代码,做重复造轮子的事情,这种开发成本当然很大,其中明显有问题。
这里有一个很有趣的问题,如果牛人写出来的精致无比的代码是否就一定是具有好的开发体验的代码?这还真不一定。如果确实周围的人一个都看不懂这代码,要么就不要把代码写那么好,浅显一点会更好,要么就多找一点能看懂这种代码的牛人。过于美妙而难以理解的代码是定时炸弹,一旦牛人离开就会面临难以维护或者必须重写的风险,这对于公司而言是不可接受的。说到底,体验是人的主观感受,不同的受众就有不同的体验,好的体验的定义也不同。
做好了开发体验,其次要做的是运维体验。运维体验主要包括更新服务、排错、监控的复杂程度等,主要的用户是运维人员。现在搭建一个大容量的网络应用至少需要几十台机器,机器之间的互相依赖如果管理不好就会变成网状,有点牵一发动全身的味道。有些时候开发者相比运维体验,更关心功能是否能实现,这是有问题的。对于互联网企业,不变的是变化,任何一个服务上线之后都会有用户不满意的地方,如果升级的运维成本比较大,开发者/产品负责人就会惧怕改变,这将直接影响服务质量和用户体验,最终还是害了产品。
此外,作为开发者应该时常思考如何量化服务的质量。是不是满足了一定的服务质量指标就好了?还有没有其他指标?在不同阶段这些问题的答案都不一样,比如已有服务基本稳定之后,开发者可能会从最初的服务质量转而关注如何发现服务性能瓶颈上,这时,难以运维(或者说“监控”)的服务就会显示出弊端,甚至变得没法满足运维体验方面的需求,导致重新开发。
所以在代码设计完了之后就开始考虑如何运维它是一个很值得建议的做法。
最后,好用的产品要落实到用户身上,他们的用户体验是绝对产品成败的关键。在这个时候,开发者可能有的误区是追求完美,希望在项目结束的时候就解决所有已经发现的问题,这其实完全没必要。很多大软件(例如微软的各种软件)遗留一堆bug就敢发布,为什么,就是因为开发者应该追求的是用户体验,而不是那些完全不影响用户体验、只有geek可以发现的微小缺陷。
另外,有这种追求完美思想的另一个原因是惧怕变化,希望一次性做完之后再也不去碰这份完美的代码,实际上这也是不切实际的。保持重构才是我们应该追求的目标,无论是针对代码本身,还是各种体验。
我们在某些时候或许可以追求快而放弃一个或两个体验而直接追求用户体验,但最后还是要补课,欠下的总要还。同时,不要一次性就把三种体验追求到极致,它们应该是迭代完成的。
要想一开始就能做到较好的开发体验、运维体验直到用户体验其实并不难,难就难在有没有这样去理解这些事情。说白了,就是有没有在各个环节为他人着想、为未来打基础,这才是一种做产品的开发者。
Let’s Scrum!
为期五天的流程培训结束了。把它说做是流程培训确实有些不准备,准确来说,它的全称叫做“卓越软件工程培训”(Engineering Excellence Training),整个过程除了一些“讲授”的过程,更多的是让我们自己实践——在实践中碰壁,在实践中成长。这个培训的本质目的是为了让新员工熟悉微软的工作流程、各种工具和各种角色的职责,其中我们最常说的就是:Let’s Scrum!
Scrum是一种敏捷开发方法,具体的细节我就不说了,网上随便都可以搜索到。Scrum的本意是“橄榄球中的并列争球”,引申到这个开发方法之中就是:思维碰撞与迅速交流。
Scrum中最有特色的是“净室”(Clear Room)理论,提倡在有限的资源之中获取可用的结果。举一个很形象的例子,假如计划在一段时间内榨取一定量的橙汁,那么Scrum就会要求在这一段时间内一定要得到橙汁,无论是多是少都无所谓,但一定要得到的是橙汁而不是榨到一半的橙子。这也就是说,在Scrum里面,延期交付是不应该有的,加班也是不应该发生的,如果实在快要完不成任务了,应该去删减不必要的需求,而不是拖延交付时间。通过这样的开发模式,整个软件都能在一个可观测的进度中进行,每过一段时间都可以拿到一个功能并没有完全实现、但主要功能已达成并且经过完整测试的版本。
Scrum中还有名为Scrum会议的一种每日例会形式。这种会议其实对我来说并不陌生,因为我曾经就在团队中宣传过每日会议,每日会议的五个问题(本来只有三个,我根据《敏捷迭代开发——管理者指南》这本书的建议,又加上了两个问题)早就在Dian团队的各个实验室贴满(除了东一以外),而且现在应该还找得到。微软的Scrum会议是原始的三个问题版本,包括“之前完成的任务”、“将要进行的任务”和“有没有阻碍目标的事宜”,这是最经典的问题模式。关于每日会议,可以看看我原来写的文章做一个回顾软件开发中的理想与现实(五)——知己知彼,百战不殆。
Scrum是一种典型的“个体软件工程”。在“个体软件工程”之中,开发者是以个体存在,并没有一个项目经理统管全局。不过确实有一个和开发者平级的Program Manager,他负责收集需求和驱动开发人员进行开发。所谓的“驱动”而不是“管理”,这意味着他并不干涉开发者的工作,也并不决定开发者的工作表,而是拿着自己手中的需求“求着”开发者来为自己干活,如果项目进度紧张,他还要主动地砍掉低优先级的需求以满足时间点要求,这样,他就必须用一种非常亲和的姿态与开发者进行沟通。同样,在测试那边,Program Manager的角色也是类似,也是一种驱动的方式进行管理。这种方式充分的保证开发、测试和Program Manager都能充分发挥自己的能力,让个体个性充分体现。同时,通过Scrum会议和其他各种方式(还有很多,Scrum还有很多东西我无法说出来),让项目还能按照既定的方向顺利进展。
当然,所有的敏捷软件开发都会要求用测试先行的方式开发,任何的形式上的模仿可能都会造成很大的副作用。个体软件工程本身往往并没有什么问题,但是对个体的素质要求却限制了它在低水平开发中应用,真是可惜呢。
希望大家都能练好编码和测试的基本功,然后大声疾呼:Let’s Scrum!
