从鹅厂出来之后的这几年,在创业公司做了很多产品技术方面的实践工作,得到一些关于产品技术管理方面的心得,这部分比实际完成一些什么样的系统设计和开发更加宝贵,这是有钱都买不来的。后面一段时间,我尽量将这些心得以博客文章的形式写出来。 之前尝试过大而全和分章节的描述手法,在废弃了十版左右的草稿之后,决定还是用随笔的手法吧,划定一个小范围,想到哪儿写到哪儿,不拘一格。大而全格局太大,自己荒废了很长时间没写文章,把控不住;章节形式专业性太强,没做好写论文的准备,就不拿一些带主观心得的东西贻笑大方了。

相较于我刚开始学互联网编程的那段时间,也就是二十一世纪初的那几年,现在的互联网盈利模式更加清晰,业务和产品趋于红海竞争,值得去尝试的蓝海领域越来越少。带来的一个好处是:产品技术方面能够复用的东西越来越多。

举个现实中的例子。因为花椒、映客等等关系,最近遇到一些朋友想要做直播平台,要我给他们建议。我大致估了一下,质量上以产品原型计,大约有百分之八十以上的组件,包括比较难的 P2P、DHT、CDN、视频实时压缩等都有成熟的第三方解决方案,只有涉及到所谓『痛点』的大约百分之十几的那部分逻辑需要自己去做。这些成熟的第三方解决方案不管是开源软件也好,还是云服务的方式也罢,都能避免创业者重复造轮子,大幅降低开发维护成本,还能提高用户体验。

然而更厉害,就算是差异化的那百分之十几的逻辑,我们现在也可以利用工程化的手段让它们的产出更加高效更加顺畅。

最近一年我在创业公司积极推进一件事情,就是把初级工程师的成果有效化。出发点是帮助公司降低对工程师水平的依赖,用技术手段提高工程师的工作效率,提高输出成果的有效性。这事儿说透了也很好理解:既然创业公司的项目需求更多是原型实现,并且还有那么多可靠的第三方资源可用,技术团队也就更像是在做集成,而不是技术创新,对工程师的初始能力要求不应该特别高。当然,公司肯定也会同意,因为省钱嘛。o(╯□╰)o

创业公司对初级工程师倒不一定有什么特别的偏好,不过创业公司的 boss 们大多对技术人才无法做到『准确识人』,这是事实。有时候哪怕他们自己想找一些大牛合作,也苦于无法辨别。就算找到真正的牛人,在工作方式方法上通常也会出问题,至少是让其能量发挥不出来。所以干脆的,很多创业公司 boss 与其花冤枉钱碰运气找大牛,不如直接找初级工程师先实现原型好了。很无奈,也是事实。既然是事实,我们首先得尊重它,而不是抱怨,然后才能往后考虑,怎么样改进。

当然,先解释下:依靠初级工程师实现的原型在技术上是不是能够拥有可扩展性,今后是不是可以生长和健壮起来,是个问题。考虑到这是架构师在开工之前需要完成的设计工作来决定的,不可能指望初级工程师去完成,所以这点不在我们今天的讨论范围之内。所以首先,假设我们有一位有能力有担当并且对项目理解深刻的架构师吧。

话说初级工程师的工作一般都不可靠,特别在他们工作拥有自由度的时候,自由度越高则可靠性越差。要提高初级工程师的工作有效性,首先考虑的是怎么『约束』他们,降低他们可以自由发挥的空间。这个思路跟现在流行的互联网『颠覆』的观点可能会有点相冲——你把空间限定死了再做事,还谈什么互联网颠覆呢。不过我认为,就现实中的中小公司创业环境,技术上的创新总是局部的,否则研发成本太高,就是作死,运营和产品上的创新才是具有颠覆性的关键。

通常我给初级工程师『画地为牢』限定他们工作空间的办法有下面几种。

  1. **必须全程参与需求评审,独立完成功能设计文档。**会议和文档化是让很多工程师头痛的两件事情,但是在任何团队中,首先要保证的大家目标一致,花点精力在统一目标上,经验告诉我们,绝对值。
  2. **统一的代码风格和注释要求。**每种语言都有好多种代码书写风格,团队统一采用一种就好,这没什么可争辩。至于注释,最好也要统一一下要求,以便工程师可以在代码中合理添加注释。代码风格可以通过 lint 来检验,而注释则只能通过代码审核的过程,人工指正。
  3. **代码审核后才能合并到开发分支。**一方面是代码的质量控制,确保代码仓库里面的代码都是有效代码;另外一方面,代码审核恐怕是帮助这些初级工程师成长最快的方式。一个好的 reviewer 胜过任何职业培训学校里面的任何授课老师。
  4. **一个严厉的非黑即白的框架。**我不会浪费时间跟初级工程师在技术方案的可行性上做探讨——你当然这样做也能实现功能那样做也能实现功能,但你就是得按照我说的做。整个团队都是这样。没得商量。而保证这一点的最佳手段,就是用一个非常严厉、越雷池半步就报错的框架。
  5. **统一的开发环境和部署环境。**同样,我也不会在这方面跟工程师们有太多商量的余地,必须统一。部署环境由于涉及到运维的配合,与用框架不同一样,从一开始就必须大家都统一。不同的是,开发环境这方面我通常会给工程师们一个过渡期,过渡期内我会推荐我认为效率最高的系统、IDE 甚至 IDE 配置文件,并且提供支持。通常来说,一到三个月的过渡期之内,就能把这事儿统一下来。
  6. **保持一致的沟通腔调。**技术上,各种专有名词和特定的描述方式很多,沟通中大量使用专有名词虽然有时候看起来很装逼,但这样的确可以大大提高沟通效率。对初级工程师,以及我们的产品经理同学,通过在文档、会议中不断加以引导的方式,来强化他们对一些常用名词和描述方式的概念,让他们既能懂也能用,从而提高整个团队的沟通效率。

这样执行之后,做执行的工程师基本上不再可能有什么自助发挥的余地,就像谷歌技术团队的风格:一千人写的代码,读起来就好像是一个人写的。无论是代码和注释的书写风格,功能实现的方式,都是一致的。这样的代码就算放个两三年换个人来维护,也没有障碍。

另外一方面,想要提高工程师效率通常意味着激发个人的积极性,释放他们的工作热情,同时帮助他们扫清工作之外的障碍。从字面上理解,这和上面限定他们的空间相左。说细了,不矛盾。

  1. **统一的开发环境、沟通腔调,降低沟通中的障碍。**在拥抱变化的场景下,沟通随时随地都在发生,如果不能把沟通过程做顺畅,尽力消除沟通中的阻碍,工作效率自然没法儿提高。初级工程师最容易遇到的问题就是遇到问题表达不清晰,想帮助他也无从下手。统一开发环境、沟通腔调,团队成员基于一个场景在沟通,效率自然就提高了。
  2. **把开发流程中重复的步骤工具化。**例如:分情况 pull 代码;根据事件和关键词创建新分支;检测代码风格;部署代码到线上之前跑单元测试;部署代码到线上服务器;排查应用日志…… 如果每次手动做这些事情,势必影响编码的连贯性,把它们做成工具,每次运行一两条命令就可以完成一件事情,不仅可以提升工作效率,还可以提高试错的次数,小步快跑、敏捷迭代。
  3. **研发生命周期的管理从头到尾要做好,对工程师尽量友好。**工程师只有一个工作是有效的,就是编码,其余的工作都是辅助,不能直接产出价值。所以,工程师越能专注地编码,生产效率越高。除需求评审和写文档之外的必要开销,确保工程师大部分工作能够在两到三个界面完成,是最优的结果。这就需要团队能有一套很好的研发管理系统,不是松散的几个第三方工具,而是一个有机的整体,涵盖整个研发生命周期。听起来很高大上,可喜的是,对创业公司也有第三方的选择,只不过需要自己做集成。
  4. **生产环境要有带检索的日志系统和调试工具。**这个就不说了,也可以看做是从第二点中延伸出来的。单独提是因为,线上排错不知道坑了多少工程师的时间,熬夜加班,专门等午夜人少时重现错误,说多了都是泪。浪费的时间不是一点半点。

能帮工程师把编码之外的工作梳理清楚,减少他们被干扰的次数和时长,对于提高生产效率,规避编码中的 bug 效果很好。虽然上面几点在创业公司里面实施起来有些难度,但做总好过不做。况且,其中一部分已经有第三方成熟的解决方案,具体实施的时候只需要做集成即可。

在是给与工程师一个明确的施为空间,帮他们扫清编码障碍之后,技术团队在执行阶段的高效率,维护阶段的清爽,都是可以预料到的。这些准备工作虽然表面看不到有什么明显收益,但是对于公司在中期对外连续作战帮助非常之大。

附录一:推荐的几个第三方工具和服务

  • 代码仓库:gitlab。同时基于 gitlab 的 web service hook,还可以扩展出涵盖大半段研发生命周期的系统,以此完成工具化的搭建。
  • 需求管理:tower。这个纯粹是个人习惯,其实 worktile、trello、teambition 等等都不错。tower 虽然也有 api,可以做信息流集成,但貌似只限于收费的 Pro 版。
  • OS + IDE:Linux + vim。作为后端码农,这是不二选择。在这个前端要会用 linux 的时代,不会 linux 不能作为理由,只能是工程师自己的耻辱。前端码农根据项目不同,酌情选择更优的 IDE,例如 xcode(iOS APP)、atom(React)、Android Studio(Android APP)等。
  • 后端开发框架:Laravel(PHP)。作为一款大量应用现代语言特性的开发框架,laravel 的缺点也是它的优点:太多的新特性,让初级工程师困在它规划好的地盘里,只能照做。