本文首发于硅谷io

谷歌的软件工程:软件开发

业界公认,谷歌是一家工程能力超强的公司。它有哪些好的工程实践?我们可以在里面得到哪些启发?其中又有哪些地方是被人诟病的?这些内容比较细致我们慢慢讲,本篇主要是讲开发。

代码库

  • 截止15年有 20 亿行代码存在少量的 Monorepo
  • 单一代码库中,绝大部分代码对所有人是可见的。谷歌鼓励工程师见到有问题就可以改,只要所有人审核通过,就能进库。
  • 几乎所有的开发都是在代码库的头部 (head) 进行的,而不是在分枝上,避免 merge 时候遇到问题,安全修复也更方便。
  • 每个改动都会触发测试,有错几分钟内就能通知作者和审查者。
  • 代码库的每个子树至少有两个所有人,其他开发者可以提交修改,但是所有人批准才能进库。

构建系统

  • 分布式构建系统 Blaze 让编译、链接、测试轻松快速。
  • 成百上千台机器。
  • 可靠性高,确定的依赖输入导致确定的结果输出,不会出现奇怪的不确定的抖动。
  • 快。一个构建结果缓存了,依赖它的构建会直接采用缓存,不必重新勾结。只会重新构建改动的部分。
  • 提交前自检 (pre-submit checks)。一些快速的测试可以在提交前先执行。

代码审查

  • 有代码审查工具
  • 所有改动必须有审查
  • 发现 bug 之后可以去之前的那个审查上指出问题,相关人员会被邮件通知到
  • 实验性质的代码不用强制审查,但是生产环境下的代码一定会被审查
  • 鼓励每个改动尽量小。百行以内是“小”,三百行以内是“中”,一千行以内是“大”,超过一千行是“超tm大”。

测试

  • 单元测试
  • 集成测试、回归测试
  • 提交前检查
  • 自动生成测试覆盖率
  • 部署之前做压力测试,并产生相应的关键指标,尤其是延迟、错误率随着负载的变化
  • Bug 追踪工具
  • Bugs, feature requests, customer issues, process 等等都记录起来,需要时常 triage 以确认优先级然后分配给相应的工程师。

编程语言

  • 限制有五个官方语言 C++, Java, Python, Go, JavaScript,以便代码重用和开发协作。每种语言有风格指南。
  • 工程师要经历代码可读性培训。
  • 当然某些场合的 DSL (Domain-specific language) 也不可避免。
  • 这些语言之间的数据交互主要是通过 protocol buffers。
  • 通用流程很重要,不同的语言,同样的工作流程

Debug 和分析工具

  • 服务器崩溃时,崩溃信息会自动记录下来。
  • 内存泄漏会附带上当前的 heap 对象。
  • 有大量的 web 工具帮你检测 RPC 的请求、改变设置、资源消耗等等。

发布

  • 大多数的发布工作是普通的工程师自己做的
  • 及时发布很重要,因为快速的发布节奏能够极大地激励工程师多干活、更快地得到反馈
  • 典型的发布过程:
    • 找最新的稳定 build ,做一个 release branch,可能再附带 cherry-pick 一些小改动
    • 跑测试与构建、打包发布到 staging 服务器上内部测试,这时候可以 shadow 一下线上的流量,看看有没有问题
    • 发布到 canary上承接少量的流量公开测试
    • 逐渐发布给所有的用户
    • 对发布的审查
      用户可见的、或者是重大的发布必须有相关的法务、隐私、安全、可靠性、业务需求相关的审查批准,确保相关人员被通知到。有专门的工具来辅助这个流程。

尸检报告

  • 有重大的 outage 事故发生之后,相关责任人必须写尸检报告,内容包括
    - 事件标题
    - 总结
    - 影响:发生了多久、影响了多少流量、损害了多少利润
    - 时间轴:记录时间的发生、诊断和消弭
    - root causes
    - 做的好的地方,做的不好的地方:有什么经验能够帮助他人在下一次更快更准地找到并解决问题?
    - 接下来的可行动作:有什么接下来可以做的事情能够避免将来类似的事情发生?
  • 对事不对人,这里的关键是理解问题本身、以及将来如何避免类似问题。

重写代码
大量的软件每隔几年就会被重写一次。坏处是确实成本高,好处是

  • 保持敏捷。市场在变,软件的需求也一直在变,代码也需要随之变化以应对不时之需。
  • 降低复杂度。
  • 传承知识给新人,让他们有拥有感。
  • 提高工程师的移动性,促进跨领域创新。
  • 采用最新的技术栈和方法论。

我的评论

  • 谷歌的单一代码库和强大的构建系统是小公司不可学的,毕竟小公司没有资源和能力让构建系统快到敏捷可用;保持小、简单、快速会让小公司跑得更顺畅,更加专注于核心业务逻辑。
  • 构建系统通常是定制化的,你的知识无法迁移和衍生。强大的构建系统对新手甚至是有害的,因为提高了新手俯瞰全局的成本。
  • 知识无法迁移和衍生也是完善的内部工具 (in-house tools) 的问题。我在职业生涯中会尽量避免使用不会开源的内部工具,比如 Uber 的 Schemaless,只针对特定的场景且没打开放出来算做大做强 ;而相反的, Linkedin 的 Kafka 则是一个有开放性和衍生性的知识的好产品。
  • 在公开市场,这整个开发、测试、集成、发布的流程都有非常好的工具帮你来做,举个 JS 社区的例子:

流程 工具

代码库  Github, Gitlab, Bitbucket, gitolite
代码审查    Github Pull Requests, Phabricator
提交前自检、测试与 Lint  husky, ava, istanbul, eslint, prettier
Bug Tracking    Github Issues, Phabricator
测试与持续集成 CircleCI, TravisCI, TeamCity
部署  发布在线服务的 Heroku, Netifly, 发布移动 App 的 Fastlane, 发布库的 NPM

最后,我可能有一个洞见,不注重这些工程流程自动化的细节的公司,在工程上会损失巨大的竞争力。我甚至为了良好的工程实践自己配了一个 JS 全栈开发框架 OneFx。快节奏与慢节奏、高质量与低质量差别,通常是指数级别的,因为 —— 通常,快会让你更快更多,差会让你更差更少。

原文
https://arxiv.org/pdf/1702.01715.pdf
https://news.ycombinator.com/item?id=13619378

微信原文
扫码获取更多有价值资讯

谷歌的软件工程:软件开发相关推荐

  1. 软件工程-软件开发的工程思维

    软件工程-软件开发的工程思维 目录 软件工程-软件开发的工程思维 前言 什么是软件工程? 定义 出现的背景 软件工程核心知识 与项目管理的区别 软件工程的目标 为什么需要软件工程 如何做好软件工程:原 ...

  2. 北京大学 软件工程1 软件 软件工程 软件开发 软件工程框架

    软件的定义 重新定义软件 新一代信息技术 区块链 创造性思维 软件的特点 软件的种类 支撑软件:VC++,PyCharm等 应用软件:QQ,微信 软件工程的起源 软件开发的三个阶段 软件工程概念的提出 ...

  3. 软件工程——软件开发阶段(概要设计、详细设计)

    需求分析确定了系统的开发目标,下一步工作就是软件设计.软件设计可以进一步地 分为两个阶段:总体设计和详细设计.确定系统的具体 实现方案.给出软件的模块结构.编写各个文档 目的是什么? 承上(需求)启下 ...

  4. 谷歌高效开发的秘密:来自谷歌前员工的软件开发工具指南

    点击上方 "程序员小乐"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 关注订阅号「程序员小乐」,收看更多精彩内容 每日英文 Smile, Beca ...

  5. 【软件工程】RUP与软件开发5大模型

    软件开发的5大模型 1.瀑布模型:按照人的思维一步一步的开发下去,如果需求分析得当,每个阶段顺利,结果还不错! 2.快速原型模型:后来人们发现,自己不可能一下子就把所有的需求搞清楚,总是在开发的过程中 ...

  6. 软件工程方法论为我们经软件开发有多大用处?谈谈你的看法。

    软件工程方法论为我们经软件开发有多大用处?谈谈你的看法. 软件工程的各个阶段对软件开发与维护有指导作用和实际意义, 软件工程生命周期的各个阶段相互关联, 对软件的开发和维护均有重要作用. 为了摆脱软件 ...

  7. 软件工程模块开发卷宗_软件智能化再进一步,未来人人都能开发软件?

    工人日报客户端11月18日电 一个普通的IT工程师通过飞算全自动软件工程平台,只输入流程图,不敲一行代码就实现了后端开发,仅仅用28分钟就完成了3个资深IT工程师近2个小时的开发工作,而且在抗并发等效 ...

  8. 多元化时代敏捷软件开发的崛起与传统软件工程的延续

      多元化时代敏捷软件开发的崛起与传统软件工程的延续 1.传统软件开发模式 1.1瀑布模型 1.1.1概念 瀑布模型,顾名思义,软件开发的过程如同瀑布飞流一般,自上而下,逐级下落.瀑布模型的核心思想是 ...

  9. 软件工程---3.敏捷软件开发

    敏捷软件开发 极限编程(XP, Beck1999) Scrum方法(Schwaber and Beedle 2001) DSDM方法(Stapleton 2003) 敏捷软件的开发宣言 个体和交互胜过 ...

最新文章

  1. 数据结构遍历顺序栈_链栈的初始化与遍历
  2. er图转为数据流程图_draw.io for Mac(流程图绘制工具)
  3. k8s v1.9.6 超详细搭建步骤
  4. 点击文字弹出一个DIV层窗口代码 【或FORM表单 并且获取点击按钮的ID值】
  5. 按钮button的常用属性和事件
  6. 【数据结构总结】第五章 树和二叉树(非线性结构)
  7. php7 加的新特性积累
  8. poj 1634 Who's the boss?
  9. 如何用Java代码在SAP Marketing Cloud里创建contact数据
  10. nodejs即时聊天
  11. 结合 Apache Kafka 生态系统,谈谈2018年机器学习五大趋势
  12. python读取文件时提示“UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xad in position 1264: illegal multi
  13. 计算机网络管理员考试试题,计算机网络管理员考试试题和答案
  14. Lambda表达式与Stream
  15. IE11浏览器缓存bug
  16. C#实现超市管理系统(进销存--(包含部分用户权限的管理))
  17. 2.Java语言基础——流程控制语句与方法
  18. 照片变漫画的方法有哪些?推荐两个方法给你
  19. 配置OSPF负载分担
  20. 手机客户端设置同济邮箱的方法

热门文章

  1. 【Android进阶】4、用 ViewModel 和 onSaveInstanceState 实现旋转屏幕时 UI 状态的保存和恢复
  2. svn upgrade
  3. C语言的error: two or more data types in declaration specifiers
  4. Netty模拟OOM-Metaspace
  5. linux apache htaccess,Apache下htaccess的配置使用详解
  6. 新息自适应卡尔曼滤波matlab代码,基于新息协方差的自适应渐消卡尔曼滤波器.pdf...
  7. JWT与Signature
  8. 摩根大通财报里,美国梦何所依
  9. Cannot find class [org.springframework.scheduling.quartz.CronTriggerBean]
  10. 阿里云全方位布局物联网