开发团队的效率

开发团队的效率

我之前写过一篇叫《加班与效率》的文章,从概念上说了一些我对“效率”的认识,但是那篇文章趋于概念化,对于一些没有经历过这样的环境的同学来说,可能会觉得太抽象了。很早以前就想写一篇更具体一点的,可执行的文章与《加班与效率》这篇文章相辉映,并再把我两年前在杭州QCon上的那个鼓吹工程师文化”的《建一支强大的小团队》(新浪微盘)的观点再加强一下。

但是我遇到了一些思维方式上的麻烦——我讲的总是从我的经历背景出发,没有从其它人的经历背景来讲。这就好像,我在酷壳里说了很多东西(比如:专职的QACode Review很重要编程年龄创业的Rework的……),有好些人觉得是不可能甚至太理想,其实我说的那些东西都是实实在在存在的,也是我所经历过的。于是,不同的经历,不同的环境,不同的眼界,造成了——有些人不理解我说的,而我也不能理解他们所说的。

所以,过去的这段时间我一有机会就找一些人交流并观察一些身边的事情,并去试着跟从和理解那些我不能理解的东西。现在觉得差不多了,所以,写下了这篇文章。(但越是去理解对方,我就越坚持我的观点,所以这篇文章可能还是会出现鸡同鸭讲的情形,无所谓了)

本文不讨论任何业务上的效率问题,只讨论软件开发或是软件工程中的效率问题。虽然产品和业务上的效率问题是根本,但是因为本文不是拉仇恨的,我也不想混在一起谈,所以请原谅我在这里先说开发团队的,以后重新开篇文章专门谈产品和业务的。

我下面会罗列几个非常典型的开发方式——软件开发中的“锁”接力棒式软件开发保姆式软件开发WatchDog软件开发故障驱动式软件开发

软件开发中的“锁”

如果你搞过并发编程,你一定知道什么是“锁”,锁就是用来同步和互斥。我发现有好些开发部门里的各个开发团队间存在很多锁。比如:

  • 技术能力上的锁。有一个项目需要在不同的地方做开发,这些模块用到不同的技术,比如:Java, C/C++, Python,Javascript,但是,这个团队里的每一个开发人员就只懂一门语言,于是,需要配合,需要任务排期,同步互斥锁就很多,于是,一个本来只需要2个人干3周的的工作变成了8个人干两个月。
  • 负责模块上的锁。同理,不同的人负责不同的模块,于是一个项目要动好多模块,那么你就需要把这些模块的人找过来,和上面一样。每个人都有自己的时间安排,人越多,锁越多。于是,一个来来只需要2个人干2两周的事,变成了7、8个人干一个多月。

我上面并非瞎扯,这都是事实。我们可以看到,

  • 时间锁、进度锁。这堆有不同技能或是负责不同模块的开发人员有锁,有锁你就要等,他们有自己的安排,所以,要协作起来,你就需要排期,去同步。而参与的人越多,你的锁就越多。你协调他们的时间就更复杂。
  • 沟通锁、利益锁。而且,最恐怖的事情是,他们之间的沟通成本巨大。他们会花大量的时间在讨论,一个功能是实现在你那边,还是我这边,每个人都有自己的利益和算盘。无形中增加了很多推诿、官僚和政治上的东西。

有时候,我们会觉得分工和分模块是产生效率的前提,但是实际情况并不是这样。我们也可以看到,所谓的“分工”被彻彻底底的滥用了。他们把“分工”当成了永远只干一件事的借口。

【解决方案】

一个程序员应该能够掌握多个语言,也能够负责多个模块甚至不同的职责。如果一个程序员觉得多学习一门语言,多掌握一个模块是件很困难的事,那么这个程序员本质上是不合格的

“接力棒式”软件开发

在有各种“工作锁”的软件开发团队里,一般都无法避免“接力棒式”的开发。也就是说,底层的C程序员干完了,交给上层的Java程序员,然后再交给更上层的前端程序员,最后再交给运维人员。这就是接力棒式的开发。

而且,更糟糕的是,如果在引入了软件流程下,这种“接力棒的方式”真是会把你搞崩溃的。比如下游团队开发一个月,交给QA测试一个月,再交给运维分步上线一个月,然后,上游团队拿到下游开发的API后开发一个月,再交给自己的QA测试一个月,然后再交给自己的运维上线一个月,于是,半年就这样过去了。这是一个由一个一个小瀑布叠出来的一个大瀑布

哦,你会说,这个好办啊,上下游不会先商定好接口么?然后做并行开发么?是的,这是其中的一个优化方式,但是需要很好的接口设计。但是,在实际过程中,你会发现(这时我并非信口开河,我说的都是事实),

  • 如果这两个上下游团队在一起还好办,要是不在一起,那么,实际情况是,后面的团队会等到前面的团队提测了,才开始开发,本质上就是串行开发的。
  • 如果有更多的团队呢?比如:A团队 -> B团队 -> C团队 ->D团队呢。接口就变得非常地关键了。而在实际情况下,因为没有好的接口设计人员,所以,在开发过程经常性地修改接口,或者是因为接口不好用也只得忍着。
【解决方案】

我以前写过一篇叫《IoC/DIP其实是一种管理思想》,对于这种接力棒的方式,应该反过来,如果业务应用团队是A团队,那B/C/D团队应该把自己的做成一个开发框架也好,服务化也好,让应用团队自己来接入。比如:前端做好一个前端开发框架,PE做好一个运维开发框架、各种工具,共享模块团队做好开发框架,让应用团队自己来接入,而不是帮他做。你会发现,在这么多团队各自P2P勾兑出来的很随意的接口的所带来的成本已经远超过一个统一标准的协议

“保姆式”软件开发

所谓“保姆式”软件开发就是——我只管吃饭,不管做菜洗碗,就像——衣来伸手,饭来张口的“小皇帝”一样,身边有一堆太监或宫女,不然生活不能自理。这种情况经常见于开发和测试,开发和运维间的关系。很多公司,测试和运维都成了开发的保姆。

我就能看到,很多开发快速写完代码后基本上都不怎么测试就交给QA去测试了,QA一测,我草,各种问题,而只会做黑盒的QA并不能马上就能确定是代码的问题还是环境的问题,所以还要花大量时间排除不是环境问题,才给开发报BUG。很多问题,可能只需要做个Code Review,做个单测就可以发现了,硬要交给QA。运维也是一样的,开发出来的软件根本就没有考虑什么运维的东西,因为有运维人员,所以我才不考虑呢。

这和我们带孩子的道理是一样的,对于孩子来说,如果父母帮孩子做得越多,孩子就越觉得理所应当,就越不会去做

“保姆式”开发一般会进化成“保安式”开发

  • 因为你的团队开发人员的能力不行,设计不行,Code Reivew/UT不做,你就只能找堆QA看着他。
  • 因为Dev/QA只管功能不管运维,所以,还得找堆运维人员看着他们。
  • 因为你的技术人员不懂业务,不懂需求,需要再找个BA,找个产品经理来指挥他。
  • 因为你的技术人员不会管理项目,所以,再搞个项目经理,找个敏捷教练、以及SQA来管着他。

就这样,你不行,我找人来看着你,看你的人不行,我再找人来看着看你的人……层层保姆,层层保安。于是,你就会发现,团队或部门里的人员越来越多,你整天都在开会,整天都在互相解释,互相争吵,会扯淡的人越来越多。那还有个屁的效率。

网络上一个非常经典的图片,来源不详,程序员在挖坑,其它人站在当监工

【解决方案】

1)不要招只会写代码的“码农”,要招懂“需求”,注重“软件工程”和“软件质量”和“软件维护”的“工程师”

2)最好的管理,不是找人来管人,而是自己管自己

3)组织和团队中支持性工作的人越少越好,最好不要

4)服务化。我服务于你并不代表我要帮你干活,而是代表——我要让你干活干得更爽

我在微博上说过下面的话,(大家可以体会一下保姆和服务的差别)

运维要用“云服务”的思路去做。如果一个公司内的运维团队开发出一堆工具,让做应用开发团队可以很容易地申请机器、存储、网络、中间件、安全等资源,并很容易管理、监控和部署应用,并提供运维资询。而不是帮应用开发团队干活擦屁股当保姆。那么,这个公司就会不经意地做出一个云计算平台来了。

 

“WatchDog式”软件开发

什么是WatchDog?就是说——为了解决某个系统的问题,我要用一个新的系统去看着它

  • 我的系统架构太复杂,出了问题不好查找。咋办?那就搞个专门的特殊的监控系统吧……
  • 我的系统配置太复杂,容易配错了。咋办?那就加一个配置校验系统吧……
  • 我的系统配置和真实的情况有时候可能会不一性。咋办?那就加一个巡检系统吧……
  • 我的系统测试环境和线上环境有时候会搞混了。咋办?那就为线上环境加一个权限控制系统吧……
  • 我的系统有单点,那就加个负载均衡器吧,负载均衡器的单点呢?那就再加个等价路由器吧……

做加法谁不会?就不想去简化一样系统吗?就不能不拆东墙补西墙么?这些了系统加的越来越多,我看你以后怎么运维。

一开始没有想清楚就放到线上,然后,出了故障后,也无法重新设计和重新架构,只能以打补丁地方式往上打,这就好像一个本来就有缺陷的楼没有盖好,你要拆了重盖是不可能的,也只能不停地打补丁了。字是一只狗,越描越丑。

【解决方案】

1)设计想好了再做,多评估几个设计没坏处,简化,简化,简化。

2)残酷无情地还债,就算是CEO来了,也无法阻止我还债的脚步。

 

“故障驱动式”软件开发

WatchDog式的软件开发通常来说都是“故障驱动式”软件开发的产物。这种开发方式其实就是在表明自己智力和能力的不足。以上线为目的,上了线再说,有什么问题出了再改。

上面的老大或是业务方基本上会说,没关系,我们不一开始并不需要一个完美的系统,你先上了再说,先解业务的渴,我们后面有时间再重构再完善。而有的技术人员也会用“架构和设计是逐步演化出来的”这句话来证明“故障驱动”开发是值得的。

我同意逐步迭代以及架构演化论,但是,我觉得“系统迭代说”和“架构演化论”被彻彻底底地成为那些能力有限甚至不学无术的人的超级借口

你们有没有搞错啊?你们知道什么叫迭代,什么叫演化吗?你们知道,要定位一个线上的故障需要花多大的力气吗?(看看这篇文章你就知道了)你们知道,随随便便去应付局部上你会快,但总体上来说你会慢。

虽然,我看到那些系统在一个又一个的故障后得到一点又一点的改善,但是我想说,为什么一开始不认真不严谨一点呢?我从来就没有见过一个精良的系统是靠一个一个的故障和失败案例给堆出来的,就算是Windows 95/98这样史上最烂的操作系统,如果没有设计精良Windows NT的补位,Windows也早玩完了(看看IE的下场就知道了)。

【解决方案】

1)基础知识和理论知识非常重要。多多使用已有的成熟的方案是关键。

2)对技术要有一颗严谨和敬畏的心。想清楚了再干,坚持高标准,Design for failure! 很多事情都急不得。

 

其它开发方式

其实,这样的事情还有很多。比如:

1)配置管理上的问题。对于源代码的配置管理,其实并不是一件简单的事情。配置管理和软件和团队的组构的结构非常有关系。我看到过两种非常没有效率的配置管理,一种是以开项目分支的方式来做项目,同时开很多分支,分支开的时间还很长,导致merge回主干要花大量的时间去解决各种冲突,另一种是N多的团队都在一个代码库中做修改,导致出现很多复杂的问题,比如某团队的改动出现了一个bug,要么所有的团队的功能都得等这个bug被修复才能被发布,要么就是把所有的改动回滚到上一个版本,包括其它团队开发的功能。很明显,软件模块的结构,软件的架构,以及团队的组织形式都会严重影响开发效率。

2)人肉式的软件开发。大多数的软件团队和主管都会用“人手不够”做为自己开发效率不够的借口,而大多数故障发生的时候,都会使用更重的“人肉流程”来弥补自己能力的不足。他们从来没有想过使用“技术”,使用更“聪明”的方式来解决问题。

3)会议驱动式开发。人多了,团队多了,想法也就多了,沟通也就多了,于是需要不停得开会开会开会。

 

总结一下

综上所述,我有如下总结:

1)软件工程师分工分得越细这个团队就越没效率,团队间的服务化是关键的关键。不管是从语言上还是从软件模块上的人员分工,越细越糟糕。服务化不是我要帮你做事,而是我让你做起事来更容易。

2)你总需要在一个环节上认真,这个环节越往前就越有效率,越往后你就越没效率。要么你设计和编码认真点,不然,你就得在测试上认真点。要是你设计、编码、测试都不认真,那你就得在运维上认真,就得在处理故障上认真。你总需要在一个地方认真。另外一篇文章你可以看一下——《多些时间少写些代码

3)“小而精的团队”+“条件和资源受限”是效率的根本。只有团队小,内耗才会小,只有条件或资源受限,才会逼着你去用最经济的手段做最有价值的事,才会逼着你喜欢简单和简化。

4)技术债是不能欠的,要残酷无情地还债。很多事情,一开始不会有,那么就永远不会有。一旦一个事情烂了,后面只能跟着一起烂,烂得越多,就越没有人敢去还债。

5)软件架构上要松耦合,团队组织上要紧耦合

6)工程师文化是关键,重视过程就是重视结果。只重视结果的KPI等同于“竭泽而渔”和“饮鸩止渴”。

(全文完)

(转载本站文章请注明作者和出处 酷 壳 – CoolShell ,请勿用于任何商业用途)

好烂啊有点差凑合看看还不错很精彩 (114 人打了分,平均分: 4.65 )
Loading...

开发团队的效率》的相关评论

  1. 小而精巧的软件开发管理模式为上,和我最近看的《人月神话》软开的成本控制管理类似

  2. 在国企呆过一年,被他们标本似的“保姆式”软件开发和“故障驱动式”软件开发所震惊。当时无法用语言定义他们的开发方式,看完此文总算可以描述出了。

  3. 感同身受,尤其是软件开发中的锁,保姆式,故障驱动式的软件开发。

  4. 说的太对了
    现在这家公司,技术人员有20+,才搞出一个独立ip 1w左右的站点,还各种报错;
    开发部门众多,但从来没有一个部门会在代码设计阶段主动跟运维沟通,测试和qa居然不关注测试环境,而是去统计线上出现的各种bug,典型的保姆式 + 故障驱动式;
    最终的结果就是,运维上很认真,故障处理时很认真,这种工作真心很累

  5. 很赞同博主的观点,在工作当中确实是这样的。但其实很多问题根本也许就不是问题,比如公司从上到下都重视话,也就简单了,但是光是下的人暴露问题,上面的人只管结果,这样就很悲催了,总之,很多事情看人的素质,特别是带头的素质。

  6. 绝对赞同。

    其实大多工程师都有多种语言的能力(不是多高的门槛),也不缺掌握多个模块的能力,问题是不愿意“摊事“,各个团队的小算盘,各人的小算盘从中做梗。能拖上三个月,为什么三周就交差,其实三天就能搞定又有什么“好处“,劳模成了贬意词。缺少足够的激励,赏罚不分明。

  7. 赞同是赞同,但真的要改变可就真的难了。Keep small是很难的,而一旦团队组织已经很庞大,要精简到small,那基本上等同于商鞅变法。

  8. “你总需要在一个环节上认真,这个环节越往往前就越有效率,越往后你就越没效率。”
    非常同意这个观点,感觉每过一个环节,认真所需要耗费的精力是指数上涨的,像我这种处在整个流程下游的真的很苦逼。
    很期待那篇讲产品和业务的文章。
    另,发现几个貌似是错字:
    1. “接力棒式”软件开发 一节中“(这时我并非信口开河,…”| 这时 -> 这事
    2. “WatchDog式”软件开发 一节中 “这些了系统加的越来越多”| 奇怪的的“了”字
    3. 还上上面这一节中 “字是一只狗,越描越丑。”| 读着别扭呢?
    4. 全文最后一句 只重视结果的KPI等同事“竭泽而渔”和“饮鸩止渴”。| 等同事 -> 等同是

  9. 总结的很精辟,最后几条总结堪称一针见血,结合我们项目实际情况来看,有太多地方需要改进。可惜我们是外包的,很多东西没法去推动改进,所谓的管理层和高层也不会care这些东西,在他们眼里只有KPI。

  10. 哈,太贴切了。
    之前的公司就是故障驱动式,欠了一屁股技术债,现在想还都还不清,而且影响恶劣,能走的基本都走了。
    现在公司是典型的保姆式开发,尾大不掉,研发不会搭基本的代码环境,各种项目经理、方案经理。
    简直就是哎呦啊

  11. “你总需要在一个环节上认真,这个环节越往往前就越有效率,越往后你就越没效率。”
    就是常说的:要在尽早的阶段 发现、解决问题,代价才越小!最早就是 需求分析,老话就是 磨刀不误砍柴工。
    另外一个就是 框架、接口、协议 的选择、确定、设计,必须是老手、高手来进行才行。

    1)软件工程师分工分得越细这个团队就越没效率,团队间的服务化是关键的关键。不管是从语言上还是从软件模块上的分工,越细越糟糕。服务化不是我要帮你做事,而是我让你做起事来更容易。

    4)技术债是不能欠的,要残酷无情地还债。很多事情,一开始不会有,那么就永远不会有。一旦一个事情烂了,后面只能跟着一起烂,烂得越多,就越没有人敢去还债。
    一个是广度,一个是深度
    1也是 沟通的困难 导致的

    5)软件架构上要松耦合,团队组织上要紧耦合。
    模块间的传递数据,由xml/json/ini取代二进制结构,也是松耦合的表现

    1. 这就是我看始说的——“有好些人觉得是不可能甚至太理想,其实我说的那些东西都是实实在在存在的,也是我所经历过的。于是,不同的经历,不同的环境,不同的眼界,造成了有些人不理解我说的”

  12. IoC/DIP其实是一种管理思想——其实你的主要观点和SOA类似,所以很多问题是相通的。

  13. 对“保姆式”和“WatchDog式”感同身受。
    关于“保姆式”开发:作为研发人员,需求调研、设计、测试、运维本应是分内之事,即使团队很大,分工明细,也不应该盲目的依赖其他人,如果真的热爱自己开发的产品,那么肯定想尽力做到更好,这也是对自己负责。
    关于“WatchDog式”开发:这也是自己的设计水平导致,只能努力提升自己。

  14. “我们不一开始并不需要一个完美的系统” 这句好像多了个“不”字。

    我们公司就有鲜活例子。
    1. 开发的人不做code review(或者是没做好),上了线,要dba来擦屁股。
    2. 前人搞出来的架构严重失败,要后人来改架构,相当痛苦。
    3. 人家管的系统有问题,水平不够还很拽,你想帮个忙,人家还不乐意。办公室政治。

  15. 做全栈工程师很牛,做全栈的人不是更牛么,这些开发方法语言也只是现实某种抽象和简化,努力理解看不顺眼事物的原理,然后解决,比吐槽有意义多了。

  16. 非常赞同“接力棒式”软件开发 的观点,激进的说,模块化系统在某种程度上已经过时,服务化的软件结构在是先进生产力所在;也很赞同对“人”的理解,最好的管理就是自己管自己。

  17. 又在谈理想啊~~写的挺好,其实道理大家都懂~~就是利益出现的时候就都傻了!?

  18. 阅读器上不能评论,特意转过来说两句,读起来太有带入感了。文中的以下几点不能赞同得再多,在我司长久存在。
    1、“你不行,我找人来看着你,看你的人不行,我再找人来看着看你的人……层层保姆,层层保安”,这就是我们当前组织结构的现状。
    2、“上面的老大或是业务方基本上会说,没关系,我们不一开始并不需要一个完美的系统,你先上了再说,先解业务的渴,我们后面有时间再重构再完善”。上面老大首要关注的是交付进度,进度是最直观可度量的,质量不行,暴露有个延迟,至少得上线后才能摆上台面讲,到那时可以再搞出一堆质量保障活动来应对,不怕没事儿干。开发有时感叹这个模块要不重构下,满地是雷,旁边老员工会提醒他,你说重构就重构啊,有哪机会吗,谁给你投人力,排版本。开发就只能忍了。
    3、“以开项目分支的方式来做项目,同时开很多分支,分支开的时间还很长,导致merge回主干要花大量的时间去解决各种冲突”,要起一个新的迭代版本,从主干上拉一个分支,开发人员还要在主干和分支上同步修复的bug,一件事重复干几次,遇上公司修改bug的流程还很繁锁,这就成了个体力活,开发怨声载道。后来从友商那学来一种叫onetrack的东西再加上大boss的强力砍版本,好转了一阵子,不过最近又有复活的迹象。
    4、“好了一段时你总需要在一个环节上认真,这个环节越往往前就越有效率,越往后你就越没效率间”。我们也一直在讲问题出现得越早并解决成本就越低。实际执行过程中呢?总是在赶进度,这个道理早抛到九霄云外。

    不说了,说多了就成吐槽了。现状是改变不了了,就当个人以验积累吧,自己开发的时候在小范围组织内尽量避免,生命短暂,尽量避免在无为的事上浪费。博主给出的解决方案很赞!

  19. 软件开发锁的论断很精辟,曾经历过这样的团队,当时也很痛苦,解决方案不错,适合小而强大的团队。其他软件开发方法也或多或少遇到过,谢谢皓哥的经验。
    这里常看,第一次回复,我是个伸手党,皓哥勿怪。主要目的是请教个问题,已经email你了,应该是沉入了你的email海洋中,就到这里来请教了,
    iteye的问答频道有个关于java线程交互的问题,http://www.iteye.com/problems/101719,虽然被采纳的回答也算解决了问题,但是疑问肯定还有,为什么问题中的代码每次都有不确定的输出?很是不明白,很久也没有搞明白,希望皓哥指点,谢谢

  20. 在《奋斗吧,系统工程师》里看见过类似情形,开发部和运维部都到剑拔弩张的地步了

  21. 上面的老大或是业务方基本上会说,没关系,我们不一开始并不需要一个完美的系统,你先上了再说,先解业务的渴,我们后面有时间再重构再完善。而有的技术人员也会用“架构和设计是逐步演化出来的”这句话来证明“故障驱动”开发是值得的。

    我同意逐步迭代以及架构演化论,但是,我觉得“系统迭代说”和“架构演化论”被彻彻底底地成为那些能力有限甚至不学无术的人的超级借口。
    ……………………………………………………………………………………………………………………………………………………………………………………..
    我真的想说这些经验是必须要经历过才会体会。一些领导或者主管根本就没有软件工程的意识,只知道一味的催促让你快点上线,尽快做出示范,而根本不从软件开发的实际角度出发。我很多时候都怀疑他们有没有从事过具体的软件代码编写工作,因为一套方案的实现是必须建立在灵活高效的程序框架上,而无论是尽快做出原型还是示范,都必须先设计并完成一套质量很高的程序框架,保持可维护性,可扩展性,但那些资质平庸的工程师和主管最喜欢说的一句话就是你先做出来嘛,有什么问题后面再改,通常面对这种情景我都只能保持沉默。

  22. 很有感触… 很多问题在项目的开始就可以避免的,而不是一直去打补丁.
    程序员的自我修养很重要.

  23. 一个人会很多技能,在开发的时候逢山开路遇水搭桥,就像特种部队一样,效率肯定高,这样的人毕竟不多而且很贵啊!

  24. 非常好的一篇文章。 真正时经验的总结啊。
    顶耗叔。
    以前看到有的同学把博主叫做耗哥。 后来看到有人叫耗叔,是调侃博主老了嘛。 不知道博主怎么看捏?

  25. 读了一下,深有感触。
    以前我的公司最初是略理想的那种开发测试“懂需求”“会代码”“能编程”,注重“软件工程”和“软件质量”和“软件维护”的“工程师”,每个人都能做需求分析,都能做产品定向,功能定位,还都有技术支持能力(所谓敢吃自己的狗屎),虽然时常会因为工作问题争吵,但是工作很开心。
    后来公司变了,新招了一堆“领导”,将原来的高层或是降级,或是边缘化。测试这边开始实行保姆式-保安式的工作方式,而且由这些新领导招进来的测试工程师全部放弃培养,将“测试只会黑盒”进化的淋漓尽致。而开发这边则开始遵循“故障驱动式”,做出垃圾来再修垃圾。当然,大家都有得写周报了!
    和我一批进公司的同事,以及我的前领导和前导师,都已经纷纷离职了。我也离职了。离职之后这个月初新找的工作,仍然是测试工程师,不过工作内容大不如前,测试已经不再是“黑盒”了,而变成“发散”,无规无矩,(如果您懂得东北方言的话,用‘虎’这个形容词最恰当不过)。
    我现在对测试工程师很迷茫……

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注