嗯?軟件工程?

由於奇怪的課程要求,在接下來的小半年中每周我都會開一趟車-唔...是發一篇關於軟件工程的小短文.靠,我寫MCMod教程都沒這麼勤快過,這就是軟院對計院的復仇嗎?

大多數高等院校的信息類學科都被分為計算機科學和軟件工程兩個部分,關於科學與工程的區別,一個常見的解讀是"科學是在解決一個舊問題的同時提出兩個新問題,而工程是在不引發新問題的前提下解決掉舊問題".顯然客戶總是希望產品能夠準時準點地交付,而非一次又一次地次元突破Deadline.軟件工程就是為軟件的編寫提出一個章法,給世界上最桀驁不馴的一群人套上韁繩,讓他們製造出一個可靠的工程,而不是一個充滿了各種奇思妙想和奇技淫巧的垃圾堆.

The_Tower_of_Babel
老彼得·勃魯蓋爾的《通天塔》,在《黑客與畫家》一書中被用作封面.傳說中通天塔的建造由於人類的語言不通而最終以失敗收場,軟件開發中由於人員矛盾導致的殘局也是數不勝數.

想深入地探討軟件工程確實不是一件容易的事,因為它不止受限於人的經驗,還受限於閱歷,用木板搭建一個貓城堡和用磚塊砌一座樓房是完全不同的體驗,而建造一座樓房與建造一棟摩天樓又是兩碼事,一個人設計的平房再多,也掌握不到設計樓房所必需的技巧,這也是為什麼架構師很多而系統架構師卻很少的原因之一,隨便一個碼農只要自己獨立做過一個程序就敢自稱做過架構,而有幸能參與並且有能力參與一個大型項目的架構設計的卻少之又少.

同樣的,對於同樣規模的項目,由於團隊配置和設計目標的不同,開發流程也是有千差萬別.一個獨立開發的項目的開發速度完全取決於開發者最近的心情,一個二人團隊甚至可以用QQ來完成版本控制(諸君,來猜猜這是哪個項目??),一個短小精悍的外科手術式團隊只要有恰當的管理依然可以完成規模龐大的工作,而一個幾十上百人的團隊僅是管理工作就要投入不少精力;編寫開源和閉源項目可以是不同的編碼規範;開發一個庫和開發一個應用在設計上會是截然不同;最合適的開發模型也受市場需求的影響,讓Office採用敏捷開發的話一周一小更一月一大更恐怕會嚇走很多不願意倒貼錢作測試的企業用戶,讓一個互聯網應用採用瀑布模型很可能當浪潮退去時項目還沒完工.顯然一個銀彈式的通用解決方案僅存在於暢銷書中,正如有人說設計模式的套用是在無形中實現而不是像熱血凍鰻中出招時先要喊出招式名那樣,軟件工程也是一個"具體問題具體分析"的工作.

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

項目管理基本原理

與其他大多數行業不同的是,軟件開發屬於硬件成本低人力成本高的行業,說到底軟件也是Mankind's work,到目前為止還依然是靠人一個字一個字地碼出來,在軟件開發這一過程中人是成本最大的,也是出力最多的,對團隊而言人力的選擇配置是決定成敗的關鍵.儘管我估計起碼有九成的程序員(包括我)反對對他們的工作使用貨幣或者等價手段進行量化衡量,但如果換個說法,告訴他們說在上級看來他們認真干一天的工作與鄰座刷一天微博的實習生的"工作"是等量的話,他們(include me, again)肯定又會是另一種態度.因此工作量化還是有必要的,長痛不如短痛,晚撕不如早撕嘛.?

衡量手段:工作時間?

工作時間恐怕是最早出現的工作量化指標,自打人類有了僱傭關係的概念後,衡量一個人工作努力程度的最佳手段當然是看他的工作時間,在以體力勞動為主的時代這當然是奏效的,然而對於軟件工程來說,一個高效率的程序員的工作速度可能達到一個平庸的程序員的數倍之多,以工作時間來衡量成果的話對於那些手腳麻利能夠又好又快地完成工作的人來說是不公平的,不幸的是在大多數環境當中工作時間還依然是衡量工作效率的手段.

衡量手段:工作量

當工人聰明到發現辛苦幹一天與僅在早晚開工收工時辛苦那麼一下得到的報酬是相同的時,僱主們的末日便到來了,因此一個更靈活的工作量化手段應運而生,以一個人的勞動產出為根據來衡量其努力程度是一個相對更公平的方式,一個高效的程序員可以選擇用更短的時間拿到原定的報酬,也可以選擇用原定的時間拿到更多的報酬,而不再是受制於單位大門的打卡器.然而這又帶來一個問題,同樣是工作,有些工作簡單並且容易出數,而有些工作卻是困難而又關鍵,如果一個工地有兩項工作 - 將磚頭從原料區搬到樓底下,和將磚頭從樓底下搬到樓頂,倘若只統計搬磚數量,而又允許工人自由選擇工作的話,顯然所有人都願意選擇平地搬磚的工作,因為它明顯比爬樓輕鬆得多,但也顯然只把磚頭堆在樓底是不能讓建築完工的,只考慮工作量而忽視工作難度對那些專心攻關難題的人來說有些不公平.

衡量手段:工作難度

當工人都去搶着干輕鬆而又出數的工作,沒有人去做費力不討好的活時,僱主們的第二次浩劫到了,這一次他們不得不推出了另一個量化手段:工作難度.工作生而重要,然而有些工作更重要.顯然對於專心攻克疑難問題的工程師應當給予更多獎勵,這樣既彰顯了公平,又能鼓勵更多有潛力的人參與到難題攻關中.然而工作難度只能作為一種參考,或者說是在工作量化時的一個係數,你可不能小瞧人類為偷懶而被激發出的創造力,總會有人賴在"疑難問題"上磨洋工,如果不考慮工作量,那疑難問題就都變成了挖不完的金山了.

衡量手段:維護工作

僱主總得有一個為他自己開工資的理由,一個團隊也總會有一些額外的維護工作需要由人來完成,這些維護工作各式各樣,有些是可以被近似地歸為另一種工作,比如軟件工程時搭建測試服務器或維護CI服務器這種稱不上工作但又不得不考慮的;也有一些管理類的文書工作,比如對外公關和對內的工作管理與統計;又或是一些維持團隊凝聚力的社交工作,一個長期的團隊總會有幾個活躍氣氛的開心果,就像我加過幾個國內的MCMod團隊作為老司機-不對,作為吉祥物去參與日常吐槽侃大山什麼的(當然,這個吉祥物偶爾還能解答個疑難問題啥的,笑?).

如果要量化一個人的工作,我想這個公式大概是:工作量*工作難度+維護工作 沒錯,我沒有加入工作時間這個因素,在我看來這實在是沒有必要的,很多團隊認為工作時間可以被算入辛苦分,但我相信這樣的團隊很多都被淘汰了,我可從來沒覺得摸魚辛苦...這樣確實可能對專心攻關難題但進展不大甚至陷入死胡同不得不推倒之前工作的人來說不公平,作為補償,尚未完成的工作也應視其已有進展被納入工作量的考核,陷入技術歧途而拋棄的工作也應將其積累到的成果納入量化範圍.當然,現實中工作量化遠比這個要困難,畢竟這三個參數都是主觀性很強的,為了客觀很多傳統的計量方法只以實打實的統計量來計量,比如代碼行數,這種方式幾乎與統計工作時間無疑,碼農總能想出各種謎之設計將自己的代碼越扯越多.

這篇文章大致就到這裡了,下一周我看看能不能介紹手頭哪個項目的設計(比如CustomSteve?咳,I'm afraid that's classified...?),或者是吐槽一下之前參與過的項目?如果你有過坑爹的項目經歷的話可以在留言中貼出來分享.☺