<谷歌的软件工程>读后感

Jimmy Lee

阅读|Aug 22, 2022|Last edited: 2022-8-23|
icon
Update time
Aug 23, 2022 01:16 PM
Internal status
READY TO PUBLISH
password

前言

近期,阅读了<谷歌的软件工程>,记录一下.
 
我对谷歌这家公司还是比较好奇和欣赏的,不管都是对于拉里佩奇,还是现在阿尔法特(谷歌母公司)的CEO 桑达尔·皮查伊, 个人都非常敬佩.毕竟都是有真正实力的大佬.
 
谷歌运行着目前世界上最大的服务器集群,这个不容置疑.我个人也非常好奇,如此庞大的规模的机器,他们如何调度,如何监控,我们这种小公司是否有可以借鉴的地方.因此,当我发现这本书的时候,我觉得这就是我一直寻找的书.
 
其实在这之前,我已经看过<Sre google运维解密>,收获良多,我的DevOps概念就是从这本书中学来的.个人在之后的工作中也引入了这套工作流程,砍掉了运维工程师,由开发自己负责从开发部署,持续运维监控的全流程,开发人员反馈良好,接触到了很多之前不可能接触到的生产服务器,积累了宝贵的线上故障处理经验,培养了项目主人公的感觉.
 
以下为书籍内容的摘抄,仅供参考.
 

第一章

失败奖励

在谷歌X部门——该部门负责研究自动驾驶汽车和通过热气球提供互联网接入等 "登月计划"——故意将失败次数纳入其激励系统。人们会想出一些稀奇古怪的想法,同事们也会受到积极的鼓励尽快实现它们。每个人都会得到奖励(甚至是竞争),看看他们能在一段固定的时间内反驳或否定多少观点。只有当一个概念真的不能在白板上被所有同行揭穿时,它才能进入早期原型。
 

无责的事后文化

在谷歌X部门——该部门负责研究自动驾驶汽车和通过热气球提供互联网接入等 "登月计划"——故意将失败次数纳入其激励系统。人们会想出一些稀奇古怪的想法,同事们也会受到积极的鼓励尽快实现它们。每个人都会得到奖励(甚至是竞争),看看他们能在一段固定的时间内反驳或否定多少观点。只有当一个概念真的不能在白板上被所有同行揭穿时,它才能进入早期原型。
 

谷歌味儿

谷歌最终解决了这个问题,明确定义了我们所说的“谷歌特质”(Googleyness)——我们所寻找的一套属性和行为,代表了强大的领导力,体现了 "谦逊、尊重和信任":
  • 在模棱两可中茁壮成长 即使在环境不断变化的情况下,也能处理相互冲突的信息或方向,建立共识,并对问题做出改进。
  • 重视反馈 谦虚优雅地接受和给出反馈,理解反馈对个人(和团队)发展的价值。
  • 走出舒适区 能够设定宏伟的目标并去追求,即使有来自他人的抵制或惰性。
  • 客户第一 对谷歌产品的用户抱有同情和尊重,并追求符合其最佳利益的行动。
  • 关心团队 对同事抱有同情心和尊重,并积极主动地帮助他们,提高团队凝聚力。
  • 做正确的事 对自己所做的一切有强烈的主人感;愿意做出困难或不易的决定以保护团队和产品的完整。
 
 
 

如何激励人们记录工作

传统上,鼓励工程师记录他们的工作可能是困难的。编写文档需要消耗编码的时间和精力,而且这些工作所带来的好处并不直接,大部分是由其他人获益的。鉴于许多人可以从少数人的时间中获益,像这样的不对称权衡对整个组织来说是好的,但如果没有好的激励措施,鼓励这样的行为是很有挑战性的。我们在第57页的 "激励和认可 "一节中讨论了其中的一些结构性激励。

奖励方式

工作阶梯的期望是一种自上而下引导文化的方式,但文化也是自下而上形成的。在谷歌,同行奖金计划是我们拥抱自下而上文化的一种方式。同行奖金是一种货币奖励和正式认可,任何谷歌员工都可以将其授予任何其他谷歌员工,以表彰他们的超越性工作。例如,当Ravi将同行奖金发给Julia,因为她是一个邮件列表的顶级贡献者——定期回答问题,使许多读者受益,他公开承认她的知识共享工作及其对团队以外的影响。由于同行奖金是由员工驱动的,而不是由管理层驱动的,因此它们可以产生重要而强大的基层效应。

第三章 知识分享 内容提要

  • 心理安全是培养知识共享环境的基础。
  • 从小事做起:问问题,把事情写下来。
  • 让人们可以很容易地从专家和有记录的参考资料中获得他们需要的帮助。
  • 在系统的层面上,鼓励和奖励那些花时间去教授和扩大他们的专业知识,而不仅仅是他们自己、他们的团队或他们的组织。
  • 没有什么灵丹妙药:增强知识共享文化需要多种策略的结合,而最适合你的组织的确切组合可能会随着时间的推移而改变。
 

第四章 公平工程

  • 偏见是默认的。
  • 多样性是正确设计综合用户群所必需的。
  • 包容性不仅对于改善代表不足的群体的招聘渠道至关重要,而且对于为所有人提供一个真正支持性的工作环境也至关重要。
  • 产品速度必须根据提供对所有用户真正有用的产品来评估。与其发布一个可能对某些用户造成伤害的产品,还不如放慢速度。
 

第六章 规模优先

  • 至此,假设我们已经知道了领导的本质,那么到底什么才能让你提升为一个真正优秀的管理者呢?这就是我们这里想要讨论的,我们称之为“管理上的三个总是”:始终保持决断力,始终保持离开,始终保持扩张。
 

第七章 测试工程效率

  • 如何测量软件过程
    • 在谷歌,我们使用目标/信号/指标(GSM/ goal signal metric)框架来指导指标创建。
    • 目标是一个期望的最终结果。它是根据你希望在高层次上理解的内容来表述的,不应包含对具体测量方法的引用。。
    • 信号是你如何知道你已经实现了最终结果。信号是我们想要衡量的东西,但它们本身可能是不可测量的。
    • 指标是信号的代表。它是我们实际上可以测量的东西。它可能不是理想的测量,但它是我们认为足够接近的东西。
    •  
 

第十章 文档

  • 工程师们越是把文档工作当作软件开发的必要任务之一,他们就越是不反感写文档的前期成本,也就越能获得长期的收益。此外,让文档工作变得更容易,可以减少这些前期成本。
  • 写文档的秘诀
    • 5W,who,what,when. where, why
    • who: 文档受众
    • what: 确定文档用途的内容
    • when: 何时确定本文件的创建、审查或更新时间
    • where: 文档应该放在哪里
    • why: 设定文件的目的
    •  

第十一章 测试概述

  • GWS的经验告诉我们的一个重要启示是,你不能仅仅依靠程序员的能力来避免产品缺陷。即使每个工程师只是偶尔写一些bug,当你有足够多的人在同一个项目上工作时,你也会被不断增长的缺陷列表所淹没。想象一下,一个假设的100人的团队,其工程师非常优秀,他们每个人每月只写一个bug。而这群了不起的工程师在每个工作日仍然会产生5个新的bug。更糟糕的是,在一个复杂的系统中,修复一个错误往往会导致另一个错误,因为工程师们会适配已知的bug并围绕它们编写代码。
概要
  • 自动化测试是实现软件变革的基础。
  • 为了使测试规模化,它们必须是自动化的。
  • 平衡的测试套件对于保持健康的测试覆盖率是必要的。
  • "如果你喜欢它,你应该对它进行测试"。
  • 改变组织中的测试文化需要时间。
 

第十二章 单元测试

  • 努力实现稳定的测试。
  • 通过公共API进行测试。
  • 测试状态,而不是交互。
  • 使你的测试完整和简明。
  • 测试行为,而不是方法。
  • 强调行为的结构测试。
  • 使用被测试的行为来命名测试。
  • 不要把逻辑放在测试中。
  • 编写清晰的失败信息。
  • 在共享测试的代码时,遵循DAMP而不是DRY。
 

第十五章 弃用

  • 与直觉相反,推广强制性“弃用”工作的最佳方法是将迁移用户的工作交给一个专家团队——通常是负责完全删除旧系统的团队。该团队有动力帮助其他人从过时的系统迁移,并可以开发可在整个组织中使用的经验和工具。许多这些迁移可以使用第 22 章中讨论的相同工具来实现。
  • 向用户发出的任何“弃用”警告都需要具有两个属性:可操作性和相关性。 如果用户可以使用警告来实际执行某些相关操作,则警告是可操作的,不仅在理论上,而且在实践中,即要提供可操作的迁移步骤,而不仅仅是一个警告。
  • TL;DRs
- 软件系统具有持续的维护成本,应与删除它们的成本进行权衡。 - 删除东西通常比开始构建它们更困难,因为现有用户经常使用超出其原始设计意图的系统。 - 如果将停机成本包括在内,就地改进系统通常比更换新系统便宜。 - 很难如实地评估 “弃用”所涉及的成本:除了保留旧系统所涉及的直接维护成本外,还有多个相似系统可供选择 所涉及的生态成本,互有干涉。旧系统可能会暗中拖累新系统的功能开发。这些不同的生态所带来的成本则分散且难以衡量。“弃用”成本通常同样分散。
 

第十六章

  • 对任何大于“只有一名开发人员且永远不会更新的玩具项目”的软件开发项目都要使用版本控制。-
  • 当存在 "我应该依赖哪个版本 "的选择时,就会存在内在的扩展问题。
  • 单一版本规则对组织效率的重要性出人意料。删除提交地点或依赖内容的选择可能会导致显著的简化。
  • 在某些语言中,你可能会花一些精力来躲避这个问题,比如着色、单独编译、链接器隐藏等等技术方法。使这些方法正常工作的工作完全是徒劳的--你的软件工程师并没有生产任何东西,他们只是在解决技术债务。
  • 以前的研究(DORA/State of DevOps/Accelerate)表明,基于干线的开发是高绩效开发组织的一个预测因素。长周期的开发分支不是一个好的默认计划。
  • 使用任何对你有意义的版本控制体系。如果你的组织想优先考虑为不同的项目建立独立的仓库,那么取消存储库间的依赖关系/“基于头部”/“基于主干”可能仍然是明智的越来越多的VCS和构建系统设施允许您拥有小型、细粒度的存储库以及整个组织一致的“虚拟”头/主干概念。
 

第十七章

  • 最重要的一点可能是显而易见的:理解代码是开发和维护代码的关键,这意味着投资在理解代码上将产生可能难以衡量但实实在在的红利。我们添加到代码搜索中的每个功能都被开发人员用来帮助他们完成日常工作(诚然,其中一些功能比其他功能更多)。两个最重要的功能,Kythe 集成(即添加语义代码理解)和查找工作示例,也与理解代码最明显相关(例如,查找代码或查看代码如何更改)。就工具影响而言,没有人使用他们不知道存在的工具,因此让开发人员了解可用工具也很重要——在谷歌,它是“Noogler”培训的一部分,即新人的入职培训和聘请的软件工程师培训。
  • 帮助您的开发人员理解代码可以大大提高工程生产力。在 Google,这方面的关键工具是代码搜索。
  • 作为其他工具的基础以及作为所有文档和开发工具连接到的中心标准位置,代码搜索具有附加价值。
  • Google 代码库的庞大规模使得定制工具(例如,与 grep 或 IDE 的索引不同)成为必要。
  • 作为一种交互式工具,代码搜索必须快速,允许“问题和回答”的工作流程。预计在各个方面都有低延迟:搜索,浏览和索引。
  • 只有当它被信任时才会被广泛使用,并且只有当它索引所有代码、给出所有结果并首先给出期望的结果时才会被信任。但是,只要了解其局限性,较早的、功能较弱的版本既有用又可以使用。
 

第十八章

  • 一个功能齐全的构建系统对于保持开发人员在组织规模扩大时的生产力是必要的
  • 权利和灵活性是有代价的,适当地限制构建系统可以使开发人员更容易使用它
 

第十九章 体验:谷歌的代码审查工具

  • 信任和沟通是代码审查过程的核心。工具可以增强体验,但不能替代它们。
  • 与其他工具的紧密集成是获得优秀代码审查体验的关键。
  • 小的工作流程优化,如增加一个明确的 "关注集",可以提高清晰度并大大减少摩擦。
 

第二十章 静态分析

  • 关注开发者的幸福感。我们投入了大量精力,在我们的工具中建立分析用户和作者之间的反馈渠道,并积极调整分析以减少误报的数量。
  • 将静态分析作为核心开发人员工作流程的一部分。谷歌静态分析的主要集成点是通过代码评审,在这里,分析工具提供修复并让评审人员参与。然而,我们也在其他方面(通过编译器检查、选通代码提交、在IDE中以及在浏览代码时)集成分析。
  • 授权用户做出贡献。通过利用领域专家的专业知识,我们可以扩展构建和维护分析工具和平台的工作。开发人员不断添加新的分析和检查,使他们的生活更轻松,使我们的代码库更好。
 

第二十一章 依赖管理

谷歌在推出不兼容的依赖的版本时,基本会提供迁移工具,这在大型项目重构中可以节约很多人力
 
当谷歌的工程师试图导入依赖关系时,我们鼓励他们先问这个(不完整)的问题清单:
  • 该项目是否有你可以运行的测试?
  • 这些测试是否通过?
  • 谁在提供这个依赖关系?即使在 "无担保 "的开放源码软件项目中,也有相当大的经验和技能范围--依赖C++标准库或Java的Guava库的兼容性,与从GitHub或npm中随机选择一个项目是完全不同的事情。信誉不是一切,但它值得调研。
  • 该项目希望达到什么样的兼容性?
  • 该项目是否详细说明了预计会支持什么样的用法?
  • 该项目有多受欢迎?
  • 我们将在多长时间内依赖这个项目?
  • 该项目多长时间做一次突破性的改变?项目多久进行一次突破性的变更?
在此基础上,添加一些简短的内部重点问题:
  • 在谷歌内部实现该功能会有多复杂?
  • 我们有什么激励措施来保持这个依赖性的最新状态?
  • 谁来执行升级?
  • 我们预计进行升级会有多大难度?
 
 
致谢:
💡
有任何问题,欢迎您在底部评论区留言,一起交流~
 
 

开始订阅我的关于终生学习, 生产力以及知识管理的文章. 订阅后, 您将收到我的精选文章.

©2014-2024 Jimmy Lee. All rights reserved. 公众号: 技术管理方法论
Powered By My Lovely Children