8

有些工程原则是创业团队必需践行的!

 3 years ago
source link: https://blog.dteam.top/posts/2017-04/%E6%9C%89%E4%BA%9B%E5%B7%A5%E7%A8%8B%E5%8E%9F%E5%88%99%E6%98%AF%E5%88%9B%E4%B8%9A%E5%9B%A2%E9%98%9F%E5%BF%85%E9%9C%80%E8%B7%B5%E8%A1%8C%E7%9A%84.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

创业是苦差事,并且风险极高,在这样的条件下,如果还不依据一定的工程原则做事,无异于在黑暗中走钢丝。

虽然哥创业时间不长,且目前尚无过人业绩,但文中所列工程原则却也来自一线实战,如今写出来,既是个人总结,也是经验分享,算得上对这些年奋战的交代。

原则 1:不折腾

如今,创业的技术门槛要比以前低很多。随着开源精神的深入人心,目前的绝大多数技术问题都有相应的开源解决方案,而且质量不低。因此,作为技术队伍,主要目的就是能够善用这些工具,快速给出业务解决方案,赢得市场和客户。

然而,话虽如此,选择适合团队的技术工具栈却并非那么简单。有人可能会说“跟着大家一起走就好了”,可问题的关键在于,适合大家的技术和工具是否就一定适合你呢?况且,目前各大巨头的技术营销能力都不差,在这样的情况下,这道选择题就没有那么容易了。

就我个人的原则来讲,技术选择的最高要义就是:不折腾。选择必需结合团队本身的特点和工具本身的成熟度,尽量不要将宝贵的时间浪费在对于这些工具的折腾上。

案例:为何我选择 Angular 2 作为团队的前端基础?

目前,前端工具的当红炸子鸡当非 React 和 Vue 莫属。当初,我曾考虑过是否在团队中引入 React,但经过一番考察和思索之后,我毫不犹豫弃之转而拥抱 Angular 2。令我做出如此决定的原因主要基于如下考虑:

  • Angular 2 是一个整体的工程解决方案,从开发、测试、打包和部署,都提供了工具支持。尤其是 Angular CLI,对于简化开发起到了巨大的作用。相比而言,React 仅解决了 V 的问题。
  • 团队内部移动端的技术选型为Ionic 2,它恰恰使用了 Angular 2 作为开发基础。相比起 React Native,它更成熟。
  • AngularJS 1 的若干问题已经在 Angular 2 中解决,这样一来,React 显现出的优势并不大。而且,相比起 React 的使用,个人认为 Angular 2 更容易让团队成员上手。

注意,这里并非说 React 不好,而是觉得相比起 Angular 2 而言,使用 React 会让团队更折腾,这不是我期望看到的。至于个人是否玩 React/Vue,我并不关心,甚至是鼓励。

原则 2:守规矩

我曾经看到过这样一句话:“以敏捷的名义裸奔”。这句话非常贴切,而且在创业团队里类似的事情并不少见,只不过“敏捷”两字被“时间紧”替代而已。

正如有些钱是省不掉的,有些做事的原则必需遵守,否则崩溃是高概率事件。个人认为,流程再如何简化,对于开发而言,至少有三件事省不掉:

  • 问题跟踪,不论新需求还是错误,都需要用 issue tracking system 管起来,这样起码能做到对于项目当前的工作量一目了然,它也是计划的基础。
  • 版本控制,这个的重要性就不必再强调了,如果连这个系统都没有,那根本算不上是一支合格的开发队伍。在此之下,采用何种工作流程和分支模型,其实并无定论,采用适合自己的方式就好了。
  • 持续集成,它是区别“乌合之众”和“正规军”的基本标志,这句话说得虽然武断,但大致不会错。CI 系统难以实施的关键点在于缺乏自动化测试,单纯地验证编译通过,价值其实并不大。

然而,遗憾的是,当我向面试者问起有关这三件事的问题时,能清晰明白回答的人寥寥无几。或许这也跟面试者的群体有关:由于目前公司名气不大,愿意来公司面试的人员本身素质大多都不咋地。

案例:我们目前的工程管理工具集

目前,我们的开发流程基本按照 SCRUM 来走,开发中所有的内容都会落实到以上的三个系统中:

  • 问题跟踪:Redmine
  • 版本控制:Gitlab
    • 只从主库编译打包。
    • 团队各自提交代码到各自的开发库之后,再向主库发起 merge request,由负责人 review 代码并合并(没错,负责人必需有开发技能)。
    • 开发者严格遵循 branch per feature。
    • 每次发布之后,负责人会打 tag。
  • 持续集成:Jenkins
    • 代码需要有自动化测试。
    • 每次 MR 会触发测试运行。
    • 建立了发布流水线,构建成功之后,发邮件给相关人员,人工确认部署。

对于自动化测试代码,我们并不严格遵循 TDD 方式,只是规定需要有,但不关心它是先于产品代码写的,还是事后写的。就现阶段而言,我不关心。并且,目前并不强调测试覆盖率,优先核心代码的自动化测试,要求发现错误之后,尽量用测试复现之后,再修改代码让测试通过。

测试并不仅限于单元测试,关键场景的压力测试和功能测试也是要求的。就测试而言,我们的工具集:

  • 单元测试和集成测试:Spock + Jasmine
  • 压力测试:Gatling + 自行开发(压测设备接入量,需要实现设备的接入协议,基于Vert.x
  • 功能测试:Geb + Phantomjs

原则 3:不教条

《孙子兵法》指出:“凡战者,以正合,以奇胜”,这恰恰点明了不教条的重要性。个人以为,这一原则在创业团队身上体现在几个方面:

开发岗位的设置

人力永远是创业团队的稀缺资源,如果不管三七二十一照搬大公司的细致分工,不仅造成运营成本的增加,同时也会因为增加了沟通成本而让“船小好调头”的优势丧失殆尽。

“兵贵精而不在多”,这是小公司克敌制胜的基础,与其照搬繁杂的岗位设置,不如好好找到几个具有高成长性的弟兄,以简单粗暴的方式尽快让产品上线面市,然后想办法边把船造大边修船。至于如何招兵买马,那是另一个话题了,不在本文讨论之列。

开发流程的制定

讲到开发流程,家家都有本难念的经。不论大小公司,似乎在此上面都有说不完的话。既然如此,还何必照搬呢?流程是为事情服务,同时要兼顾团队成员的能力。如果制定流程只是为了让开发显得“正规”,那这样的流程不要也罢!

就小团队来讲,流程宜简不宜繁,将关键的环节卡住,其他放手让队员去干即可。待问题发现时,再思考是否可以通过改善流程来避免和优化也不晚。通过这种方式形成的流程也更容易让人接受,深入人心,也方便老队员对于新进队员的解释。流程这种东西,总得有拥护者才能真正的实行下去,否则就只剩下一层皮,实在没有什么意思。

产品架构的设计

这一点是最容易让人迷失的地方。由于创业者的野望,总是幻想要为海量用户服务,自然那些出自巨头、自带光环的产品架构很容易会落入他们的眼帘。但遗憾的是,这种架构其实并非总是像技术营销中说的那么完美,实做起来对于开发、运维和部署环境都有不低的要求。贸然进入,很容易就陷进去,想退也退不出来。

创业初期,最重要的目的在于验证业务的合理性,找到买单人。这期间,对产品技术上的要求是能够快速迭代、快速发布,而非应对海量用户请求。只有证明业务方向正确,用户访问不断增加之后,大型分布式网站的需求才会浮现。否则,要是一开始就按大型网站的思路去做事,绝对会贻误战机!套句风水上的一段话:“人少屋大,主凶”。

案例:我们在这三方面的做法

相比起来,我们的工种设计要简单很多:Web 开发、移动开发、网络开发和运维:

  • 在我们这,Web 开发必需自己写前端代码,尽管我们也采用前后端分离,但是并没有严格地区分前端开发工程师和后端开发工程师。也正是出于这样的原因,一开始我就会尽量寻找能够降低开发难度的工具:
  • 按照同样的原则,我们的移动开发并不区分 iOS 和 Android,而是统一采用 ionic 2 来搞定。采用这样的思路还有一个原因在于,我们的业务对于移动端的性能并不要多 NB,普通的混合开发方式就够了。当 H5 无法解决时,只需写一个 Native 插件搞定即可。这种模式跟多年前的“VB【做 UI】+VC【做控件】”开发模式没有本质区别。
  • 网络开发和运维目前属于合体,因为有不少重叠的知识点,同时也因为初创期间没有那么多运维任务,在将必要的运维任务自动化之后,有大把空余时间。同时,网络开发更偏技术底层,变化的频率并没有那么高。所以这样看来,两者的结合简直是天作之合。

至于其他,如 DBA,也主要由经验丰富的老同志和运维兼任,同时通过其他方式降低运维成本:如开发均遵循 DBMigration,定期执行典型场景的压力测试,倒逼开发优化查询。

换句话讲,在我们这:“一专多能”是常态。

而开发流程,则基本按照 SCRUM,但没有设置那么多的流程角色,基本就是几个关键实践:计划、每日立会、演示和回顾。同时结合自动化测试、Code Review 和 CI。

讲到产品架构,虽然未来已确定要走微服务之路,但就目前而言,其实业务层代码也就是简单而普通的单体应用,只是为了在未来拆分成服务方便,事先分好了包。

此外,在前端页面和后端服务之间引入了自研的dgate,起到基本的解耦和熔断目的,其他的则通过前置的 NGINX 去搞定。

只有设备接入层才真正实现了微服务的雏形,初步具备了水平扩展的能力。

原则 4:重实利

如果一支创业队伍重虚名而轻实利,那失败是必然的。所谓重实利,最直接的表现就是要考虑投入产出比。看到这里,可能不少看官觉得这是一句能把耳朵磨出老茧的“废话”。可问题是,你真的会从投入产出比的方面思考吗?

在我看来,只是简单地从输入和输出角度思考并不够。一个合格的重实利创业者应该按照这样的顺序来考虑问题:

  1. 哪种产出对于业务发展是最关键的?
  2. 从投入到那个已确定的产出,有哪些关键环节?
  3. 为了打通这些关键环节,需要有哪些投入,并且哪些投入是必不可少的?
  4. 在众多可能性中寻求最佳组合?

由此看出,这并非是一个简单的求最大最小问题,而是先确定方向,再寻求优化的做事方式。否则,只是按照“做这个很快,做那个要费些时间”的思路来做事并没有什么益处。记住,将你的宝贵资源(包括人力、资金、时间等等)投入到对业务起到推动作用的事情上。有时候,捷径往往比大路要难走得多,但它能很快达到目标。

案例:我们的设备数据采集器和商城

说到硬件采集器,其实并没有什么技术含量,基本的实现都是一个简单的透传模块。但如果要满足下面几个约束条件就没有那么容易了:

  • 用户透明性,即用户可以很快在现场安装调试完成
  • 设备透明性,即一款硬件、一套代码可以满足市面上大多数机器
  • 位置透明性,开发人员不必在现场就能协助安装

以上 3 点恰恰是我们的设备数据采集器的优势所在,不仅极大降低的运营成本,并且也拥有良好的用户体验。同时也是让竞争对手百思不得其解的地方!

这种设计恰恰是重实利的表现,在关键地方,不能省功。如果当初只是单纯的按投入去考虑,绝对不会有这样的设计。

最后,简单提一下我们商城上线的过程。

一般来讲,商城肯定会分前台业务和后台业务,虽然技术含量一般,但每一块的业务都不会太简单。那么,如果按照一般思路,将前后台业务都完成之后再上线,那么时间会拉的比较长。

而按照事务的一般规律,业务总是从简单到复杂。上线伊始,复杂的后台业务并不会太多,结合一定的人力和自动化工具就能支撑,比如商品上架。那么这个时候,其实将火力集中在前台业务,使之相对完善,即能很快上线,使自家囤积的商品开卖,快速转化成为现金流。

基于这样的考虑,第一版本的商城上线时,我们只实现了前台业务,后台业务通过直接与 DB 交互手工完成。随着业务运营的不断深入,后台业务逐渐上线,替代人工。这种方式有一个很形象的比喻:

  1. 当资金有限时,先摆个地摊,将仓库的货先卖起来。
  2. 随着货品的变现,手头有了多余的资金,地摊升级为小卖部。
  3. 在小卖部开卖的同时,它的身后在造一间百货大楼。

如此渐进的方式,不仅让运营和开发可以同时进行,而且也缩短了上线时间,方便快速试错和调整方向。

当然,还有看官可能会说:这样会造成一些重复的开发任务。但在我看来,这种重复是可以接受的,而且是一种健康的、螺旋上升的重复开发。相比起一开始天真地本着一劳永逸的方式去开发某个功能,这种方式更可控,而且更能让开发队伍体会到成功的快感。

并且,我还想问:你怎么能够断定你那所谓的伟光正设计就一定适应未来呢?进化和改变才是这个世界的常态吧?!

原则 5:常总结

我总是对开发队伍说的一句话是:你去观察那些学习好的同学,他都有一个特点,那就是总结。的确,如果不总结,也就不会有那些公式定理,就连 1 到 100 的求和估计都要算半天。

复盘和总结是为了避免将来犯类似的错误,同时将好的经验能够发扬光大。但,如果这些不能得到固化,那效果必然会打折。所谓固化就体现在以下几处:

  • 工作流程,流程必需要定期翻新,否则必然人浮于事,最终徒留形式。同时,流程和当前团队的自动化水平息息相关,最好尽可能地自动化。
  • 工作代码,将错误解决之道和经验固化成为代码的最大好处就是节约时间,同时锻炼了队伍。它的作用跟数学公式其实是相似的。

同时,为了让队伍养成总结习惯,而不是机械地在每个 SCRUM 回顾会上才“用心”总结,必要的强制手段是需要的。比如,鼓励队员分享和写文章。

案例:DTeam 团队日志诞生记

DTeam 团队日志是我创建的团队日志,它的目的就两点:

  • 技术营销,方便外界了解我们的队伍。我相信每个有进取心的开发都会希望进入一个有技术氛围的团队,团队日志恰恰非常擅长充当团队的技术窗口。当然,单纯仅靠技术是无法吸引人才的。关于如何招人,未来有机会再谈。
  • 强制总结,通过邀稿的方式,逼着队员自我进行总结,养成自我总结的习惯。因为在审稿的同时,我会顺带指出一些思考上的问题,引导他们如何进行自我思考。

原则 6:志高远

前面说了那么多原则,其基本立意就是“现实”。到了最后这一条,必须谈谈“理想”。一支没有理想的队伍走不远,一名没有理想的大哥也不配被追随。

作为团队的大哥,一定要记住:当前的选择都是权宜之计,为了应对未来的风雨,眼下就应该开始着手准备。他必须是一个不安分的人,原则 1 的“不折腾”是针对于团队而言,即不要折腾团队。但他必须自己折腾自己,把大部分坑自己都踩过了,再去考虑团队内部是否推广的问题。

说得通俗点:让团队做眼前的事,作为大哥,他需要做好未来的安排。不论这个事情是他亲自做,还是别人做,都必须有人做。说着说着好像有点像“预研部”了,;)

案例:我是如何为团队做技术储备的?

其实,作为互联网创业的后进,为未来做技术储备和选型其实并没有什么困难的。因为只要按着前人走过的道路走,然后结合自身的特点就好了。你会发现,大家走的路其实都差不多。

通过查阅和了解成功互联网公司的架构演进,可以很容易总结出架构发展的几个阶段,而且你会发现大家的架构也都差不多,只是在实现方式上不同而已。问题的关键在于确定合适的引入时机。它由几个条件决定:

  • 首先,最重要的就是业务的发展水平。
  • 其次,就是团队是否为这种演进做好了技术准备。
  • 最后,确定目标之后的行动步骤。

第一点靠系统监测的各项指标可以很容易的掌握;第二点就在于提前的技术布局和相关的技术培训;至于最后一点,就是所谓的项目实做了,并不困难。

这篇文章缘起于最近的一次回杭之旅:

  • 与原杭州公司同事聚会时,提到新旧公司的差异。原话是:“原来还没有觉得咱们公司技术挺牛的,现在到了新公司,感觉差别一下体现出来了。”
  • 参加了久违的 EGO 小组交流会,会上就某个话题展开,进行了短暂的创业公司的工程实践讨论。

其实,我想说的是:以上原则都是一支正规队伍的基本做事原则,如果连这些都做不到,那真是无话可说了。换句话讲,不是我们太强,而是对方太弱。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK