打造工程师文化可以做的十件事
英文原文:What makes a good engineering culture?
我作为面试官最喜欢问工程师的问题是要告诉我在他们以前的公司,他们喜欢和不喜欢的关于工程师文化的事。我采访了很多人 - 其中许多来自顶尖高科技公司,如 非死book,谷歌,亚马逊,Pinterest- 随着时间的推移,这种面试问题也告诉我优秀工程师喜欢和尽量避免地方。根据采访答复和我个人经验,我总结了为建立一个良好的工程文化一个团队可以做的十件 事情。
1. 优化迭代速度。
快速迭代的速度提高了工作积极性和兴奋度。一些工程师在面试时对他们为什么要离开公司列举了最常见的令人沮丧的原因是基础设施和繁冗流程阻碍他们部署代码或者上线功能。
在组织上,快速迭代意味着给工程师和设计师的灵活性和不设限自主做日常决策。我在谷歌,任何用户可见的搜索结果改变,即使是低流量的实验,需要 玛丽莎梅耶在每周 UI 审查批准。虽然这允许谷歌保护它的搜索的品牌,但它明显阻碍创新。优化迭代速度也意味着,有明确定义的流程推出产品,而不会说花了大量时间投入后意外发 生。
优化迭代速度意味着建立持续部署以快速验证,提高测试覆盖率,减少构建和网站当机次数,快速单元测试,并鼓励大家来运行,快速增量编译和重新加 载,以缩短开发时间。持续部署,提交马上到线上特别重要。 迭代速度至少在小工程队利大于弊(线上出错的风险)。人们更兴奋看到功能和修复 Bug 是因为很快看到实时流量变化。这要比超过一周或成批的代码提交,要更容易推断和精确定位错误源的位置。
团队智慧,快速迭代的速度意味着有强有力的领导者,帮助协调和推动团队的工作。在决定关键点上负责人需要有效地作出决定,并承诺他们的选择。借 用比尔 · 沃尔什,一个领导 49 人队 3 次进超级碗的一句话,强有力的领导者需要 “承诺,引爆,恢复”,这意味着承诺攻击计划,执行它,然后看反应结果。优柔寡断团队只会导致个人努力白费。
2. 尽量自动化。
在技术讲座 “规模化 Instagram”,Instagram 的联合创始人迈克 · 克里格引 “优化最少的操作负担” 作为一个重要的教训,领导他的 13 人团队用户增长到几千万。 产品的增长意味每工程师的操作负担加重,如用户跟工程师或者特定功能跟工程师的比率。 像 非死book 号称每个工程师支持超过 100 万的用户比例指标。
自动化解决方案和脚本去重复执行任务很重要,因为它们解放工程团队,让他们为实际产品工作。确保如有失败服务自动重启和方便快捷在流量高峰期替代是在管理大而复杂产品的明智方案。在短期内可以对应用做快速修复,而长期还是要依赖自动化测试,这需要权衡。
Etsy 的的座右铭 “衡量所有,衡量一切”。支持像开源监控和制图工具 graphite 和 statsd 突出自动化 - 即自动化必须由数据和监控驱动。如果没有监控和日志你怎么知道什么事情错了,为什么错。自动化是困难的。一个后续的座右铭是 “衡量所有,衡量一切,并尽可能自动化。”
3. 建立合理的软件抽象。
我的麻省理工学院教授和本科生研究顾问丹尼尔 · 杰克逊说的软件抽象的重要性:
“选择正确的方式,程序化自然而然地设计; 模块化就是有小而简单的界面; 新功能在不影响全局的情况下产生。要是搞错的话,程序将是一系列的讨厌的坑:接口很笨拙因为他们无法适应一些意料之外的交互,即使是最简单的改动将是很难维护 “。
是什么在谷歌让数千名工程师建立可扩展的系统,是因为他们有非常聪明的工程师像杰夫 · 迪恩和桑杰 · 格玛沃特创建了简单,但丰富的抽象,如 MapReduce 的,SSTable,Protocol Buffer 等。是什么让 非死book 工程这么支持大规模,是因为专注于核心,同样喜欢抽象和简单,Thrift, Scribe, Hive。是什么让设计人员能够有效构建产品,Webnode,Livenode 也是基于同样的理解。
保持核心抽象的简单和减少自定义解决方案,并增加团队熟悉度和对专业知识的抽象。日益普及系统像 Memcached,Redis,MongoDB 等系统都是降低建立定制存储和缓存系统的必要。团队重点转移到少数核心抽象,而不是分裂在很多临时解决方案,让公共库更稳健,监控更智能,性能更易理解, 测试更全面。所有这一切都有助于搭建一个简单的系统,降低操作负担。
4. 注重代码审查,编写高代码质量。
维持高品质的代码库增加了整个工程团队的工作效率。清洁代码更容易便捷发展和维护,更适应变化,不容易引入错误。健康的代码审查过程使之成为可能。
建立及时代码审查流程,不管是预提交或提交后,能有几种方法的提高代码质量。首先,知道有人会检查你的代码,提交写得不好的代码可能会辜负你的队友。那些难以维护,或未经测试的代码是一种压力。第二,代码审查也提供了评审和相互学习编写更好代码的机会。
代码审查更容易接触到其他工程团队成员,评论也带动了 a)增进一段时间内审查代码的责任感 b)允许团队成员 - 特别新手 - 观摩别人的好代码,c)加快最佳编码实践的传播。
有种说法,灵活的团队没多少时间花费在代码审查而忽视了技术债务,可以很容易地从写得不好的代码积累。 在创业早期就为了完成尽可能多的功能而忽略代码审查; 其结果是,虽然最初的产品更迅速地拥有了市场,但代码变得修改痛苦,我们花了一年多时间仅仅是改写脆弱的代码,以偿还技术债务。
谷歌预先进行审查所有的代码,但规模较小的团队并不需要那么全面和严格,因为不是所有的代码需要使用相同的标准审查。 公司后来采用后提交的评论通过电子邮件通知核心处危险的变化。我们用 Phabricator 对所有的代码审查,大多后提交,并采用了不同的标准模型,比如控制器代码和视图代码; 对于敏感的代码或新工程师的代码,我们要么做预提交的评论或试图在几个小时被提交的代码中查看它们。
5. 保持一个尊重的工作环境。
同事之间的尊重构成开放交流的基础。靠谱的想法获得往往通过大家辩论,这种挑战也是感觉很舒服的方式。人们不爽的是重要反馈没有及时回应。
1948 年,亚历克斯 · 奥斯本概述了在过去的几十年中在工作环境中流行方法,参与者走到一起,抛开批评和负面的反馈,共同凝聚在一起不用担心被评判,头脑风暴会议。最近的心理学 研究已经开始推翻奥斯本的做法,表明在头脑风暴会议,鼓励辩论实际上避免群体思维并产生更有效的思路。鉴于这一研究,一个尊重环境变得更加重要使得攻击仅 仅是观点而不是个人。
工程往往跨越广泛的领域(系统,机器学习,产品等),而不是每个人都有相同的专业知识在每个领域。其实是一个强大的团队应该具备,在某些领域都 有能干的牛人,即使他们最终会被替代。这有时很麻烦,让一个系统工程师来评估产品工程师的能力,但在一个健康的工程师文化中尊重这些差异很重要,并不是完 全根据自己的优势来判断。
6. 建立共享代码所有权。
虽然有些人自然就成为精通代码库或基础设施的各个部分,但没有一个人应该觉得他们拥有或任何一件的唯一维护者。虽然有个人一年以上能在一些领域成为专家,在短期内有成效,这种做法最终伤害长期利益。
在组织上,共享的代码所有权提供了三个好处。首先,保持因子 8 大于 1 可以减轻压力和降低团队维护者离开的风险。这也使人很难在休息时间无忧。我清楚记得,当我夏威夷火山上徒步旅行度假时候,得到报警,因为我是公司的日志处理器的唯一维护者。
其次,共享所有权让工程师不限制在特定区域,以促进新的见解。它让工程师们从他们被困在某些项目上离开,并鼓励他在多样性项目上工作,这有助于保持工作有趣性,并提升员工学习积极性。从长远来看,它降低组织风险,一些工程师感到停滞就会决定离开。
第三,共享所有权还设置了有多个团队成员(从敏捷开发的一种技术)一起在一个高优先级的问题,必要时更迅速地完成战略目标奠定了基础。而孤立的所有权,负担通常落在一两个人。
很多工程组织犯的错误是为时过早将整个团队分成子团队。子团队会形成责任的阻碍,并很难去打破所有权的墙,因为个人可能会被其子团队的目标进行 评估。 有很多小团队,我很珍惜与一些其他团队的工作机会; 他们使用敏捷开发,重心放在共享代码所有权,使得工作幸福感和生产力更佳。 初期我喜欢的一个方面是更强调项目而不是团队,让我有机会合作的项目从用户增长,机器学习,工具,推荐,分析,网站的速度,和垃圾检测。
7. 投资自动化测试。
单元测试和集成测试覆盖率是管理一个大的代码库与一大群人没有不断被破坏构建或产品的唯一可扩展的方式。自动化测试提供了对提高代码质量的大规 模重构的信心和也进行有意义的保护。缺乏严格的自动化测试,需要手动测试无论是对工程团队或外包测试团队,是容易令人害怕的,很容易陷入恐惧改善代码的文 化,只是因为它有可能破坏以前的。
在实践中,自动化测试是对持续部署工作团队成长的要求。代码库规模随着时间的推移增长,但熟悉的代码库多少会随团队成员新人加入而减少。测试和 验证是最容易被原代码作者完成,因为在他们脑子里还是清晰的,而不是被稍后几个月或几年尝试修改代码的人。鼓励单元测试是让作者为自己工作责任。
8. 分配 20% 的时间。
Gmail 是保罗 · 布赫海特的 20% 的项目,第一个版本在一天搞定。 谷歌新闻,谷歌公交,和谷歌建议也是推出的 20% 的项目。我用 20% 的时间,而在谷歌写一个 Python 框架,使得它更容易建立搜索页面演示。而谷歌的 20% 的时间在创业初期可能降低生产力,让工程师们花 20% 的时间做某件事情而不是他们的产品规划上,仍然是小型工程组织的创新摇篮。
Ooyala 公司没有正式 20% 的时间,我们花了一些时间写了一个命令行构建工具 Flex 和 ActionScript,加快了团队构建时间。正当 Adobe 的 Flex Builder 工具降级时候我完成了它,在工程团队超过两倍大小时该工具仍然在使用。 Atlassian 公司在尝试一年后通过 20% 的时间。非死book 后来又增加了一个 20% 时间的变化是周期性的黑客比赛 - 一晚上的事件,规则是,你可以做任何东西,除了你的正常项目的工作。
自上而下的方法对产品的规划,对公司的总体方向是重要的,不能指望从工程师中冒出很多的想法。只要工程师对他们 20% 的时间和专注于什么可以有很大影响的负责,这些项目可能会导致很大的向前发展。没有官方的 20% 的时间,它仍然是可能的,对工程师和设计师可能更难去尝试疯狂的想法 - 基本上都找周末或假期做。
9. 建立学习和持续改进的文化。
学习和得到充分得到挑战是心理学教授米哈里 · 米哈伊称之为 “流”,一个人是如此的完全集中在他们做的事情,他们甚至忘了时间。 直接即时的反馈能够适应更快的迭代周期。
每周技术会议给工程师分享他们的设计或者正工作的项目,创造了一个机会,工程师们为他们工作感到自豪,并学到更多工作以外的范畴。内部文档记录电子邮件服务的工作原理或如何让排名改变搜索服务,让工程师学习和探索新的东西,也很好地补充了 20% 的时间。
建设学习文化的一个办法是注重指导和培训,以确保每个人都掌握基本的算法,系统和产品成功所必需的技能。工程组织的成长,花在招聘(尤其是高校 招聘)越多,更多的努力需要投入到指导和培训。一个导师每天花一个小时为一个新员工的前 4 周工作上似乎是很大负担,但投资是总时间的新员工将在一年内花费不到 1%,并能帮助到此人是否真正成功。
10. 招最好的人。
雇佣最好的人是许多其他列出的基础。如果你认为自己是一个 B 级工程师很难有人尊重。如果你不信任他们开发产品能力,很难给别人自主权去开发产品。如果没有足够的工程经验,很难识别正确的抽象去构建系统。这很容易陷 入构建复杂结构的陷阱,又没有其他聪明人来挑战你的想法和推动你走向简单正确的道路。
在硅谷的史蒂夫 · 乔布斯说,“A 等人聘请 A 等队员。 B 等人聘请 C 等人。“关注招聘和雇佣合适的人很难,但这对工程组织有效增长很关键。黄易山,是前 非死book 一个工程经理和总监,认为招聘必须是工程组织的首要任务,不只是管理者,工程师也如此。 他也正确地指出 “雇佣最好的” 和 “雇用你面试过的最佳人选” 的区别
在初期,我们在客户工作上不堪重负,我们很想降低我们的招聘门槛,这样我们可以聘请足够的人来做大量工作。我很高兴我们没有,因为低质量的代码和较弱的工程师团队积累技术债对团队和产品的伤害是很大的。
建立一个良好的工程文化无疑是一个大量的工作,但由此产生的工作环境是值得的。