团队软件库_Google公司的软件工程之道 (1)

徐文锦等 软件质量 道 2017-02-24

28ceb55aff229f2768600593590d5057.png

Google(谷歌)已经是一个非常成功的公司,除了谷歌搜索和AdWords的成功之外,谷歌还向我们提供许多优秀的产品,如谷歌地图、翻译、语音识别、Chrome和Android等。谷歌还通过兼并小公司,拥有像阿尔法狗、YouTube等产品,并展示了一些尚未推出的惊人产品,例如自动驾驶汽车等。

谷歌的成功有很多原因,包括开明的领导力、优秀的人才、招人高门槛,以及有良好的财务实力可以成功利用快速成长的市场中的早期领导者。但其中一个不可忽视的原因是谷歌不断积累了优秀的软件工程实践,助成功一臂之力。借助许多全球最有才华的软件工程师的积累和智慧的结晶,随着时间的推移而不断提升软件工程实践。

  1. Google软件开发之道(1)(2)
  2. Google软件项目管理之道
  3. Google人员管理之道

全面呈现,细节是魔鬼,值得大家仔细阅读】

第1部分 Google软件开发之道

1. 如何管理源代码/strong>The Source Repository)

大部分的代码都用统一的源代码库(repository)来管理,允许所有Google的软件工程师访问。同时也有以下几种值得注意的例外情况,如:

  • 像大型开源项目Chrome和Android使用了独立的开源代码库
  • 一些高价值的或高安全性的代码,则设定了严格的读取权限

但是大多数的程序依然是共享同一个代码库。截止到2015年1月,这个86TB的代码库已经存有10亿多个文件,其中有900多万源代码文件,其代码行数高达20亿,并包含了3500万代码提交(commits/check in)记录,每天还以4万次提交在增长(译者注:谷歌有超过3万开发人员)。对代码库的写权限是被限定的:只有列出的每个库subtree(译者注:Git 的术语)的所有者(Owner,译者注:本来也可以不翻译)有权批准对subtree的修改。但一般来说,任意一位工程师都可以访问任何代码,可以检出(check out)所需代码并进行构建,也可以在本地对其修改、测试, 并且经代码的所有者复审/评审(review)通过后提交(check in)新修改的代码。谷歌的企业文化鼓励工程师跨越项目边界去修复他们认为受到破坏并知道如何修复的任何缺陷。这给了工程师更多授权,并促使达到高质量的基础设施,以更好地满足其使用需求。

几乎所有的开发均发生在代码库的“head”上(译者注:git中的head,即要merge到master之前的分支), 而不是在subtree上。这有助于尽早识别出集成问题并最小化所需的合并工作量。同时也使得安全补丁能够更容易和更快的上线。

更多的Google源代码存储库详见[17、18、21],关于另一个大公司又是如何处理同样挑战的, 可参见[19]。

2. 构建系统(The Build System)

谷歌使用一个被称为Blaze的分布式构建系统,此系统负责软件编译、链接及其测试。它提供了用来构建和测试软件的标准命令, 并适用于整个代码库。这些标准命令和高度优化的工具意味着任何Google工程师构建版本和测试软件通常是非常简单和快速的。这种一致性在帮助工程师能够跨越项目边界进行修改起着关键作用。

程序员需要为Blaze编写如何完成版本构建的“BUILD”文件。诸如库、程序和测试这些构建实体,均由高级的声明式构建规范(declarative build specifications,DBS)进行声明,描述具体的每一个实体,如实体的名称、源文件、相关的库文件或所依赖的其它实体。这些DBS是由被称为“构建规则”的声明来组成,每个声明均用来指定如“一个拥有依赖于其他库的一系列源文件构成的C++库” 这样的高层次概念,并取决于构建系统将每项构建规则和一系列的构建步骤映射起来,例如为每个源文件进行编译的步骤、链接的步骤,以及确定使用哪个编译器和编译标志。

在某些情况下,特别是Go程序,因为BUILD文件中的依赖性信息 (通常)是源文件依赖信息的抽象,所以构建文件是可以自动生成 (和更新) 的。尽管如此,这些文件也要被检入到代码库中。这就确保了构建系统通过分析构建文件而不是源文件来快速地确定依赖关系,并以此避免了构建系统和编译器或者用于支撑其他编程语言的分析工具之间的过度耦合。

构建系统使用谷歌的分布式计算设施进行实现。通常每个构建的工作是分布在成百上千台机器中穿插进行的。这使得快速构建超大型程序或并行运行成千上万的测试成为可能。

个人构建步骤必须是“密封”的:只取决于其已声明过的输入。

所有依赖项都必须被正确的声明,这是分布式构建的必然诉求:只有已声明的输入信息会被发送到正在运行构建步骤的机器。因此, 可以依据构建系统来获取真实的依赖关系,即使构建系统的某个编译器被视为一种输入。

个人构建步骤是确定的。因此构建系统可以缓存构建结果。软件工程师可以同步其workspace回到原来的变更 再进行重新构建,以得到完全相同的二进制版本。此外,这个缓存可以在不同的用户之间安全地共享。(为了使它正常工作, 我们必须消除构建所调用的工具中的非确定性,例如通过洗掉所生成的输出文件中的时间戳)。

构建系统是可靠的。构建系统跟踪构建规则本身变更上的依赖性,这样如果某操作导致规则变化时依旧知道如何重新构建目标,即使输入对操作是不可知的,例如只有编译器选项发生改变时。同时,也能够妥善处理构建某部分被中断或在构建中修改源文件等各种情形:在这种情况下, 你只需要重新运行构建命令,但从来不需要运行“make clean”这类命令。

构建结果缓存在“在云中”,还包括中间结果。如果另一个构建请求需要相同的结果, 构建系统将自动复用而不是进行重建,即使此请求来自于不同的用户。

快速的增量构建。构建系统一直驻留在内存中,因此可以仅仅针对上次构建之后修改过的文件来进行增量分析来完成新的构建。

预提交检查针对启动代码审查和/或准备提交变更到存储库时,谷歌有工具自动运行一组测试。每个库subtree都可以包含一个配置文件,以确定要运行哪些测试, 以及是否在代码评审时进行测试、或在提交之前即刻运行测试,或者两者都需要。测试可以是同步的,例如在发送变更给审查之前运行,和/或在提交变更到代码库中之前运行(有利于快速测试)。测试也可以是异步的,即通过邮件将结果发送到评审讨论线程(thread)。[评审线程正是代码审查活动发生的电子邮件线程, 所有线程的信息也会在基于web的代码复查工具中呈现出来。]

3.代码评审(Code review)

除了主库部分(main section of the repository),“实验性”的代码库部分就没有强制要求执行常规的代码评审。然而,在产品线上运行的代码必须存储在主库中,而且鼓励工程师一开始就在主库的管理下开发代码,而不是先在实验库中研发之后再将其移动到主库中。因为在刚写完代码后就进行代码审查是最有效的,而不是彻底完成代码开发工作之后再进行代码评审。实践中,有些工程师甚至会在实验阶段就请求进行代码评审了。

  • 对于30~99行的添加/删除/删除等类型的变更,标注为 “medium-size”;
  • 对于300行以上的变更,根据其程度进行标注,如(300~999)为 “large”,(1000 ~1999)为“freakin huge”等等。

(然而,在常见的Google方式中,为了让工作有乐趣,每年会有几天,如“像海盗一样说话”的那天,会使用风趣少见的的描述来代替这些熟悉的描述方式)

( 待续,后面内容更精彩,敬请关注)

相关资源:TeamWare:团队软件-其它代码类资源-CSDN文

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年10月2日
下一篇 2020年10月2日

相关推荐