不通则痛

排队现象

中医有句话说「通则不痛,痛则不通」,意思是如果经络气血通畅,就不会感到疼痛或不舒服,一旦有疼痛的症状,则说明经络阻塞、气血不畅。人体经络如此,软件项目亦然。

大家在进行软件开发的时候,应该也遇到过这样的情况 —— 我们依赖了其他人的工作,但是那个人久久不能完成,继而导致我们自己的的工作延期。更加不幸的是,还有那些依赖我们工作的人,他们的工作也延期了。这种状况像极了「气血不通」,不通则痛。

这其实是软件开发中的一种任务排队现象,如何才能提高整体的工作效率呢?在 排队理论 中有一个著名的定律,称为 利特尔法则(Little's law),可以很好的解决这个问题。

限制 在制品(work-in-progress)数量,可以有效的缩短平均等待时间,从而提高「产能」

这句话比较难理解,我们可以拿排队到 ATM 取钱的场景 举个例子。队伍越长,每个人的等待时间也就越长。为了能让整体快起来,除了提高 ATM 机器的性能之外,另外的办法就是让取到钱的快点走(减少非必要操作)。

类比到软件开发,每个依赖别人工作的工程师,就好比排队到 ATM 取钱一样。队首的人占位越久,后面所有的人等待时间也就越长,这时候即使队列中有人工作效率再高,也是帮助不大的。我们应该看一下,是哪个人造成了拥堵,让它赶紧做完。

识别拥堵

上图是一个能看到 整个研发流程中各个环节 的 Kanban(这是一个专有名词),我们可以看到事项在 哪里造成了拥堵。如上图,提高「实现」环节的效率,其实作用不大,反而会造成「测试」环节的进一步拥堵。

我们应当让「测试」工作赶紧做完,要么增加人力,让更多的人进行测试,要么先交付已测完的一部分,让下游开始验收工作。由于「测试」环节的拥堵,会导致上游「实现」部分,提高效率是没有意义的。也会导致下游「发布」部分,处于长期的等待中(没活干)。

下图是一个很常用的待办事项列表,在这个列表中,我们看不到整个研发流程全景,只能看到当前自己这个环节的情况,这就不是一个严格意义上的 Kanban。我们看不到哪个环节产生了拥堵,也看不到哪个环节生产过剩。

以上的 Kanban 工具,其实来自于日本丰田公司的 精益生产。它虽然起源于制造业,但现如今已经被用于软件开发之中,通过识别拥堵,来提高软件项目整体的工作效率。

拥堵的根本原因

高速公路上的 堵车 就像谜一样,人们永远都猜不出第一辆车在干什么。为了弄清堵车的原理,科学家们做了一个实验。他们在一个环形跑道上放置了 22 辆汽车,并让车队以一定的速度匀速行驶。结果发现,其中一辆车突然刹车减速之后,车队很难在短时间内顺畅地运行起来。

所以造成拥堵的原因,主要在于原有的 流动性被破坏了。一辆车刹车或加塞,会导致这个位置 流不动 了,后续的汽车走到这里,就形成了拥堵。所以说,并不是停止造成了拥堵,而是减速。

解决拥堵

如何保证流动性不被破坏呢?提到流动性,很容易让人联想到河水。古人在治河过程中,确实积累了很多经验。为了避免河水泛滥,通常的做法就是修堤筑坝,限制河水在河道内部流动。但对于某些含沙量比较高的河水(例如 黄河),很容易产生淤积,导致堤坝越垒越高,甚至有超过两岸农田的情况出现。这样一旦决口,危害性反而更大了。

中国 明末专家 潘季驯 提出了一个新的思路,称为「束水攻沙」。他希望在治河的过程中增加河水流速,让河水能够快速流入大海,这样就不会造成阻塞。此外,增加流速的同时,这些水流会把河中的淤泥和沙子带走,导致河堤内部更低,即使决口造成的危险也更低。

这个治河方针对于现代,也是很有启发意义的。对于软件开发而言,我们应当从零开始持续增加流速,看看瓶颈会出现在哪个环节,优化这个环节,从而切到提高整体效率的目的(需求拉动,识别瓶颈)。

除此之外还有一个增加流速的办法,那就是小批量频繁交付。把功能拆分为容易交付的更小单元,就能避免功能模块在某个环节加工的时间过长(要么不做,要么赶紧做完)。

执行方案

上文说了这么多,具体到一个软件项目时应当怎么做呢?其实就两点:看到最慢的环节、优化。

  • 怎样才能看到最慢的环节呢?

其实是要求我们提高项目状态的可见性, Kanban 是一个很好的办法(对于本地团队而言),项目周报是另外一个办法(便于异步沟通)。

有很多项目的周报,是项目管理者通过汇总大家的进展而形成的,这个其实帮助不大,因为只有项目管理者具备全局视角。单纯汇总一下进展,并不能很好的看到瓶颈之所在。所以,应当由项目管理者向项目组发周报,而不是反之。并且需要在周报中,注明风险和举措。这样所有相关方都会对项目状态有所了解,在非薄弱环节加大人力投入是没有意义的。

  • 看到了最慢环节之后,该如何优化呢?

项目管理者需要分析,为什么这个地方会这样慢,有没有办法让它更快的交付出去(拆成更小的任务,或者重排优先级),不要让大家都等着它。 通常某个环节慢的原因在于,单点压力太大,人力紧缺,做不了那么多的事情,却安排了特别多。另外一个原因在于,当前环节一下子答应了太多要求,而导致任务批量太大,其实可以按照优先级拆出更紧急的那部分优先交付。

值得注意的是,一旦优化了最慢的环节,次慢的环节就变成下一阶段的优化目标了。优化是一个持续不断的过程,以提高流速为目的。

小结

本文介绍了软件项目常见的病症 —— 拥堵。从整个研发链路角度来看,某个环节待办太多处理不过来了,从而导致下游所有人都在排队等待,这种现象在未经治理的软件项目中经常发生。大家都没有意识到拥堵的严重性,也不知道为什么拥堵,更不知道如何解决拥堵问题。

其实要处理这个问题非常简单,只要 通过不断增加流速,识别并优化最薄弱的环节 即可。所采用的办法多种多样,为了能识别出来,需要提高项目的可见性。为了能在不加人的情况下做出优化,我们可以减少任务的批量大小。这些都是行之有效的办法,可以视实际情况而用。