我平时很少写博客,我是个技术人员,一般来说技术人员的博客应该以技术为主,但同时我又是一个懒人,对于技术我喜欢“亲身体验”而不喜欢“写出来”,因为我觉得把技术对别人说清楚要比实现它更困难。实际上这段时间我都在看别人的博客,所以一直以来我只是个吃白食的:)
为什么现在我要跨界谈一个偏重管理类的话题呢?因为过去经历的一些事促使我对项目的流程管理进行一些思考,并形成了自己的一套看法和逻辑,而我也很愿意将我的看法发表成文,不喜欢憋在脑海里太久。至于能得到多少认同倒是并不在意,我觉得一个人观念的形成源于他对事物本质的理解和认知,而这种理解和认知又同他过去的经历有关。在此通报一下我过去的工作经历,本人电气专业出身,在一家台资IC企业做过三年软件工程师,无任何工程管理上的学位和经验,所以题目定为“一个工程师的思考”以避免把话说太满。但我不认为一个话题出自一个非专业人士之口就得贴上“瞎BB”的标签,作为工程师的我好歹也是大工业时代整条生产链上的一颗“螺丝钉”,虽然项目流程不是我设计的,但身为一颗“螺丝钉”也有反馈一下的权利吧。何况我也不想洋洋万言写成精品,权当一家之言耳。
流程管理在生产上已被奉行多年,但围绕它的争议仍不停歇。有些人喜欢它,认为流程提升了生产效率,有利于培养企业文化;有些人排斥它,认为它束手束脚,僵化死板。前者大多出自管理层,后者大多出自工程师,他们都是站在自己的立场看问题的,能不能统一起来看呢?我们到底需不需要流程?或者多大程度上接受它?在阐述我的逻辑之前,先从我对流程的认知说起。
流程的本质是什么?我的理解是流程是一种介入机制和托管机制。“介入”是指生产环节上多大程度让外部势力参与和干预,主要表现为人员分工;“托管”是指存在一种自动化工具帮你简化一些步骤,表现为对工具的使用。它们的区别相当于载人飞船和无人飞船。当我们说“这个项目应该走个流程”实际上等价于“要让外部人员参与进来”以及“你该试试这个工具”这些同义语。
让我们以开源项目Linux为例深入解释一下。在上世纪90年代初出现了Linux内核,是由芬兰21岁的大学生Linus Torvalds开发的,他先是写了一个多任务的终端仿真程序来连接modem,又写了一个磁盘驱动程序访问硬盘,再写了一个文件系统管理资源,后来又移植了bash和gcc,一个操作系统雏形就这样建立起来。在这个阶段都是Linus一个人DIY,并没有他人介入,顶多也就通过邮件同少量用户交流一些需求。而且当时工具也不太发达,他甚至不得不手动修改gcc源代码以实现内核自编译。不管怎么样,个人项目还是发布了。后来开始有人协助加入图形、网络各种服务和模块,再后来就演变成一项声势浩大的开源运动,连商业公司都参与进来开发各种发行版。这是Linus意识到自己必须放手,因为随着用户需求的增多,代码量膨胀,版本发布周期也在缩短,这也是为何Linus又发明了版本控制软件git;社区发展壮大导致成千上万开发者参与其中,不仅仅贡献代码,测试、写文档、打包、做网页、翻译、技术支持、售前售后……把整条生产线纳进来了。这么多人,这么多活,没有分工,没有秩序显然是行不通的,于是就像商业公司一样,开源项目也要建立一套好流程,以便外部人员顺利平滑地介入。
上面提到的“介入”和“托管”两种机制,前者是参与分工,后者是工具使用,现在大多数开发者和管理层对工具使用都有某种共识,而且事实上实施很多年了。真正的分歧在于“介入”,这也是流程管理中最大的争议,因为工具是可以替换的,而一旦“介入”是不可逆转的,因为一旦介入,你很难把别人清退出去。何时介入,介入程度多深都会成为争议焦点。一个工程师在项目早期的构思建模阶段一般是不欢迎他人参与进来的,很多人说这会干扰他们的思路,顶多开放一些有限的口头交流,但想要往我的代码中提交pull request(以下简称PR),没门!这种情形不禁让人联想到家里养的母猫在小猫尚未睁眼之前不允许任何人触碰,就算自家主人也不行,不然就摆出一副凶巴巴要跟你拼命的架势(狗妈妈可能无所谓,这也是为何有的程序员性格更像猫而不是狗一样易于管教)。母猫的想法可能是这样的:1.这是我亲生的,凭什么让你碰?2.抚养的细节只有我最懂,兽医也不行。这同一些主观意识强烈的工程师心理如出一辙,这也解释了他们同别的工程师甚至管理层在流程问题上发生争执,说白了就是不想被介入。但随着小猫的成长,母猫终究还是会允许主人帮忙照料养育自己的孩子,以分担一些麻烦,如同工程师最终还是会与团队一同坐下来商谈软件打包发布等各种琐事,以及放开并回应来自社区提交的PR。
如何看待流程早期介入的必要性?从工程师的角度看我更倾向于早期不介入为好,因为程序最初的构造是靠人的创造性思维,开发人员需要在脑海中(或纸上)精心构建一座模型大厦,这种思维具备某种独立性和连贯性,最不希望被打断或中途崩塌,否则情绪上无法接受。对项目主管来说,如果限定时间内一个人就能搞定的模块,就让他放手去做好了;如果是几个模块分工,就按照个人的专业水平安排各写各的好了;时间允许的话,最好不要几个人共写一个模块,除非结对编程。用Linus的话来说“从一开始就告诉自己这份工作只有你一个人负责,并且做好完成它的准备。如果你一开始就认为全世界的人们都会联合起来为你的项目工作,一起创造一个更美好的世界,那么你可能不会走得很远。”
这里还有成员之间的信任问题,主管是否应该在背后监视每一行代码?这是值得讨论的,我还是引用Linus那句话:“不要试图控制别人和他们的代码。”有的主管提出代码质量的忧虑,但这引申出另外一个命题,如果代码质量可以衡量一个程序员个人能力,你担心开发过程中的质量,那当初何必把他招进来呢?如果代码质量真出了问题,那就是招聘时埋下的隐患了,作为管理层自身也有责任的。
这里还要说一下,不介入不等于成员之间不交流不讨论了,不同意见的交换是有益的,但只是参考而不是强制性的,而且这种交流最好由工程师主动提出来,主管只负责调整项目进度。另外code review是十分必要的,但时间线最好授权给工程师自己把握,免得一个不成熟的构思匆忙提交下去一通review给提前定型了,何况开发人员在此期间还会私下里觉得不满还会推翻重来,搞得其他成员浪费时间白白折腾。当然我相信一个好的工程师也应该有良好的自觉性和自律性,在招人的时候成为考察重点,要胜过在开发过程中背后另外搞一套监控。
以上讨论的主要是流程管理早期介入的问题,中后期的介入机制会比较复杂比较细节化,由于笔者经验水平所限不便多谈。个人觉得介入也需要同项目团队的规模匹配,根据现状和进度因势导利,逐步介入,而非开闸泄洪,一口一个胖子。另外不同公司的流程制度照搬要谨慎,如同协议那样,如果达不成共识而强行介入,反而对团队不利。
下面谈谈托管机制,也就是工具的使用。其实比起介入没啥好谈的,因为无论是管理层还是工程师都认同工具在流程效率上的重要性,事实上早已使用很多年了。就我个人而言,版本控制用过perforce和git,项目管理用过redmine和trello,各有各的特色。工具也不限于软件,开发语言本身也是一种工具,比如一些高级语言实际上也提供了“托管”功能,帮程序员管理内存、实现并发之类的。工具的一个优势在于将一些重复低效的劳动从流程中剥离出来,简化为开发人员对工具的使用技能,比如面试官在招人时只需要问你会不会使用git而不会让你自己手动merge代码。另一个优势就是讲流程中的操作规范化、标准化,比如git的成功在于它借鉴了Unix的KISS原则设计了一套简单命令接口:clone、add、reset、rm、commit、checkout、push、pull等,这么几个命令足以满足全球最大开源项目Linux的日常代码托管需求了,难怪后来衍生出github、gitlab各种git家族都遵循同一套命令接口,如同达成默契的协议,你只要会用git,就可以在所有开源托管平台上来去自如,让流程简化效率提升。好的工具使得全球范围内的协作项目成为可能,事实也证明了Linux社区所取得的成功。
与此同时我也思考过这两种机制之间的辩证关系,因为一个是“载人”的,一个是“无人”的,我曾怀疑过当管理工具日益强大时,来自外部势力的介入需求会否因而减少,也就是说介入和托管在流程管理中的比重是否是此消彼长的?如果是,这个世界的生产链条上人是否终将被工具取代呢?过剩的人力资源是否使得未来工程师失业呢?在现实世界中的确看到大量个人项目,只要凭借个人对工具技能的掌握,完全不需要外人介入就能完成整个项目流程。然而答案是否定的。因为托管工具仅仅是将低效重复的劳动从流程中剥离,并未满足全球科技行业日益增长的创造性需求。也许以前那些从事手工merge代码的专职人员因此失业,但从全局来看是好事,那就是将开发人员从日常繁杂事物中解放出来,投入到更激动人心的创造性活动中去。只要人的脑容量增长速率追不上人类社会发展出现的各种变动,市场仍需要更多工程师投身其中,协同参与。现实世界也并未印证这种担忧,开源项目的代码量和参与人数都在逐年上升中。
如果你的团队在项目开发上进展不顺,不妨回过头来看看自己的流程管理,当初在人才选拔和介入机制上是否需要整改,亦或是换一个更先进的工具。
参考:
Linus Torvalds’s Lessons on Software Development Management