<audio id="audio" title="29 | 说说硅谷互联网公司的开发流程" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/76/7b/7668c874bd98d43a9f1f495c6883cb7b.mp3"></audio>

今天，我和你聊一聊硅谷互联网公司的开发流程。之前我的很多文章里就或多或少涉及过这一方面的内容，最近我又全程参与并负责了两个大项目，对流程有了更深一步的理解，今天就在专栏里系统地和你探讨一下。

总的说来，我们的开发流程包括这么几个阶段：

1. OKR 的设立；
1. 主项目及其子项目的确立；
1. 每个子项目的生命周期；
1. 主项目的生命周期；
1. 收尾、维护、复盘。

## 第一点，OKR 的设立

所有项目的起始，都应该从 Roadmap 做起。硅谷公司的 OKR（Objectives and Key Results）一般都是自顶而下的。也就是说，先有整个公司的 OKR，然后有每个部门的 OKR，继而是大组的 OKR，再到小组的 OKR，确保整个公司有一致的目标。在这个过程里面，技术驱动反映在哪些方面呢：

首先，确定 Roadmap 的过程中，我们会采用调查（Survey）模式，确保工程师的声音可以准确地触达管理层。比如：工程师们觉得基础架构比较薄弱，公司就会加大这一块的支持力度。如果大家觉得开发环境很低效，就会把这个因素也放到 OKR 的考虑。硅谷的公司一般会分为产品组和系统架构组。总的说来，系统架构组的 OKR 里，工程师的声音会很大。

其次，项目怎么做，怎么规划，一般是由工程师来决定。OKR 只确立目标，是不是要构建新的服务，是不是要沿用现有的架构，如何进行技术选型等等，这些不是 OKR 的组成部分。

最后，估算 OKR 里的目标工期的时候，我们会除去一些用来做技术创新和支持的时间，比如编程马拉松，开源支持等的事务。谷歌的员工会给自己留 20% 的自由项目时间，这些都是时间缓冲区。

（注：OKR 是企业进行目标管理的一个简单有效的系统，能够将目标管理自上而下贯穿到基层。具体概念可以参考 [http://wiki.mbalib.com/wiki/OKR。）](http://wiki.mbalib.com/wiki/OKR%E3%80%82%EF%BC%89)

## 第二点，主项目及其子项目的确立

一旦确立了 OKR，下一步就是确立主项目和子项目了。主项目是主要的技术或商业产品，一般由产品经理、技术经理和一些技术骨干经过产品需求和技术讨论之后，确定要做什么（Scope），不做什么（Non Scope）和大的里程碑（Milestone）；后面我会在“工程师、产品经理、数据工程师是如何一起工作的”一文中更详细地介绍不同角色之间的合作细节。

一旦主项目确定了，就需要安排不同的人做不同的模块，也就是子项目。一般团队协作有两种方式：一种是每个人负责一个子项目，从始至终；另一种是大家先一起完成基本框架，然后逐个需求、逐个模块推进，最终一起完成整个项目。

下面，我来谈谈两种协作方式在实践中的优缺点对比。

**第一种协作方法：每人完成一个子项目。**

> 
**优点**：责任清晰，每个人都知道自己的职责，工程师们也有更多的拥有感，他们可以独立负责产品的设计、实现、测试和维护，工作贯穿整个项目过程。


> 
**缺点**：如果负责某个子项目的工程师设计或者实现能力不足，由于比较独立，这个子项目很容易成为路障或者瓶颈，工程师之间也缺乏互相学习的机会。


> 
另外，因为是按人并行推进项目，需要根据每个人设置里程碑，管理的时候，技术管理者需要常常跟进每个人的进度，管理代价更高。代码审核往往也只是有限的几个人参与。


**第二种协作方法：所有人一起逐次完成每个模块或需求。**

> 
**优点**：工程师之间合作最大化，可以彼此协调、彼此学习、在对方有事的时候相互补位。项目管理有明确的统一的里程碑，每个工程师都有机会接触更多的工作，每个人的代码可以有更多人参与审核。


> 
**缺点**：每个工程师的责任不是那么明显，很容易出现能者多劳、勤者多劳的现象。一些新人总是做一些执行或打杂的事，得不到锻炼。


这两种模式我都曾亲身经历过，感觉两者各有利弊。现实中可以根据情况组合使用。比如，两到三个人合作负责一个模块，也可以在每人一个模块的基础上，将小模块组合成大模块。然后每个大模块有个技术负责人（Tech Lead），对一些能力不足的工程师给予指导和支持等。

## 第三点，每个子项目的生命周期

子项目一旦确认，它的生命周期就融入到工程师们的日常工作中，内容如下。

1 开发初期的设计文档。一般使用可以共享的谷歌文档（Google Docs），Quip 等。不同的人可以编辑或者评论、阅读。一般设计文档会先由组内工程师和产品经理审核，然后到大组评审（包括Legal，Compliance，Finance 等等）。

如果涉及公司的整体架构，还需要发给全公司审核。参与审核的人员是所有的工程师。很多人会有选择的参与一些设计的审核，通常技术骨干会预留时间审核所有的技术设计文档。设计文档不仅包括怎么实现，还有选型的理由、考虑的因素、支持和不支持的属性、时间线等等。

2 设计测试实验，这是可选的，如果针对某个产品需求我们想知道用户的反馈，就需要数据工程师参与设计实验，也就是 A/B 测试。实验中的数据埋点也会在下一步的实现中完成。

3 一旦设计文档锁定，就可以开始实现了。不论是单人负责还是多人合作，实现都是按照多次代码提交（Pull Requests）来迭代的。每次代码提交要写清楚代码改动的摘要和测试。并通知不同的工程师审核。

4 所有的实现都要加入监控、日志、预警代码。

5 所有实现都是隐藏在一个开关后。当代码都就位后，就开始灰度发布。通常是先发布给几个开发人员测试，然后到项目组，然后到其他员工（Google 称之为 Dog Food，因为他们可以大量使用自己的产品），最后按照百分比推给用户。

推送的过程中会结合 A/B 测试，只有测试结果显示对用户体验、公司主要的指标（ Metrics ）没有明显的负面影响，才会正式发布给所有用户使用。

6 对一些需要重构的关键产品链路，有时候也会使用双重写入（Dual Write），就是新特性和旧特性都写入数据库，并通过不同方式比较两个实现的结果。只有验证结果一致时，才会将交易（Traffic ）从旧实现切换到新实现。

7 最后是一些扫尾工作，包括移除用来做 A/B 测试和灰度发布的代码开关等，有时候还会有一些次要需求的实现。

## 第四点，主项目的生命周期

主项目的生命周期根据子项目的实现方式会有所不同，但有一些特点是共有的。

1. 项目开始都有一个整体设计文档，界定所有子项目的范围和相关性、时间线等。
1. 在所有子项目进行的过程中，有时候会发现一些共同需要的架构或者服务，可以单独提取成公共服务或库，比如一个调度服务，或者一个幂等实现等等。
1. 给相关人员做进度报告，包括主项目的里程碑。
1. 由于子项目完成时间可能不一样，需要进行人员的重新配置。
1. 在开发过程中不断更新文档。
1. 因为不确定的需求变动，会取消或者生成新的子项目。
1. 有时候，也会因为公司的方向变化或战略调整，对主项目做比较大的变更，同时对应调整相关的子项目。
1. 在项目开始和结束的时候，需要做好对外的交流和沟通。一来确保自己的项目改动不会影响到其他组的项目，二来让将来会依赖这个项目的产品组了解相关信息，确定计划。

## 第五点，收尾、维护、复盘

整个项目结束后，一般都会做一些代码清理和文档的更新和整理，有时还需要写新的用户手册或 Wiki 等。一些基本的错误和异常处理要写到运维手册（Oncall Playbook）里，便于以后运维的人知道怎么处理一些已知的问题。

每个项目结束都会进行复盘，总结整个项目的教训和经验。有时候还需要在组内做些演讲，让更多的人了解这个项目。

总结一下，今天我主要和你探讨了软件产品和服务的开发流程，一般硅谷里稍具规模的互联网公司都会遵循类似的流程，他们就是通过这样的流程开发出了创新性的产品。

这些流程包含什么内容呢：首先在公司内部确认 OKR，然后确定主项目和子项目，开始进行产品实现，也就是完成主项目和子项目的生命周期，最后进行项目的收尾、维护和复盘，一个大项目就开发完成了。

你的项目开发流程有什么异同吗？可以在留言中告诉我，大家一起进步。感谢你的收听，我们下期再见。

<br> 

[戳此获取你的专属海报](https://time.geekbang.org/activity/sale-poster?utm_source=app&amp;utm_medium=zhuyun-article&amp;utm_campaign=zhuyun-saleposter&amp;utm_content=zhuyun0416)
