Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gitbook #5

Open
wants to merge 77 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
6ad5c15
initialize gitbook branch
franczx Oct 21, 2019
d7f2372
Update README.md
zijinshi Oct 21, 2019
446f15a
Update preface.md
zijinshi Oct 21, 2019
76eb189
Update README.md
zijinshi Oct 21, 2019
16c543d
Update preface.md
zijinshi Oct 21, 2019
bea61d1
generate pdf doc
franczx Oct 21, 2019
da25480
Update README.md
zijinshi Oct 21, 2019
c4cfc20
generate pdf doc
franczx Oct 21, 2019
187dbbb
Update index.md
zijinshi Oct 21, 2019
4f0b856
Delete index.md
zijinshi Oct 21, 2019
cf894a1
Delete emergencies.md
zijinshi Oct 21, 2019
5a0d292
Delete cl-descriptions.md
zijinshi Oct 21, 2019
08961f3
Delete handling-comments.md
zijinshi Oct 21, 2019
439551f
Delete index.md
zijinshi Oct 21, 2019
b96abc0
Delete small-cls.md
zijinshi Oct 21, 2019
3309663
Delete comments.md
zijinshi Oct 21, 2019
2609518
Delete index.md
zijinshi Oct 21, 2019
3c136ca
Delete looking-for.md
zijinshi Oct 21, 2019
edfb4c7
Delete navigate.md
zijinshi Oct 21, 2019
a30c60f
Delete pushback.md
zijinshi Oct 21, 2019
dc0123f
Delete speed.md
zijinshi Oct 21, 2019
83734fe
Delete standard.md
zijinshi Oct 21, 2019
24ac564
GitBook: [gitbook] 5 pages modified
zijinshi Oct 21, 2019
eeaf10f
Delete readme.md
zijinshi Oct 21, 2019
969c6de
Update SUMMARY.md
zijinshi Oct 21, 2019
acdfa2e
Update README.md
zijinshi Oct 21, 2019
aa00263
GitBook: [gitbook] one page modified
zijinshi Oct 21, 2019
c2c09c5
Rename README.md to introduction.md
zijinshi Oct 21, 2019
d20b9e2
Update and rename preface.md to readme.md
zijinshi Oct 21, 2019
5d388ab
Update SUMMARY.md
zijinshi Oct 21, 2019
07acdc0
Update SUMMARY.md
zijinshi Oct 21, 2019
40674ed
Rename readme.md to README.md
zijinshi Oct 21, 2019
9b35442
Update SUMMARY.md
zijinshi Oct 21, 2019
3ce3cda
GitBook: [gitbook] 3 pages modified
zijinshi Oct 21, 2019
f76b449
Update SUMMARY.md
zijinshi Oct 21, 2019
fbcf453
Update SUMMARY.md
zijinshi Oct 21, 2019
7f7c259
correct pdf link
franczx Oct 21, 2019
9bee9db
correct pdf link
franczx Oct 21, 2019
d73b16b
correct pdf link
franczx Oct 21, 2019
769540c
pdf
franczx Oct 21, 2019
0f7070f
Added book
franczx Oct 22, 2019
5dff0e9
Update readme.txt
zijinshi Oct 22, 2019
63a5fb5
updated pdf book
franczx Oct 22, 2019
9387976
Update introduction.md
zijinshi Oct 24, 2019
dfd422c
re-generate pdf file
franczx Oct 24, 2019
072a38b
Update looking-for.md
zijinshi Nov 14, 2019
64ae63f
Update SUMMARY.md
zijinshi Nov 14, 2019
1b06f9a
Update README.md
zijinshi Nov 16, 2019
500e2a8
Update standard.md
zijinshi Nov 16, 2019
99e3726
Update standard.md
zijinshi Nov 18, 2019
a2b2620
Update looking-for.md
zijinshi Nov 26, 2019
bcda903
Update looking-for.md
zijinshi Nov 26, 2019
371201d
Update looking-for.md
zijinshi Nov 26, 2019
637748b
Update navigate.md
zijinshi Nov 26, 2019
d5dcf5a
Update speed.md
zijinshi Dec 14, 2019
8c3ce1f
Update introduction.md
zijinshi Jan 2, 2020
f30150c
Update introduction.md
zijinshi Jan 2, 2020
b4c083e
Update review.md
zijinshi Jan 2, 2020
07a4857
Update README.md
zijinshi Jan 2, 2020
27a1c9e
Update small-cls.md
zijinshi Jan 2, 2020
2370789
rebuild pdf
franczx Jan 2, 2020
08534e4
Update introduction.md
zijinshi Jan 2, 2020
a50dec6
rebuild pdf
franczx Jan 2, 2020
a3a4e10
rebuild pdf
franczx Jan 2, 2020
d512743
Update emergencies.md
zijinshi Jan 2, 2020
d233293
Update emergencies.md
zijinshi Jan 2, 2020
050e4e2
rebuild pdf
franczx Jan 2, 2020
5382591
v1.3
franczx May 6, 2024
54022ed
Delete Google的工程实践文档.pdf
zijinshi May 6, 2024
b41d206
v1.3
franczx May 6, 2024
c795dff
v1.3
franczx May 6, 2024
be79e0a
v1.3 updated looking-for
franczx May 7, 2024
751b574
v1.3 updated looking-for
franczx May 7, 2024
115a962
Update _config.yml
zijinshi May 8, 2024
8924b58
Update _config.yml
zijinshi May 8, 2024
880ea16
Update _config.yml
zijinshi May 8, 2024
3d22c3a
Update _config.yml
zijinshi May 8, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/_book/
Binary file added Google工程实践文档.pdf
Binary file not shown.
Binary file added Google工程实践文档_v1.2.pdf
Binary file not shown.
Binary file added Google工程实践文档_v1.3.pdf
Binary file not shown.
43 changes: 15 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,30 @@
# Google的工程实践文档
# Google工程实践的一些感悟

Google有很多优秀的工程实践,这些实践遍布公司内的所有项目,覆盖了几乎所有编程语言。 随着开发项目的增多,我们不断总结经验,把这些最佳实践以文档的形式整理出来。这份文档是我们集体经验的结晶。除了我们之外,相信其他公司、组织或开源项目也能从中受益,现在时机成熟了,我们决定将其公开发布
自认为是一枚资深码农,对代码review早已驾轻就熟。读完之后,仍旧受益匪浅。受到原文中“希望其他组织也能从中受益”这句话的感召,我决定将其翻译成中文,托管到Github上,与大家一起分享

这份工程实践文档包含如下内容:
* [Google的代码审核指南 (Google's Code Review Guidelines)](review/index.md),它包含两部分:
* [代码审核者指南 (The Code Reviewer's Guide)](review/reviewer/index.md)
* [代码提交者指南 (The Change Author's Guide)](review/developer/index.md)
原文标题为工程实践文档,表达更直接点,就是代码review规约。全文分两部分,一部分是针对代码审核人的指南,另一部分是针对代码提交人的指南,两部分文档交相呼应。

## 术语
这份文档讲述了代码review的标准是什么,详细列举了在代码review过程中常见的问题,如何避免或解决这些问题,同时讲解了这么做的原因以及不这么做可能产生的后果。

在文档中,我们用到了一些 Google 内部术语,为避免误解,我们稍作解释:
文档列举了不少正面与反面的例子,可操作性很强。相信企业文化接近的朋友在读了本文之后,会有很深的认同感。在文档中提到、现实中做得不够好的地方,能很快掌握,并能把它融进自己所在的团队中,提升整个团队的开发效率。企业文化差距比较大的朋友读了之后,即使公司的项目管理机制受到制约,在个人的层面也有很多可以改进的地方。从事非软件开发行业的朋友读了之后,相信也能有所感悟。文中提到的一些软技能,如情绪管理、沟通技巧等,在日常生活与工作中也非常有用。

* **CL**: 即“changelist”, 中文可以翻译成修改列表,它是提交到版本控制工具中的一次代码修改(即将审核的代码)。有的公司或组织称它为 “改变”(change)或“补丁”(patch)。
* **LGTM**: “Looks Good to Me.” 的缩写,“看起来不错”。 当一个审核者这么说的时候,意味着他会批准这个CL。
* **g3doc**: Google内部的工程文档平台。
回顾自己过去二十多年review代码与被review代码的经历,有些事项一直都这么做,我知道为什么应该这么做;有些事项一直都这么做,至于为什么这么做我颇有微词;也有事项直到今天才知道原来这样做更好。

荀子在《劝学》中提到:不积跬步,无以至千里。抗战时期“积小胜为大胜”的战略思想,也是同样的道理。在本文中,鼓励 **每次都做一点微小的改进,多次微小的改进比一次大的改进容易得多**。这与Scrum把大User Story拆分成小User Story的观点相吻合。因为Points比较大的User Story,往往因为太大而无从下手,时间上也不可控。在进行Scrum指导时,我常对团队说“我们一个迭代周期只需改进两三个重要的问题,不必一次到位。习惯的力量太强大,需要逐步改进、适应,再改进,直到我们需要改进的措施成为我们的习惯。”

## 版本
英文原文来自 [Google's Engineering Practices documentation](https://github.com/google/eng-practices),中文版由 [ zijinshi ](https://github.com/zijinshi) 翻译整理。根据中文表达习惯,在原文基础上有少量删改。
原文提到一条看似要求很低的原则:**在修改时,至少不要恶化代码。** 不要恶化代码是底线,一旦发生微小的恶化,破窗效应开始起作用,代码的健康状况会飞流直下。制定过高的标准,容易让人受挫;而合理的标准配以可实操的步骤,更容易达到目标,建立自信心。

我见过这样的主管,一次性提出很多要求,让下属立即(或很快)按照要求实施,而他要求的这些改变与团队当前的环境、习惯、认知存在很大的差距。立即实施的要求看似简单,但缺乏行之有效的措施,忽视了客观环境,忽视了突然改变所付出的代价与造成的负面影响,注定无法长期坚持下去。道理很简单,反面教材在生活中的确很常见,如上海严格的垃圾分类政策。

| 版本 | 日期 | 说明 |
| :--- | :--- | :--- |
| 1.0 | 2019.10.07 | 初版完成 |
| 1.1 | 2019.10.18 | 修复某些翻译不准确的地方 |
关于尊重,在彼此尊重的环境里,大家心态比较放松,愿意以积极的心态去避免或解决问题。因为彼此的尊重,大家更愿意通过沟通、讲理的方式去解决问题,而非依职位定高下。在这方面,不少企业还有很大的提升空间。

中文版同时发布于网站:
* [Google的工程实践文档](https://zijinshi.github.io/google_eng_practice/index)
提到沟通,本文提到了一些沟通与冲突解决的技巧。如,当审核者与开发者有不同观点时,文档对审核者说,“开发者对代码更熟悉,先考虑对方的看法是否是正确的。”对开发者说,“先思考审核者提供的反馈中是否存在有价值的部分。”很有趣,在冲突解决时,都是先审视自身,对方是否是对的。如果每个人都以这种方式处事,相信全人类离世界和平的愿望又接近了一步。

PDF版本下载:
* [Google的工程实践文档](https://github.com/zijinshi/google_eng_practice/raw/gitbook/Google%E7%9A%84%E5%B7%A5%E7%A8%8B%E5%AE%9E%E8%B7%B5%E6%96%87%E6%A1%A3.pdf)
世事并不完美。在代码审核过程中,“违反专业礼仪是一件很严重的事情。我们可以保证自己遵守,但永远没法保证他人不违反。”当他人违反了专业礼仪,我们该怎么做呢?本文也提出了解决方案。

[译者序](preface.md)
还有一点很重要,“**不要在代码审核中带着情绪回复评论。**” 为人处世也是如此,在情绪激动(或紧张)时,人很难理智地思考,此时做出的决定往往会让自己后悔。不如先采取措施让自己冷静下来,之后再做决定。

## License
本文遵守 CC-By 3.0 License([中文版](https://creativecommons.org/licenses/by/3.0/deed.zh)、[英文版](https://creativecommons.org/licenses/by/3.0/))。
以上是我的个人感悟,有兴趣的朋友读读原文吧。

The documents in this project are licensed under the CC-By 3.0 License, which
encourages you to share these documents. See
https://creativecommons.org/licenses/by/3.0/ for more details.
<p align="right">Frank<br>2019.10.18</p>

<a rel="license" href="https://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by/3.0/88x31.png" /></a>
17 changes: 17 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Summary

* [Google工程实践文档](introduction.md)
* [代码审核指南](review.md)
* [怎样做代码审核](index/README.md)
* [代码审核的标准](index/standard.md)
* [代码审核过程中要看些什么?](index/looking-for.md)
* [代码审核的步骤](index/navigate.md)
* [代码审核的速度](index/speed.md)
* [怎样写代码审核的评论?](index/comments.md)
* [代码评论被拒绝时,应如何处理?](index/pushback.md)
* [代码开发者指南](developer/README.md)
* [编写良好的 CL 描述](developer/cl-descriptions.md)
* [小 CL](developer/small-cls.md)
* [如何处理审核者的评论](developer/handling-comments.md)
* [紧急情况](emergencies.md)
* [Google工程实践的一些感悟](README.md)
62 changes: 62 additions & 0 deletions book.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"output": null,
"generator": "site",

"title": "Google工程实践文档",
"author": "Frank",
"description": "Google有很多优秀的工程实践,这些实践遍布公司内的所有项目,覆盖了几乎所有编程语言。 随着开发项目的增多,我们不断总结经验,把这些最佳实践以文档的形式整理出来。",
"isbn": "",
"language":"zh-hans",

"extension": null,

"plugins": [],

"pluginsConfig": {
"fontSettings": {
"theme": "white",
"family": "serif,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji",
"size": 4
}
},

"variables": {},

"links": {

"sidebar": {
"官网": "https://delphi.zijinshi.org"
},


"sharing": {
"google": null,
"facebook": null,
"twitter": null,
"weibo": null,
"all": null
}
},


"pdf": {

"pageNumbers": true,

"fontSize": 15,

"paperSize": "a4",

"margin": {
"right": 28,
"left": 28,
"top": 26,
"bottom": 26
},


"headerTemplate": null,

"footerTemplate": null
}
}
13 changes: 9 additions & 4 deletions review/developer/index.md → developer/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
---
description: 代码开发者指南
---

# 代码开发者指南

本文包含开发者怎样让代码审核容易通过的最佳实践。在读完本指南后,相信能够让你的审核质量更高,速度更快。作为开发者,可以选择阅读自己感兴趣的部分。当然,我们还是建议你按顺序通读全文,你会发现这篇文档对你非常有用。

- [编写良好的 CL 描述](cl-descriptions.md)
- [小 CL ](small-cls.md)
- [怎样处理审核者的评论](handling-comments.md)
* [编写良好的 CL 描述](cl-descriptions.md)
* [小 CL ](small-cls.md)
* [怎样处理审核者的评论](handling-comments.md)

如果你是代码审核者,可以参考[怎样做代码审核](../index/README.md)。

如果你是代码审核者,可以参考[怎样做代码审核](../reviewer/)。
129 changes: 129 additions & 0 deletions developer/cl-descriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# 编写良好的 CL 描述

CL 描述是一项公开的记录,其内容包含修改了 **什么** 与 **为什么** 这么修改。 虽然你的 CL 只是在你与审核者之间发生,但它是版本控制历史的一部分,若干年之后,很有可能会有成百上千的人阅读。

以后的开发者可能会根据描述搜到你以前写的 CL 。在没有精确数据的情况下,他可能根据自己的模糊记忆搜索 CL。如果所有的信息都只包含在代码里面,描述中几乎没有相关内容,那么定位到你的 CL 将会花费太多的时间。

## 第一行 <a id="first-line"></a>

* 简短描述做了什么。
* 完整的句子,祈使句。
* 后面空一行。

CL 描述的 **第一行** 应该是一句简短的描述,用以说明 _CL做了_ **什么** 。在第一行后面留一空行。以后有开发者搜索版本控制历史的代码时,这是他们看到的第一行,所以第一行应该提供足够的信息,他们不必阅读代码,也不必阅读整个描述,只需扫一眼便知道 CL 做什么,或者知道这条 CL 与其他 CL 的区别在哪里。 也就是说,第一行应该是独立的,以便阅读代码的人快速的了解代码的功能或作用。

尽量保证第一行简短、重点突出、切中要害。对读者而言,清晰度和实用性是最重要的。

一般而言,CL 描述的第一行是以命令口吻(祈使句)写的一句话。举例说明,我们应该写“ **删除** FizzBuzz RPC,并用写的系统 **替换** 它。”,而不是写成 “ **删除了** FizzBuzz RPC,并 **已经** 用写的系统 **替换** 它。” 当然,第一行写成祈使句就可以了,其他内容不必如此。 \(译者注:原文中的反面例子是现在进行时。但在中文中现在进行时与祈使句基本一致,不好翻译。此处改成了现在完成时。\)

## 描述内容要提供充分的信息 <a id="informative"></a>

第一行应该是简短、重点突出的摘要,而描述的其他部分应包含详细信息,包括阅读代码的人全面理解修改内容所需的任何补充信息。它可能包括对正在解决的问题的简要描述,以及为什么这是最好的方法。如果该方法有任何缺点,应该指出来。如果有相关背景信息的,如 bug 编号、基准结果和设计文档的链接。

如果包含的链接是外部资源,请考虑访问限制或保留策略,未来的读者可能看不到这些链接。在描述中尽可能包含足够的上下文,以便审核者和未来的读者理解 CL。

即使是小的 CL,也应该包含这些信息。

## 糟糕的 CL 描述 <a id="bad"></a>

“修复 bug”是一个很不恰当的描述。哪个 bug ?你做了哪些事情来修复它?通通都没有。类似糟糕的描述还包括:

* “修复编译。”
* “增加补丁。”
* “把代码从 A 移到 B。”
* “第一阶段。”
* “增加方便的功能。”
* “清除死链。”

以上这些都是我们在真实案例中见过的 CL 描述。作者可能认为他们提供了足够的信息,其实它们不符合 CL 的目的描述。

## 良好的 CL 描述 <a id="good"></a>

这是几个良好描述的样例。

### 功能修改 <a id="function_change"></a>

> RPC:移除 RPC 服务器的消息空闲列表的大小限制。
>
> 服务器(如 FizzBuzz)有大量的消息,可以从重用中受益。使空闲列表更大,并添加一个goroutine,随着时间的推移缓慢释放空闲列表,以便空闲 服务器最终释放所有空闲列表。

前面几句话描述了 CL 做什么的,接下来描述解决了什么问题,为什么这是一个好的解决方案,最后涉及到了一些实现细节。

### 重构 <a id="refactoring"></a>

> 构建一个带 TimeKeeper 的 Task,以便使用它的 TimeStr 和 Now 方法。
>
> 在 Task 中增加一个 Now 方法,然后删掉 borglet\(\) 方法(这个方法仅仅被 OOMCandidate 使用,它调用了 borglet 的 Now 方法)。这样就替换掉 Borglet的方法,把它委托给 TimeKeeper。
>
> 让 Tasks 提供 Now 是减少对 Borglet 的依赖所做的一小步。最终,从 Task 上调用 Now 的方式会替代成直接调用 TimeKeeper,我们会逐步实现。
>
> 继续重构 Borglet 层次的长期目标。

第一行描述了 CL 做什么的,以及过去它是怎么改变的。描述的其他部分谈到了具体实现、CL 的上下文,这种方法并不完美,但在朝着完美的方向前进。而且也解释了 _为什么_ 应该这么改。

### 需要一些上下文的小 CL <a id="small_cl_context"></a>

> 为 status.py 创建一个 Python3 的编译。
>
> 在原始的编译(Python2)旁创建一个 Python3 的编译,让已经使用过 Python3 编译的用户根据某些规则选择 Python3 还是 Python2,而不是依赖于某个路径。 它鼓励新用户尽可能使用 Python3 而不是 Python2,并大大简化了当前正在使用的某些自动编译文件重构工具。

第一句话描述做了什么,其他部分解释 _为什么_ 要这么修改,并向审核者提供了不少额外的上下文信息。

### 使用标签 <a id="tags"></a>

标签是手动输入的,目的是便于对 CL 进行分类。 工具可能支持标签,或者根据团队习惯使用标签。

例如:
* "[tag]"
* "[a longer tag]"
* "#tag"
* "tag:"

使用标签是可选的。

当添加标签时,考虑是否要把标签添加到 [CL 描述内容](#informative)中,或[第一行](#first-line)中,以便把它与内容区分开来。

以下是有标签和没有标签的例子:

``` {.good}
好的标签样例

// 第一行中的标签保持简短。
[banana] Peel the banana before eating.

// 标签可以内嵌在内容中。
Peel the #banana before eating.

// 标签是可选的。
Peel the banana before eating.

// 如果能保证简短,多个标签也是可接受的。
#banana #apple: Assemble a fruit basket.

// 标签可以放在 CL 描述中的任何位置。
> Assemble a fruit basket.
>
> #banana #apple
```

``` {.bad}
不好的标签样例

// 在第一行中包含太多标签(或标签太长)。
//
// 对于这种情况,可以考虑把标签移到描述内容中,或把它修改得更简短。
//
[banana peeler factory factory][apple picking service] Assemble a fruit basket.
```

### 自动生成的 CL 描述 <a id="generated_cl_descriptions"></a>

有些 CL 是有工具自动生成的。如果可能的话,它们的描述也应遵循此处的建议。也就是说,它的第一行应该简短、重点突出、独立的,并且 CL 描述正文应该包含信息丰富的细节,以帮助审核者和未来的代码搜索者了解每个 CL 的功能或作用。


## 提交 CL 之前审核描述 <a id="review_before_submit"></a>

在审核过程中,CL 可能会发生重大改变(与最初提交审核的 CL 相比)。在提交 CL 之前有必要再审视一遍 CL 描述,确保描述能够正确地反映 CL 做了什么。

下一章: [小 CL](small-cls.md)

Loading