译者边注

这篇文章是几月前看到的,现在打算翻译一下来回顾以及加深里面的内容,作者以系统思考的方式论证什么因素对于软件开发速度是重要以及不重要的,以及它们之间的复杂关系,文风诙谐幽默,可读性非常高,最后相信你会从线性思维方式的方式转变过来,能够认识到软件开发速度不是单单靠某个因素就能提高的。

每一个 IT 公司的 CEO 都希望开发软件的速度能再快些,而时间又是最昂贵也是最有价值的资源,因此你不能把它浪费在返工、重构、开会甚至体育活动上面。是吗?看情况。

那么多的公司成长,老去,然后倒闭。良好的开发节奏对于生存来说至关重要。想象以下,在很多种情况下,你有一个非常伟大的愿景。你很确信(当然了,现实中很难,这里只是想象而已,明白?)这个产品肯定会受市场的热烈欢迎,你所要做的只是去实现它。

你有一个有才华横溢,经验丰富的工程师的团队,你会在两年内开发完成以及发布。整个团队精疲力尽,发布的产品却只实现了大概 10% 的愿景。所有人都说,你们潜力无限,但是 10% 是不足以搞定整个市场的。然后你挣扎了几个月,产品没有足够吸引力,市场表现低于预期,于是没有收入,最终,没了公司。伟大的愿景被缓慢的行动拖累致死,怪谁呢?也许这个问题太困难了,两年是完全合理的时间框架。也许是团队向前冲得太快,有过几次很好的发布,但是最终被淹没于复杂度以及技术债务了。软件开发的速度是一个非常复杂的课题。它会收到许多因素的影响,而且往往会以让人吃惊的方式出现。在这篇文章中,我将尝试分享我对速度的看法。

速度的两面性

大部分的用户会认为速度是一个单一因素,但是,亲爱的,并不是。在这里会有两个非常不同的类型的速度:短期速度 (冲刺)以及长期速度(马拉松)。冲刺以及马拉松是一个非常合适的比喻,在软件开发中(也在软件运行中)你不能两者兼得。让我们采取抽象点的说法,比如分数。在冲刺模式下全速工作,每个月可以交付 100 分。然后就引出了我的第一个论点:

在漫长的产品开发周期中,你是无法保持冲刺速度的。

也许你能保持每月 100 分的速度三到六个月,但是这几乎不可能保持一年。而且随着高速发展,阻力会明显增强。终有一天你会后悔你做过的一些。


在某个点,大部分的开发者会到达一个『去你喵的点』(红色的点)然后失去大部分的开发效率。

你的目标是以最快的速度跑很长的距离,这就是马拉松的意义所在,你需要耐力以及均匀分配你的精力。

如何在更长时间内更快地创建软件? 这是一个 “100 万美元” 的问题。对于每家公司来说,最有可能的答案是独一无二的,但是我们仍然可以构建一个合理的粗略模型,而且这个模型很有用。

冲刺,马拉松以及间隔

首先,请允许我介绍三个观点:

观点 1:极限冲刺

你可以全速跑,每天工作 12-14 小时,桌子上堆满充满活力的饮料,咖啡因,糖的燃料,上帝知道还有什么。累了你可以睡一觉,睡几个小时,并且在吃、洗、锻炼等方面花费最少的时间。我会给你一个月的时间,如果你处在一个完美的状态的话,也许三个。这种模式的好处是每个人都知道它有多糟糕:职业倦怠来的很快。

边注

我知道一个人在这个模式工作了一整年!他学到了很多东西,技巧也有了很大的提高,但这并不是白白得到的的,极有可能他目前的健康问题是由这个极限冲刺模式造成的,用健康换取经验是一个好主意吗?我可不这么认为。

观点 2:温和冲刺

你可以每天工作 8-10 个小时,榨干每一滴生产力。没有闲聊,没有工作期间的体育活动,没有乐趣。一些公司没有在使工作有趣,富有挑战和乐趣的方面做过任何事情。项目总是延期,每个人都经常受到压力。不幸的是,这种模式可以持续多年。人们可以习惯它,不会注意到他们自己是多么的悲惨,然后他们试图在家庭中寻找家庭和业余爱好的补偿。这是一个真正的危险,因为经过几个月的这种工作,没有人会注意到生产率下降。于是导致人们深入思考自己并有一些见解可能需要几年的时间。

观点 3:马拉松

这种模式看起来最佳。你每天工作 6-8 小时,抽出时间放松和锻炼。你不会一分一秒地抓住时间,而是奢侈花时间去地思考一个问题。不急于把事情从推出门外。这听起来不错。不过,许多经理人对马拉松的节奏并不满意。因为他们想要更快地交付东西。我相信这种纯粹的模式在现实中是相当罕见的。在大多数公司,管理者总是试图以最愚蠢的方式加快速度:加班,推动任务还有 “我们是英雄” 的鸡血。

乍一看,看起来没有什么了,但我认为我们还有一个选择,说实话,我从来没有听说过。

观点 4:间隔

我不是在谈论迭代式发展。事实上,迭代开发可以同样应用于中等冲刺或马拉松模式,间隔开发就是混合模式。短时间内,你可以做冲刺,然后切换到马拉松模式。在我看来,好的时间表可以是:

1 个月 - 快速冲刺
3 个月 - 马拉松
1 个月 - 快速冲刺
……

然后让我解释一下快速步伐模式。在这种模式下,团队(或整个公司)放弃所有次要活动:关于未来的所有会议,学习活动,人力资源活动等。团队专注于提供价值:编写代码,测试,创建文档和发布。

快速节奏模式后,以休息一周结束,然后这一周将会致力于对未来的重构,讨论和思考。

这样做的好处是明显的:平均速度将比马拉松模式更高。在快速的冲刺模式,随后是一个没有压力并且体面的马拉松时期。而且,这也可能是一个激励:当团队卷起袖子,做好狗屎,快速发布。当你发布东西之后,会让你感觉良好,因为这是一个成就,一个里程碑,这也是一个麻醉剂,也许这就是为什么人们可以在极速模式下工作一段时间。

软件开发速度模型

让我们从概述开始。下面这张图片肯定会看起来吓人,但是请放心,我会解释每一处细节的,最后你将学会一种非常强大的工具去分析相似的问题。

这张图显示了默写事情和影响开发速度的活动,绿色意味着增加速度的活动,你拥有越多越好。黄色表示存在一些最大值,例如,你可以积累技术债务和提高速度,但是如果积累太多,会显著减慢你的速度。红色表示的是减慢开发的事情,他们越少越好。然后,绿色箭头表示增加的效果,例如,专注工作会提高开发速度。

红色箭头表示减少的效果,例如,更好的开发技巧减少系统的复杂度(好的工程师创造更少复杂的系统)。

现在你可以看着图,然后问出这样的问题:『什么会增加开发的速度?什么会减少?什么会使我们开发软件更快,并且更好?』这个模型也许不是十分完美,但是无所谓。你可以修改它。

好了,现在我将要解释这个模型中不同的部分,分析他们并且提供一些关于开发速度的想法。我希望它对于为将来更深入地思考这个问题以及产生更多的解决方案是一个好开头。

让我们开始吧。

技能以及经验

很明显,技能提高了开发速度。更熟练的开发人员可以更快地解决问题并创建更简单的解决方案。有人说,在技术娴熟和技术一般的开发人员之间可能会有 10 倍的生产力差异,尽管我不认为这是一个普遍的情况。

那么,问题就来了,如何提高开发人员的技能?首先,你只能聘请熟练的开发人员。这可能有效,但这种模式不容易扩展。熟练的人倾向于在需要技能的难题上工作。世界上有多少公司在真正困难的问题上工作?没那么多。另一方面,如果你的产品不是火箭科学,你不需要充满博士学位的团队。所以任何公司所需要的技能都是不同的:Google 的熟练开发人员并不等于某个外包公司的熟练开发人员。

好了,你为贵公司定义了熟练开发人员,但仍然很难找到他们中的很多人,可扩展性问题依然存在,所以你不得不雇佣不那么熟练的开发者来培养。这是可以的,但绝对需要雇用喜欢学习新事物的人,如果有人不喜欢学习,谁会获得技能?好奇心,活泼的头脑,激情:这些优点是最重要的。

一个公司应该提供任何可以帮助人们学习的东西。 一些选项如下:

购买任何大家需要的书

任何公司都应该有一个好的图书馆。我认识的大多数伟大的开发者都很喜欢阅读,你没有办法强迫人们阅读书籍,但至少应该提供很容易去抓一本好书来阅读的条件。

让大家去参与各种会议

大多数人认为会议是新知识的来源。也许,但我认为他们是激情驱动者,会议激励你不断学习,不断尝试新事物,并在最好的情况下,给你一些方向。

我喜欢参加关于新的主题的会议。例如,当我开始学习用户体验时,我参观了两个大型会议。第一个特别有用,第二个不太好。

组织学习活动

学习一些最好的方法之一就是写一本关于这个话题的书。不太极端的方法是准备一个演示文稿或一个研讨会。公司应该组织内部会议来推动这个过程,不是每个人都有准备在观众面前说话,但很多人会尝试。在我们公司,我们每 6 个月举办一次为期两天的会议,没有外部发言者,所有会议都由我们的团队成员准备。

另一个好的做法是为各种社区聚会提供一个空间,我们有一个可容纳 80 人的小型会议室,并且很乐意为本地用户体验社区、.NET 社区以及 iOS 社区提供服务。

肯定还有其它的方式来开展内部活动。

提供学习新事物的时间

这听起来不像是强制性的做法,也许不是。如果一家公司提供一些专门用于学习的空闲时间,那真是太棒了。有名的 20% 谷歌的时间就是一个很好的例子(有传言说这种做法已经被取消了,但是这些传闻没有被证明)。在 Targetprocess 我们有橙色的星期五。

每个星期五都致力于个人项目或学习。许多人学习 Coursera 课程,阅读文章,跟进新技术,衡量这种做法的有效性是不太可能的,但会有很多好处:

  • 其实这意味着 4 天的工作周。至少第五天不是平常的工作日。
  • 它吸引了喜欢学习的人,所以这对招聘来说是一个很大的好处。
  • 容易留住人才,因为他们可以选择自己尝试新的东西。
  • 大家会更快获得新技能。

只有一个缺点:这可能会降低整体开发速度。人们每周工作一天,这将直接影响开发速度的 20%。那么,什么更重要?这取决于具体情况。如果你离发布日期很近,在战术上,每个星期五在教育方面都是不明智的;如果你在马拉松模式 - 这可能是值得的。

无耻的广告

我使用 Targetprocess - 一个非常酷的可视化项目管理软件。如果您需要为您的 Scrum,看板或其他项目提供敏捷工具,请尝试一下

帮组大家更好得理解领域知识

领域知识对于任何软件开发人员都至关重:它有助于更深入地理解问题,更快地创建更好的解决方案,并减少重复工作。它允许开发人员更早地发现不良解决方案 没有领域知识,开发人员会盲目地实施业务分析师或产品所有者提供的解决方案。 有了良好的领域知识,开发人员可以轻松地自行创建出色的解决方案,或成为用户体验团队的一员,集思广益。

领域知识在产品开发中尤为重要。生命短暂,你将会很难深入地学习许多领域。所以聚焦最终会是件好事,你最好找到什么驱动你,然后动手去做。

好,现在让我们谈一下经验吧。

经验

大多数情况下的工作经验也会影响速度。具有 20 年经验的开发人员通常比具有 5 年经验的开发人员(即使他们具有相同的技能)更快地解决问题。但是,请注意,该技能不等于经验。如果你有很多经验,却应用相当不相关的技能,那么你将无法解决当前公司拥有的大多数问题。

我个人认为技能是提高发展速度的最有影响力的因素。如果你有一群熟练的开发人员,设计师和测试人员 - 他们有很大的机会去创造一些好的东西。如果你只有新手开发人员 - 几乎没有什么能帮助加速开发。

大多数公司都有各种各样的问题:其中一些简单,其中一些是具有挑战性的。没有经验的开发人员对任何事情都充满热情,几乎任何问题都会给他们带来一些新的知识。有经验的开发人员更挑剔,最好给他们足够复杂的问题。所以在公司内部拥有广泛的熟练以及有经验的人员是很好的,但平均技能水平应该高一些,你至少需要考虑下这个问题,因为良好的内部人员经验的均衡对每个公司都是独一无二的。

系统复杂度

软件变得越来越复杂,40 年前有数十种技术,现在有数千种:更多的 LOC,模块,平台,更多的一切。

复杂性是不可避免的,这就是进化如何工作的,人类比病毒复杂得多(这并不意味着人们能够更好地生存)。我们可以通过复杂的软件来获得越来越多,所以我们必须忍受这一点。 复杂性不会消失,开发人员应尽可能建立简单的系统,但不能太简单。

不必要的复杂性对软件系统来说是一个巨大的抑制剂:添加新功能比较困难,要发现和修复错误,就很难理解 “这里到底发生了什么!”。正如我们已经讨论过的那样,好的技能可以让人们建立一些不太复杂的系统,新手开发者往往倾向于创建脆弱的,过于复杂的解决方案。例如,他们喜欢 Macaroni 代码,并把所有东西放在一个单独的文件中:HTML,Javascript,ASP.NET 和 C# 代码 - 都在一个!单个文件听起来可能比 4 个文件更简单,但修改和扩展要困难得多。

什么使得软件更复杂?

技术债务

你可能知道,技术债务概念是由 Ward Cunningham 创造的,技术债务是由实施非最佳解决方案或者编写不是最好的代码以便更快地发布软件这样的过程中产生的。如果你做出不好的解决方案,并且不知道你写的是不好的代码 - 这不是技术债务,如果你不知道你有了它,那不是债务,那只是一个糟糕的架构。

大多数人认为技术债务总是不好的。不是这样,与金钱的直接比喻显示债务是可以有的(有时),所以有一些技术债务是可以的。Ward Cunningham 本人支持这一观点:

“我认为借钱是一个好主意,我认为把软件赶紧发布出去,去获得一些经验是个好主意。“

技术债务可以在短期内提高速度,但这会增加系统的复杂性并降低你的速度,你总是需要权衡一下。那么如何处理技术债务?

首先,你们应该以某种方式跟踪。关于技术债务的每一个决定应该被记录为用户故事或类似的东西。这有助于了解你已经借了多少钱。在某个时候,你可能会想:“为什么我们要标记时间?”, 但是问题出现时,不妨查看下在一堆的需求列表中有多少带有 “技术债务” 标签的用户故事,在这一点上唯一的选择是停止并偿还债务,并归还利息。

其次,每一个关于借款的决定都应该被认真考虑。产品负责人说 “嘿,我们在 2 周内需要这个功能,伙计们,偷工减料就行”,这很容易,也很吸引人。每一位优秀的开发人员都要全面负责解释这个决定将导致的所有后果,作为一名软件开发人员,你的工作是提供论证和捍卫良好的架构。 最后,你会形成一个协议,但这比每次都是一个慎重的决定要好得多。

再其次,技术债务应通过重构或全面重写来减少。这些活动可以是定期的(预定的)或临时的。

Steve McConnell 提供了一个关于技术债务的惊人推理

“技术债务的重要意义之一是必须提供服务,即一旦发生债务,就会产生利息费用。如果债务增长得足够大,最终公司将花更多的钱来偿还债务,而不是投资增加其他资产的价值 “

技术债务可以量化吗?是的

技术债务是为了达到理想的质量水平而修复软件系统质量问题的成本。

下图为技术债务,如果没有解决,它的利息会随着时间而增长。增长速度可以快或慢,这取决于债务累积速度 总的来说,一个系统总是有一些技术性的债务,零债务在经济上是不切实际的,这会减缓新功能的交付。Henrik Kniberg 对技术债务也有一个有趣的看法。

重构

重构是降低系统复杂性并支付技术债务的一种自然方式,但是,没有自动化测试,重构是不可能的。我无法想象任何没有自动化测试的严重的系统。没有单元以及集成测试的开发就像跨越在鸿沟的燃烧的并且没有回头路的桥。没有自动化测试的大系统实际上注定了最终会垮掉。

自动测试给人一种温暖的信心:你可以通过微小的代码来改变代码,并保持系统的功能。这就是重构的意义所在,当然,也会有一些相当罕见不能创建自动化测试的情况:

  1. 非生产代码(原型,快速脚本)。
  2. 你 100% 确定在代码中不会有任何修改,在发布之后,没有人会支持该解决方案。在所有其他情况下,自动化测试真的很有用。

如果重构是如此的好,我们可以一直重构吗?当然不,重构是一个非增值活动,重构系统时,你不会添加任何业务价值。你可以减少复杂性,支付技术债务 - 是的,但客户一无所获。业务价值由新代码生成,我们能写出完美的代码,并一次性创造完美的解决方案吗?我希望我们可以。但是我们不能,而且,那时候需求改变了,最初的决定也不再合适。这就是为什么我们必须迭代和重构。

缓慢以及不稳定的自动化测试

自动测试是伟大的,但他们也可以是一个真正的痛苦所在。想象一下,你有一个巨大的系统,它需要 24 小时运行自动化测试。重构不再有趣,是的,你会发现哪里出了问题,也能够解决问题,但反馈周期变得太长。几分钟是极好的,几小时是可以忍受的,几天… 它几乎毁了自动化测试的用处。

另一个不好的情况是测试的不稳定。 “它在我的机器上没问题” 是一个常见的借口,但这个说法是难以接受的。不稳定的测试让人发狂,是因为我们犯了一个真正的错误,还是因为不稳定而变成红色?我们可以将这个版本标记为 “粉红色” 并发布吗?

我们在 Targetprocess 中有两个问题,说实话。缓慢的测试部分通过并行化解决。现在我们有 60 台运行所有测试的虚拟服务器,但仍然需要大约 90 分钟的时间来测试执行(包括单元测试,集成测试和功能性 UI 测试)。我们实施了一个内部系统,将 Jenkins,Git 和 Targetprocess 整合在一起:

测试稳定性问题是非常难以解决的。一些功能自动化测试是相当不稳定的,很难定位问题的根源。我们在测试稳定和重写上花费了大量的时间,但是我们仍然有一些不稳定的测试。

系统复杂性使得自动化测试变得更加困难,并且更加缓慢了所有的发展,所以这里有一个非常讨厌的反馈循环。

牛仔编码

许多开发人员不喜欢流程。他们中的一些人是喜欢,但总的来说,他们大多数都享受自由和不喜欢规则。有经验的开发人员明白,一些规则是真正需要的,牛仔编码人员会忽视开发过程,并随意向前推进。这并不总是不好的:如果你单独工作,或者在一个小团队中工作,那么可以,但是在任何严谨的开发团队中,这会导致更多的复杂性和更多的混乱。

牛仔编码人员倾向于尽可能快地省略细节并向前进。我是一个牛仔编码者,我喜欢看到一个实施的解决方案,我倾向于牺牲代码质量为此目标。现在我明白了好的工程实践和 “牛仔编码” 风格所带来的所有问题的重要性。

任何有 20 多人的公司都应该有明确的开发流程。例如极限编程是一个非常有纪律的过程。它需要充沛的精力和最大的关注度,但是最终它的速度和代码质量都很好。

短期加速

有时在短期内促进发展是绝对必要的。例如,你有一个重要的博览会或一个坚持在特定日期发布的重要客户。从商业角度来看,用质量换取时间是可以的。

你应该明白,没有免费的午餐,短期的加速可能会导致长期的减速。

截止日期

截止日期设定了一个目标,在大多数情况下,这个目标是发布新的功能。 我从来没有听说过 “6 月 13 日我们绝对要支付所有技术债务的 40%” 或者 “我们应该在 6 月 13 日之前优化内部的架构”。相反,我听说最后期限如 “我们应该在 4 月 11 日之前发布第 3 版”。截止日期施加了时间压力,时间压力迫使我们把重点放在最终目标 - 功能上。我们偷工减料,写不好的代码,少测试。这很明显会导致更高的技术债务和更多的复杂性。

而且,截止日期通常作为一个开关打开 “搞定狗屎” 模式,就像 “我们是英雄!我们要不就发布这个版本,或者去死!“ “搞定狗屎” 模式增加了更多的技术债务,所以最后期限可以用于短暂的提升,但是要非常小心。

截止日期以及迭代开发

现在我将分享一个相当有争议的思想,熟悉敏捷软件开发的人会明白:迭代开发实际是一组小型的截止日期。事实上,时间框意味着我们必须在迭代结束之前完成一组定义的工作。考虑一下,这是否意味着与一个大的期限相同的后果?不完全是,而是相似的。如果一个团队在 sprint#4 中承诺了 9 个用户故事,它会尝试完成所有这些故事。正确的解决方案是缩小范围,放下质量不佳的故事。但是,例如 Scrum 需要承诺,因此它会让人有心理压力,于是人们开始偷工减料,这在短时间内是肯定的,正如我们已经知道的那样,这并不总是坏的,但是我们必须意识到这种适得其反的副作用。

加班

提高整体生产力的一个显而易见的(好的)方法是更多的工作。通过工作更多时间,我们可以完成更多的东西,并提前发布,对么? Jason Fried 认为这种做法是完全错误的:

“这不仅是不必要的工作狂主义,这是愚蠢的。更多的工作并不意味着你更在乎或完成更多,这只是意味着你工作更多。工作狂结束后会创造更多的问题,而不是解决问题。首先,像这样工作是不可持续的,而当倦怠崩溃来临时,事情会更加难做。

平衡的观点表明,一些加班是可以的。当你试图加速发布,并准备作出最后的突破 - 这是可以的,工作 2-4 周,加班 20% 的时间。但从长远来看,这种做法最终将会失败,而且反弹是不可避免的。

我们不提倡在 Targetprocess 中加班,决不,唯一极其罕见的例外情况是,当我们的生产服务器停机或阻塞程序存在时。

Klint Finley 写了一篇关于加班的非常有趣和深刻的文章,不妨一探究竟。

激情

激情是好的,充满激情的人真的关心他们的工作。他们尽其所能编写出好的代码,创造出色的解决方案,并推进事情。每个雇主都希望拥有尽可能多的充满激情的人。

但激情并不全是光明的,富有激情的人往往工作更多,很难找到工作与生活的平衡职业倦怠是真实的,所以保持平衡状态要好得多。否则,你可能会有健康问题,心理问题,家庭问题和抑郁症。

激情是好的,它加快了项目速度,但是它应该被一些非工作活动所平衡。

专注工作

你每天有多少次打扰? 软件开发需要深入的专注和聚焦。程序员在他们的脑海中建立了巨大的模型,每一次中断都会打破模型状态,所以需要时间来重建模型。

重点工作是要削减所有浪费的活动,并帮助开发人员潜入心流模式,让我们来回顾一下从专注的状态转移人们。

不稳定的团队,人员流动

团队稳定性如何影响生产力还不是很清楚。直觉上,我们可能认为稳定的团队表现更好。在这种情况下,我们的直觉是正确的。Rally 的研究表明:

“长期保持一个团队的完整性可以使生产力提高 60% 团队更具可预测性和反应能力。“

这是为什么?每个团队都有一个生命周期。Tuckman 定义了团队发展的四个阶段形成 - 震荡 - 规范 - 成熟。很明显,一个团队在最后一个阶段表现最高。如果你轮换队员,你打散了队伍,所有这些阶段将再次重演。然后再次。然后再次。在最糟糕的情况下,不存在 形成 和 成熟 阶段,只有人员流转造成的持续震荡。

配对编程中考虑轮流配对是很有趣的。开发人员每天都在不同的工作对中这真的很好吗?我们在 Targetprocess 上试了一下,结果很糟糕,现在我明白了为什么。首先,有个人的喜好,有些人跟另一些人是非常没有生产力的。其次,每天轮换时很难建立良好的关系。事实上,你延长了上述所有的四个阶段,真正的成熟阶段可能永远不会发生,所以我不喜欢流转。

团队在其他领域的表现如何稳定?足球怎么样?这里有一个吸引人的研究稳定性和足球队的表现(pdf),结论是非常明确的:

“这些调查结果显示,稳定性可以促进认知和身体的合作,然后进一步促进职业足球队的表现。”

大约一年前,我们决定组建四支稳定的队伍。他们工作了三个月,显然两支队伍都没问题,但另外两支队伍都没有下降,他们的生产力也是平均的。 我们决定重组这两支队伍。现在回顾起来,这是一个非常好的决定。现在,所有四支队伍在成熟阶段都表现出了良好的生产力,但是为了克服了震荡阶段需要花费数月的时间。

开放空间

我不喜欢开放空间。当耳边有一个不断的嗡嗡声时,真的很难专注工作。正如我们已经讨论过的,稳定的团队比较好。稳定的团队是相当独立的,而且不是很大,在我们公司一个团队的典型规模是 6 人。这个团队内部的沟通非常密集,但是各个团队之间的沟通并不那么密集。

这意味着每个团队应该有一个单独的房间(墙壁)。

下面是一个典型的开放空间,很多人在很大的领域,你听到四面八方的声音。人们经过时,你不可避免地把注意力转移一小会儿(人们倾向于注意移动的东西,这是从我们以前的本能)。电话铃声,有人嘎吱嘎吱的饼干包装。热烈的讨论在桌子之间产生和传播,人们在工作场所附近互相问候,听起来很熟悉? 这里很难专注。 唯一的关注点就是戴上耳机,让音乐响起来… 更响亮… 非常响亮… OMFG! 我会去买昂贵的降噪耳机,马上!

现在比较一下 6-8 个人一起工作的小房间,手机铃声不经常响、周围的声音也很少,最后大部分的谈话对于听到和渗透沟通工作来说都是相当重要的。白板就在墙上,热烈的讨论应该是意义明确的,直接的。

我认为这个设置是最好的。确实,私人办公室能够最大限度地关注。但是,它打破了沟通。人们很懒,不能起身离开位置去问一个问题。如果你能方便地问一个问题,那就会有很大的不同。在我看来,“团队型房间” 只是我们可以拥有的最好的平衡点。

即时通信

消息传递服务和各种通知可以毫不留情地命名为 “焦点吸盘”。在右上角会弹出一些东西,然后移动眼睛来检查它,聚焦丢失;红色的气球出现在 Skype 的图标上,你感到一种紧张感,使你感到恼火,并迫使你打开 Skype 并检查消息,聚焦丢失;我敢打赌,你不会注意到这些中断。他们小而慢,嵌入你的日常生活中,事实是,这些小的中断足以危险地把富有生产力的一天变成非富有生产力的一天。你检查,回复,尝试着聚焦,再次检查,再次回复,试图集中精力 - 在一天结束的时候,你所有的回复邮件,许多 Skype 讨论,几行代码和无尽的聚焦。

如何决绝呢?当你真的要聚焦和编码时,退出 Mail,退出 Skype,关闭所有通知服务。在 Twitter 上看到新的回复或 Facebook 上的新状态更新至关重要吗?我敢打赌,这不是,全关掉。

这听起来很简单,但是试着去做,你会发现习惯很难改变。突然间,你想问一些问题,再次启动 Skype,问问题,不退出,然后被新的通知中断。我知道,因为我自己有这个问题。

在我们公司,我们使用了很多 Skype。有各种聊天组。每个队都有一个聊天。我们有公司聊天,产品聊天,销售聊天,运营团队图表,支持聊天,用户体验聊天等。

Skype 的

看起来像所有这些都是必需的,但消息的数量是巨大的。我不知道如何在系统层面解决这个问题。我们需要所有的沟通渠道,但是我们每天付出不间断的高昂代价。

一个伟大的沟通频道非常有针对性。最好的情况是,当真正需要的人收到消息时,他们会以某种方式作出反应。然而,定义这一群人并不容易。更小的有针对性的聊天可能会比几个普通的聊天更好,最近我们切换到了 Slack,它有更好的通知系统,不那么烦人,但是仍然有聊天造成的本质上的负担。

多任务并行

有两种类型的多任务:当你同时进行编码和通话,以及当你有几个任务完成并从一个任务切换到另一个。第一种类型显然是一件坏事,第二种类型也不好,但我们仍然是多任务的。我个人每天都从事几项任务,我知道我不应该这样做,但是迄今为止我没有更好的重点,上下文切换可以轻松干掉生产时间:

如何解决这个问题呢?上下文切换应该减少到最小。最好的方案是完成单个任务直到完成,然后切换到新任务。容易说,难以遵循。我想一些技巧可以帮助我们在这里, 有科学证明冥想是有帮助的(pdf)

一个可行的选择是将工作分解成块,我听说很多人用番茄工作法取得了很好的效果(但是到目前为止我还没有尝试过)。

返工

任何返工肯定会降低开发速度,零工作是不可能的,但我们可以尽量减少它。

返工主要有三个来源:

  1. Bugs
  2. 不明确的需求
  3. 完成错误的事情

我们从 Bugs 开始吧。

Bugs

我无法想象没有 bugs 的软件开发,开发人员不喜欢测试他们的代码,他们中的大多数人无法擅长测试。开发中的错误是不可避免的,测试人员应与开发人员合作,尽早找到并修复。

早期发现错误非常重要。在这种情况下,开发人员对代码有较新的记忆,并且很可能会很快修复错误。如果你的测试周期较长(超过一周),则可能会严重降低错误修复速度。一周就足以忘记代码的一些部分,这显然是上下文切换导致的。

在生产中发现的错误是最昂贵的修复。通常情况下,您会收到一封来自客户的电子邮件,其中包含一些奇怪的行为,花费一些时间进行沟通,重现错误并在待办列表中添加 bug。然后有人优先考虑去修复这个 bug,询问更多细节,然后开发人员开始修复这个 bug,再次与测试人员交流,等等,由于在生产中发现了一个错误这个简单的事实,将会造成巨大的开销。

不明确的需求

大多数错误是由不明确的要求造成的。通常开发人员会阅读需求文档,提出问题并开始开发。在需求文档中经常有不清楚的陈述,很多时候开发者不会发现它们。产品负责人常常不能立即回答问题,因此开发人员必须做出有根据的猜测。往往他们的猜测是错误的,这会导致返工,让我们简单尝试一下最明显的解决方案。

用户体验到开发的转变

首先,开发人员应该了解一个功能的上下文。 你不能只把他们扔在那里,等待下个月的最终解决方案。 开发人员必须了解客户面临的实际问题,以及为什么这些问题如说明书中所述能够得到解决,有几种方法可以解决这个问题。

  1. 开发人员可以从第一天开始参与 UX,这将帮助他们了解业务如何运作,以及为什么提出的解决方案是好的;
  2. 每个功能或用户故事都可以有一个 “启动会议”,会议的目标是将每个人都放在同一个地点:开发人员,测试人员,产品负责人在一起讨论功能或用户故事详情,审查可能的失败测试案例,然后开发人员提出他们的问题。我们有这样的会议,他们的工作很有魅力,开始会议期间,解决方案通常会发生变化!
  3. 写好需求文档(不可能!)。
需求文档

良好的需求文档是罕见的。很明显,良好的需求文档有助于更好地理解解决方案,减少错误数量,减少重复工作并节省时间。

我写了一篇大文章,讨论为什么许多需求文档很差劲,以及如何改进。简而言之,有多种技术来描述和解释人们的解决方案,视觉技术在许多情况下是最好的。下面的图表显示了所有这些技术。X 轴显示创建规格所需的时间和精力。显然,生动的原型比素描要花费更多的精力,Y 轴显示技术价值,伪叙述性说明书是低价值的,而设计和原型是非常有用的。

完成正确的事情

Bugs 是差劲的,但没有人使用的功能呢? 想象一下? 你所有的时间花在设计,实施和测试上都是浪费。我个人设计和实现了几乎没有人使用的 Targetprocess 中的几个功能。

如何做正确的事情?有没有简单的解决方案,很难确切知道客户真正想要什么。 更难说他们真的会用什么,仍然有几件事情可以做,以更好地了解客户的需求和优先事项。

沟通渠道

为客户提供非常简单的方式来提供反馈,你会很容易为此目的找到好的服务,比如 UserVoice 或 Desk.com。

使用统计

你怎么知道什么功能是流行的,什么不是?对于每个功能实施,考虑使用指标是有帮助的。我们怎么知道这个功能是成功的?有多少人每天 / 每周使用它?这些指标将有助于验证初始假设,如 “我们相信 50%的用户每天都会使用此功能”,这样,你将从错误中学习,并在未来做出更明智的决定。

功能排名模型

你怎么知道接下来要做什么功能?产品负责人的直觉可能不是最好的选择方式。简单的线性模型胜过专家,所以使用它们吧,创建一个简单的模型,用模型对特征进行排名,在几个特征上验证它,纠正它,然后信任它。我们花费了几个月在 Targetprocess 的 Feature Ranking 模型。我们回顾了各种渠道,讨论了优先事项,积累了客户的反馈意见,最终创造了一个人人都信赖的好模式

当我们添加所有参数和计算得分的功能时,似乎对于其中的大多数我们的直觉工作得不错,但有几个令人惊讶的功能冒了出来,我们讨论了它们,然后发现了一些模糊的属性,改变了我们对这些特征的看法。我不想在这里详细说明,只是提供一个公式:

特征分数 = 30% x 卖点
        + 15% x 使用传播
        + 15% x 客户投票
        + 15% x 功能大小
        + 15% x 痛点
        + 10% x 使用频率

最大特征分数是 100%。看来,我们正在研究的两个主要特征在列表中间。他们没有我们想象的那么重要。不过,我们完成了这些功能。你知道吗?对这些特征的初步认识是相当浅薄的,没有那么多人像我们预期的那样真正使用它们。现在我们正在研究名单中的排名优先的功能,我相信他们会更受客户的欢迎。

用户体验反馈

从客户那里获得有关所有主要功能和 UX 变化的反馈是值得的,创建原型,共享草图,执行 A/B 测试,积累数据并进行分析。

我想说,如果你解决了这个问题,你会大大减少重复劳动。

更多的人,更多的团队

大公司总是工作得更快,发步速度更快。对吗?不完全是。小公司有更好的单位速度,而大公司有更好的整体速度,但通常会成本很高。让我们组成一个团队(6 人),并将其分成两个不同的公司。我保证这个团队在小公司工作会更快。但是在一个大公司里会有几十个团队,所以整体开发产量会比较高。

为了保持高的单位速度而增长是更好的,但是更多人意味着更多的协调,更多的会议,更多的浪费。

招聘

新人从长远来看会形成新的开发队伍,提高开发速度。但是,这个过程不可避免地会降低当前的开发速度。首先,一些开发者会被技术面试分散注意力。假设你试图雇用优秀的人,会有很多面试,而且大部分会导致什么都不做。我认为一个人雇佣需要 10-40 个小时的面试。

其次,新人应该受到指导。有人应该帮助他们理解这里的事情。这个过程需要 1-3 个月的时间,在这段时间内,开发人员的工作效率不高。我相信人们在 6 个月后才开始全速工作。

这是什么意思?如果你有一个紧急的截止日期(比如 6 个月),不要招聘,这会拖慢你的速度。如果你没有最后期限,并且准备放慢速度,改天再加快速度 - 那么请招聘。

有趣的问题需要考虑的是:我们可以聘请新的人,而同时不会分散开发人员的注意力?我们可以用其他的东西来代替技术面试吗?如何花更少的时间在培训上面,但会有同样的结果?

工作协调

大公司效率不高,更多的人需要更多的协调。通常解决办法是增加管理层次,但是层次更深,意味着会议更多,政治游戏更多,生产时间更少,最终导致拉低平均的发展速度。

我不喜欢深层次的结构,我喜欢具有自主跨职能团队的网络和平面组织

在 Targetprocess 中,我们有 5 个完全独立的开发团队。每个团队都包括功能所有者,开发人员,测试人员和设计人员(通常他们是共享的)。团队全面负责功能实施,并对功能做出所有重要决定。

问题是产品本身应该足够模块化以支持独立团队。模块之间应该有最小的关系,否则集成将是一个问题,Targetprocess 还没有。

边注

公司架构将在产品架构中被复制。例如,我很好奇比较 IBM 和 Atlassian 的产品架构。IBM 使用深度继承模型吗?Atlassian 是否更依赖关联和组合?可能会发生这样的情况:灵活平坦的公司创造灵活的产品。如果是这样的话,那么公司结构对产品成功的影响是巨大的。
(即康威定律,系统设计 (产品结构) 等同组织形式,每个设计系统的组织,其产生的设计等同于组织之间的沟通结构 — 译者注)

浪费和非增值活动

我们已经讨论过分心如 Facebook 或 Skype。但是,有许多危险的活动看起来像真正的工作,但最终没有产生任何价值。

会议

大多数会议很糟糕,这是一个我从书中发现的很好的会议价值测试:

回想一下你说 “哇,这真是一个很棒的会议!” 的频率

我敢打赌,这并不经常出现。大公司有更多的会议,小公司可以完全没有会议而活得好好的,每一次会议都可以是浪费的。每天站立的会议?当然,UX 会议?为什么不呢。我很容易想象一个完全浪费的日常会议,每个人都在进行状态报告,没有人关心别人谈论什么。我参加了很多用户体验会议,这些会议很痛苦,没有任何实际产出。

有关高效会议的书籍很多,你知道吗?他们真的有用:每一次会议都应该有一个议程,准备参与者,良好的协调,诚实和开放的沟通和明确的结果。

我们不能完全放弃会议,好的会议是有趣的和有益的。这是一个活动,你可以与其他人讨论问题,集中精力并完全沉浸在讨论中。我认为会议吸引了一帮人的想法,但是它们对于想法筛选是有用的,头脑风暴不是发明新思路的最佳方式,我更相信独处,思考和时间。

为了产生新的东西,你必须花时间思考。

相信你自己可以毫无准备地参加会议并解决问题的话,这就天真了。

在工作中运动

我希望越来越多的公司信任员工,我希望现在看到这样一个场景是很罕见的:

经理在上午 11 点来到一个厨房,看到两个开发人员正在啜饮咖啡,互相聊天、一起嘲笑着什么。经理的脸色变成紫色,大声喊道:“你为什么在这里干什么?我们在这个星期五有一个截止日期!“开发者匆匆离开杯子走开。

可怕… 工作不应该是一个无聊的地方,人们编码,测试和发布的东西。创造性的工作需要体力活动,停顿和谈话。有一个乒乓球,教练员,瑜伽 / 跳舞 / 办公室里的任何课程(当然还有淋浴)是很好的。锻炼有助于降低压力水平,最终帮助人们提高生产力。

你真的认为人们会完全用工作时间去打网球,踢球或其他的吗?如果是这样,你有严重的问题。也许他们无聊到死,厌倦了上个月的任务。或者你雇用了错误的人无论如何,这是在那里发生错误的表现。

所以工作中的运动是好的,你可以把这个时间想象成浪费,但事实并非如此。

在工作中学习

每个软件开发公司都希望有人学习新事物。尽管如此,没有那么多公司提供学习新事物的机会。我们已经在前几节讨论了学习,但是一些公司认为在工作中学习是一种浪费。事实上,它不会产生任何价值,所以这项活动是无价值的。在软件开发中,我们应该把重点放在 “工作更聪明,更难” 上,从这个角度来看,工作中的学习变得相当有趣。

我们可以衡量橙色星期五的结果吗?图书?会议?业余项目?这真的很难。结果是长期的(几年),而且也没有明显的模式来将知识量化为金钱。

工作与生活的平衡

本节将会简短,我们已经提到了倦怠,软件开发是一个你会一直思考的活动。当你在软件中遇到一个复杂的问题时,你到处想着它。当你和女朋友散步的时候,它突然间就会弹出来,一些想法出现在淋浴中,而你的大脑甚至试图在最不适当的时刻加强这个问题,学习如何关闭是非常重要的,体育,旅游,瑜伽和爱好是最好的选择。


公司应该鼓励人们有一些业余爱好和支持,对于体育活动也是如此。

零加班规则应该由高层管理者进行宣传,如果你越来努力地工作的话,在某个时间点之后,你将会变得越来越笨拙。

总结

我认为强调一些观点是有帮助的。

软件开发节奏 / 生产力 / 速度是一个复杂,相互依赖和多方面的概念。它没有简单的解决方案,你不能对 “加快工作” 的人大喊大叫,你不能盲目偷工减料,只能专注于增值活动。唯一的解决方案是深入思考公司,以及开发流程,人员,工具等,最后建立一个模型并深入思考。

我对于进一步发展间隔开发的的概念很有兴趣,这感觉对我来说非常耐人寻味,而且这种模式很有可能是良好的速度和耐力的恰当平衡,马拉松和中等冲刺混合的比喻打开了许多新的探索方向。

还有一些关于模型的文字。

为模型添加权重很有意思。一些活动对速度的影响很大,而其他的则不是那么多。 每个公司都有独特的权重,但是如果我们能够以某种方式定义它们,我们可以把重点放在最重要的事情上

感谢您的时间。

附 1:我不知道这篇文章可以扩展成一本书吗?嗯…

附 2:Reddit 讨论


首发于 Github issues: https://github.com/xizhibei/blog/issues/65 ,欢迎 Star 以及 Watch

本文采用 署名-非商业性使用-相同方式共享(BY-NC-SA)进行许可
作者:习之北 (@xizhibei)
原链接:https://blog.xizhibei.me/2017/12/23/speed-in-software-development/