孙子兵法的智慧——拯救死亡行军

entersunzi

我们看了太多失败的和即将失败的项目,在软件领域更是如此。每天早上醒来在朋友圈里看到半夜更新的,不是身在国外的朋友,就是在办公室为了项目上线而加班的朋友。

Edward Yourdon为那种项目约束与目标之间相差一倍以上的软件项目专门写了一本书,叫《死亡行军(Death march)》。

我曾经亲眼见证过几个“死亡行军”项目的立项过程。

其中一个项目,那时候我才工作不久,一个项目从无到有,“大领导”希望在21天之后上线,这个日期包含了周六和周日。但是按我们的预估——当然我们也不会盲目乐观到每天只工作8小时,这个项目按现有资源起码需要3个月到4个月。在产品立项过程中,“大领导”坚决不肯让步,时间、范围均压得死死的。就这样,我们在会议室里博弈了整整两天,最后的结果是我忧心忡忡地走出会议室,问我身边的同事:你觉得咱们能办到吗?同事的表情我至今印象深刻,那是一种释然和轻松——他笑着说:怎么可能嘛。

最后的结果,项目延期了半年。


如何能够让自己的项目稳定运行并得到期望的结果呢,避免死亡行军,打一场胜仗呢?

几千年前的孙子兵法已经给我们提供了思路:

故知胜有五:知可以战与不可以战者胜,识众寡之用者胜,上下同欲者胜,以虞待不虞者胜,将能而君不御者胜。

我们只做高价值的事情

价值驱动作为敏捷开发的两根支柱之一,为软件开发提供了一种全新的思路。在上世纪八十年代之前,软件开发的时候还有这样的等式:功能=价值。
所以奇怪的一幕出现了:软件开发这个行业一边承受着巨大的进度压力,一边在生产着没有人用的功能。

微软曾经发起office 2003用户调查,希望调查用户希望 Office 2007实现哪些新特性,结果收获了让人吃惊的消息。产品总经理 Takeshi Numoto 如是说:“超过90%的特性请求早已存在于 Office 中可供使用”。

更何况对于所有的软件开发组织来讲,资源不足都是常态,识别出来哪些可以不做,我们才知道应该去做什么。

知可以战与不可以战者胜。

通过限制在制品的方式来缩短前置时间

对于缩短产品交付周期,一向是很多客户都会提到的问题,特别是电信级的产品,动辄一年的交付周期。当前市场环境已经变得越来越快,根据波士顿咨询公司的调查,最近的20年已经成为变化最剧烈的20年。

22484-8eb1d728c83ca707

《经典战略工具过时了?BCG矩阵新解》

在这样的市场环境下,“响应速度”就被提到越来越高的位置上,而衡量响应速度最直接的指标就是“前置时间”(lead time)。一个需求从产生到变为现实,究竟可以有多短?

利特尔法则是一个神奇的公式,它简单到甚至可以被10岁的孩子所理解:平均吞吐率=在制品数量/平均前置时间。对于一般的组织来讲,平均吞吐率约等于团队的产能,把它视作常量的话,我们想得到更短的平均前置时间,就需要控制在制品数量,小批量地快速流动。

要么不做,要么快完。

识众寡之用者胜。

团队所有人目标一致

“我们所处的项目,目标是什么?”有没有保证项目有着一个清晰而具体的目标?有没有保证所有成员都能够理解并执行?

在客户现场的时候,我经常听到的问题是:“作为一个管理者,我如何能够准确看到员工的人员利用率?你有没有办法让团队里所有的人都忙起来?”每听到一次这个问题,我在心里就会默念:“你可以让闲着的人都出去跑圈啊,这样大家都忙起来了。”

软件开发的项目,绝大多数(保守了,其实可以说“所有”)的目标都不是“所有人都忙起来”,而是“快速交付价值”。也就是说我们做任何的努力,都是为了能够让需求尽快上线。

而敏捷开发中的各种可视化手段,包括故事墙、故事地图,都起到了这样的作用——目标可视化。特别是树立在团队中间的物理看板,我们真正的目标都清晰地挂在上面,所有人的工作和努力,都是在推动着一张张卡片从板子的左边挪向右边,如果你做的事情对于推动卡片没有起到直接或者间接的作用,那就要好好思考一下了:我们的目标究竟是什么?

至于说人员利用率——谁知道一个正在端着咖啡面对窗外发呆的知识工作者(译作Thought Worker)是不是在为接下来消灭更多卡片而在布局呢?

上下同欲者胜。

做好风险管理

在客户现场待了一年,看的项目虽然不多,但也发现了一些共通的问题,其中最大的一个就是风险管理。

有不少项目在前期根本就没有做风险识别,或者识别的风险缺乏跟踪,到项目执行中仍然会像放炮仗一样一个接一个的爆炸。其实风险管理作为PMBOK九大知识领域之一,管理和应对手段都很成熟了。

应对的思路就有“转移、接受、缓解、消除”四种,而我看到的情况通常都以“接受”为应对手段,赌这个风险不会发生,或者等一个Risk变成了Issue再去想应对方案。

风险识别不论是在需求优先级排序还是在架构设计上都是非常重要的一环,我们之所以把高价值、高风险的需求视作第一优先级,是因为我们希望尽早识别风险,尽早释放风险。我们提的“简单设计”简单到什么程度,也是由是否能够涵盖最大的风险作为边界的。

以虞待不虞者胜。

团队应当自组织,领导者应当负起管理者的责任

客户现场另外经常被提及的问题就是:“如何打造自组织团队?”“团队自组织了,我们经理怎么办?”

我的答案通常是:团队自组织应当是一个逐步打造的过程,而领导者更应该负起管理者的责任。《管理3.0》中提到,授权有七个级别:从不信任到信任,或者说团队成熟度从低到高分别是:告知→贩卖→咨询→商定→建议→征询→委托。

作为管理者,打造自组织团队的过程也是逐步团队赋能的过程,团队成熟度不高而采取放任的做法,对于自组织的打造百害而无一利,反之亦然。所以作为管理者,最重要的责任就是在对团队赋能,当上面的四条团队都掌握了玩法,管理者就可以采取更高层次的授权了。

而所谓自由,就是团队的事务管理者不要管,团队外的事务管理者尽量多去做。区分管理者水平高低的点就在于如何判断一件事属于团队“内”还是“外”。

将能而君不御者胜。

我们总结一下

故知胜有五:知可以战与不可以战者胜,识众寡之用者胜,上下同欲者胜,以虞待不虞者胜,将能而君不御者胜。

 

Share

You are not your job

agile-standup

受到光磊的系列文章——《Scrum:死马?》的启发,我也来谈谈Scrum中的元素之一——站会。


还记得经典Scrum站会上我们要问的三个问题吗?

  • 我昨天做了什么?
  • 我今天打算做什么?
  • 我遇到了什么障碍?

在初次接触Scrum的团队中,一般都会让团队成员去遵守“Scrum教义”中的做法,其中就包括了在站会上依次回答这三个问题。
一般我们会看到这样的情景:
张三说:我昨天把这个故事的代码写完了,今天打算自测一下,没遇到什么障碍。
李四说:我昨天被叫走解决某个紧急故障了,今天打算继续这个故事,遇到的障碍就是最近打断比较多。
……

如此往复,基本上几周之后,站会就变成一个人兴趣索然地说,其他人目光游离地听;不低头玩手机都已经算是给面子的了。

德鲁克在《卓有成效的管理者》中曾经写到过:

“在组织的内部,不会有成果出现,一切成果都存在于组织之外。举例来说,企业机构的成果,是通过顾客产生的,企业付出的成本和努力,必须通过顾客购买其产品或服务,才能转变为收入和利润。”

“在组织内部所发生的,只有人工和成本。”

这个说法不论在组织的任何层级都是奏效的:从企业的角度,只有不断创造价值去缩小人类理想和现实之间的鸿沟的公司才能做到基业长青;从团队的角度,只有持续对组织有所贡献的团队才算是高绩效团队。

同样,作为个体,只有你的劳动真正被别人承认并消费,你所做的事情才算得上是卓有成效。

只不过在历史上作为体力劳动者,员工的劳动基本上等同于创造的价值,因为他们创造的是有形的产品,不论是搬的砖、制造的零件还是放牧的羊群。而在今天作为知识工作者的代表,IT项目和从业者产出的都是无形的知识、创意或者信息,而这些无形的东西在被别人消费或者影响到别人之前,都不能产生任何价值。

所以我们回头检视一下刚才提到的三个问题,是不是能够从这个角度来提升一下我们站会的效率呢?我们能不能从外部的影响来重新考虑如何回答这三个问题呢?

  • 我昨天做的事情,对我们的项目产生了什么样的影响?今天谁可以来消费我昨天的工作成果?
  • 我今天打算做的事情,可能会使用谁的知识或者信息?
  • 我遇到的障碍会不会是我们项目中潜在的一个风险?

作为知识工作者,不光考虑自己所做的事情本身,多去考虑自己做的事情对于自己的伙伴、团队所造成的影响,就走上了“卓有成效”之路。

Share

看板和利特尔法则

利特尔法则(Little’s Law)作为一个非常朴素的原理,为看板方法奠定了一个理论基础,看似简单的公式背后却有其复杂的一面。

一、利特尔法则

利特尔法则的公式是这样的:

平均吞吐率=在制品数量/平均前置时间

举个例子,假设你正在排队买快餐,在你前面有19个人在排队,你是第20个,已知收银窗口每分钟能处理一个人的点餐需求,求解你的等待时间。

如果你已经决定要排队,并且站到了队尾,那么在制品数量就是20(个),平均吞吐率是1(人/分钟)。
从你站到队尾的时候开始,一直到你点完餐,这个时间就是你的“前置时间”。
即使我们没有学习过利特尔法则,也可以轻易地算出来:

    1 = 20 / x
    x = 20(分钟)

因为在一段时间之内,保持工作量饱满的话,我们每天能做多少工作基本是一定的,所以吞吐率基本上不会发生太大变化。
如果这个时候我们想缩短平均前置时间,也就是等待的时间,利特尔法则告诉我们:可以通过减少在制品数量来达成这个目标。
在这个例子中,就是减少排队者的数量。

这也很好理解,10个人的队列和20个人的队列,前者需要等待的时间会更短。 [1]

二、限制在制品的意义

如上面所说,在制品数量和前置时间是成正比的,缩短前置时间的最有效手段就是减少在制品数量。

前置时间的增长会导致交付周期变长,这一点基本毋庸置疑。

前置时间的增长会导致交付的可预测性下降,俗话说“夜长梦多”,长时间停留在某一个阶段会带来一些额外的风险。

如果我们的交付周期比需求变化周期更长,那么会有更多的紧急任务,所以交付周期变长会导致更多的紧急任务。

如果我们管理不好紧急任务的插入,会增大我们的在制品数量。

如果交付团队的可预测性很低的话,那么会影响到IT研发组织和业务部门的信任关系,当业务部门无法预测一个需求提交给研发部门什么时候能交付的时候,那么唯一可行的手段就是一次性把要做的事情全部都压给研发部门,直接增大了研发部门的在制品数量。

同时在制品数量的增长会带来的另外一个后果就是故障发现得很晚,这一点在过去三四十年的软件工程方法论中都得到了验证。

发现的故障需要资源和时间来进行修复,带来的就是在制品数量的上升和前置时间的增长。

以上所有的事情我们放到同一张图中,可以看到下面的情况,实线表示两者之间存在因果关系,同时还是正比的,因增大,果也会增大。虚线表示两者之间存在的因果关系是反比的,因增大,果会减小。

22484-4c2d36ae3b6f766f

因果回路图

而在这众多因素之中,只有在制品数量是我们能够最有效的直接加以干预的。
而只有前置时间我们是可以直接观测的。

就像我们正在开车一样,我们踩油门的时候,速度表会发生变化,从60迈到100迈,但我们真正关心的并不是仪表盘的变化,而是真正汽车行驶的速度。

所以我们采用控制在制品数量的手段,通过观测前置时间的变化来观察我们的改进是否有效,但更重要的是整个系统是否正在向着更好的方向迈进。

三、在制品数量是不是越低越好

我们用直觉感受一下,在制品数量如果越低越好,那限制到1怎么样?限制到0怎么样呢?

很显然,在制品数量如果过低的话,团队成员可能会产生空闲的现象,很大一部分产能会被浪费掉,那在制品数量限制到多少是最合适的呢?

我们都知道,一个任务如果2周能完成,两件任务串行,需要的时间是4周,但两件任务并行,绝不是2周能完成,有可能5周的时间都完成不了,所以直觉上在制品数量过高也不能带来产能的上升。

所以一个朴素的原则就是:
团队中每个人在任意时刻,手中只有一件事的时候,效率是最高的。团队的在制品数量低于这个值,会造成产能的浪费,如果高于这个值,会造成前置时间的变长。

那我们再用定量的方式模拟一下吧。

假设我们有一个三阶段的开发流程:分析、开发、测试,平均每张卡片需要4天时间分析、5天时间开发、6天时间测试。

为了简化计算,我们把分析、开发、测试三个阶段设一个总的在制品数量限制。 [2]

22484-5996f0d58c826265

模拟看板

当我们有1个分析人员、1个开发人员、1个测试人员的时候,会得到下面这个结果:

WIP平均前置时间平均产能1150.072150.133180.164240.165290.166350.167410.168470.169520.1610580.16

22484-b95912514fb62b9e

折线图这个实验可以重复,有兴趣的同学可以自己写代码重复一下。

结论

  1. 减少在制品数量可以缩短前置时间,但前置时间的缩短是有极限的,就像我们不可能让10个妈妈在1个月之内完成怀孕的全过程一样。
  2. 增加在制品数量可以提升平均产能,但平均产能的提升是有极限的,1个人每天8小时的产能再想提升只有加班加点。
  3. 最短的前置时间和最大的平均产能不可并存,在“平均每人手头有一件事”的时候,在制品数量稍微小一点,可以达到最短的前置时间,在制品数量稍微大一点,可以达到最大的产能。至于各个组织如何选择,看自己的需求了。

[1]: 道理看似很简单,但放在软件研发领域就变得非常复杂,我们需要平衡需求和产能之间的关系,控制队列长度实际上就是在控制期望和承诺。在尊重事实的前提下,我们尽量让队列的长度变短,不去承诺不切实际的东西。

[2]: 所谓“排队”,实际上软件开发真正的“收银窗口”就是最终交付的环节,在这个环节之前的所有需求其实都是一个队列,队列的末尾就是我们最近承诺的一个需求。所以一旦我们承诺了无法立刻着手的需求,那么就会产生极大的浪费。

Share