如何建设好的工程师文化

写得非常好,值得细细品味。

英文原文: http://www.quora.com/Software-Engineering/What-makes-a-good-engineering-culture
========================  分割线 ==========================

如何建立一个好的工程师文化,对任何一个技术团队都是一个挑战。很有幸看到了quora上的这篇文章。翻译如下:

What makes a good engineering culture?
我最喜欢的一个面试问题是,在上家公司的工程师文化里,什么是你最喜欢的,什么是你最不喜欢的。

经历了数百个面试之后,这道面试题让我知道了,什么文化是优秀工程师追求的,什么是他们想避开的。我也总结了自己在google,Ooyala,Quora的六年工作经历,提炼出了一些营造好的工程师文化的原则:

1.优化迭代速度
快速迭代能让人鼓足干劲,使人兴奋。在面试中,被问到为什么离开上家公司,工程师最常提到的是基础设施的缺乏和官僚主义阻碍了快速开发和发布,这让他们非常沮丧。

组织良好的快速迭代,意味着工程师和设计师有更大的灵活性和自主权去做一些日常的决策,而不用事事都得请示。我在google的时候,搜索结果上任何的用户可见的改变,甚至是低访问量的实验,都必须在每周的UI review上获得google副总裁Marissa Mayer的许可。无可置疑,这样可让google保护他的搜索品牌,但这这也明显阻碍了创新。优化迭代速度,也意味着有组织的很好的发布产品流程,以便在出现意外时及时回退。

在基础架构方面,快速迭代意味着持续快速的开发;高的测试覆盖率来减少编译和部署时的错误;快速的单元测试;快速的增量编译和重新加载。特别值得一提的是,持续部署,将提交的代码立刻部署到生产环境中。在Quora刚使用这种方式时,我难以适应,我无法打消它带来的风险要大过它带来的益处的念头,尤其是对小team。但人们很乐于这样修改bug,因为所有的代码改变都可以实时的在线上看到。比起一周或是一个月提交一次代码分支来说,这种小的提交窗口更容易定位代码中的错误。

团队智慧,快速的迭代意味着得有一群强有力的leader去协调和驱动团队。一个决策的相关人,需要能有效的做出决定并执行它。借用Bill Walsh(带领49人队三进超级碗的教练)的一句话,有力的领导需要“分派”、“爆发”、“恢复”,这是说,规划一个攻击计划,执行它,然后处理结果。一个被犹豫不决拖累的团队,将会导致个人努力的白费。

2. 无情的推进自动化
Instagram的联合创始人Mike krieger在《Scaling Instagram》的讲座中谈到,“为减少操作负担而优化”是他13个人的团队,在产品扩展到千万用户中,学到的关键一课。可以用用户和工程师的比率,或者产品和工程师的比率,来量化减少操作负担的程度。例如,在facebook,众所周知,每个工程师可以支持1百万用户。

自动化解决方案和可重复脚本任务是非常重要的,因为他们可以把工程师团队的精力解放出来,放在真正的产品上。当服务有故障时可以自动重启,在访问高峰时,服务可以很方便和容易的复制,这些都是在管理复杂的伸缩性问题上,唯一可靠的方式。比起有远见的团队采用自动化方式,短视的团队更容易受到诱惑,用手工方式解决问题。

Etsy的座右铭“量化任何事情,量化每件事情(measure anything, measure everything)”,和他支持的开源监控和图表工具graphite和statsd,都强调了自动化的另一个重要方面——自动化必须被数据和监控驱动。如果没有监控和记录去获取事件,如何发生,为什么出错的话,自动化是非常困难的。由上面的话可以推导一个更好的座右铭“量化任何事情,量化每件事情,自动化所有可以自动化的。”

3. 构造正确的软件抽象
MIT教授Daniel Jackson点破了好的软件抽象的重点:先看好的那些抽象,程序将遵循设计的本质;模块有小而简单的接口;新的功能很容易放进去,而不需要经过额外的重组。再看坏的那些,程序变成了一系列令人不快的惊讶;接口将变得怪异复杂而且笨拙,就像他们是被强塞进接口里一样,一些最简单的改动也会变的异常复杂。

由工程师构造的可伸缩性系统,在google其中的代表是非常聪明的工程师Jeff Dean和 Sanjay Ghemawat构造的万能抽象,如:MapReduce,SSTable,protocol buffers,诸如此类。而在Facebook,工程师做所的横向扩展的工作集中在小一些的核心抽象上,例如Thrift,Scribe,Hive。而Quora 做的Webnode和Livenode是相当容易理解和在此之上开发的。

保持核心抽象简单和通用,能够减少客户化的需求,增加团队的熟悉和精通程度。一些流行的健壮的系统像Memcached,Redis,MongoDB之类,减少了建造自有存储和缓存系统的需求。聚焦团队的注意力在少数几个核心抽象上,要好于分散到很广的面上,这意味着通用组件更加健壮,监控也更加的智能,行为特征更容易被理解,而且测试也会更加全面。所有这些都帮助实现一个更加简单的,能降低操作负担系统。

4. 保持高品质的代码和code reviews
维持高质量的代码能够提升整个开发团队的生产效率。 整洁的代码更容易被理解,更快的在此基础上开发,更可靠的变更,更少的引入bug。一个健康的code review过程使这些成为可能。

建立一个适时的code review过程,无论是预提交(pre-commit)或者是后提交(post-commit),都能在多个方面提升代码质量。知道你的代码会被同行检查,会带来很大的压力,避免写出难以理解的代码,没有测试的代码等等。第二,code review提供了一个很好的机会,可以彼此学习优秀的代码。

如果这个code reviews是很容易被团队中的其他成员访问到的。那么这种review也能带来好处:a)提升了复查代码的责任心。b) 允许团队成员,特别是新成员,模仿好的代码review。加速好的编码风格的传播。

反对意见认为,敏捷团队没有时间做code review;这种想法忽视了垃圾代码堆积,造成技术债的情况。在Ooyala早期创业的日子,为了尽可能多的开发各种功能,我们没有做code review。这样虽然让产品快速推向市场,但是产品代码维护起来变得非常的痛苦,为了剔除这个技术债,我们又花了整整一年时间来重写代码!!

像google这样的大公司,会对所有的代码做提交前代码审查(code review),不过小团队不必如此严格,至少没必要对所有代码都如此严格。Ooyala后来对核心和风险性高的代码,采用了post-commit代码审查。在Quora,我们用Phabricator做代码审核,其中大多数使用post-commit,对不同的模块采用不同的审核标准,对敏感代码,对新工程师,我们也采用per-commit代码审核,在他们提交代码前数小时。

5. 保持一个尊重的工作环境
彼此间的尊重会促进沟通。一个可以挑战任何人观点的地方,一定是一个可以产生好主意的地方。一个容易被攻击的地方,是会抑制反馈的。

在过去的几十年里,头脑风暴(Alex Osborn 在1948年创立)风靡于工作场合,同事们聚集在一起,放弃批评和负面情绪,不用担心被评价,提出各种创造性的想法。充满敬意,推迟评价是头脑风暴的关键。但最近的心理学研究,正在颠覆Osborn的方法,新的研究鼓励在头脑风暴中争论,这样实际上能避免团队思想的僵化,从而产生更有效率的想法。根据这个理论,一个尊重的环境,能够产生更好的主意。

工程的领域一般都很广(系统,机器学习,产品等等),不是每一个人在每一个领域都有相同的经验。实际上一个强有力团队里的每个人都应给在某个领域很强,即使在其他领域可能很弱。一个系统工程师不应该和一个产品工程师放在一起评估,在一个健康的工程师团队里,这是很重要的,尊重彼此的差异,不用单纯用一方的强项去评判另一方。

6. 建立共享代码所有权
没有人对代码的某部分熟悉后,就觉得他应该独自拥有或是维护这段代码。在短期内,某个人成为产品某个部分的专家,在一年或更长的时间里也许会提升效率,但长期来看,这种方式最终会带来伤害。

有组织的共享代码,会带来三个好处。第一,保持公开,能够更好的减低维护者的压力,也能够降低维护者离职,给团队带来的风险。这也让无忧无虑的休假变得不那么困难。我不会忘记,在我独自维护Ooyala 的日志处理系统的时候,有次我在夏威夷穿越,结果不断的收到报警短信的那些日子。

第二、共享所有权,能帮助那些没能参与某个领域的工程师,扩展新鲜视野。而且这样也可以避免工程师有“我必须扎根一个项目”的想法,可以鼓励他们参与多个项目。这个可以帮助保持工作兴趣,增进雇员不断学习和保持动力。长期来看这样也可以降低工程师感到停滞而辞职的风险。

第三,共享代码还有这样一个功能,当有一个战略级的目标需要更快速的完成时,多个团队成员可以云集在一个高优先级的问题上,优先解决它。如果私密化代码,那么责任只能落在一两个人身上。

一个工程师团队容易犯得的错误是:在整个team不大的时候,就把团队分成了若干子团队。子团队会垒砌一堵墙,妨碍共享代码,因为每个人会受到子团队目标的影响。Ooyala在我在的时候,就分了小团队,这使我失去了和另一个团队的人一起工作的机会,对此我非常遗憾。因为那个团队采用了一种敏捷开发方法,他们很关注共享代码所有权,我听说这给工作满意度和工作效率带来了很大的提升。而我热爱Quora的一个重要方面,就是我们强调项目属于整个团队,这让我有机会参与,用户增长,机器学习,监督工具,推荐,分析,站点提速,垃圾判断等项目。

7. 在自动化测试上投资
单元测试加集成测试,是那些大型的,产品相对稳定的团队,仅可用的控制大型代码质量的方法。而对于那些为了提高代码质量进行的大规模的重构,自动化测试可以提供一种可靠的保护。如果缺乏严格的自动化测试,那么用工程师团队自己测试,或者聘用外包团队测试,时间成本都会变得很高。而且这样容易陷入一种害怕通过重构提升代码质量的不良文化。

在实践中,自动化测试伴随着团队的成长,需要不断的开发。代码数量随着的产品的成长在不大增大,但是由于新人的加入,团队成员对代码的熟悉程度却在降低。对工程师对代码还有印象的时候进行测试,比起几个月或几年后再进行测试要容易的多。所以鼓励加强单元测试的文化,能让作者更有责任感,能保证产品质量。

8. 自由支配 20% 的时间
Gmail来自于Paul Buchheit的20%项目,他第一版的开发时间加一起不超过一天。Google News,Google Transit,Google Suggest 也都开始于20%项目。我在google的时候,用20%的时间,写了一个python框架,它能够很容易的搭建一个搜索页面原型。虽然现在google20%时间的效率可能比早期低了,但是这种观念,容许工程师花费20%的工作时间在其他项目上的观念,依然会是小工程师团队创新的摇篮。

Ooyala没有官方的20%时间,至少我在的时候没有,但是我仍然想办法,写了一个命令行Flex和Actionscript编译工具,它能提高团队编译的时间,其实就是一个Adobe&#39s Flex Builder工具的降级版本。虽然现在工程师团队已经增长了三倍,但是这个工具仍然在被使用。Atlassian在尝试了一年以后,正式才用了20%时间。 有个facebook创立的20%时间的变种,Ooyala后期也采用它,是周期性的hackathons,--整夜的干,规则就是你可以干任何事情,除了你的本职项目。

从上到下的指定计划的方式,在关注整个公司的方向的时候是非常必要的,但是不适合管理众多的来自紧贴现实的工程师的创意。只要工程师负责的对待20%的时间,并且专注在那些可能产生重大影响项目上,那么这个过程中可能会产生重大的进步。没有官方认可的20%时间,这些仍然是可能的,但是更加的困难,设计和工程师想去实现那些疯狂的想法,就必须要牺牲周末和假期的时间了。

9. 建立一种持续学习提高的文化
学习和有足够的挑战,是心理学教授Mihaly Csikeszentmihalyi所说的达到“FLOW”所需要的要素,在“flow”里人们关注他们所做的事情,并且被它激励着,甚至都忘记了时间的存在。快速迭代带来的直接反馈循环是达到flow的另一要素。

每周的技术讲座,为工程师提供了一个论坛分享他们的设计,他们的构建,也为工程师提供了一个为自己工作感到自豪的机会,而且这样也能让其他工程师学到他们领域以外的知识。内部(知识管理系统),诸如,email系统如何工作,搜索服务如何排序等,也能鼓励工程师学习和发布他们掌握的知识,以及更好的完成20%的时间。在Quora,我们跑了一个内部的Quora服务来做这个事情,在上面我们提一些产品或开发的相关问题。

建设学习文化的目的,是通过教育和训练,确保每一个人都具备做好工作所需要的“基本算法”、“系统”、“产品”等技能。随着工程师团队的成长,团队会把越多的精力放在招聘上(尤其是校园招聘),那么,就需要更多的在指导和训练上投资。在新雇员到来的头四个星期,导师每天花一个小时来辅导,这可能对导师来说是一个负担,但是,这个只花费了导师一年工作时间的1%的投资,会有显著的杠杆效用,这会决定,新雇员是否会取得成功。

10. 雇佣最好的
雇佣最好的,是实现以上各项的基础。如果你认为你的工程师是B级人物,那么你就很难尊敬每个人。如果你不信任他们在产品上的直觉,那么就很难给每个人以自主权。如果没有充足的经验,就能难正确抽象,构建基础模块。如果没有其他人挑战的方案,驱使你更加简化,你就容易陷入复杂的陷阱。

在硅谷,流传着一句乔布斯创造的一句话“A等角色雇佣A等角色。B等角色雇佣C等角色。”聚焦在招募和雇佣正确的人,是很难,但是对团队的成长是很关键的。黄一山(Yishan Wong)前facebook工程经理和总监,谈到雇人是团队中每个人的第一优先级的工作,不只是对经理而言。他也很好的解释了“雇佣最好的”和“雇佣你面试的人里最好的”之间的差别。

在Ooyala早期,我们被接踵而来的客户需求工作淹没,所以我们不得不降低我们的雇佣标准,以便能雇佣的足够的人手帮我们完成工作。我真的希望,我们没有这么做,这些低质量代码欠下的技术债和team中差劲的工程师最终伤害了team和产品。

营造好的工程师文化是一系列的工作,但是这事非常值得去做的。

猜你喜欢

转载自hot66hot.iteye.com/blog/1736114