嗯?软件工程?

由于奇怪的课程要求,在接下来的小半年中每周我都会开一趟车-唔...是发一篇关于软件工程的小短文.靠,我写MCMod教程都没这么勤快过,这就是软院对计院的复仇吗?

大多数高等院校的信息类学科都被分为计算机科学和软件工程两个部分,关于科学与工程的区别,一个常见的解读是"科学是在解决一个旧问题的同时提出两个新问题,而工程是在不引发新问题的前提下解决掉旧问题".显然客户总是希望产品能够准时准点地交付,而非一次又一次地次元突破Deadline.软件工程就是为软件的编写提出一个章法,给世界上最桀骜不驯的一群人套上缰绳,让他们制造出一个可靠的工程,而不是一个充满了各种奇思妙想和奇技淫巧的垃圾堆.

The_Tower_of_Babel
老彼得·勃鲁盖尔的《通天塔》,在《黑客与画家》一书中被用作封面.传说中通天塔的建造由于人类的语言不通而最终以失败收场,软件开发中由于人员矛盾导致的残局也是数不胜数.

想深入地探讨软件工程确实不是一件容易的事,因为它不止受限于人的经验,还受限于阅历,用木板搭建一个猫城堡和用砖块砌一座楼房是完全不同的体验,而建造一座楼房与建造一栋摩天楼又是两码事,一个人设计的平房再多,也掌握不到设计楼房所必需的技巧,这也是为什么架构师很多而系统架构师却很少的原因之一,随便一个码农只要自己独立做过一个程序就敢自称做过架构,而有幸能参与并且有能力参与一个大型项目的架构设计的却少之又少.

同样的,对于同样规模的项目,由于团队配置和设计目标的不同,开发流程也是有千差万别.一个独立开发的项目的开发速度完全取决于开发者最近的心情,一个二人团队甚至可以用QQ来完成版本控制(诸君,来猜猜这是哪个项目??),一个短小精悍的外科手术式团队只要有恰当的管理依然可以完成规模庞大的工作,而一个几十上百人的团队仅是管理工作就要投入不少精力;编写开源和闭源项目可以是不同的编码规范;开发一个库和开发一个应用在设计上会是截然不同;最合适的开发模型也受市场需求的影响,让Office采用敏捷开发的话一周一小更一月一大更恐怕会吓走很多不愿意倒贴钱作测试的企业用户,让一个互联网应用采用瀑布模型很可能当浪潮退去时项目还没完工.显然一个银弹式的通用解决方案仅存在于畅销书中,正如有人说设计模式的套用是在无形中实现而不是像热血冻鳗中出招时先要喊出招式名那样,软件工程也是一个"具体问题具体分析"的工作.

你能让一个女人用十个月生一个孩子,也可以让十个女人用十个月生十个孩子,但你不能让十个女人用一个月生一个孩子.

项目管理基本原理

与其他大多数行业不同的是,软件开发属于硬件成本低人力成本高的行业,说到底软件也是Mankind's work,到目前为止还依然是靠人一个字一个字地码出来,在软件开发这一过程中人是成本最大的,也是出力最多的,对团队而言人力的选择配置是决定成败的关键.尽管我估计起码有九成的程序员(包括我)反对对他们的工作使用货币或者等价手段进行量化衡量,但如果换个说法,告诉他们说在上级看来他们认真干一天的工作与邻座刷一天微博的实习生的"工作"是等量的话,他们(include me, again)肯定又会是另一种态度.因此工作量化还是有必要的,长痛不如短痛,晚撕不如早撕嘛.?

衡量手段:工作时间?

工作时间恐怕是最早出现的工作量化指标,自打人类有了雇佣关系的概念后,衡量一个人工作努力程度的最佳手段当然是看他的工作时间,在以体力劳动为主的时代这当然是奏效的,然而对于软件工程来说,一个高效率的程序员的工作速度可能达到一个平庸的程序员的数倍之多,以工作时间来衡量成果的话对于那些手脚麻利能够又好又快地完成工作的人来说是不公平的,不幸的是在大多数环境当中工作时间还依然是衡量工作效率的手段.

衡量手段:工作量

当工人聪明到发现辛苦干一天与仅在早晚开工收工时辛苦那么一下得到的报酬是相同的时,雇主们的末日便到来了,因此一个更灵活的工作量化手段应运而生,以一个人的劳动产出为根据来衡量其努力程度是一个相对更公平的方式,一个高效的程序员可以选择用更短的时间拿到原定的报酬,也可以选择用原定的时间拿到更多的报酬,而不再是受制于单位大门的打卡器.然而这又带来一个问题,同样是工作,有些工作简单并且容易出数,而有些工作却是困难而又关键,如果一个工地有两项工作 - 将砖头从原料区搬到楼底下,和将砖头从楼底下搬到楼顶,倘若只统计搬砖数量,而又允许工人自由选择工作的话,显然所有人都愿意选择平地搬砖的工作,因为它明显比爬楼轻松得多,但也显然只把砖头堆在楼底是不能让建筑完工的,只考虑工作量而忽视工作难度对那些专心攻关难题的人来说有些不公平.

衡量手段:工作难度

当工人都去抢着干轻松而又出数的工作,没有人去做费力不讨好的活时,雇主们的第二次浩劫到了,这一次他们不得不推出了另一个量化手段:工作难度.工作生而重要,然而有些工作更重要.显然对于专心攻克疑难问题的工程师应当给予更多奖励,这样既彰显了公平,又能鼓励更多有潜力的人参与到难题攻关中.然而工作难度只能作为一种参考,或者说是在工作量化时的一个系数,你可不能小瞧人类为偷懒而被激发出的创造力,总会有人赖在"疑难问题"上磨洋工,如果不考虑工作量,那疑难问题就都变成了挖不完的金山了.

衡量手段:维护工作

雇主总得有一个为他自己开工资的理由,一个团队也总会有一些额外的维护工作需要由人来完成,这些维护工作各式各样,有些是可以被近似地归为另一种工作,比如软件工程时搭建测试服务器或维护CI服务器这种称不上工作但又不得不考虑的;也有一些管理类的文书工作,比如对外公关和对内的工作管理与统计;又或是一些维持团队凝聚力的社交工作,一个长期的团队总会有几个活跃气氛的开心果,就像我加过几个国内的MCMod团队作为老司机-不对,作为吉祥物去参与日常吐槽侃大山什么的(当然,这个吉祥物偶尔还能解答个疑难问题啥的,笑?).

如果要量化一个人的工作,我想这个公式大概是:工作量*工作难度+维护工作 没错,我没有加入工作时间这个因素,在我看来这实在是没有必要的,很多团队认为工作时间可以被算入辛苦分,但我相信这样的团队很多都被淘汰了,我可从来没觉得摸鱼辛苦...这样确实可能对专心攻关难题但进展不大甚至陷入死胡同不得不推倒之前工作的人来说不公平,作为补偿,尚未完成的工作也应视其已有进展被纳入工作量的考核,陷入技术歧途而抛弃的工作也应将其积累到的成果纳入量化范围.当然,现实中工作量化远比这个要困难,毕竟这三个参数都是主观性很强的,为了客观很多传统的计量方法只以实打实的统计量来计量,比如代码行数,这种方式几乎与统计工作时间无疑,码农总能想出各种谜之设计将自己的代码越扯越多.

这篇文章大致就到这里了,下一周我看看能不能介绍手头哪个项目的设计(比如CustomSteve?咳,I'm afraid that's classified...?),或者是吐槽一下之前参与过的项目?如果你有过坑爹的项目经历的话可以在留言中贴出来分享.☺