猜你喜欢
Google软件工程

Google软件工程

书籍作者:提图斯·温特斯 ISBN:9787519864705
书籍语言:简体中文 连载状态:全集
电子书格式:pdf,txt,epub,mobi,azw3 下载次数:4967
创建日期:2023-03-21 发布日期:2023-03-21
运行环境:PC/Windows/Linux/Mac/IOS/iPhone/iPad/Kindle/Android/安卓/平板
内容简介

你将学习到软件组织在设计、架构、编写和维护代码时应牢记的三个基本原则:时间如何影响软件的可持续性,以及如何使代码随着时间的推移而具有韧性。模如何影响工程组织内软件实践的可行性。在评估设计和开发决策时,一位典型的工程师需要做出哪些权衡。

作者简介

Titus Winters,谷歌高级软件工程师,他是谷歌C++代码库的领导者:2亿5000万行代码,每月成千上万名不同的工程师在这些代码上工作。

Tom Manshreck,在谷歌软件工程部担任技术作家。他是C++ Library Team的成员,负责开发文档,开展培训课程以及为Abseil,谷歌的开源C++代码,编写文档。

Hyrum Wright是谷歌的一名软件工程师,他领导着谷歌自动化变更工具团队。Hyrum对谷歌代码库的编辑比公司历史上任何其他工程师都要多。

译者介绍

陈军,江湖称号“军少”,深圳敏捷社区发起人,腾讯T12工程效能专家,现主要从事研发效能提升工作,多年软件工程方法和技术实践经验。

周代兵,华为软件工程专家,有多年辅导团队应用软件工程方法和技术提升研发能力实践经验。

邱栋,东南大学软件工程博士,华为软件工程技术专家,有多年软件工程技术研究和实践经验,研究方向包括软件架构分析与评估,智能化软件工程等。

前言

前言
本书的书名是“Google 软件工程”。软件工程到底是什么意思?“软件工程”与“编程”或“计算机科学”有什么区别?为什么谷歌会把自己对软件工程独特的观点编写成一本书,在50 年软件工程的历史中留下这一笔?
术语“编程”和“软件工程”在我们的行业中已经交替使用了相当长的一段时间,尽管它们都有不同的重点和含义。大学生们倾向于学习计算机科学,并获得以“程序员”的身份编写代码的工作。
然而,“软件工程”听起来更为严肃,似乎它意味着应用一些理论知识来构建真实而精确的东西。机械工程师、土木工程师、航空工程师和其他工程领域的工程师都从事工程实践。他们都在现实世界中工作,运用自己的理论知识创造出真实的东西。软件工程师也创造“真实的东西”,尽管它相比其他工程师创造的东西来说并没那么实实在在。
与那些更成熟的工程专业不同,当前的软件工程理论或实践并没有那么严格。航空工程师必须遵循严格的指导方针和实践,因为他们计算中的错误会造成真实的损害。总体而言,编程在传统上没有遵循这样严格的实践。但是,随着软件越来越融入我们的生活,我们必须采用和依赖更严格的工程方法。我们希望本书能帮助其他人看到一条通向更可靠的软件实践的道路。
编程的时间性
我们认为“软件工程”不仅包括编写代码的行为,还包括组织在一段时间内用来构建和维护代码的所有工具和流程。一个软件组织可以引入哪些实践来最大限度地保持其代码的长期价值?工程师如何使代码库更具可持续性以及软件工程学科本身更为严格?对于这些问题,我们没有基本的答案,但我们希望谷歌过去20 年的经验能够为我们找到这些答案指明可能的道路。
我们在这本书中分享的一个关键见解是,软件工程可以被认为是“随着时间而不断集成的编程”。我们可以为我们的代码引入哪些实践,使其在整个生命周期内,从概念到上市、到维护、再到弃用,具有可持续性(能够对必要的变更做出反应)?这本书强调了我们认为的软件组织在设计、架构和编写代码时应该牢记的三个基本原则:
时间与变化
代码在其生命周期内需要如何适应。
规模与增长
组织在发展过程中要如何适应。
权衡与成本
组织如何从时间、变化、规模和增长中所学到的经验来做出决策。
贯穿所有章节,我们试图围绕这些主题,并指出这些原则是如何影响工程实践的,并让它们可持续的发展(完整讨论见第1 章)。
谷歌的视角
鉴于我们的规模和历史,谷歌对可持续软件生态系统的增长和演变有着独特的视角。我们希望我们所吸取的经验教训能对贵组织的发展和拥抱更多可持续性实践有所帮助。
我们将本书的主题分为谷歌软件工程领域的三个主要方面:
61 文化。
61 流程。
61 工具。
谷歌的文化是独特的,但我们在发展我们的工程文化中所吸取的教训是广泛适用的。我们关于文化的章节(第二部分)强调了软件开发企业的集体性,软件开发是一种团队工作,恰当的文化原则对于一个组织的成长和持续健康至关重要。
我们的流程章节(第三部分)中概述的技术对大多数软件工程师来说都很熟悉,但是谷歌庞大规模和多年积累的大型代码库为开发最佳实践提供了一个更完整的“压力测试”。在这些章节中,着重讲述了我们发现随着时间的推移以及规模的增长而起作用的东西,并且也还有我们仍然没有得到满意答案的领域。
最后,我们的工具章节(第四部分)说明了我们如何利用对工具基础设施的投资,来为日益增长和老化的代码库带来收益。在某些情况下,这些工具是谷歌特有的,尽管我们指出了开源或第三方的替代方案(如果适用的话)。我们期望这些基本见解适用于大多数工程组织。
本书中概述的文化、流程和工具描述了典型的软件工程师希望在工作中学到的经验教训。当然并不是只有谷歌才能提供好的建议,我们在这里介绍的经验不是要指示你的组织应该做什么。本书是我们的观点,我们希望你会发现它是有用的,不管直接采用这些经验,还是在考虑自己的实践时将它们作为出发点,专门针对自己的问题领域进行优化。
这本书也不打算说教。谷歌本身仍然没有完美地应用书中的许多概念。我们从失败中吸取的教训是:我们仍然会犯错误,执行不完美的解决方案,并且需要不断改进。然而,谷歌工程组织的庞大规模使得每个问题都有多种解决方案。我们希望本书包含了其中的精华。
本书不包含的内容
本书并不涵盖软件设计,这是一门需要独立出书(并且已经有很多内容)的学科。尽管本书中有一些代码用于说明,但这些原则与编程语言无关,在这些章节中几乎没有实际的“编程”建议。因此,本文没有涉及软件开发中的许多重要问题:项目管理、API 设计、安全强化、国际化、用户界面框架或其他特定编程语言的关注点。它们在这本书中被遗漏并不意味着它们不重要。相反,我们选择不在这里讲述它们,是因为我们无法提供它们应得的待遇。我们试图使本书中的讨论更多的是聚焦于工程,而不是编程。
临别赠言
这本书代表了所有贡献者付出的努力和汗水,我们希望你能收到它:把它当做一个了解大型软件工程组织如何构建其产品的窗口。我们也希望,这是众多的声音之一,有助于推动我们的行业采取更具前瞻性的思维和可持续的实践。最重要的是,我们希望你喜欢这本书,并能从这本书中获得你关心的观点。
—— Tom Manshreck
内容约定
本书采用以下排版约定:
斜体(Italic)
表示新术语、URL、电子邮件地址、文件名和扩展名。
等宽字体(Constant width)
用于程序示例,以及段落中引用程序元素,如变量或函数名、数据库、数据类型、环境变量、语句和关键字。
等宽黑体(Constant width bold)
显示用户应键入的命令或其他文本。
等宽斜体(Constant width italic)
显示应替换为用户提供的或由上下文确定的值的文本。
O’Reilly 在线学习平台(O’Reilly Online Learning)
近40 年来,O’Reilly Media 致力于提供技术和商业培训、知识和卓越见解,来帮助众多公司取得成功。
我们有一群独家专家和创新者,他们通过图书、文章、会议和在线学习平台分享知识和技术。O’Reilly 的在线学习平台提供按需访问的直播培训课程、详细的学习路径、交互式编程环境,以及由O’Reilly 和其他200 多家出版社出版的书籍和视频。
详情请访问http://oreilly.com。
联系我们
任何有关本书的意见或疑问,请按照以下地址联系出版社。
美国:
O’Reilly Media, Inc.
1005 Gravenstein Highway North
Sebastopol, CA 95472
中国:
北京市西城区西直门南大街2 号成铭大厦C 座807 室(100035)
奥莱利技术咨询(北京)有限公司
我们有本书的专属网页,你可以在那儿找到本书的勘误、示例和其他信息。网页地址:https://oreil.ly/software-engineering-at-google。
如果你对本书有一些评论或技术上的建议,请发送电子邮件到 [email protected]
有关其他图书、讲座、会议、新闻的信息,请访问我们的网站:http://www.oreilly.com。
Facebook:http://facebook.com/oreilly。
Twitter:http://twitter.com/oreillymedia。
YouTube:http://www.youtube.com/oreillymedia。
致谢
没有无数其他人的努力是不可能有这本书的。这本书中的知识都来自我们在谷歌的职业生涯中许多其他人的经验。我们是使者,他们来到我们面前,在谷歌和其他地方,教导我们现在呈现给你们的东西。我们不能在这里一一列举,但衷心地向你们致谢。
我们还要感谢Melody Meckfessel 在项目初期的支持,以及Daniel Jasper 和Danny Berlin 在项目完成过程中的支持。
如果没有策划人、作者和编辑的大量合作是不可能有这本书的。尽管作者和编辑在每一章或标注中都得到了明确的认可,但我们还是希望再次感谢那些对每一章做出贡献的人,他们为本书提供了深思熟虑的意见、讨论和评审。
Tom Manshreck:感谢我的父母让我相信自己,和我一起在餐桌旁完成工作。
Titus Winters:感谢父亲,为我指明道路。感谢母亲,倾听我的声音。感谢Victoria 对我的支持。感谢Raf,做我的后盾。此外,还要感谢Snyder,Ranwa,Z,Mike,Zach,Tom ( 以及Payne 一家), mec,Toby,cgd 和Melody,感谢他们的教诲、指导和信任。
Hyrum Wright:感谢父亲和母亲的鼓励。感谢Bryan 和Bakerland 公司,给了我第一次尝试软件的机会。感谢Dewayne,与我并肩作战。感谢Hannah,Jonathan,Charlotte,Spencer 和Ben,感谢他们的爱和关注。感谢Heather 一路的陪伴。

目录

目录
序 1
前言 3
第一部分 理论
第1 章 什么是软件工程 13
时间与变化 15
海勒姆定律18
案例:哈希排序 18
为什么目标不是“没有变化”呢 20
规模与效率 21
阻碍规模化的政策 22
促进规模化的政策 24
案例:编译器升级 24
左移思想 26
权衡与成本 28
案例:白板笔 29
决策投入 30
案例:分布式构建 30
案例:时间与规模的博弈 32
数据驱动的决策 32
软件工程VS 编程 33
小结 34
本章要点 34
第二部分 文化
第2 章 如何更好地参与团队合作 37
隐藏代码 37
天才神话 38
隐藏有害 40
及早检测 41
巴士系数 41
小步快跑 42
拒绝隐藏 44
一切为了团队 44
社交的三大支柱 45
三大支柱的重要性 46
谦虚、尊重和信任 46
无指责的回顾文化 50
谷歌范儿(Googley) 52
小结 53
本章要点 53
第3 章 知识共享 55
学习的挑战 55
知识共享的哲学 57
设定基调:心理安全 58
导师制 58
大型群体的心理安全 59
不断充实知识 60
提问 60
理解上下文61
扩大提问渠道:向社区提问 62
群聊 62
邮件列表 63
YAQS:问答平台 63
分享你的知识:你总有可以教别人的地方 64
Office Hours 64
技术讲座与课程 64
文档 65
代码 67
组织知识发展 68
培养知识分享的文化 68
建立规范的信息源 70
让信息流动73
可读性:通过代码评审规范化指导 74
什么是可读性流程 74
为什么需要可读性流程 75
小结 78
本章要点 78
第4 章 平等工程 79
人类的偏见 80
理解多样性的必要性 82
建立多元文化能力 82
使多样性具有可操作性 84
拒绝单一的方式 85
挑战既定流程 86
价值观与成果 87
保持好奇心,向前推进 88
小结 88
本章要点 89
第5 章 团队领导的艺术 91
经理和技术主管(或两者兼任) 91
工程经理 92
技术主管 92
技术主管经理 92
从个人贡献者到领导者 93
唯一需要担心的是……嗯,一切 94
仆人式领导95
工程经理 96
“经理”是一个令人厌恶的词 96
如今的工程经理 96
反模式 98
反模式:雇用平庸的人 98
反模式:忽视低绩效员工 99
反模式:忽视“人”的问题 100
反模式:做老好人 101
反模式:打破招聘门槛 102
反模式:像对待孩子一样对待你的团队 102
积极的模式 103
抛弃“自我”意识 103
成为一名禅师 104
成为催化剂106
移除障碍 106
成为老师和导师 107
设定清晰的目标 107
坦诚 108
追踪幸福感109
出乎意料的问题 110
其他提示和技巧 111
对待人像植物一样 113
内在激励和外在激励 114
小结 115
本章要点 115
第6 章 大规模团队领导力 117
总是在做决策 118
飞机的故事 118
识别盲点 119
识别关键的权衡 120
决策,然后迭代 120
总是不在场 122
你的使命:建立一个“自驱”的团队123
划分问题空间 123
总是在扩展 126
成功的循环127
重要VS 紧急 128
学会放弃 130
保护你的精力 131
小结 133
本章要点 133
第7 章 度量工程生产力 135
为什么要度量工程生产力 135
鉴别:它值得度量吗 137
根据目标和信号来选择有意义的指标 141
目标 142
信号 144
指标 145
使用数据验证指标 145
采取行动并跟踪结果 150
小结 150
本章要点 150
第三部分 流程
第8 章 风格指南与规则 155
为什么要有规则 156
创建规则 157
指导原则 157
风格指南 165
修改规则 168
流程 169
风格仲裁者170
例外情况 170
指南 171
应用规则 173
错误检查工具 174
代码格式化工具 175
小结 177
本章要点 177
第9 章 代码评审 179
代码评审流程 180
谷歌如何进行代码评审 181
代码评审的好处 184
代码正确性185
代码理解 187
代码一致性187
心理和文化方面的好处 188
知识共享 189
代码评审最佳实践 190
礼貌而专业190
小的变更 191
清晰的变更描述 193
评审者数量最少化 193
尽可能的自动化 194
代码评审类型 194
绿地代码评审 194
行为变更、改进和优化 195
缺陷修复和回滚 195
重构和大规模变更 196
小结 197
本章要点 197
第10 章 文档 199
什么是文档 200
为什么需要文档 200
像代码一样对待文档 202
了解文档的读者 204
读者的类型205
文档类型 206
参考文档 207
设计文档 210
新手教程 210
概念文档 212
着陆页面 213
文档评审 214
文档的哲学 216
WHO,WHAT,WHEN,WHERE 和WHY 216
开头,中间和结尾 217
优秀文档的要素 217
丢弃文档 218
什么时候需要技术文档工程师 219
小结 219
本章要点 220
第11 章 测试概述 221
为什么要写测试 222
“Google Web Server”的故事 223
当今开发速度下的测试 224
编写,运行,响应 224
测试代码的好处 227
设计测试套件 228
测试粒度 229
测试范围 233
碧昂丝规则235
代码覆盖率236
谷歌规模下的测试 237
大型测试套件的陷阱 238
谷歌测试的历史 239
入职培训课240
测试认证 241
“马桶测试” 241
如今的测试文化 242
自动化测试的局限性 243
小结 244
本章要点 244
第12 章 单元测试 245
可维护性的重要性 246
防止脆弱的测试 247
努力做到不更改测试 247
通过公共API 进行测试 248
测试状态,而不是交互 252
编写清晰的测试 253
使测试完整简洁 254
测试行为,而不是方法 255
不要把逻辑放进测试 260
编写清晰的失败信息 261
测试与代码共享:DAMP,而不是DRY 263
共享值 265
共享设置 267
共享helper 和验证 269
定义测试基础设施 270
小结 270
本章要点 270
第13 章 测试替身 273
测试替身对软件开发的影响 274
谷歌的测试替身 274
基本概念 275
测试替身的示例 275
缝(Seams) 276
模拟(Mocking)框架 277
使用测试替身的技术 279
伪造(Faking) 279
打桩(Stubbing) 279
交互测试 280
实际实现 281
实际实现比隔离更好 281
如何决定何时使用实际实现 283
伪造(Faking) 285
为什么伪实现(Fakes)如此重要286
什么时候写伪实现 286
伪实现的保真度 287
伪实现应该被测试 288
如果没有伪实现怎么办 288
打桩 289
过度使用打桩的危险性 289
何时使用打桩合适 291
交互测试 292
状态测试优于交互测试 292
何时使用交互测试合适 293
交互测试的最佳实践 294
小结 296
本章要点 296
第14 章 较大型的测试 299
什么是较大型的测试 299
保真度 300
单元测试中的常见问题 301
为什么不要有较大型的测试 303
谷歌的较大型的测试 304
较大型的测试和时间 305
谷歌规模下的较大型的测试 306
大型测试的结构 308
被测系统(SUT) 309
测试数据 314
验证 315
较大型的测试的类型 316
一个或多个交互二进制文件的功能测试 316
浏览器和设备测试 317
性能、负载和压力测试 317
部署配置测试 318
探索性测试318
A/B 差异回归测试 319
用户验收测试(UAT) 321
探针和金丝雀分析 321
灾难恢复与混沌工程 322
用户评估 324
大型测试和开发者工作流 325
编写大型测试 325
运行大型测试 326
大型测试的所有权 329
小结 330
本章要点 330
第15 章 弃用 331
为什么弃用 332
为什么弃用很难 333
将弃用融入设计 335
弃用的类型 336
建议性弃用336
强制性弃用337
弃用警告 338
弃用流程的管理 339
流程负责人340
里程碑 340
弃用的工具341
小结 342
本章要点 343
第四部分 工具
第16 章 版本控制与分支管理 347
什么是版本控制 348
为什么版本控制很重要 349
集中式版本控制系统VS 分布式版本控制系统 351
真实来源 354
版本控制VS 依赖管理 356
分支管理 356
分支等同于在制品 357
开发分支 358
发布分支 359
谷歌的版本控制 360
单一版本 361
场景:多个可用版本 362
“单一版本”规则 363
(几乎)没有长周期的分支 363
发布分支呢365
单一代码仓(Monorepos) 365
版本控制的未来 367
小结 369
本章要点 370
第17 章 代码搜索 371
Code Search 的用户界面 372
如何使用Code Search 373
在哪里 373
做什么 374
如何用 374
为什么 375
谁以及何时375
为什么需要一个单独的Web 工具 375
规模 375
无需设置即可浏览全局代码 376
专业化 377
与其他开发工具集成 377
开放API 379
规模对设计的影响 379
搜索查询延迟 380
索引延迟 381
谷歌的实现 382
搜索索引 382
排序 383
权衡 387
完整性:代码库的Head 387
完整性:所有结果VS 最相关的结果 387
完整性:Head VS 分支 VS 所有历史 VS 工作空间 388
表达性:Token VS 子串 VS 正则表达式 389
小结 390
本章要点 391
第18 章 构建工具与构建哲学 393
构建系统的目的 393
没有构建系统会发生什么 395
但是我只需要一个编译器 395
用shell 脚本来拯救 396
现代构建系统 397
一切都是为了依赖 397
基于任务的构建系统 398
基于制品的构建系统 402
分布式构建408
时间,规模,权衡 412
处理模块和依赖 413
使用细粒度依赖与1:1:1 规则 413
最小化模块可见性 414
管理依赖 414
小结 419
本章要点 420
第19 章 Critique:谷歌的代码评审工具 421
代码评审工具的原则 421
代码评审流程 423
通知 424
第一步:创建一个变更 425
差异比较 425
分析结果 426
紧密的工具集成 428
第二步:请求评审 429
第三步和第四步:理解和评论变更 430
评论 430
了解变更状态 432
第五步:批准变更(评价变更) 434
第六步:提交变更 435
提交后:跟踪历史 436
小结 437
本章要点 438
第20 章 静态分析 439
有效静态分析的特点 440
可扩展性 440
易用性 440
让静态分析发挥作用的关键经验 441
关注开发者的体验 441
让静态分析成为核心开发者工作流的一部分 442
赋予用户贡献的权力 442
Tricorder: 谷歌的静态分析平台 443
集成的工具444
集成反馈渠道 445
建议的修复446
按项目定制447
预提交 448
编译器集成448
编辑和浏览代码时的分析 449
小结 450
本章要点 450
第21 章 依赖管理 451
为什么依赖管理这么难 453
冲突的需求和菱形依赖 453
引入依赖 455
兼容性承诺455
引入时的注意事项 457
谷歌如何处理引入的依赖 459
从理论上讲,依赖管理 460
没有变化(又名静态依赖模型) 461
语义化版本号 462
绑定分发模式 463
Live at Head 464
SemVer 的局限性465
SemVer 可能过度约束 466
SemVer 可能过度承诺 467
动机 468
最小版本选择 469
那么,SemVer 有效吗 470
资源无限的依赖管理 471
导出依赖 473
小结 477
本章要点 477
第22 章 大规模变更 479
什么是大规模变更 480
谁来处理LSC 481
原子变更的障碍 483
技术限制 483
合并冲突 483
“没有闹鬼的墓地” 484
异构性 484
测试 485
代码评审 487
LSC 的基础设施 489
政策与文化489
代码库分析490
变更管理 491
测试 491
语言支持 491
LSC 流程 493
授权 493
变更创建 494
切片与提交494
清理 498
小结 498
本章要点 498
第23 章 持续集成 499
CI 的概念 501
快速反馈循环 501
自动化 503
持续测试 505
CI 的挑战 511
封闭测试 512
谷歌的CI 515
CI 案例研究:Google Takeout 518
但是我无力做CI 524
小结 525
本章要点 525
第24 章 持续交付 527
持续交付在谷歌的习语 528
速度是一项团队运动:如何将部署分解为可管理的单元 529
隔离评估变更:特性开关 530
力求敏捷:建立发布火车 531
没有一个二进制是完美的 531
赶上你的发布期限 532
质量与聚焦用户:只发布有用的功能 533
左移:更早地做出数据驱动的决策 534
改变团队文化:建立发布规则 535
小结 536
本章要点 537
第25 章 计算即服务 539
驯服计算环境 540
将琐事自动化 540
容器化与多租户 542
总结 545
为托管计算编写软件 545
为失效设计架构 545
批处理VS 服务 547
管理状态 549
连接到服务550
一次性代码551
CaaS 随时间和规模的演化 552
抽象容器 552
一个服务统御余众 555
提交的配置557
选择计算服务 558
集中化与定制化 559
抽象层次:Serverless 561
公有云VS 私有云 565
小结 566
本章要点 567
后记 569

产品特色