《Google软件工程》简介:
你将学习到软件组织在设计、架构、编写和维护代码时应牢记的三个基本原则:时间如何影响软件的可持续性,以及如何使代码随着时间的推移而具有韧性。模如何影响工程组织内软件实践的可行性。在评估设计和开发决策时,一位典型的工程师需要做出哪些权衡。
《Google软件工程》摘录:
我们在这本书中分享的一个关键见解是,软件工程可以被认为是“随着时间而不断集成的编程”。我们可以为我们的代码引入哪些实践,使其在整个生命周期内,从概念到上市、到维护、再到弃用,具有可持续性(能够对必要的变更做出反应)? 这本书强调了我们认为的软件组织在设计、架构和编写代码时应该牢记的三个基本原则: 时间与变化 代码在其生命周期内需要如何适应。中规模与增长 组织在发展过程中要如何适应。 权衡与成本 组织如何从时间、变化、规模和增长中所学到的经验来做出决策。
《Google软件工程》目录:
目录
序 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
· · · · · ·