Google 的软件工程经验总结
摘录翻译自“Software Engineering at Google”,作者:Fergus Henderson
软件开发
代码库
大部分的 Google 代码都存在统一的源代码库中,可供 Google 内部所有工程师访问。但是 Chrome 和 Android 则分别有单独的代码库。
Google 的代码库,在 2015 年 1 月的统计中,共计 86T 数据,上10亿个文件,9百万个源代码文件,其中包含了 20 亿行代码。迄今为止共计 3500 万次提交,每个工作日平均发生 4 万次更新。
任何 Google 员工,都可以随意的访问所有代码,并下载、编译,可以在自己的环境下自行改写,但任何更改的提交,都需要通过代码负责人的审批才可以。
所有的开发都在库的头部进行。对代码进行任何更改后,自动化系统将进行测试,并在几分钟内通知开发者和代码审查者,对更改的测试是否失败。
代码库中每个分支都有单独的文件注明“代码所有人”,只有代码所有人才有权利审核提交的更改。通常情况下,项目组的所有成员都是“代码所有人”。
编译系统
Google 使用分布式编译系统,叫做 Blaze。Blaze 提供了标准的命令,用于编译和测试库中的所有代码。Blaze 这种统一的编译工具,让 Google 公司的所有工程师都能随时编译和测试任何软件,也都能跨项目工作。
程序员需要撰写“BUILD”文件,用来引导 Blaze 如何编译软件。在Go语言的代码中,build 文件可以自动生成。
每个编译步骤必须是“隔离”的,只依赖于声明的输入。为了实现编译的分布式运行,必须强制要求正确输入所有的依赖:只有声明了的输入才被发送到进行编译的机器上去。
每个编译步骤的结果是确定的。这样保证了编译系统可以缓存编译结果。软件工程师可以回退到老的版本号,并重新编译,且得到完全一样的二进制结果。
编译结果缓存在云端。包括中间结果,这样当有别的编译请求过来,系统直接应用缓存的结果。
增量的重新编译非常快。编译系统运行在内存中,当重新执行编译任务时,它能够分析文件上次编译后发生的增量变化。
提交前检查。Google 有专门的自动化工具,用来在发起代码审查和准备提交更改到代码库时,进行一整套的标准检查。
代码审查
Google 开发了基于 Web 的代码审查管理工具。程序员可以申请对代码进行审查,审查者可以在浏览器上比较差异,并写上评语。当写代码的人发起一次审查申请,则系统自动发邮件给审查者,并附上代码查看页的链接。
对源代码的任何更改,必须经过最少一次审查。如果更改不是由“代码所有人”做出,则还必须由所有人中的一位进行审查。
系统可以自动推荐合适的审查者。当然,写程序的人,可以自己选择审查者。
Google 鼓励工程师们,将每一次代码更改控制在较小的规模上。 30-99 行的代码更改,通常视为“中等”;300 行以上则标记为“大”; 1000-1999 行,则是“巨大”;
测试
单元测试是必须的,在 Google 的开发中广为采用。集成测试和回归测试,也较为普及。Google 有一个自动化的工具,用来衡量测试覆盖的范围,这个结果也在代码浏览器中可以查看。
部署前一定要做压力测试。项目组要用表格或者图标显示关键参数,尤其是压力之下的延迟和错误率。
Bug 跟踪
Google 使用的 Bug 跟踪工具叫 Buganizer。有的团队,安排专人分配 Bug,有的团队则在例行的会议中分配。
开发语言
Google 内部有四大语言,一般都建议工程师在这四种里挑选。四大语言是: C++,Java, Python, Go。不用多说,减少语言数量,可以增加代码复用,并提高内部协作。
每种语言都有代码规范,保证风格统一。公司范围内,还有针对“代码可读性”的培训,由经验丰富的老司机,对新人进行培训。代码审查,也需要对“可读性”做专门的评审。
在不同语言之间的交互操作,要通过Protocol Buffers 来处理。Protocol Buffers 是 Google公司开发的一种数据描述语言,类似于XML能够将结构化数据序列化,可用于数据存储、通信协议等方面
调试工具和性能分析工具
Google 的服务器连接了很多库,提供用于调试服务器的工具。服务器崩溃时,可以自动导出堆栈轨迹到日志文件。 还有 Web 界面用于调试,可以用来查看呼入和呼出的 RPC 调用、更改的命令行标志值、资源消耗、性能分析等。
发版
Google 的大部分项目组,都有固定的软件工程师负责发版。
大部分的软件,发版比较频繁。通常是周发版,或者每两周发版,有些项目组甚至每天发。所以,自动化进行发版就是必须的了。频繁发版有助于工程师们保持斗志,提高整体速度,实现更多的迭代,从而也可以获得更多的反馈,并做出更多有益的更正。
上线
要上线任何更改,并对用户可用,则需要项目组外很多人的审批。审批来自多个方面,包括法律合规、隐私保护、安全要求、可靠性、业务需求等等。
Google 有一个内部的上线审批工具,用来执行审查和上线审批。通过定制,这个工具,对不同的产品有不同的审查和审批流程。
过错总结
发生了重大的服务事故后,相关人员要起草过错总结报告。文档描述事故细节,包括标题、概要、影响、时间段、原因、故障组件、行动。 总结的聚焦在于问题,以及未来如何解决,而不是聚焦在于人,也不是为了惩罚责任人。
频繁的重写代码
Google 鼓励频繁的重写代码,任何软件每隔几年就重写一遍。一来可以优化产品,采用最先进技术,去掉无用的功能,另外还可以转移知识到新员工,并保持员工的斗志。
项目管理
20%的自由时间
尽人皆知,google的工程师拥有 20%的自由时间,可以随意做感兴趣的东西,而无需审批。这当然是为了激发工程师的各种创意,同时也让工程师们保持高效率,而不是窒息在必须完成的任务中。 另外,也考虑到,很多员工都会私下里自己做一些东西,那么还不如鼓励大家将这些研究方向公开。
目标和关键结果
不论个人还是团队,都要明确的写下自己的目标,并评估达成目标的进度。每个季度的末尾,要根据关键结果,对目标达成情况进行打分,分数从 0 分到 1 分。这 OKR 分数是全公司内部公开的。但这并不直接用作个人绩效评估的输入。
平均得分是 0.65,但鼓励大家将目标定的高一些,所以在可完成任务之上,再加 50% 的工作量是正常的。
项目立项
对于项目立项审批,以及项目取消,Google并没有清楚定义的流程。即便是在 Google 做过 10 年的老经理,也不知道决策是如何做出的。很可能因为在公司范围内,流程并不一致,经理们可以自行判断并决策。有时候,决策是由下而上进行的,因为项目组的人都走光了。有时候,决策是自上而下的,老板们决定哪些项目得到更多的预算,那些则必须关闭。
机构重组
当关闭一个大项目时,工程师们可以自行寻找新机会,加入新团队。有的时候,还会搞“去碎片化”行动,把琐碎的分散的团队合并,这个时间工程师也可以自行选择团队和工作地点。
经常进行重组,有利于突破大公司的低效陷阱。
人的管理
岗位
Google 将“技术路线”和“管理路线”分开;将“技术领导” 从“管理”中分出;将“研究”综合到“工程”中;设置“产品经理”、“项目经理”、和“站点可靠性”来支持工程师们。
工程中主要的岗位包括:
- 工程经理
这是工程序列中唯一的“人员管理”岗位。软件工程师也“可能”管理人,但工程经理“总是”管理人。工程经理通常以前就是工程师,具备技术经验,以及管理人的技能。
技术领导力与人员管理能力之间,是有区别的。
“工程经理”不一定带领项目;项目通常由“技术组长”负责,当然“技术组长”也可能由“工程经理”担任,但大多数情况下都是“工程师”。项目的“技术组长”对项目中的技术问题,具有决定权。
经理负责选择“技术组长”,并监控团队绩效。工程经理还负责职场发展的培训及引领,进行绩效评估,并部分负责薪酬制定。还要做一些招聘工作。
一般来说,工程经理管理 3 - 30 个人,普遍情况下是 8 - 12 人。
- 工程师
在 Google,“工程”和“管理”的职业发展路线是不同的。工程师可以管理下属,但这不是必须的。在更高层次,领导力是必须的,但领导力不一定从对人的管理中来。比如,开发了极具影响力的软件,或者写的代码被很多工程师使用,也是一种领导力。
- 研究科学家
科学家的招聘的门槛更高,需要有学术上的论文发表能力和代码能力。除了科学家需要论文和著作外,科学家和工程师没有显著的区别。在Google,科学家和工程师一起工作,同样研发产品,同在一个团队。这样的安排为的将研究成果更好的导入产品中。
- 站点可靠性工程师
对系统的维护由软件工程师团队负责,而不是通常的系统管理员。站点可靠性工程师的技能要求,比软件开发工程师要稍低。
- 产品经理
产品经理负责管理产品,他们协调软件工程师的工作,宣讲功能特性,与其他团队配合,跟踪bug和进度,保证一切顺畅运行以开发出高质量的产品。产品经理不写代码。
- 计划经理/技术计划经理
计划经理有点类似产品经理,但他们不管产品,而是管理项目、过程、或运营。
工程师与产品经理、计划经理的比例,一般非常高,大约在4:1 到30:1之间。
设施
Google 有很先进的各种设备,包括游戏房、健身房,以及提供各种美食的免费餐厅,这一切都是为的将员工留在公司,多多工作。还可以带朋友来蹭饭,这样就增加了将朋友招聘进来的机会。
Google 的座位都是开放的,甚至有点拥挤,这有助于加强交流,但同时也影响了个人的专注,算是权衡之下的损失了。员工虽然有自己的座位,但每 6 -12 个月就要换一换,也是为了加强交流。
培训
Google 的培训有一下几种:
- 新员工 (Nooglers)都要参加一个入职培训教程
- 技术员工要参加一个“Codelabs”,进行短期的在线培训课程,其中还有编码练习
- 许多在线和现场的培训课程
- 对于参加外部机构的课程,Google也给予支持
每个新员工,都被指派一名正式的“导师” 和一名“搭档”,以帮助他尽快上手。
换岗
鼓励换岗流动,以在公司范围内传播知识,并提高跨组织的交流。在一个岗位工作 12 个月后,可以选择其他项目,也可以选择换个办公室。
绩效评估和奖励
Google 非常欢迎互相评价。 工程师可以彼此互赠正面评价,一种是“同事奖金”,一种是“点赞”。每名员工,每年拥有两次机会,给予其他员工以“同事奖金”提名,奖金是 100 美元。这种“同事奖金”是为了奖励员工在职责之外帮助他人。“点赞”则仅仅是表扬,没有现金奖励。
经理可以发放奖金,包括一种在项目完成后的特殊奖金。Google和其他公司一样,也有年底绩效奖和股权激励。
绩效优秀,可以晋升。而绩效差的,则需要进行改进,但有意思的是 Google 很少开除员工。员工还要对经理的绩效进行评估,以保证管理效率和管理质量。