研究思考丨关于软件复杂度的困局

Posted 阿里系统软件技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了研究思考丨关于软件复杂度的困局相关的知识,希望对你有一定的参考价值。

本文主要阐述了个人对软件复杂度的思考,分析了导致软件复杂度的原因、软件复杂度的度量方式以及阐述了自我理解的如何避免软件复杂度的问题。

作者:王洋(古训)

前言

大型系统的本质问题是复杂性问题。互联网软件,是典型的大型系统,如下图所示,数百个甚至更多的微服务相互调用/依赖,组成一个组件数量大、行为复杂、时刻在变动(发布、配置变更)当中的动态的、复杂的系统。而且,软件工程师们常常自嘲,“when things work, nobody knows why”。

本文将重点围绕软件复杂度进行剖析,希望能够帮助读者对软件复杂度成因和度量方式有所了解,同时,结合自身的实践经验谈谈我们在实际的开发工作中如何尽力避免软件复杂性问题。

导致软件复杂度的原因

导致软件复杂度的原因是多种多样的。

宏观层面讲,软件复杂是伴随着需求的不断迭代日积月累的必然产物,主要原因可能是:

1.对代码腐化的退让与一直退让。

2.缺乏完善的代码质量保障机制。如严格的 CodeReview、功能评审等等。

3.缺乏知识传递的机制。如无有效的设计文档等作为知识传递。

4.需求的复杂性导致系统的复杂度不断叠加。比如:业务要求今天 A 这类用户权益一个图标展示为✳️,过了一段时间,从 A 中切分了一部分客户要展示

关于软件研发生产力的误区与思考

软件系统的高效开发从来没有像现在这样重要,因为疫情已经迫使全球很多软件工程师在家工作,开发人员和管理者脱离了以往的工作场所和团队。虽然出乎意料,但这个变化构成了一个罕见的“自然实验”,使人们在许多不同的环境中研究、比较和理解开发人员的生产力。疫情的影响以及今后的远程/本地混合办公,进一步加速了了解开发人员生产力的必要性。

在软件工程中,开发人员的生产力是复杂而微妙的,对软件开发团队有着重要的影响。定义、衡量和预测开发人员的生产力可以提升组织、管理者和开发人员开发高质量软件的能力,并使其更有效率。不幸的是,如何衡量生产力,甚至如何定义生产力都是非常困难的事,而关于研发效率的误区也是常见的。

“No measurement,no management”,很多时候,研发团队的管理者试图用简单的度量标准来衡量开发人员的生产力,用“一个重要的度量标准”来表达生产力。然而,开发人员的生产力不仅对于提高工程成果是必要的,而且对于确保开发人员的满意度也是必要的,生产力和满意度错综复杂地联系在了一起。

这里尝试枚举了关于开发人员生产力的几个常见误区和误解。最重要的是,研发效率不能降低到单一的维度。打破这些误区需要一个实用的多维框架,通过一系列指标,我们才能理解开发人员的生产力。通过认识和衡量生产力,可以更好地理解开发人员和团队如何工作,以便做出更好的决策,进而提升研发效率。

误区一: 生产力完全取决于开发人员的活动

这是最常见的误区之一,它可能会导致不良后果以及开发人员的不满。有时,由于各种原因,出现了大量的活动,任务密集,工作时间的延长可能意味着开发人员必须“加班”以克服计划不周,来满足预定的时间表。另一方面,这些增加的活动可能是由于工程环境的糟糕,因此需要为开发人员提供完成工作所需的有效工具,或者需要更好地与团队成员协作沟通,以解除代码变更及代码评审的阻碍。

开发活动的度量本身并不能直接揭示背后的原因,也不应该孤立地用作奖惩。即使是简单的度量标准,如代码提交或代码审查的数量,也很容易因为数据缺口和度量误差而出现错误,而这些度量标准也会失去在结对编程或头脑风暴中获得的协作好处。另外,开发人员经常灵活安排工作时间以满足最后期限,例如一次性提交,这使得某些活动难以应用于生产力的评估。

误区二: 生产力只与个人表现有关

虽然工程师的个人表现很重要,但是为团队成功而做出的贡献对于生产力的衡量也是至关重要的。平衡开发人员、团队和组织的绩效度量非常重要。就像踢足球那样,最终的胜利既取决于球员的个人表现,也取决于球队的整体表现。

一个只为自己绩效负责的工程师可能会损害团队的生产力。那些以团队为中心的活动,如代码审查、事件响应、开发和管理工程平台等,有助于维护代码库和产品/服务的质量。在优化个人、团队和组织生产力时找到正确的平衡点,理解可能的权衡才是关键。

误区三: 一个指标可以告诉我们一切

关于开发人员生产力的一个常见误区是,只采用一个通用的度量标准,而且这个“重要的度量标准”可以用来给团队的整体工作打分,并与一个组织甚至业内的其他团队进行比较。

实际上,这并不能真实地反应生产力水平,开发人员的生产力涵盖了工作中的多个重要方面,并在很大程度上受到工程环境的影响。了解衡量标准的上下文很重要,理解指标的相关因素,以及如何改进工程系统和团队的反应。因此,没有“一个唯一的度量标准”。

误区四: 度量指标只对管理者有用

开发人员经常说生产力的度量指标是无用的。这可能来自于管理者对度量方法的滥用,当生产力得不到很好的衡量和实施时,就会导致在组织中的不恰当使用,这是令人失望的。

不管是出于个人原因,还是出于与他人沟通的目的,开发人员都会注意到追踪自己研发效率的价值。开发人员可以利用它来获得对研发工作的洞察力,这样就可以调控工作时间和精力。例如,高效率与对工作的满意度高度相关。提高效率的方法也包括在工作中引入更多快乐,减少沮丧。

误区五: 生产力只与工程系统及开发工具有关

便捷的监控系统、客服系统、问题分发系统、日志分析系统都将有助于提高开发人员的效率。虽然开发工具和工作流程对开发人员的生产力有很大的影响,但是开发环境和文化等人为因素也有很大的影响。通常,对于保持工作环境和团队文化的健康,所需的关键工作对于许多人来说是“看不见的”,或者对于传统用于衡量生产力的指标来说是“看不见的”。诸如团队建设、现场指导团队的新成员和鼓舞士气、以及知识分享这样的工作对于支持一个富有成效的工作环境都是至关重要的,但往往不能衡量。

另外,如果开发者晚上在家工作的时候因为某个事件而被不断地呼叫,那么这些“看不见的”因素尤其会影响他们的工作效率。因此,有利于团队整体生产力的“看不见的”工作与其他更常见的测量维度一样重要。

误区六: 个人解决的问题数量才是最重要的

与软件开发生命周期中的许多其他活动一样,事件(如故障)处理也是一种团队活动。一个导致大量中断和花费更多时间进行恢复的服务会对开发和维护服务的整个团队造成不良影响。更多以团队为中心的活动,例如知识共享、准备故障排除指南、帮助其他团队成员、指导团队的新成员、进行适当的交接和分配任务,都是事件处理的重要方面。 

思考开发人员生产力的度量指标

软件研发的生产力不仅仅是个人或工程系统的问题,也不能仅仅通过单一的指标或活动数据来衡量,更不是只有管理者才关心的问题。软件开发生产力度量指标不是一个,而是多维度的衡量,这些维度包括: 

  • 员工满足感; 

  • 绩效表现; 

  • 研发活动; 

  • 沟通协作; 

  • 流程效率。

理性思考生产力及研发效率,需要理解度量指标的背后含义,尤其是它们的限制条件。

满足感

满足感是开发人员对自己的工作、团队、工具或文化的满意程度。很明显,员工满意度是生产力的重要方面。生产力和满意度是相互关联的,满意度和参与度的下降可能预示着即将出现倦怠并导致生产力下降。例如,在疫情期间,居家办公时,生产力的某些指标(例如代码提交和合并的速度)出现了上升。虽然这些活动指标看起来是积极的,但满足感指标描绘了一个更全面的图景。

满足感的度量通常可以通过调查得到较好的体现。为了评估满意感,可以测量以下几点:

  • 员工满意度,以及他们是否会向其他人推荐自己的团队。

  • 开发人员是否拥有完成工作所需的工具和资源。

  • 是否压力过大、持续时间过长。

绩效表现

绩效表现是一个系统或过程的结果。软件开发人员的绩效表现很难量化,因为很难将个人贡献与产品结果直接联系起来。写了大量代码的人可能不会产出高质量的代码,而高质量的代码也可能无法为客户提供价值。取悦客户的特性并不总能带来积极的业务结果,即使某个特定工程师的贡献可以与业务成果联系起来,但这并不总是对业绩的反映,因为他也可能被分配了一个不那么有影响力的任务,而某些人通过政治手段选择了更有影响力的工作。

此外,在许多公司和组织中,软件是由团队而不是个人编写的。软件系统通常是许多开发人员贡献的总和,这加剧了评估单个开发人员绩效表现的难度。由于这些原因,绩效表现通常最好作为结果而不是产出来评估。对于软件开发人员的绩效表现来说,最简单的观点可能是: 开发人员编写的代码是否可靠地完成了它应该完成的任务?绩效表现的度量指标可能包括:

  • 质量、可靠性、无缺陷和持续服务。

  • 客户满意度、客户采纳和保留、功能使用和成本的降低。

研发活动

研发活动是在完成工作的过程中完成的动作或产出的计数。如果测量正确,研发活动可以提供关于开发人员生产力、工程环境和团队效率中有价值但有限的见解。由于开发人员执行的活动复杂且多样,因此这些活动不容易衡量或量化。事实上,对跨越团队和跨工程环境的研发活动进行全面的衡量和量化,几乎是不可能的。然而,一个设计良好的工程环境将有助于在软件开发生命周期的不同阶段获取活动的度量,并在规模上量化开发人员的研发活动。一些可以相对容易测量和量化的活动包括:

  • 设计和编码:设计文档和规格、工作项、提交和代码审查的数量或计数。

  • 持续集成和部署:构建、测试、部署/发布和基础设施利用率的计数。

  • 业务活动:根据事件/问题的严重程度、及时响应的参与程度和事件解决程度,统计事件/问题的数量和分布情况。

这些度量标准可以作为衡量某些易于处理的活动数据,鉴于已知的局限性,不应该单独使用它们来判定个人或团队的生产力。它们起到模板的作用,应该根据组织的需求和工程环境进行定制。

沟通协作

软件开发是一项协作性和创造性的任务,它依赖于团队内部以及团队间广泛而有效的沟通、协调和协作。高效团队依赖于高透明度以及对研发活动和任务优先级的认知。此外,团队内部和团队之间的信息流动方式影响了文档的可用性和可发现性,而这些文档是有效地协调和整合工作所必需的。高效团队在正确的问题上工作,“做对的事情,然后把事情做对 ”。这样就更有可能集思广益,并会从所有的选择中判定更好的解决方案。

有助于团队整体或支持另一个团队的的工作可能会牺牲个人的生产力,也可能会降低工作动力以及满足感。然而,有效的协作可以降低某些单独活动的需求(例如,不必要的代码审查) ,进而帮助提升生产力并避免倦怠。

然而,理解和衡量团队的生产力和团队成员的期望是复杂的,一些项目是难以衡量的,例如看不见的工作协调和规划团队任务的衔接工作:

  • 文件和专业知识的可发现性;

  • 工作和资源整合的速度有多快;

  • 代码审查的质量;

  • 显示谁与谁有联系以及如何联系的网络指标;

  • 新员工进入状态的时间。

流程效率

最后一个度量维度是以最小的时间中断或延迟来完成工作,这可以包括团队内部和团队之间的活动是否协调良好,以及是否正在取得持续的进展。

在最少干扰或中断的情况下,生产力与完成复杂任务的能力相关。当许多开发人员谈到他们的工作在“流程”中的时候,或者在寻找和优化流程时遇到困难的时候,都在探讨如何以可控的方式实现一种积极向前的状态。对于流程中的个人效率而言,设定职责边界并保持生产力很重要,例如,在一段时间内专注于某事而避免阻断。个人效率通常以不间断的关注时间或创造有价值代码的时间来衡量。

在团队和系统层面,效率与价值-流程的映射有关,价值-流程映射捕捉了从设计到交付给最终客户所需的步骤。为了优化价值-流程的映射关系,最小化延迟和任务的切换是很重要的。DevOps 框架引入了几个度量标准来监控团队内部的流程,例如,部署频率来衡量一个团队成功发布到生产环境的频率,而变更的前置时间衡量了承诺进入生产环境所需的时间。

除了变更流程之外,知识和信息的流动也很重要。流程效率的某些方面同样是难以衡量的,但通常可以发现并消除流程的低效环节。对用户没有价值的活动造成了研发浪费,例如重复造轮子、因任务没有正确完成而推倒重来、以及耗时的体力活动。

以下是一些捕捉效率和流程维度的示例度量:

  • 一个过程中任务在不同团队之间的移交次数;

  • 能否保持流畅地完成工作;

  • 中断的数量、耗时、间隔,及其对研发工作和流程的影响;

  • 工程系统测量到的时间,包括总时间、增量时间、等待时间等。

流程效率与所有的空间维度相关。个人、团队和公司层面的效率与满足感的提高呈正相关。然而,过度追求高效也会对其他因素产生负面影响。例如,最大化的流程提速可能会降低系统的质量,并增加客户可见的缺陷数量。通过减少中断来优化个人效率可能会降低协作能力,阻碍其他人的工作,并降低团队的头脑风暴能力。

研发生产力的一个场景示例

以代码评审作为一个示例场景,这个场景可以涵盖所有五个维度的度量。

  • 满足感

关于代码评审的测量可以揭示开发人员是从好的角度还是坏的角度来看待这项工作。例如,是否提供了学习、指导或者塑造代码库的机会。这一点很重要,因为如果一些开发人员认为他们被分配了不成比例的代码审查时间,那么代码审查次数过多可能引起他们的不满,因为那样他们就没有时间做其他工作。

  • 绩效表现

代码评审速度既可以反映个人完成审查的速度,也可以反映团队的约束,所以它既是个人层面的度量,也是团队层面的度量。例如,一个人可以被指派在一个小时内完成一项审查,但有可能团队有一个政策,让所有的审查开放24小时,以便让所有人都能看到目标的变化。

  • 研发活动

代码评审的完成数量是一个单独的度量指标,用于衡量在给定的时间内完成的审查数量,并为最终产品做出贡献。

  • 沟通协作

代码评审本身是开发人员通过代码进行协作的一种方式,而代码评审质量的度量或评分是协作和交流的一个重要的定性度量。

  • 流程效率

代码评审很重要,但是如果它中断了工作流程,或者延迟导致了发布环境中的约束,那么代码评审就会面对挑战。类似地,等待代码评审可能会延迟开发人员继续工作。批量化的代码评审可能不会中断开发人员的编码时间(这会影响单个度量) ,同时也不会造成发布的整体延迟(这会影响系统度量) ,这样可以让团队有效地交付代码(团队级度量)。因此,衡量代码评审时间对个人、团队和系统的效率和流程的影响很重要,这可以通过对评审的耗时和中断的特征(如时间和频率)进行测量来完成。

在这个示例中,研发活动度量是个体级别的指标: 提交次数、编码时间(总时间或每天的时间)和完成代码评审的次数,描述了直接有助于最终产品的工作,有利于理解工作模式和行为如何受到团队和环境的影响。

流程效率是更广泛的混合度量指标。自我报告的生产力指标是在个体层面的体现: 询问开发人员是否具有生产力盲点的影响,同时询问该成员是否干扰最小的情况下完成工作是一个有用的信号。无论是代码、文档还是其他项目,都可以测量工作流程,并获得诸如所用时间、移交次数、延迟和软件交付流水线中的错误等度量指标,这些指标构成了系统级度量。

对提升软件研发生产力实施路径的思考

为了衡量开发人员的生产力,团队领导者应该在多个维度上建立多个度量指标,至少三个以上。例如,如果已经在度量代码提交次数,就最好不要简单地再添上编码时间,因为这两者都是研发活动的度量指标。

另外,是否至少应该有一个指标包括感知测量,如调查数据。通过对员工满足感的感知,可以构建一个更完整的生产力图景。很多时候,感知数据可以提供比从系统行为中观察到的更加准确和完整的信息。

多维度量常常会产生方差较大的分布,但是,一个平衡的视图提供了一个更真实的现状。这种平衡的观点应该有助于加强团队成员之间更明智的决策和权衡,否则,他们可能会专注于工作的一个方面,从而损害整个系统。

用户故事就是一个例子,通常,它是敏捷开发中用来评估团队级别进度的度量指标。如果一个管理者仅关注用户故事的完成梳理,那么团队成员就会专注于优化他们自己的环境,而不去完成那些对其他人有帮助和对公司来说很重要的潜在的无形工作。如果领导者使用用户故事来衡量进度而不询问开发人员快速工作的方式,将无法确定是否有什么工具不工作,团队正在进行方案B而精疲力尽,或许,一个新的创新工具可以用来帮助当前处于困境的团队。

这就引出了关于度量指标及其对团队和组织的影响的一个重要观点: 度量指标意味着什么是重要的。团队是如何被衡量的,这通常传达了什么是有价值的,并影响人们的行为和反应方式。例如,关心员工健康并希望留住员工的公司很可能会将满足感纳入生产力指标。同理,添加或删除度量标准可以推动团队的行为方式,这同样传达了什么是重要的。

再例如,“生产力 = 代码行数”的团队与“生产力 = 代码行数+代码评审质量+客户满意度”的团队非常不同,后者将对生产力的认知推向了一个既重视团队合作(通过重视经过深思熟虑的代码评)又重视最终用户(通过重视客户满意度)的方向。

度量标准塑造了行为方式,所以通过添加两个度量标准,就可能帮助团队和组织形成变化。这就是为什么确保从多个维度中抽取是如此重要: 这将在团队和系统层面上导致更好的结果。

一些局限的反思

太多的度量指标也可能会导致混乱和积极性的降低,并不是拥有所有维度才会有帮助。例如,如果向开发团队提供了一个广泛的度量矩阵和改进目标列表,那么可能会让人感觉这是一个无法实现的目标。考虑到这一点,一个良好的生产力度量标准至少包括三个维度上的一些指标; 这些指标可以提示一个整体的观点,并且足以激发改进。

任何测量范式都应该谨慎使用,因为没有任何度量是完美的。有些指标是糟糕的度量,因为它们是杂乱的近似值。例如,员工离职率会被用来衡量员工满足感,然而,这不仅仅只是满足感,它还可以反映薪酬、晋升机会、团队问题,甚至老板的变动。在团队层面,一些经理可能会阻止内转,以保护他们自己的职级。即使员工离职率确实反映了员工的满足感,也只是一种滞后的衡量指标,团队知道的时候已经为时已晚。

度量指标的建立应该注意到开发人员的隐私,并且只体现在匿名的聚合结果。然而,对于开发人员来说,个人层次的生产力分析可能很有见地。例如,开发阶段的工作依赖,能否在一天中有更多的编码时间等。

最后,任何度量范式都应该有偏差检查和规范,这些都是可能改变或影响具体实施的外部因素。

结束语

软件研发的生产力不仅仅是个人的研发活动或者软件发布的工程效率,它不能用单一的度量标准或维度来衡量。没有多维度分析,关于软件研发生产力的误区可能会持续存在。

通过多维度的分析,可以逻辑地、系统地思考生产率问题,并谨慎地选择与目标相关的平衡指标,以及这些标准将受到怎样的限制。如果衡量研发活动的代价是总体流程的中断,就需要考虑到无形工作以及增加工作量等变化的连锁效应。

随着世界慢慢回归到一个“新常态”,在未来的变化被提出和制定时最好考虑多维度分析,进而确立个人、团队和组织相关的衡量标准,从而呈现出生产力及研发效率的整体图景,进而提升软件研发的生产力水平和研发效率。

【关联阅读】

喔家ArchiSelf

一半是20多年老程序员的技术生涯,一半是人到中年却仍向往青春的生活感悟,交织起来,是一个享受生活的老码农。------Architect oneSelf 架构自己

以上是关于研究思考丨关于软件复杂度的困局的主要内容,如果未能解决你的问题,请参考以下文章

(转)关于软件产品化,平台化的思考

由编程语言和代码质量的相关性引发的思考

决胜人工智能之巅:核心算法缺失背后的中国“AI”困局

Ubuntu丨关于没有可用的软件包 open-vm-tools,但是它被其它的软件包引用了的问题

Ubuntu丨关于没有可用的软件包 open-vm-tools,但是它被其它的软件包引用了的问题

关于软件研发生产力的误区与思考