编者按:本文系 InfoQ 中文站向陈天的约稿,在硅谷的日子里,陈天常参加一些 meetup 和聚会,这些活动有时会有工程师介绍他们团队的文化和处世之道;平时他也会经常看各种有关创业团队文化的文章 / 视频,来充实自己的管理思想。这是「创业及管理」系列文章的第一篇。以后会有更多文章刊出,但并无前后依赖的关系,每篇都自成一体。
写在前面:创新是需要不断摸索的,一个公司的文化越有利于员工的探索,就会越有利于创新。敏捷(Agile),如今是个让每个科技公司恨不得天天挂在嘴边的词语。然而,很多公司搞敏捷,只不过是在流程上引入了一些敏捷的实践,却未曾从工作环境和文化上注入敏捷的原力。本文介绍 experiment-friendly 的公司文化的意义,以及如何实施这样的公司文化。
正文:
敏捷(Agile),如今是个让每个科技公司恨不得天天挂在嘴边的词语。在这个 CMM (Capability Maturity Model) 已褪去光环,敏捷大行其道的时代,如果一家科技公司不搞些敏捷的实践,仿佛就成了旧时代的破落户一般。然而,很多公司搞敏捷,只不过是在流程上引入了一些敏捷的实践,却未曾从工作环境和文化上注入敏捷的原力。我见过有公司从 waterfall 转向 scrum,培养了 scrum master,培训了员工,投资了各种新生工具,daily standup 做得有声有色,甚至真的通过 planning poker 的方式过家家般来做软件工程里面最难搞定的决策:estimation。
可是,工程文化层面上的反敏捷,导致这一切徒劳无功,敏捷的实施往往就这样虎头蛇尾、无疾而终了。
公司文化的反敏捷
那么,究竟什么是公司文化层面的敏捷呢?我认为是以一个对团队而言最合适的迭代速度持续地探索、学习和改进。其实很多敏捷的实践都是围绕着这个目标而努力的,只是使用者在使用的过程中迷失了方向,比如说每日例(晨)会。本文从探索这个主题讲起,讨论我们该如何构建一个友好的工作环境,让工程师能够最大可能地不断摸索,解决各种各样的工程问题。
有人看到这里会不禁莞尔:作为工程师,我们工作的目的就是不断摸索出解决各种问题的方案,难道真会有公司愚蠢到压制工程师的探索欲望么?
我们先看一些反例:
- 改两行代码,却要花费几十分钟编译链接。
- 测试一个新想法(新功能),没有 sandbox 或模拟器,只能在实体硬件上完成(想象一下 iPhone 开发没有模拟器,每次都要将编译好的 ipa 安装到手机上)。
- 修复了一个 bug,只有几十行代码,code review 却要花上数周和无尽的催促才能被 approve。
- 做好了一个 feature,半年后甚至更久才能跟客户(用户)见面。
- 使用了某开源 MIT 协议的第三方库或者某个新的技术(如 AWS lambda)做了个 feature,虽然解决方案大大简化,却被告知我们不希望引入更多的依赖,徒增加团队学习的负担。
- 辛辛苦苦做出来的成果,demo 时得到的都是负面的评价(而非建设性的意见,更别说赞许)。
- 想尝试 AWS 上的某个新的功能,却因为权限不足被阻挡在门外(申请权限又需要一个极其漫长的审批流程)。
- 手工部署上线一份新的代码,出了纰漏,造成了无法挽回的损失和影响,于是,当事的「实习生」被裁。
- 公司把你禁锢在某个工作岗位上,于此不相关的非机密项目的技术讨论不希望你参加(美其名曰不浪费你的时间),甚至,文档代码连读都读不到。
这些例子都是真实的例子,想必很多读者,尤其在各种大公司打工的读者,也都会遭遇到类似的场景。它们就像某种慢性的毒药,一点点把员工的激情和探索欲望消磨殆尽,而这些消逝的激情和欲望,纵使用豪华的办公环境、米其林大厨精心烹饪的午餐,也很难挽回。
我们看上述例子,有些是在工程上有解的问题,比如 1,2,8;有些是流程上有解的问题,比如 3,4,7;还有一些是文化上需要改变才能得到改观的问题,比如 5,6,9。然而,工程上有解而不去解决,流程上有解却没能解决,归根结底还是公司文化层面的问题。公司在文化上不重视打造利于探索的工作环境(experiment-friendly environment),反映在日常的工作中,便是掣肘丛生,前进三步却要付出倒退两步的代价。就好比在玩三国杀,满腔热血的忠臣,拿着一副好手牌,意图大展拳脚,忠君报国,绞杀反贼,却不料前有主公冷嘲热讽,后有小内暗箭伤人,只能堪堪自保。
讲了这么些反例,想必大家对 experiment-friendly 有一个更好的理解了。公司需要为员工的高效产出扫清组织上,流程上,沟通上和工具上的障碍,让工作变得更有成就感,让探索和创新随时随处可达。
这事说起来容易做起来难,每个公司都有各自不同的「国情」,很难找到一种“放之四海而皆准”的文化。我们可以学习一些公认的敏捷的公司,如 Facebook,但很难将其文化直接照搬。依我看,如果做好下面的一些事情,那么,公司文化会离 experiment-friendly 更近一步。
敏捷文化之工具流
我们先说工具。工具上的问题是最容易看到收获的,效果也比较好量化。比如说引入各种自动化工具。凡是有过软件项目经历的人都知道 —— 任何严丝合缝的流程,其中最薄弱的一环肯定是人。对于重复性的机械劳动,人是最容易犯错的。这时候要尽可能地把流程工具化。比如说:
- git commit 时设置 commit hook 对代码做 lint 和 static analysis。有多少公司的 codereview 把时间和精力浪费在了 code style 这样本可以用工具来完成的事情之上?
- 使用 CI 工具自动化构建。有多少团队在产出 iOS / Android 的版本时还在本地构建?
- 使用更合适的测试工具来测试你的系统。有多少 android app 的开发者还在吭哧吭哧完全依赖手工对各个机型进行 acceptance test,而非借助 AWS device farm,以及 calabash 等测试工具的力量?
- 使用可反复执行的脚本来部署一个软件系统(如 ansible,cloudformation)。有多少 ops 还在纯手工地上线系统,然后惴惴不安地期待没有问题?
当然,并非所有的工具都能取代人工处理,但我们需要尽可能地借助工具的力量,减少重复性地手工劳动。只有如此,才能节省出更多的时间和减少各种愚蠢的问题,从疲于奔命到处救火中解脱出来,把精力集中到其他更值得解决的问题上。
工具的完善不是一蹴而就的,而是在每个研发周期里不断改进的。一开始,很多事情不得不靠手工完成,可同样重复的事情做了几次之后,就该考虑将其工具化。
流程的敏捷之道
前面提到的 codereview 反馈周期长的问题,就是一个典型的流程问题。当团队或者个人处在自顾不暇的地步,哪有功夫去读别人的 diff?于是就放在一边,能拖多久就拖多久。
这样还会形成一个恶性循环:code review 的作者(reviewee)得不到 reviewer 的快速响应,只好减少发送 review 的频次,导致 code review 的代码量变大,进而导致 reviewer 更不愿意在短时间内做出决策。就这样,本来一个个小的 pull request、代码量控制在三五个文件、几十或者顶多几百行代码内、一到几个 reviewers 应该每日完成的 review 工作,最后变成了跨越若干个模块、几十个文件、成千上万行代码、需要几个 team 联合 review 才能完成的工作,这样不拖到好几周才怪!
所以第一步是稍稍减轻每个人的负担,使其每周有 4~5 个小时时间(可根据情况增减)用于 code review。code review 可以分成两个部分:pre-review 和 post-review。对于一个 pull request,在 pass CI 之后(CI 应该做了 lint,static analysis 和 test),reviewee 要求和 reviewer 坐在一起花个 10~30 分钟走读代码,然后当场决定是否允许 merge,这就是 pre-review。pre-review 不花费 reviewer 过多时间,也不过多阻碍 reviewee 后续的工作,还可以能够扫除大部分潜在的问题。
在 pre-review 中,坐在一起(或者通过 google hangout 等视频方式)共同走读代码很重要。很大一部分 code review 的时间花费在 reviewer 领会理解 reviewee 的代码的意图上面,一起走读对双方而言是时间最优的方式。走读还有一个好处是:reviewee 在讲解的过程中自己就能意识到一些错误。不知道大家是否有这样的经历:自己写的代码,自己反复 review 的时候都没有感到有任何问题,但当把这个代码讲给别人听时,即便别人还将懂未懂,尚在斟酌思度,你自己已经发现了各种问题。这是因为自己读时,思维还是撰写时候的思维,而读给别人时,切换到了想方设法让对方理解的思维上,换了个角度,也就更容易发现问题。
post-review 更多地用于从宏观上发现隐患。一周下来,或者一个 sprint 下来,代码积攒了不少,feature 虽说可以正常工作,但难保没有全局的问题。这时候,多个工程师坐在起,花 1~3 小时(可根据情况增减)把这段时间里团队的所有 diff 过一下,查漏补缺既是一种好的事后补救也是一个相互学习的过程。
简言之,pre-review 工作量小,易于快速完成,为后续工作扫清障碍;post-review 虽然工作量很大,但能够查漏补缺,弥补 pre-review 的缺陷,同时还能促进团队内的相互学习。
一个公司没有合适的流程注定只能小打小闹,上不得台面;但如果把流程抠得太死,明明已经不适应工作的需要,还强行使用,只会降低公司的效率。我们知道,流程其实是在不断解决问题的过程中发现的模式(pattern)。当这些模式固化成流程后,下次遇到类似的问题便可以快速处理。这就好比软件中的 fast path 和 slow path 一样。然而,流程不能一成不变,必须随着公司 / 文化 / 人员的变化而变化。上述的 code review 的流程,如果放在一个跨时区的 distributed team 中,就会遇到很多问题。所以,流程一定要随需而变、不断调整,找到对团队而言最合适的点。
同时,我们还需要很聪明地设置流程。比如上述的问题 7(想尝试 AWS 的新功能却权限不足),流程制定者的目的是为了安全性而牺牲了易用性。那么,有什么方式能够兼顾安全性和易用性呢?我们可以使用沙箱(sandbox),把安全等级高的行为和安全等级低的行为区别开来。对于 AWS 而言,multiple accounts + consilidation billing 就是对此最佳的解决之道,公司可以开设不同的 account 对应不同的使用场景,比如说:production, development & backoffice。production 和 backoffice 只授予 devops / IT 高级权限,而 development 可以授予任何工程师高级权限。这样,即兼顾了流程对于安全性的需要,又使得工程师可以在一个安全的沙箱内随意尝试,一石二鸟。
在构建 experiment-friendly 的工作环境的过程中,只要肯扩大眼界,用心思考,工具和流程会是比较容易实施且很好看到效果的方法。
一些思考
最后是文化层面的考虑。也就是对于人的管理,授权和培养。对于本文而言,我觉得三点很重要:
- 信任优于控制(Trust over control)
- 承诺优于服从(Commitment over Compliance)
- 数据优于权威(Data over authority)
拿「数据优于权威」来说,它其实解决这样一个问题:究竟是上级(权威)的个人品味重要,还是真实的、有说服力的数据重要?相信没有人会认为权威比数据重要,然后在实际工作中,往往是「官大一级压死人」,领导的喜恶常常决定了产品的方向。这个只能靠自上而下推行的文化层面的努力来消弭了。
文化是一个很大的主题,且很难找到又具体又放之四海而皆准的经验。在这里就不展开讲了。
感谢魏星对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ , @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群(已满),InfoQ 读者交流群(#2))。
评论