醉创业
首发于醉创业
专题 | Edmond Lau:如何创建良好的工程师文化?

专题 | Edmond Lau:如何创建良好的工程师文化?

导语:

小专题继续。今日我们推荐一篇如何构建工程师文化的。

话说本公号为什么这么关注工程师文化呢。首先是,对于现在的创业公司来说,如何伺候好工程师们应该是第一要务;其次呢,就是因为我不懂啊...不懂就只能学...

本文的作者是 Edmond Lau,他现今是Quip的资深工程师,之前在Quora做了3年时间。嗯,写到这儿我实在是写不下去了...其实是我的工程师朋友们说这篇不错,就推荐给他大家了。我看了一遍大概看懂了一半吧...


What makes a good engineering culture

作者:Edmond Lau

翻译:爱小逗逗的@fish、新年新气象的@华华钟

原文链接:What makes a good engineering culture?

面试工程师时,我最喜欢问的问题之一是:在上一个公司,关于工程师文化你最喜欢和最不喜欢的一点分别是什么?我面试的人数超过500,其中大部分来自顶尖的科技公司比如Facebook、Amazon、Palantir和Dropbox。经过时间的证明,这道面试题目让我了解优秀的工程师在寻找和避免什么。回顾这些面试以及我个人过去7年在Google、Ooyala和 Quora的经验,我提炼出以下十点来为一个团队创建良好的工程师文化。

1. 优化迭代速度

快速的迭代速度增加工作的动力和刺激。工程师在面试时解释他们为什么从上一家公司离职的最常见的和最令人沮丧的原因在于:基础架构和官僚主义的障碍影响了代码的部署和功能的发布。

从组织上看,快速的迭代速度意味着让工程师和设计师能自由自主地做日常决定,而不需要获得批准。当我在Google的时候,从所有在用户界面能看到的改变到搜索结果,甚至是低流量的试验,都需要在每周用户界面会议上获得Marissa Mayer的批准。虽然它保护了Google搜索的品牌,但很显然它妨碍了创新。优化迭代速度也意味着产品的发布有界限明确的过程,所以投入一定时间后后不会出现突然取消产品发布。

从基础结构来看,优化迭代速度意味着扩建持续的资源配置来支撑快速验证,意味着足够广的测试覆盖率来减少缺损的建立和设置,意味着快速的单元测试来鼓励人们来使用,也意味着快速的、递增的编制和重装以减少程序调试的时间。持续的资源配置特别值得注意,因为它能让提交快速变成产品。在Quora采用它之前,内化对我来说并不难,因为它给迭代速度带来的益处超过系统崩溃的危害,至少对于小的工程师团队。人们对产品特点更有兴趣,更容易被激励去修复缺陷,因为改变会即时被大家看到。比起用一周或更长时间来成批地去改变,从已提交的代码中的狭窄窗口期去推出和定位缺陷的来源更简易。

团队层面的、快速的迭代速度意味着一批给力的领导协调和驱动团队合作。一个决定中的关键利益相关者需要有效地做决定,并坚持他们的选择。借用Bill Walsh的一句话,如果训练49人队参加3场美国橄榄球超级杯大赛,给力的领导应该去「委任、爆发、恢复」,这意味着实施攻击的计划、执行它并对结果做出反应。一个犹豫不决的团队只会使个人的努力付诸东流。

2.持续地推进自动化

Instagram的联合创始人Mike Krieger在他的科技演讲「规模化Instagram」中说道,他的13人团队中在规模化一个上千万用户的产品中学到的关键教训是「对最小化的操作压力进行优化」(optimize for minimal operational burden)。随着产品的发展,每个工程师的运营负担也增加,运营负担是指用户/工程师比或产品特性/工程师比。比如,Facebook就以规模化的特性闻名,比如每个工程师能支持超过一百万用户。

自动化解决方案和脚本的重复性工作非常重要,因为它能解放工程师团队来做一些真正的产品。在规模化管理复杂性时,唯一的明智的办法是:确认服务运行失败时能尽可能自动重启以及服务能在高峰期轻易且快速地复制。从短期来看,比起自动修复以及测试长期修复功能,采用手动修复总是容易地多。

Etsy的名言「测量所有事,测量每件事」以及他们对于开放源代码检测和绘制类似graphite和statsd工具的支持都强调了自动化的一个重要方面——自动化必须由数据和检测来驱动。如果没有检测和日志来了解是什么、是怎么样以及为什么事情出错了,自动化将会很难。所以那句话可以改成,「测量所有事,测量每件事,并尽可能实现自动化。」

3.建立正确的软件抽象(software abstractions)

我在MIT的教授兼本科的研究导师Daniel Jackson充分地意识到了 software abstractions 的重要性。

「选择正确的软件抽象,程序从设计之初会自然向前流动;模块界面会小且简单;新功能会更容易嵌合而不需要大量的再组。选择错误的软件抽象,程序会如同一系列烦人的奇袭:界面会呈现巴洛克风格且不易使用,因为它们被迫适应意外的交互,甚至连最简单的改动都很难实现。」

让Google上千的工程师创建可扩展系统的部分原因在于极其聪明的工程师如Jeff Dean和Sanjay Ghemawat能创建出简单且通用的抽象,比如 MapReduce、SSTable、 Protocol Buffers 等。让Facebook能规模化编程的原因在于专注在例如Thrift、Scribe和Hive的核心抽象。让Quora的设计师能有效地创建产品的部分原因在于 Webnode 和 Livenode 是相当容易理解,并且容易在此基础上再建。

保持核心抽象简单并通用,这减少了定制解决方案的需求,也增加了团队对于普遍抽象的熟悉度和精通。Memcached、Redis和MongoDB等系统的日渐受欢迎和受信赖已减少了创建自定义储存和缓冲系统的需求。团队的注意力集中在小规模的核心抽象而不是分割为大量的专项解决方案意味着常见库变得更壮大,检测变得更智能,性能特性变得更易懂以及测试变得更全方面。所有这些益处都归功于减少了运行负担的更简单的系统。

4.专注高质量代码和代码审核

维持一个高质量的代码库增加整个工程师团队的工作效率。简洁的代码更容易去推导,更能接受改变,更不容易受到程序漏洞的影响。一个健康的程序审核可以实现这些可能。

不管是在提交前还是提交后,建立一个程序及时地审核代码,都能从几个方面改善代码的质量。首先,来自同行的压力,想到写一个很烂的代码会让其他同行对自己失望,大家就不会写太烂的且不能维护或测试的代码。其次,代码审核提供一个机会让代码审核者及编程者可以互相学习。

如果代码审核员可以接触到编程团队里的其他人,那么审核还有以下好处:1)及时的增加代码审核的责任;2)让团队成员,尤其是新成员,学习别人优秀的代码审核;3)加速最有效的代码的传播。

反驳说小的团队没有时间去审核代码的人忽视了技术债务很容易来源于质量差的代码的积累。Ooyala公司在最初的创业期习惯去优化产品中尽可能多的性能,却没有审核代码。结果导致:最初的产品进入市场越快,其代码就越难修改。我们当时花费了一年的时候去重写脆弱的代码以消灭技术债务。

Google根据它的规模,所有的代码都会在提交前审核,但是小团队不需要这么严格,而且不是所有的代码都不需要这么严格地审核。此后,当我在Ooyala工作的时候,他们采用了提交后邮件审核模式来审核一些核心或有风险的改动。在Quora,我们通过Phabricator管理所有代码审核,主要是在提交后,并且对于模式或控制器代码用不一样的标准;对于敏感的或者新工程师编写的代码,我们采用提交前审核或者尝试着在提交前数小时审核。

5.营造一个相互尊重的工作环境

尊重同事能创造一个开放交流的平台。人们对于质疑能包容的地方才是通过辩论锻造出明智想法的地方。人们对于质疑容易动怒,那么重要的反馈就被保留。

在1948,Alex Osborn罗列出在过去几十年职场上受欢迎的类似头脑风暴的方法,所有参与者聚集在一起,挑出批评和负面反馈,这样能汇集创意想法而不用担心被评判。受尊重的延缓批评是这种头脑风暴环节的关键。近期的心理学研究开始推翻Osborn’s的方法——鼓励头脑风暴实际上有助于避免群体思想并产生更有效的思想。根据这项研究,一个充满尊重的环境变得至关重要,攻击应针对思想而不是依据个人偏好。

编程一般涉及广泛的领域(系统,机器学习,产品等等),但不是每个人在每个领域都精通。也许实际上,一个强大的团队应该拥有专才而不是全才。这有时候不好说,一个系统工程师要评估产品工程师的熟练程度,但是在一个健康的工程师文化里尊重这些不同而不是基于自己的优势去批判他人是非常重要的。

6.共享代码所有权

虽然对个人而言,精通代码或底层结构的各个部分是自然而然的,可是没有人觉得他们应该拥有或是成为任何一部分的唯一维护者。尽管有些人已经成为那个领域一年以上的专家,或者可能会在短期内更富有成效,但这种做法并非长远之计。

共享代码所有权有三个优势。首先,能保持公交因素 bus number 大于缓解来自维护者的压力和降低维护者离开后的风险。这也让个人可以开始享受无忧无虑的假期。我无法忘记那一天,我成为了Ooyala公司的日志处理器的唯一维护者,并且是夏威夷火山上徒步旅行时得到这个消息。

其次,共享所有权可以授权那些在特定领域涉猎不深的工程师,贡献他们新的见解。它让工程师们从被困住的项目上解放出来,并鼓励他们增加项目的多样性,这有助于让工作变得有趣,员工的学习态度和动机也得到提升。从长远来看,这样做降低了某些工程师因为感到停滞、决定离开而带来的组织风险。

第三,在需要更迅速地完成战略目标的关键时刻,共享所有权让多个团队成员能够群集(一种敏捷开发的技术)在一起处理高优先级的问题。而所有权独享的后果,通常是负担落在一两个人的肩上。

在团队早期规模尚小的时候,很多组织常犯的一个错误是为时过早地将整个团队分成若干子团队。因为个人可能会被其子团队的目标评估,子团队会构建所有权的壁垒,减少交叉的动机。 我在Ooyala公司的时候,子团队的存在使我错过了,与其他团队其他同事一起工作的机会。他们已经采用了一种花大力气在共享代码所有权上的敏捷开发过程,我听说工作幸福感和生产力因此得到大幅的提高。 在Quora初期,我很享受的一点是我们强调了项目的团队合作,我有机会合作完成诸如用户增长,机器学习,适宜的工具,建议,分析,网站的速度,和垃圾邮件检测等各类项目。

7.投资自动化测试

想和一大群人一起管理代码库而不是靠持续地破坏构建或者产品,那么单元测试的覆盖范围和一定程度的集成测试覆盖率是唯一可扩展的方式。对于需要提高代码质量的大规模重构,自动化测试提供了完成的信心和有意义的保护。由于缺乏严格的自动化测试,使得手动测试的时间变长,令工程团队或者外包测试团队望而却步,从而容易产生一种因担心可能会崩溃,而不愿去优化一段代码的文化。

在团队成长的实践中,自动化测试是完成持续性资源部署的必然要求。代码库的大小跟着产品的长期增长而增长,但随着新人的加入,团队成员对代码库的平均熟悉度却会降低。当代码刚写好不久时,编程人员做出测试和校验要比在几月甚至几年后再尝试修改代码,要容易得多。鼓励培养浓厚的单元测试文化,会将校验代码的责任转向原作者。

8. 分拨20%的时间

Gmail起源于Paul Buchheit的20%项目,而且第一版还是他在一天之内拼凑出来的。同时推出的还有20%项目中的谷歌新闻、谷歌公交和谷歌推荐。在谷歌时,我用20%的时间写一个Python框架,让建立搜索页面演示变得更便捷。虽然现在谷歌20%时间的项目可能没有公司初期那么高效,但对于小的工程组织而言,让工程师们花20%的时间做某件事情而不只花在他们的产品图上,这样的理念能够孕育创新。

我在Ooyala公司时,没有官方的20%时间。不过我为Flex和ActionScript写了一个命令行构建工具,可以加快团队的构建时间。在Adobe’s Flex Builder工具链开始解离的时候我完成了它,并且该工具仍然在使用,甚至这时工程团队的规模已超过原来的两倍大小。在实验一年之后,Atlassian采纳了20%时间的项目。 20%时间的一个变化是,Facebook的喜欢和Ooyala公司后来的增加,这是周期性的编程马拉松——全晚的事件,其中的规则是,你可以做除了日常工作外的任何事情。

自上而下地进行产品规划,同时还必须关注公司的总体方向,这并不能解释为什么有许多点子出自一线工程师。只要工程师对他们20%的时间负责并专注于能够产生深远影响的改变,这些项目就能带来巨大的进步。没有官方的声明,20%时间仍然是可行的,虽然对于工程师和设计师来说,尝试疯狂的想法变得更加困难——基本上不得不利用周末或假期来做。

9.建立学习和不断改进的文化

一个人全身心投入到正在做的事情,甚至可以忘记时间的存在,心理学教授 Mihaly Csikszentmihalyi 称这种状态为「心流」,其中不断学习和得到充分的挑战是达到这种状态的必要条件。 此外,还需要由更快的迭代周期提供的,直接、即时的反馈回路。

每周的高科技对话为工程师们提供了,一个可以分享个人设计或者构建的论坛,同时创造了一个让工程师们体会工作自豪感,并拓宽团队视角的好机会。记录内部的流程,例如电子邮件服务的工作原理或如何改变搜索服务的排名还能让工程师很好地利用那20%的时间,自己去学习和探索新的东西。在Quora,我们是这样做的:运用内部实例,提出和产品、发展有关的问题。

建设学习文化的一个推论是注重指导和培训,以确保每个人都有基本的算法、系统和产品成功所必需的技能。工程组织成长得越快和花在招聘上的努力(尤其是高校招聘)越多,越需要投入更多到员工的指导和培训上。对一个辅导员来说,在入职的头四周里,每天花一个小时为一个新员工指导工作似乎是种负担,不过这种占用新员工一年工作总时间不到1%的投入,却是十分重要的,在很大程度上决定了此新人是否能够获得成功。

10.雇佣最好的

雇佣最好的是其他列出的建议的基础。很难有人尊重,如果你认为某工程师的水平一般,那么你很难青睐他,如果你不信任某人对产品的直觉,也很难让他自主开发产品。如果没有足够的编程经验,则很难识别正确的抽象层。如果没有其他聪明的人来挑战你的想法并促使变得简单,那么很容易陷入构建复杂东西的陷阱。

在硅谷流传着史蒂夫·乔布斯的一句话,「A级的雇主聘请A级的雇员,B级的雇主家聘请到的是C级的雇员。」关注招聘并雇佣到合适的人是很难的,但对工程组织的成长却至关重要。曾任Facebook的工程经理和总监的黄易山,认为雇佣是工程组织的首要任务,不只是对于管理者而言,对工程师同样重要。 他也相当犀利地指出了「雇佣最好的」与「雇用应聘者中最佳的”二者之间的区别。」

在Ooyala的初期,入站用户的工作队列令我们不堪重负,为此我们几乎屈从于降低应聘要求,以聘用足够的人手来维持运转。不过我很庆幸我们没有选择这样做,如果那样,低质量的代码和较弱的工程师团队带来技术债,最终会伤害团队和产品,走到尽头。

建立一个良好的工程文化无疑需要很多努力,但由此产生的良好工作环境值得我们这样做。

编辑于 2015-03-01

文章被以下专栏收录