{"id":1411,"date":"2024-06-15T19:44:14","date_gmt":"2024-06-15T11:44:14","guid":{"rendered":"https:\/\/moneystock.net\/wp_e\/?p=1411"},"modified":"2025-01-19T19:31:49","modified_gmt":"2025-01-19T11:31:49","slug":"book-software-engineering-at-google","status":"publish","type":"post","link":"https:\/\/moneystock.net\/wp_e\/2024\/06\/15\/book-software-engineering-at-google\/","title":{"rendered":"Book &#8211; Software Engineering at Google"},"content":{"rendered":"<p>Summary Notes\u00a0 from the book, Software Engineering at Google<\/p>\n<ol>\n<li><\/li>\n<li><\/li>\n<li><\/li>\n<li><\/li>\n<li><\/li>\n<li><\/li>\n<li><\/li>\n<li>Style Guides and Rules\n<ol>\n<li>Auto formatting : Resharper console app.\n<ol>\n<li><a href=\"https:\/\/blog.jetbrains.com\/dotnet\/2018\/03\/01\/code-cleanup-resharper-command-line-tools\/\">https:\/\/blog.jetbrains.com\/dotnet\/2018\/03\/01\/code-cleanup-resharper-command-line-tools\/<\/a><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Code Review\n<ol>\n<li>Review in 3 aspects\n<ol>\n<li>The code will work as intended without error.<\/li>\n<li>If code looks OK to the code owner&#8217;s view.<\/li>\n<li>If readability is OK<\/li>\n<\/ol>\n<\/li>\n<li>It might be good to see how many code reviews are made by a developer as it&#8217;s unknown effort.<\/li>\n<li>Idea: static analysis -&gt; when build in CI tool, check all warnings and send them to the committer.<\/li>\n<li>Tip: make it small.<\/li>\n<\/ol>\n<\/li>\n<li>Documentation\n<ol>\n<li>Wiki type document is hard to get it up to date, and prevent duplicate.<\/li>\n<li>Solution: add the document in source control together with source. Document should have an owner.<\/li>\n<li>Reference Document\n<ol>\n<li>Public class\/method: must write a comment describing it<\/li>\n<li>Design Doc: write and review before implementing a major project<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Testing\n<ol>\n<li>Automated testing provide developers change code with confidence.<\/li>\n<li>Adopting automated testing in Google was a cultural change. e.g. orientation class, test certified program, testing on the toilet. -&gt; demonstrating success rather than mandating it.<\/li>\n<\/ol>\n<\/li>\n<li>Unit Testing\n<ol>\n<li>Best Practice not to be brittle, but maintainable.\n<ol>\n<li>Test only public API<\/li>\n<li>Test state rather than interaction<\/li>\n<li>Clear Test\n<ol>\n<li>Make it clear and concise &#8211; be clearer over DRY principle.<\/li>\n<li>Test behaviours, not methods<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Test Doubles\n<ol>\n<li>Realistic tests rather than mocking framework whenever possible: When real logic change, logic in mocking needs to change as well. Consider factors as below.\n<ol>\n<li>Execution time<\/li>\n<li>Determinism<\/li>\n<li>Dependency construction<\/li>\n<\/ol>\n<\/li>\n<li>Faking : it can be better off than mocking. e.g. fake DB, fake service<\/li>\n<li>Stubbing: stubbing can be a reasonable technique to use, as long as its usage is constrained so that tests don\u2019t become overly complex.<\/li>\n<li>Prefer state testing over interaction testing<\/li>\n<\/ol>\n<\/li>\n<li>Larger Testing\n<ol>\n<li>Larger test is used to cover realistic test that involves multiple dependencies, and systems.<\/li>\n<li>This is needed because Unit Test only cover function level fidelity.<\/li>\n<li>Even for integration test, smaller test is better.<\/li>\n<li>Types of Larger Tests\n<ol>\n<li>Functional testing of one or more binaries<\/li>\n<li>Browser and device testing<\/li>\n<li>Performance, load, and stress testing<\/li>\n<li>Deployment configuration testing<\/li>\n<li>Exploratory testing : See if system can resilient on unexpected user input, etc.<\/li>\n<li>A\/B diff (regression) testing<\/li>\n<li>User acceptance testing (UAT)<\/li>\n<li>Probers and canary analysis\u00a0 (in production): Probers is a simple automated smoke test.<\/li>\n<li>Disaster recovery and chaos engineering\u00a0 (in production): Can do this in the case where system can affordable.<\/li>\n<li>User evaluation (in production)<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Deprecation\n<ol>\n<li>When the obslete code, depenencies, system became a burden to manage, deprecate it.<\/li>\n<li>Tip: announce it in advance, change the obslete code interface name, stop the old system to see who\/what is dependent on it. Provide benefit to move to the new system<\/li>\n<li>Consider the end of product when start builing it. e.g. structure it for a graceful deprecation.<\/li>\n<\/ol>\n<\/li>\n<li>Version Control and Branch Management\n<ol>\n<li>Do not use Dev branch. Trunk(master) masted, heavily tested and CI, disable incomplete\/untested features at runtime.<\/li>\n<li>Release branch.<\/li>\n<li>One-version rule: developers must not have a choice where to commit, or which version of an existing component to depend upon.<\/li>\n<\/ol>\n<\/li>\n<li>Code Search<\/li>\n<li>Build\n<ol>\n<li>Remote Cashing: At Google, many artifacts are served from a cache rather than built from scratch. The cach is shared by many developers.<\/li>\n<li>Artifact based building: each build worker generates artifacts independently and shared through the remote cash. A build worker may depend on the artifacts from the other worker. The dependency graph can be managed in artifact based built, but near impossible in task-based build.<\/li>\n<li>One version rule: the same dependency should be a single version in the system\/company.<\/li>\n<li>For a small projects, task based build system will be enough given the overhead of artifact based build system.<\/li>\n<li>One-time cost v.s. ongoing problem.<\/li>\n<li>Automatically managed dependencies can be convenient for small projects, but they\u2019re usually a recipe for Disaster<\/li>\n<li>we enforce a strict One-Version Rule for all third-party dependencies<\/li>\n<li>limiting engineers\u2019 power and flexibility can improve their productivity.<\/li>\n<li>My conclusion: good build system increase developers&#8217; productivity.<\/li>\n<\/ol>\n<\/li>\n<li>Code Review\n<ol>\n<li>limiting engineers\u2019 power and flexibility can improve their productivity.<\/li>\n<li>In emergency cases, the author can forcefully commit their change and have it reviewed after commit.<\/li>\n<li>Critique also surfaces the results from builds, tests, and static analyzers, including style checks<\/li>\n<li>Diff features\n<ol>\n<li>Syntax highlighting<\/li>\n<li>Cross-references<\/li>\n<li>Intraline diffing<\/li>\n<li>Ignore whitespace<\/li>\n<li>Move detection<\/li>\n<\/ol>\n<\/li>\n<li>Code reiveiw request hook can trigger automated testing, etc and let author know if not not successful<\/li>\n<li>Google greatly values the educational aspects of code review, even though they are more difficult to quantify.<\/li>\n<\/ol>\n<\/li>\n<li>Static Analysis\n<ol>\n<li>we generally focus on newly introduced warnings, unless existing warnings are critical.<\/li>\n<li>Key lessions\n<ol>\n<li>Focus on developer happiness\n<ol>\n<li>Effective false positive (perceived false positive) is important.<\/li>\n<li>Automated fix. e.g. style fix should be an automated fix<\/li>\n<li>Show error or don&#8217;t show warning as developers ignore warnings.<\/li>\n<\/ol>\n<\/li>\n<li>Make static analysis a part of the core developer workflow\n<ol>\n<li>It&#8217;s effective to run static code alanysis when PR raised and report back to author\/share with reviwer<\/li>\n<\/ol>\n<\/li>\n<li>Empower users to contribute\n<ol>\n<li>Set a feedback loop so that developers provide feedback e.g. Not Useful button.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Dependency Management\n<ol>\n<li>Dependency conflict is main concern. i.e. so called diamond dependency. Lib-user may depends on lib-a and lib-b. Both lib-a and lib-b can depend on different version of lib-base each. Lib-user try resolve this by skip forward or backward in version to find compatible version.<\/li>\n<li>&#8220;I got it to work&#8221; V.S. &#8220;this is working in a supported fashion&#8221;.<\/li>\n<li>\u00a0Solutions\n<ol>\n<li>Nothing changes &#8211; do not change dependency as far as you can.<\/li>\n<li>Semantic Versioning &#8211; major.minor.patch versioning.<\/li>\n<li>Bundled Distribution Models &#8211;<\/li>\n<li>Live at Head &#8211; Version Control &amp; CI make sure all work<\/li>\n<li>Minimum version selection &#8211; select the lowest version possible<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<\/li>\n<li>Large Scale Changes\n<ol>\n<li>Large scale changes prone to create a bug or not successful release<\/li>\n<li>Solution? Create automated tests to cover as much as possible so a large scale changes are covered and rest assured.<\/li>\n<li>Automated formatting and automated code generation helps this process.<\/li>\n<li>When a reviewer does not response, Rosie (Google&#8217;s review system) adds additional reviewers automatically.<\/li>\n<\/ol>\n<\/li>\n<li>Continuous Integration\n<ol>\n<li>The fundamental goal of CI is to automatically catch problematic changes as early as possible.<\/li>\n<li>If it isn\u2019t actionable, it shouldn\u2019t be alerting. If it isn\u2019t actually violating the invariants of the SUT, it shouldn\u2019t be a test failure.<\/li>\n<li>General CI process will be a unit test before merge to main branch, then an integration test including distributed system after the merge. When test failed, it should be rollback of fixed ASAP.<\/li>\n<li><\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary Notes\u00a0 from the book, Software Engineering at Google Style Guides and Rules Auto formatting : Resharper console app. https:\/\/blog.jetbrains.com\/dotnet\/2018\/03\/01\/code-cleanup-resharper-command-line-tools\/ Code Review Review in 3 aspects The code will work as intended without error. If code looks OK to the code owner&#8217;s view. If readability is OK It might be good to see how many&hellip; <a class=\"more-link\" href=\"https:\/\/moneystock.net\/wp_e\/2024\/06\/15\/book-software-engineering-at-google\/\">Continue reading <span class=\"screen-reader-text\">Book &#8211; Software Engineering at Google<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[690,692,688],"class_list":["post-1411","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-book","tag-google-2-en","tag-software-engineering-at-google","entry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1411","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/comments?post=1411"}],"version-history":[{"count":5,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1411\/revisions"}],"predecessor-version":[{"id":1518,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/posts\/1411\/revisions\/1518"}],"wp:attachment":[{"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/media?parent=1411"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/categories?post=1411"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/moneystock.net\/wp_e\/wp-json\/wp\/v2\/tags?post=1411"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}