Software engineering at Google 笔记(二)

这本书第二部分讲的是文化,对于技术人员来说稍微有点无聊,不过决定我们在一家公司工作舒服不舒服的,其实主要就是这些文化内容,如果用这一部分里的内容去考核那些我们日常工作中的人,可能结果也会令人失望。

这一部分的内容可以看出 Google 和国内公司的文化有巨大的差异,对国内的工程师和 manager 来说,有一些思想有借鉴意义,而另一些只当参考即可(全信的话,你一定会被坑得很惨)。

软件开发要依赖团队协作

Google 内部的代码管理系统收到过很多人的需求,希望能把项目设置成 private,这个需求来自于很多人在项目写完之前,不想让别人看到自己的代码,这种心态是由于研发人员的不安全感。比如他们可能害怕:

  • 别人嘲笑你,这样的错误你都犯,和你的工作年限是不是匹配啊,可能你其实是个菜鸡
  • 明明是自己想出来的 idea,但是最终却被别人抢去邀功了

对代码的“隐藏”行为并不能给我们带来好处,从项目开始设计一直到完成,中间要经历很长时间,如果你能够让自己的同事早期就参与到项目反馈中,那他们可以及时地向你提出一些你可能没有考虑到的问题。

如果你走了弯路,不做完就不公开,那最后可能会浪费很多无意义的时间。比如你可能自己 high 了半天,做完之后别人告诉你社区/公司里已经有更完善的轮子了,那你的工作就白搞了。做研发的时候必须要确认:

  • 你在做正确的事情
  • 你在用正确的方法做事
  • 这件事情之前没有人做过

靠你自己,这三点很难保证,同事间的反馈非常重要,并且越早期的反馈效果越好,能让你在错误的路上尽早调头,这样风险也最小。

书中提出了一个叫 bus factor 的概念,其实就是团队中的一些核心人员,如果他们休假了或者离职了,组里的工作要停摆,那么工作的安排就是有问题的。这里特意强调了文档、pair programming 的重要性。

团队内的沟通有三个基本的原则:

  • 谦虚
  • 尊重
  • 信任

要对他人的处境感同身受,向他人提意见时,应该是一些建设性的建议,而不是无意义的人身攻击或者谩骂。

作为被提意见的人,我们也不应该把代码和自身绑的太紧,是代码和项目上的问题,就事论事就可以,要愿意接受他人的意见,勇于承认错误。承认错误并不会影响你个人的名誉,愿意承认错误的人会更被他人所尊重。

在团队内要重视失败的项目,做业务也要 fail fast 并且不断迭代。当失败时,要建立不针对个人的复盘文化,道歉、借口或者互相指责没有任何意义。复盘要关心的应该是我们从失败中学到了什么,并且由于这些失败的经验,有什么样的变化是必须要被推动的。书里也给出了一个复盘的模板,感兴趣的读者可以阅读一下 p39。

作为软件公司里共事的同事,我们应该有共同的目标,所以不需要像政客那样死鸭子嘴硬不愿认错,这样对谁都没有好处。

知识分享

Google 内部对于知识的分享非常重视,首先项目要有丰富的文档,这方面外企做的都挺不错的。文档能够让你的团队 "Scale",因为后来者能够通过文档了解你们的项目背景,设计初衷,开发进度等情况。

文档平台要支持检索,并且要有评论区,这样方便大家来针对某些技术方案进行讨论。在国内某家公司工作的时候,我非常惊诧的一点是他们的内部文档系统内容检索功能稀烂,极大影响了工作效率,有人吐槽却被熟视无睹。

其次 Google 有内部的技术交流社区,包括动态的群聊和邮件列表(他们的邮件列表和国内的内部论坛比较类似)。并且建立了专门的 QA 系统,类似内部版本的 Stack Overflow。

Google 内部还建立了分享文化,有专门的 Tech Talks 和内部企业培训课。现在有一些分享也会公开到 Youtube 上,之前我看到过一些。

Google 内部的代码也是对所有人开放的。

有一点比较神奇的是,在 Google 内部,如果你经常帮助同事,理论上同事可以给你一个 peer bonus 的评分(好像),这个 peer bonus 也会成为你工资以外的一笔收入,这部分钱完全是你的同事决定的,和你的 manager 没啥关系。

也就是说,帮助别人也是可以获得回报的。

Google 内部建立了各种各样的 Developer Guide 站点,帮助新人学习和 landing。同时有 codelab 帮助员工来进行一些技能的锻炼与学习。

一些代码规范和经验会直接沉淀到静态分析工具中。内部的一些事故、新闻会有专门的 NewsLetter,每隔一段时间发给所有员工,大家可以从这些有意思的内部事故中学习到别人的事故经验。

还有一个 Readability 的认证,我以前就听人讲起过 Google 的这套机制,据说 python 之父入职 Google 之后,都好几次考 Readability 的认证没有通过。具体来说就是你要了解公司内部对于代码规范的一些要求,并且参与考试,会有已经获得了 Readability 的工程师们帮你 review 代码,如果大家都通过了,那么你就获得了 Readability 的认证。之后自己也可以申请成为 Readability 的 Reviewer。

只有通过了 Readability 的认证,才能正式向线上提交代码。

这一点我觉得还挺重要的,不知道为啥国内公司没有借鉴学习,大家每天都在埋怨代码很屎,但是好像也没有人提出可以借鉴 Google 的做法去做类似的考核。

平等的工程

这个问题是国际化公司要面对的问题,公司要 Diversity 并不是响应某些国家政府的要求,而是因为他们要在全世界做生意,每个国家因为政治、风俗的原因都有一些禁忌,如果公司内没有了解当地风俗的人,那就很容易在一些当地的敏感问题上犯错。

比如 Google 曾经的人脸识别算法把黑人识别成了猩猩,而且公司对于这场舆论危机的反应又异常地慢,影响很恶劣。

产品发布的时候,要多做评估,不要着急发布导致你的产品对某一些区域的用户产生了伤害。

这一节体会不深,没有在这样的公司工作过。

如何领导一个团队

在 Google 的制度设计中一般有两条线,一个团队里会有一个 Manager,负责绩效管理和跨团队协调;另一个角色是 Tech Lead,这个角色比较类似国内某些公司说的架构师,主要负责组内的项目架构设计,技术把关,核心组件的实现,以及其他人的方案的 Review,有些团队比较小,所以可能有人兼任 Manager 和 Tech Lead。

一个好的工程师不一定是一个好的 Manager,对于 Manager 来说,做好这个角色切换也并不容易,可能新的工作中很难获得原有的熟悉的成就感。而人们又倾向于晋升到他们所不胜任的位置上去。但你应该努力让自己的职业生涯也能 "Scale",不要偏安于一隅,如果只靠一个人写代码,你的产出终究是有上限的,而一群人则可以在你的帮助下做出,做好更大的项目。

与传统的 Manager 角色不同,互联网公司的工程师们需要一定的时间来思考和创造,所以在互联网公司内做 Manager 也不应该用那些传统公司的胡萝卜+大棒策略来管理自己的员工。

Manager 不应该成为保姆一样的角色,而应该给成员们定出清晰的技术、业务目标,成为团队的催化剂,让大家的生产力得到提升,移除团队成员们前进的障碍,保护成员不被公司内的政治所伤害,维护好组内的气氛,对组员诚实。

看看上面这些要求。。。怕是没几个人能达到的吧。。

这一节还指出了一些当 Manager 的误区:

  • 第一是只招聘听话的人,这样你永远得不到负向的反馈,那很多决策上也比较容易出问题。
  • 第二是无视那些表现差劲的成员,没有与他们及时沟通,且没有针对性地让他们来改进绩效,这样会影响组内那些绩效优秀的人,他们会认为你无法区分好坏,最终离开你的团队
  • 第三是忽视一些人的因素,只考虑技术因素,比如可能有的成员家庭有一些事情,你不能还是照以往那样去做工作安排,这是把人当成了纯粹的工具
  • 第四是和组员成为过于好的朋友,这样可能无法更客观地去处理问题,同时也会伤害你与朋友的感情(谈工作伤感情)
  • 不要为了填满 HC 降低招聘门槛
  • 不要把组员当成小孩,该给的工作材料补充要做好,比如纸、笔,这些花不了几个钱,但是能提高大家工作、交流的效率

对于 Manager 来说,有服务组员的意识,关注团队的核心方向,把精力放在怎么样让组员们工作舒服和提升效率上。一些很具体的工作,能让别人代理的工作尽量让别人来代理,不要所有事情都亲力亲为。一方面是培养他人,另一方面能够让自己有更多的机会来考虑别的事情,继续向上提升。

领导大团队

简单来说,大领导们基本都得脱离技术一线,之前在技术上的积累对工作的帮助就越来越小了。这时候可能会让人气馁,但也没有办法,这里给我们提出了三个成为好领导的指导原则,三个 Always:

  • Always Be Deciding,到了这个阶段做的就不是技术细节了,所以你所有的决策都是关于正确的 trade-off 相关的,都是要做什么事情,不要做什么事情。这个决策过程也是要不断迭代的,一边决策,一边根据效果来对决策进行调整,书里举了个例子,Google 早期的搜索体验优化聚焦在搜索结果展示上,而这会影响搜索的速度和带宽,速度又会拉低用户体验,所以会导致每做一段时间展示优化,就得回去做性能优化;刚做完性能优化,马上就被新的功能优化拉回到原地。通过反复的折腾,Google 总结出了搜索体验的三个关键要素:Latency,Capacity,Quality,后续的决策就是在这三个指标之间进行权衡。
  • Always Be Leaving,这个原则比较神奇,就是你要尽量让团队能够 Self-Driving,然后让自己的角色变得可有可无,基本的策略和解决技术问题类似,把一个大的问题划分成子问题,然后把这些子问题代理给下面的团队 leader,让 下面的团队去解决这些子问题。重点关注一些战略层面的事情,让这些商业、技术问题的解决是可持续的。在决策过程中,要保证下面的团队的目标是一直被锚定的,不要发生偏移。然后就要开始问自己,有哪些事情是非自己做不可的,找出来这些问题,解决掉,这样当自己离开时,团队依然能够自行运转。(个人意见,这个有点站着说话不腰疼,没有几个人愿意放弃手上已有的权力吧)
  • Always Be Scaling,这里讲的比较虚,遇到问题,分析问题,然后通过痛苦的挣扎来解决问题,总结经验,对团队做奖赏,然后再去解决新的问题。在决策循环中要分清重要和紧急的问题,同时维持好自己的精力,让自己尽量聚焦中 20% 的重要问题上,其它的委派给下面的 leader 们。

总结一下,高度不够,看着比较虚。内容也有点站着说话不腰痛。

衡量工程生产力

《人月神话》里的故事大家已经都知道了,给项目加人是没法加速软件的研发的。

提升单体工程师的工作效率却可以加速项目研发,Google 为了提升生产力,找了很多人来研究到底该监控什么样的指标,这里面还有很多心理学家和行为学家。。以数据驱动的方式来研究生产效率的提升。

为了让指标有意义,Google 发明了一套 GSM:Goals,Signals,Metrics 的方法来衡量一个指标是否合理。

Goal 是定指标的时候必须要考虑的目标,这些目标要尽量能够都满足,不能使其中一个向上而其它向下。这里的 Goals 主要有 QUANTS 五个方面:

  • Quality of the code,你的工具和指标应该能让代码质量得到提升,或者至少也不应该有负面的影响。
  • Attention from engineers,你的工具和指标会不会让工程师的注意力反复被打断?比如因为频繁推送的 notification,你的工具会让工程师不断地进行上下文切换么?
  • Intellectual complexity,你的工具和指标会不会增加工程师的心智负担?会不让因为这些工具让工程师完成任务变得更难了?
  • Tempo and velocity,工程师能以多快的速度完成任务?多快发布新的版本?在给定的时间内能完成多少任务?
  • Satisfaction,工程师对工具是否满意?工具是否满足了工程师们的需求?工程师是否经常被工具惹恼?

书里以 Readability 为例,根据上述框架来分析,每一点都要尽量达到要求。

Signal 是指我们以什么样的表现来判断我们的目标是否已经达成了。其实就是你要收集一些反馈或者数据,来判断你的工具是不是真得达成了上面那些 Goal,而不是你自己吹牛逼,还是 Readability 这套体系:

唉,说白了,就是你的晋升 PPT 上,这些东西要能自圆其说,不能是硬凹。每一条都有论据能对号入座。

Metrics 就是你要作为生产力衡量的工具或者指标,这些指标需要是可以量化的,直接从书里摘一些例子吧:

在收集到数据之后,研究工程效率的团队要根据这些数据给出后续改进的建议 action 列表,这里面的 action 可能是给生产力工具增加一个 feature,提升某个工具的延迟,改进公司内的文档,移除一些已经过时的老流程。

所有建议都尽量是 tool driven 的,经过开发或者改进,能集成到工程师的日常 workflow 流程中。而不应该是在工具不支持的前提下,让工程师改变他们使用系统或者思考问题的方法。

这一点我还是比较欣赏 Google 的,能用工具解决的,都尽量用工具来解决。通过工具的不断改进,来提升工程师的工作满意度和他们的效率。

总结

对于我们工程师来说,改变公司的文化是很难的,所以这一部分里的内容可能也就只是个参考。