在代码库中管理技术质量

2020-10-19 01:40:16

如果有一件事工程师、工程经理和技术高管可能会达成一致,那就是技术质量危机。有一个诊断和治疗方法很容易识别:我们的工程师没有把质量放在首位,我们需要雇佣更好的工程师或对我们现有的工程师进行再培训。当然,如果你觉得更舒服的话,你可以随意用产品经理或高管取代工程师。这是一个令人信服的故事,有一个明显的恶棍,而且它很方便地将责任从工程领导层身上转移出来。尽管如此,就像大多数将责任推向权力最小的人的叙述一样,这既无济于事,也是错误的。

当你接受低技术质量是由糟糕的决策造成的这一前提时,你就开始寻找糟糕的判断,而公司里的某个人肯定是罪魁祸首。是之前的CTO吗?是那个工程师紧张地看着你的那个工程师吗?是所有人吗?如果不是这些人干的,更奇怪的是,这甚至不是你的错,那该怎么办呢?

在大多数情况下,低技术质量不是危机;它是预期的、正常的状态。工程师通常会在做出合理的质量决策时做出这些决策,成功的公司会随着时间的推移提高其质量标准,因为它们会向企业用户扩展、转移或转移高端市场。在一家经营良好且成功的公司,你以前的大部分技术决定都不会达到你目前的质量门槛。缩小当前技术质量与目标技术质量之间的差距不是失败,而是有效工程领导的常规、必不可少的部分。

作为一个工程领导团队,您的目标是保持适当的技术质量水平,同时将尽可能多的精力投入到核心业务上。您必须在多个时间范围内平衡质量,而这些时间范围通常具有相互冲突的需求。例如,让关键的合作伙伴在下周的最后期限前完成的工作与构建一个支持下个季度启动速度提高10倍的平台的工作是截然不同的。

正如您公司的技术质量栏将随着时间的推移而变化一样,您管理技术质量的方法也将同步发展:

在我们深入研究这些方法的工具包时,请记住选择最便宜、最简单的可能有效的工具。技术质量是一个长期的游戏。没有胜利这回事,只有学习和赢得继续比赛的机会。

钻研手头的挑战有一种特别的乐趣,直到你发现一个普遍的问题值得解决。然而,同样重要的本能是迅速解决当前局势,并转向下一个紧迫的问题。

当您考虑对您的团队和组织进行正确的质量改进时,通常最有效的做法是从最轻量级的解决方案开始,只有在早期的努力在规模压力下崩溃时才向大规模解决方案前进。如果你不能让团队采用正确的代码拼接,那么你想要推出一个全面的质量计划的尝试注定是失败的。虽然后者在规模上可能更有效,但它们的执行难度要大得多。

即使它不起作用,你也会从没有推出简单的东西中学到越来越快的东西,而不是没有推出困难的东西。然后,您将更快地达到改进后的第二次迭代。随着时间的推移,你会走向全面的方法,但没有必要着急。不要在没有适当需要的情况下,为了企业规模协调的危险而放弃早期组织的轻松、快乐和纯真。

将这些阶段呈现为要攀登的线性楼梯很方便,但这很少是真正的组织如何使用它们。您更有可能修复质量热点,推出最佳实践,开始运行体系结构审查,取消体系结构审查,然后再回到热点问题上来一段时间。过早的过程增加的摩擦比价值更多,很快就会暴露出自己是无效的。如果有些东西不起作用,试着让它起作用,然后庆祝它的消亡。

当遇到质量问题时,第一反应通常是确定必然需要过程解决方案的过程故障。如果部署导致停机,那是因为作者没有正确遵循代码测试过程,所以现在我们将要求在每次提交时都进行测试-这将教育那些懒惰的开发人员!

关于“萨班纳-奥克斯利法案”(Sarbannes-Oxley)有一个古老的笑话:它不会降低风险;它只是清楚地表明了当事情出错时该归咎于谁。不幸的是,对于有多少组织推出流程,这个笑话毫无幽默感。问责制有其作用,但理解手头的问题并尝试直接解决它比创建流程驱动的问责制要重要得多。

流程的推出需要人们改变他们的工作方式,这是你不应该轻率承担的。与其追求流程改进,不如从穿上性能工程师的心态开始。衡量手头的问题,找出主要问题发生的地方,并将重点精确地放在该领域。

前一个未经测试的部署示例可能受益于向部署工程师提供有关更改他们的测试习惯的直接反馈。或者,如果承认你的软件设计容易出错,并采用软件设计哲学中描述的定义不存在的错误的方法,也许你会得到更好的服务。

如果您有开发速度问题,可能是优化测试运行时,将Docker编译步骤移到RAM磁盘上,或者使用软件设计X射线中描述的技术来查找需要改进的特定文件。

系统思维是我职业生涯中遇到的最具变革性的思维技巧。尽管如此,有时它可能是一个警报器,它会召唤你修复一个你可能更好地抛弃的现有系统。当然,您可以推出一个新的培训计划来教您的团队如何编写更好的测试,但或者,您也可以只删除98%的测试失败发生的那个测试文件。这就是对热点进行优先排序的不合理的有效性,也是为什么它应该是你提高技术质量的第一项技术。

在某个时候,您可能会发现您的组织造成质量问题的速度比您修复热点的速度更快,此时正是采用最佳实践的时候。

我曾经在一家没有团队计划流程的公司工作。随着时间的推移,工程负责人对无法预测目标日期越来越感到沮丧,并要求我们使用Scrum。任务完成后,一位经理在维基上编写了Scrum流程。有一则声明说我们正在使用Scrum。经理们告诉他们的团队使用Scrum。任务完成!

当然,没有人开始使用Scrum。每个人都在做他们以前做过的事。承认错误是很尴尬的,所以工程负责人宣布采用是一个重大的胜利,没有人忍心说不同的话。

这个悲惨的故事反映了有多少公司试图推出最佳实践,这也是最佳实践声誉如此糟糕的原因之一。理论上,组织将受益于在修复质量热点之前采用最佳实践,但我建议在热点确定之后采用最佳实践。采用最佳实践需要一定程度的组织和领导成熟度,这需要一些时间来发展。

当您推出一项新实践时,请记住,良好的流程是循序渐进的,而不是强制执行的。研究其他公司如何采用类似的做法,记录您打算采用的方法,与几个参与其中的团队进行实践试验,磨平粗糙的边缘,改进基于挑战的文档,然后才能进一步推广。仓促的过程是失败的过程。

同样重要的是限制并发进程推出的想法。如果你试图让团队同时采用多种新做法,你就是在与自己争夺他们的注意力。如果您正在考虑恢复或修改其中一个新的做法,这也会使以后更难将影响归因于此。这有点苛刻,但我已经开始相信,在任何给定的时间,您都应该将自己限制在一个最佳实践的推出范围内。把你所有的精力都用在让一次练习取得成功上,而不是把资源分散到少数几个人身上。

一次采用一种新的做法也会迫使您仔细考虑优先考虑哪种做法。选择下一个流程听起来很容易,但通常不清楚哪些最佳实践才是真正的最佳实践,哪些只是熟悉的或著名的。真正的最佳实践必须得到研究的支持,关于这一主题的最佳研究来源是Accelerate。

虽然Accelerate的所有建议都是数据驱动的,而且相当不错,但我发现早期采用的少数几个建议最有帮助的是版本控制、基于主干的开发、CI/CD和生产可观察性(包括他们编写的系统的开发人员随叫随到),以及在小的原子变化中工作。我还喜欢提倡许多其他的做法,他们没有在整个职业生涯中都在倡导更好的内部文件,但我不像以前那样相信自己的直觉。

从修复热点到采用最佳实践的转变是当你被太多热点搞得喘不过气来的时候。下一个过渡,从最佳实践到杠杆点,当您发现自己想要在正在进行的最佳实践生效之前采用新的最佳实践时。与其提高您的最佳实践采用进度限制,不如转向下一个工具。

在热点部分,我们讨论了如何使用性能工程师的心态来确定要修复的正确问题。优化很好地解决了您已经存在的问题,但它故意不适用于未来:性能工程的最大罪过就是将精力应用于未经证实的问题。

然而,当您查看软件如何随时间变化时,会发现有少数几个地方的额外投资会随着时间的推移保持质量,这既是通过防止严重的质量故障,也是通过降低未来质量投资的成本。

我称这些为质量杠杆点,三个影响最大的点是接口、有状态系统和数据模型。

接口是系统之间的合同。有效的接口将客户端与封装的实现解耦。持久接口公开所有底层的基本复杂性,而不公开任何底层的意外复杂性。令人愉悦的界面具有敏锐的洞察力和敏锐的渴望。

状态是任何系统中最难更改的部分,对更改的抵制使有状态系统成为另一个关键的杠杆点。国家的惯性来自其规模。它倾向于以可用性、可靠性和遵从性属性为代表的复杂性。而不是用概率而不是定理来描述这种正确性。(或者在分布状态的情况下,概率和定理。)。

数据模型是接口和状态的交集,将有状态系统的功能限制在您的应用程序认为合法的范围内。一个好的数据模型是严格的:它只公开它真正支持的内容,并防止无效的状态表达式。一个好的数据模型能够容忍随时间的演变。有效的数据模型甚至一点也不聪明。

当你确定工作中的这些杠杆点时,花额外的时间刻意地接近它们。如果它是一个接口,那么针对模拟的实现集成六个客户端。如果它是一个数据模型,那就代表六个真实的场景。如果它是有状态的,请练习故障模式,检查一致性行为,并建立类似于您的生产场景的性能基准。

把你学到的所有东西都放到一个技术规范文档中,这样你就可以在你的团队中进行交流了。从同行那里收集行业反馈。即使在你开始实施之后,也要倾听现实的声音,并对变化保持开放态度。

投资于杠杆点的潜在力量之一是,你不需要完全的组织协调来做到这一点。要写出技术远景或推出最佳实践,你需要这种认可,这就是为什么我建议从杠杆点开始。然而,如果你已经用尽了杠杆点带来的可获得的影响,那么现在可能是时候推动更广泛的组织协调了。

有效的组织将他们的大部分努力集中在一个共同的愿景上。如果你绘制每个项目,每个技术决策,实际上,作为网格上的一个矢量,这些矢量指向同一方向的越多,随着时间的推移,你就会完成得越多。相反,与我共事过的一些最令人印象深刻的工程师创造的矢量规模非同寻常,但方向错位,最终在试图领导他们的组织时损害了他们的组织。

调整技术方向的一个可靠的解决方案是将所有相关的决策都交给与其头衔中某个架构师相同的人。这工作得很好,但是扩展起来很有挑战性,架构师的决策质量会随着他们在实际过程中对实际代码的实际工作而进一步降低。在另一个极端,您可以允许每个团队做出独立的决策。但是,允许任何工具的组织都是拥有统一不支持的工具的组织。

给出直接的反馈。当人们遇到错位时,第一个答案通常是流程更改,而不是从简单地向您认为错位的个人提供直接反馈开始。尽管他们错过了你的背景,你也错过了他们的背景,一次友善、清晰的对话通常可以避免多年不必要的过程。

在一份清晰、有用的文档中阐明您的愿景和战略。(这是一个丰富的主题,我将单独讨论。TODO:一旦编写完成,请添加一个指向撰写技术策略部分的链接。)。

将您的方法封装在您的工作流和工具中。有清晰愿景的文档是有帮助的,但有些人根本不会研究您的文档。经过深思熟虑的工具创建的工作流程比培训和文档更能培养习惯。例如,提供一项新服务可能需要转到一个网站,该网站要求您添加指向该服务的技术规范的链接。另一种方法可能是,如果服务没有建立待命设置,并且某人当前处于待命状态,并且此人还必须启用他们的推送通知,则可能会阻止部署到生产环境。

在新团队成员入职期间对其进行培训。在人们养成习惯后改变他们的习惯是相当有挑战性的,如果你试图让人们采用新的实践,这是令人沮丧的。然而,如果你让人们在加入时找到了正确的方向,那么这种习惯势头将有利于保持一致。

使用康威定律。康威定律认为,组织构建反映其结构的软件。如果您的组织结构不佳,这将导致紧密耦合或错综复杂的软件。然而,如果您的组织的设计是有效的,那么它也是质量的一股力量。

使用架构审查、投资策略和采用新工具的结构化流程来策划技术变更。大多数错位来自于缺少上下文,这些是将上下文注入决策的组织杠杆点。许多组织都是从这里开始的,但这是我建议打开的最后一个工具箱。如果没有明确的愿景,您如何提供一致的体系结构审查?为什么要在他们设计了一些东西之后才告诉他们你的战略,而不是在他们的入职过程中呢?

不管您使用什么方法来调整您的技术向量,这项工作往往需要几个月甚至几年的时间才能完成。没有哪个世界可以让你写远景文档,组织就会立即与它的辉煌保持一致。更有可能的是,在你投资建设支持之前,它会积聚灰尘。

大多数公司可以将上述从热点定位到矢量对齐的技术组合成管理技术质量的成功方法,希望您也能做到这一点。然而,许多人发现它们是不够的,你会转向更重的方法。在这种情况下,第一步一如既往地是测量。

软件工程中对度量的需求通常已经超过了我们的度量状态。Accelerate确定测量速度的指标,这些指标对于定位流程和工具问题非常强大,但是这些指标在代码合并后开始。您如何衡量代码库的质量,以便找出差距,提出行动计划,并评估您改进工作的影响?

有一些流程度量与有效的更改相关。例如,您可以测量每个拉入请求中更改的文件数,因为拉入请求越小,质量通常越高。您还可以测量每个文件的代码库代码行,前提是非常大的文件通常很难扩展。这两者都可能非常有帮助,我甚至建议对它们进行测量,但我认为它们充其量是代码质量的替代测量。

我的经验是,有可能有效地衡量代码库质量,归根结底就是开发了一个非常精确的质量定义。您对质量的定义越详细,它对衡量代码库就越有用,对希望提高他们正在工作的领域的质量的人们也就越有指导意义。这种方法在构建进化体系结构和回收不合理的软件中有较详细的描述。

有多少函数具有危险的写后读行为?或者对主数据库实例执行不必要的读取?

超过一半的拉流请求中有多少热门文件被更改?

欢迎您不同意其中一些属性应该存在于您的代码库的质量定义中:您的定义应该特定于您的代码库和您的需求。重要的是制定一个精确的、可衡量的定义。在该定义的开发过程中会有不同意见,随着时间的推移,您必然会更改该定义。

在您开发了定义之后,这是一个插装真正具有挑战性的领域,插装是有用度量的一个要求。工具的复杂性是在实践中采用这些技术的最大障碍,但是如果您能够推进,您就可以解锁一些非常惊人的东西:一个真实的、动态的质量分数,您可以随着时间的推移进行跟踪,并使用它来在您的方法中创建概念对齐无法做到的清晰度。

有了质量定义和工具,您的下一步就是决定是投资于质量团队还是投资于质量计划。专门的团队易于协调,带宽可预测,通常更容易开始。

技术质量团队是致力于在您的代码库中创建质量的软件工程团队。您可以将此团队称为“开发人员生产力”、“开发人员工具”或“产品基础架构”。在任何情况下,团队的目标都是创建并保持整个公司软件的质量。

这不是有时所说的质量保证团队。虽然两个团队都在测试上投入了资金,但技术质量团队。

.