如何建立一个好的工程师文化,对任何一个技术团队都是一个挑战。在我困惑的时候,很有幸看到了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代码审核,在他们提交代码前数小时。