具体描述
The approach to and understanding of software engineering at Google is unlike any other company. With this book, you’ll get a candid and insightful look at how software is constructed and maintained by some of the world’s leading practitioners.
Titus Winters, Tom Manshreck, and Hyrum K. Wright, software engineers and a technical writer at Google, reframe how software engineering is practiced and taught: from an emphasis on programming to an emphasis on software engineering, which roughly translates to programming over time.
You’ll learn:
Fundamental differences between software engineering and programming
How an organization effectively manages a living codebase and efficiently responds to inevitable change
Why culture (and recognizing it) is important, and how processes, practices, and tools come into play
作者简介
Titus Winters is a Senior Staff Software Engineer at Google, where he has worked since 2010. Today, he is the chair of the global subcommittee for the design of the C++ standard library. At Google, he is the library lead for Google’s C++ codebase: 250 million lines of code that will be edited by 12K distinct engineers in a month. For the last 7 years, Titus and his teams have been organizing, maintaining, and evolving the foundational components of Google’s C++ codebase using modern automation and tooling. Along the way he has started several Google projects that believed to be in the top 10 largest refactorings in human history. As a direct result of helping to build out refactoring tooling and automation, Titus has encountered first-hand a huge swath of the shortcuts that engineers and programmers may take to “just get something working”. That unique scale and perspective has informed all of his thinking on the care and feeding of software systems.
Tom Manshreck is a Staff Technical Writer within Software Engineering at Google since 2005, responsible for developing and maintaining many of Google's core programming guides in infrastructure and language. Since 2011, he has been a member of Google's C++ Library Team, developing Google's C++ documentation set, launching (with Titus Winters) Google's C++ training classes, and documenting Abseil, Google's open source C++ code. Tom holds a BS in Political Science and a BS in History from the Massachusetts Institute of Technology. Before Google, Tom worked as a Managing Editor at Pearson/Prentice Hall and various startups.
Hyrum K. Wright is a Staff Software Engineer at Google, where he has worked since 2012, mainly in the areas of large-scale maintenance of Google's C++ codebase. Hyrum has made more individual edits to Google's codebase than any other engineer in the history of the company. He is a member of the Apache Software and an occasional visiting faculty member at Carnegie Mellon University. Hyrum received a PhD in Software Engineering from the University of Texas at Austin, and also holds an MS from the University of Texas and a BS from Brigham Young University. He is an active speaker at conferences and contributor to the academic literature on software maintenance and evolution.
目录信息
Preface
Programming Over Time
Google’s Perspective
What This Book Isn’t
Parting Remarks
Conventions Used in This Book
O’Reilly Online Learning
How to Contact Us
Acknowledgments
I. Thesis
1. What Is Software Engineering?
Time and Change
Hyrum’s Law
Example: Hash Ordering
Why Not Just Aim for “Nothing Changes”?
Scale and Efficiency
Policies That Don’t Scale
Policies That Scale Well
Example: Compiler Upgrade
Shifting Left
Trade-offs and Costs
Example: Markers
Inputs to Decision Making
Example: Distributed Builds
Example: Deciding Between Time and Scale
Revisiting Decisions, Making Mistakes
Software Engineering Versus Programming
Conclusion
TL;DRs
II. Culture
2. How to Work Well on Teams
Help Me Hide My Code
The Genius Myth
Hiding Considered Harmful
Early Detection
The Bus Factor
Pace of Progress
In Short, Don’t Hide
It’s All About the Team
The Three Pillars of Social Interaction
Why Do These Pillars Matter?
Humility, Respect, and Trust in Practice
Blameless Post-Mortem Culture
Being Googley
Conclusion
TL;DRs
3. Knowledge Sharing
Challenges to Learning
Philosophy
Setting the Stage: Psychological Safety
Mentorship
Psychological Safety in Large Groups
Growing Your Knowledge
Ask Questions
Understand Context
Scaling Your Questions: Ask the Community
Group Chats
Mailing Lists
YAQS: Question-and-Answer Platform
Scaling Your Knowledge: You Always Have Something to Teach
Office Hours
Tech Talks and Classes
Documentation
Code
Scaling Your Organization’s Knowledge
Cultivating a Knowledge-Sharing Culture
Establishing Canonical Sources of Information
Staying in the Loop
Readability: Standardized Mentorship Through Code Review
What Is the Readability Process?
Why Have This Process?
Conclusion
TL;DRs
4. Engineering for Equity
Bias Is the Default
Understanding the Need for Diversity
Building Multicultural Capacity
Making Diversity Actionable
Reject Singular Approaches
Challenge Established Processes
Values Versus Outcomes
Stay Curious, Push Forward
Conclusion
TL;DRs
5. How to Lead a Team
Managers and Tech Leads (and Both)
The Engineering Manager
The Tech Lead
The Tech Lead Manager
Moving from an Individual Contributor Role to a Leadership Role
The Only Thing to Fear Is…Well, Everything
Servant Leadership
The Engineering Manager
Manager Is a Four-Letter Word
Today’s Engineering Manager
Antipatterns
Antipattern: Hire Pushovers
Antipattern: Ignore Low Performers
Antipattern: Ignore Human Issues
Antipattern: Be Everyone’s Friend
Antipattern: Compromise the Hiring Bar
Antipattern: Treat Your Team Like Children
Positive Patterns
Lose the Ego
Be a Zen Master
Be a Catalyst
Remove Roadblocks
Be a Teacher and a Mentor
Set Clear Goals
Be Honest
Track Happiness
The Unexpected Question
Other Tips and Tricks
People Are Like Plants
Intrinsic Versus Extrinsic Motivation
Conclusion
TL;DRs
6. Leading at Scale
Always Be Deciding
The Parable of the Airplane
Identify the Blinders
Identify the Key Trade-Offs
Decide, Then Iterate
Always Be Leaving
Your Mission: Build a “Self-Driving” Team
Dividing the Problem Space
Always Be Scaling
The Cycle of Success
Important Versus Urgent
Learn to Drop Balls
Protecting Your Energy
Conclusion
TL;DRs
7. Measuring Engineering Productivity
Why Should We Measure Engineering Productivity?
Triage: Is It Even Worth Measuring?
Selecting Meaningful Metrics with Goals and Signals
Goals
Signals
Metrics
Using Data to Validate Metrics
Taking Action and Tracking Results
Conclusion
TL;DRs
III. Processes
8. Style Guides and Rules
Why Have Rules?
Creating the Rules
Guiding Principles
The Style Guide
Changing the Rules
The Process
The Style Arbiters
Exceptions
Guidance
Applying the Rules
Error Checkers
Code Formatters
Conclusion
TL;DRs
9. Code Review
Code Review Flow
How Code Review Works at Google
Code Review Benefits
Code Correctness
Comprehension of Code
Code Consistency
Psychological and Cultural Benefits
Knowledge Sharing
Code Review Best Practices
Be Polite and Professional
Write Small Changes
Write Good Change Descriptions
Keep Reviewers to a Minimum
Automate Where Possible
Types of Code Reviews
Greenfield Code Reviews
Behavioral Changes, Improvements, and Optimizations
Bug Fixes and Rollbacks
Refactorings and Large-Scale Changes
Conclusion
TL;DRs
10. Documentation
What Qualifies as Documentation?
Why Is Documentation Needed?
Documentation Is Like Code
Know Your Audience
Types of Audiences
Documentation Types
Reference Documentation
Design Docs
Tutorials
Conceptual Documentation
Landing Pages
Documentation Reviews
Documentation Philosophy
WHO, WHAT, WHEN, WHERE, and WHY
The Beginning, Middle, and End
The Parameters of Good Documentation
Deprecating Documents
When Do You Need Technical Writers?
Conclusion
TL;DRs
11. Testing Overview
Why Do We Write Tests?
The Story of Google Web Server
Testing at the Speed of Modern Development
Write, Run, React
Benefits of Testing Code
Designing a Test Suite
Test Size
Test Scope
The Beyoncé Rule
A Note on Code Coverage
Testing at Google Scale
The Pitfalls of a Large Test Suite
History of Testing at Google
Orientation Classes
Test Certified
Testing on the Toilet
Testing Culture Today
The Limits of Automated Testing
Conclusion
TL;DRs
12. Unit Testing
The Importance of Maintainability
Preventing Brittle Tests
Strive for Unchanging Tests
Test via Public APIs
Test State, Not Interactions
Writing Clear Tests
Make Your Tests Complete and Concise
Test Behaviors, Not Methods
Don’t Put Logic in Tests
Write Clear Failure Messages
Tests and Code Sharing: DAMP, Not DRY
Shared Values
Shared Setup
Shared Helpers and Validation
Defining Test Infrastructure
Conclusion
TL;DRs
13. Test Doubles
The Impact of Test Doubles on Software Development
Test Doubles at Google
Basic Concepts
An Example Test Double
Seams
Mocking Frameworks
Techniques for Using Test Doubles
Faking
Stubbing
Interaction Testing
Real Implementations
Prefer Realism Over Isolation
How to Decide When to Use a Real Implementation
Faking
Why Are Fakes Important?
When Should Fakes Be Written?
The Fidelity of Fakes
Fakes Should Be Tested
What to Do If a Fake Is Not Available
Stubbing
The Dangers of Overusing Stubbing
When Is Stubbing Appropriate?
Interaction Testing
Prefer State Testing Over Interaction Testing
When Is Interaction Testing Appropriate?
Best Practices for Interaction Testing
Conclusion
TL;DRs
14. Larger Testing
What Are Larger Tests?
Fidelity
Common Gaps in Unit Tests
Why Not Have Larger Tests?
Larger Tests at Google
Larger Tests and Time
Larger Tests at Google Scale
Structure of a Large Test
The System Under Test
Test Data
Verification
Types of Larger Tests
Functional Testing of One or More Interacting Binaries
Browser and Device Testing
Performance, Load, and Stress testing
Deployment Configuration Testing
Exploratory Testing
A/B Diff Regression Testing
UAT
Probers and Canary Analysis
Disaster Recovery and Chaos Engineering
User Evaluation
Large Tests and the Developer Workflow
Authoring Large Tests
Running Large Tests
Owning Large Tests
Conclusion
TL;DRs
15. Deprecation
Why Deprecate?
Why Is Deprecation So Hard?
Deprecation During Design
Types of Deprecation
Advisory Deprecation
Compulsory Deprecation
Deprecation Warnings
Managing the Deprecation Process
Process Owners
Milestones
Deprecation Tooling
Conclusion
TL;DRs
IV. Tools
16. Version Control and Branch Management
What Is Version Control?
Why Is Version Control Important?
Centralized VCS Versus Distributed VCS
Source of Truth
Version Control Versus Dependency Management
Branch Management
Work in Progress Is Akin to a Branch
Dev Branches
Release Branches
Version Control at Google
One Version
Scenario: Multiple Available Versions
The “One-Version” Rule
(Nearly) No Long-Lived Branches
What About Release Branches?
Monorepos
Future of Version Control
Conclusion
TL;DRs
17. Code Search
The Code Search UI
How Do Googlers Use Code Search?
Where?
What?
How?
Why?
Who and When?
Why a Separate Web Tool?
Scale
Zero Setup Global Code View
Specialization
Integration with Other Developer Tools
API Exposure
Impact of Scale on Design
Search Query Latency
Index Latency
Google’s Implementation
Search Index
Ranking
Selected Trade-Offs
Completeness: Repository at Head
Completeness: All Versus Most-Relevant Results
Completeness: Head Versus Branches Versus All History Versus Workspaces
Expressiveness: Token Versus Substring Versus Regex
Conclusion
TL;DRs
18. Build Systems and Build Philosophy
Purpose of a Build System
What Happens Without a Build System?
But All I Need Is a Compiler!
Shell Scripts to the Rescue?
Modern Build Systems
It’s All About Dependencies
Task-Based Build Systems
Artifact-Based Build Systems
Distributed Builds
Time, Scale, Trade-Offs
Dealing with Modules and Dependencies
Using Fine-Grained Modules and the 1:1:1 Rule
Minimizing Module Visibility
Managing Dependencies
Conclusion
TL;DRs
19. Critique: Google’s Code Review Tool
Code Review Tooling Principles
Code Review Flow
Notifications
Stage 1: Create a Change
Diffing
Analysis Results
Tight Tool Integration
Stage 2: Request Review
Stages 3 and 4: Understanding and Commenting on a Change
Commenting
Understanding the State of a Change
Stage 5: Change Approvals (Scoring a Change)
Stage 6: Commiting a Change
After Commit: Tracking History
Conclusion
TL;DRs
20. Static Analysis
Characteristics of Effective Static Analysis
Scalability
Usability
Key Lessons in Making Static Analysis Work
Focus on Developer Happiness
Make Static Analysis a Part of the Core Developer Workflow
Empower Users to Contribute
Tricorder: Google’s Static Analysis Platform
Integrated Tools
Integrated Feedback Channels
Suggested Fixes
Per-Project Customization
Presubmits
Compiler Integration
Analysis While Editing and Browsing Code
Conclusion
TL;DRs
21. Dependency Management
Why Is Dependency Management So Difficult?
Conflicting Requirements and Diamond Dependencies
Importing Dependencies
Compatibility Promises
Considerations When Importing
How Google Handles Importing Dependendencies
Dependency Management, In Theory
Nothing Changes (aka The Static Dependency Model)
Semantic Versioning
Bundled Distribution Models
Live at Head
The Limitations of SemVer
SemVer Might Overconstrain
SemVer Might Overpromise
Motivations
Minimum Version Selection
So, Does SemVer Work?
Dependency Management with Infinite Resources
Exporting Dependencies
Conclusion
TL;DRs
22. Large-Scale Changes
What Is a Large-Scale Change?
Who Deals with LSCs?
Barriers to Atomic Changes
Technical Limitations
Merge Conflicts
No Haunted Graveyards
Heterogeneity
Testing
Code Review
LSC Infrastructure
Policies and Culture
Codebase Insight
Change Management
Testing
Language Support
The LSC Process
Authorization
Change Creation
Sharding and Submitting
Cleanup
Conclusion
TL;DRs
23. Continuous Integration
CI Concepts
Fast Feedback Loops
Automation
Continuous Testing
CI Challenges
Hermetic Testing
CI at Google
CI Case Study: Google Takeout
But I Can’t Afford CI
Conclusion
TL;DRs
24. Continuous Delivery
Idioms of Continuous Delivery at Google
Velocity Is a Team Sport: How to Break Up a Deployment into Manageable Pieces
Evaluating Changes in Isolation: Flag-Guarding Features
Striving for Agility: Setting Up a Release Train
No Binary Is Perfect
Meet Your Release Deadline
Quality and User-Focus: Ship Only What Gets Used
Shifting Left: Making Data-Driven Decisions Earlier
Changing Team Culture: Building Discipline into Deployment
Conclusion
TL;DRs
25. Compute as a Service
Taming the Compute Environment
Automation of Toil
Containerization and Multitenancy
Summary
Writing Software for Managed Compute
Architecting for Failure
Batch Versus Serving
Managing State
Connecting to a Service
One-Off Code
CaaS Over Time and Scale
Containers as an Abstraction
One Service to Rule Them All
Submitted Configuration
Choosing a Compute Service
Centralization Versus Customization
Level of Abstraction: Serverless
Public Versus Private
Conclusion
TL;DRs
V. Conclusion
Afterword
Index
· · · · · · (收起)
读后感
用户评价
如果说市面上大多数系统设计书籍提供的是“骨架”,那么这本书提供给读者的就是“血肉与神经”。我之所以这么说,是因为它在处理性能优化和资源管理的细节上,展现出了惊人的深度。它不是简单地推荐使用某种缓存算法,而是详细分析了不同内存层级(L1/L2 Cache、主存、SSD)的访问延迟差异,以及如何利用这些底层知识来设计出真正高效的数据结构和算法。比如,书中关于如何优化序列化和反序列化性能的章节,对JSON、Protocol Buffers等主流格式在不同负载下的表现进行了细致的对比和性能剖析,这对于构建高吞吐量的网络服务至关重要。再者,书中对“SRE”(站点可靠性工程)理念的阐述,也比许多专门书籍更加务实。它强调的不是无休止的警报轰炸,而是通过工程手段,主动地降低故障率,并建立一套基于服务等级目标(SLO)的健康度指标体系。读完这部分内容,我立刻开始反思我们现有的监控和告警体系的有效性,意识到我们可能过度关注了“发生了什么”,而忽略了“我们承诺用户能得到什么”。
这本书最宝贵之处,在于它培养了一种“系统性思维”——看待问题不再是孤立的模块或服务,而是将一切视为一个相互作用的复杂系统。这一点在谈到安全性设计时体现得淋漓尽致。作者没有将安全仅仅视为在软件开发后期添加的“补丁”,而是将其内嵌到了需求分析、架构设计乃至部署流程的每一个环节中。比如,书中对“纵深防御”策略的阐述,不仅仅停留在防火墙或输入验证的层面,而是深入探讨了身份验证、授权模型、数据加密(静态与传输中)以及安全审计日志的不可篡改性等多个维度。这种全景式的安全视角,极大地拓宽了我对“健壮系统”的定义。此外,书中对文档和知识沉淀的重视程度也值得称赞,它将清晰的架构文档和设计评审视为与编写高质量代码同等重要的工程产物。总而言之,这本书不像是一个工具箱,更像是一份经过时间考验的“工程宪法”,它为构建、维护和演进大规模、高可靠性软件系统提供了一套坚实而灵活的指导原则。
这本书的结构安排极具巧思,它巧妙地在技术深度和广度之间找到了完美的平衡点。从软件架构的顶层设计到具体的部署流程,它无缝衔接了理论与实践的鸿沟。让我印象尤其深刻的是关于大型项目生命周期管理的讨论,特别是那些关于“依赖管理地狱”的规避策略。在如今模块化和微服务盛行的时代,如何有效地管理成百上千个内部和外部依赖项,确保版本兼容性和构建的快速迭代,是一个巨大的挑战。作者提出的多版本共存策略和版本锁定机制,经过了实战的检验,显得非常可靠。此外,书中关于自动化测试金字塔的构建,也提供了一种非常实用的视角——强调单元测试的深度和集成测试的广度,同时谨慎对待端到端(E2E)测试的投入产出比。这种对投入产出比的持续关注,体现了这本书作者群体深谙商业现实的本质:工程的终极目标是交付价值,而非单纯追求技术上的完美无瑕。它引导读者以一种更具商业智慧的方式思考工程问题。
这本书的叙事节奏和语言风格,完全不像那种枯燥的技术文档,反而更像是一系列精心策划的“工程故事会”。作者的笔触非常细腻,善于捕捉软件生命周期中那些微妙的、容易被忽略的“人”的因素。我尤其欣赏其中关于跨职能团队协作和技术债务管理的篇章。它没有简单地将技术债务视为一个需要被“清理”的负面名词,而是将其视为一种有意识的、在特定时间点上做出的商业权衡。这种成熟的视角让我重新审视了我们自己的项目路线图。书中描述的那些关于如何通过渐进式重构而非“大爆炸”式推倒重来,来管理复杂遗留系统的策略,简直是久旱逢甘霖。更值得称道的是,它深入探讨了代码审查(Code Review)的文化建设,认为这不仅是质量把控的关口,更是知识传递和团队标准统一的核心机制。这种对“工程文化”的强调,远超出了纯粹的技术范畴,直达组织效能的核心。阅读体验非常流畅,仿佛有一个经验丰富的前辈在你耳边,用最直接、最不加粉饰的语言,告诉你如何避免那些常见的“坑”。
这本书简直是一本关于现代软件开发的百科全书,虽然它没有直接提及那个特定公司的名字,但字里行间流露出的那种全球领先技术实践的精髓,是任何希望在这一领域有所建树的工程师都无法忽视的。从宏观的系统设计哲学到微观的代码质量标准,作者似乎将多年一线摸爬滚打的心得毫无保留地倾泻而出。特别令我印象深刻的是关于大规模分布式系统的构建与维护的章节,书中对“可扩展性陷阱”的剖析入木三分,它不仅仅是罗列技术名词,而是深入探讨了在处理PB级数据和亿级用户时,决策背后的权衡艺术。例如,作者对“一致性与可用性”的讨论,并非是教科书式的CAP理论复述,而是结合了实际的故障场景和业务需求,给出了极具操作性的指导方针。阅读过程中,我不断地停下来,对照我们团队目前正在处理的棘手问题,发现许多困扰我们多时的难题,在这本书中都能找到其理论基础和潜在的解决方案的影子。它成功地将那些看似高不可攀的“黑科技”转化成了可理解、可实践的工程原则。那种感觉就像是拿到了一份世界顶级研发部门内部的“最佳实践手册”,只是它用了一种更为普适和去中心化的叙事方式。
刚开始,感觉很好
虽然还没看完,但是国内现在大公司基本上在工程效率上已经跟进的差不多了。 包括构建、测试、发布及软件工程质量把控上 送大家pdf原版: http://lubansearch.com/luban/index.html/search?query=Software%20Engineering%20at%20Google
虽然还没看完,但是国内现在大公司基本上在工程效率上已经跟进的差不多了。 包括构建、测试、发布及软件工程质量把控上 送大家pdf原版: http://lubansearch.com/luban/index.html/search?query=Software%20Engineering%20at%20Google
虽然还没看完,但是国内现在大公司基本上在工程效率上已经跟进的差不多了。 包括构建、测试、发布及软件工程质量把控上 送大家pdf原版: http://lubansearch.com/luban/index.html/search?query=Software%20Engineering%20at%20Google
虽然还没看完,但是国内现在大公司基本上在工程效率上已经跟进的差不多了。 包括构建、测试、发布及软件工程质量把控上 送大家pdf原版: http://lubansearch.com/luban/index.html/search?query=Software%20Engineering%20at%20Google