600 萬行代碼!計劃兩年結果做了十二年,直到負責人被丟進監獄

我待的不是一家企業,而是監獄?

一個原本複雜性不高、預計只需兩年的政府項目,實際上最後卻用了十二年,直到項目負責人被逮起來丟進監獄才完事。一位親身經歷這個項目的程序員,在之後十年間斷斷續續寫了好幾篇博客,用以“自我療傷”。雖然這些經歷已成過去式,但是放在 2020 年的今天來看,也不過時。

我親眼看到的一切,完全超越我在多年軟件工程實踐中積累下的基本認知。在這裡,管理者的問題不只是缺乏專業能力,更多是對人格尊嚴的輕視,這讓我感覺自己待的不是一家企業,而是監獄。

先說說這個項目的基本情況:

  • 600 萬行代碼
  • 基於 C++ 語言
  • 5 萬多個類
  • 項目使用的 C++ 編寫風格早已過時,原有代碼被牢牢鎖定在特定編譯器版本上,且僅通過單一(超過維護期)操作系統進行分發
  • 基於 CORBA
  • 數據庫軟件由一家已經破產的公司提供
  • 圖形用戶界面中包含無數個層,其中不少已經停止維護
  • 32 臺並行設備,需要 48 小時才能 build 完成
  • 運行一套用戶界面需要 40 到 50 個進程同時運行
  • 沒有動態庫鏈接:可執行文件的體積高達數百 MB
  • 啟動時間約為 15 分鐘
  • 兩次崩潰間的平均間隔時長:30 秒到 30 分鐘

也就是說,這個項目需要維護多達 600 萬行的代碼,就算是一秒能閱讀一行,大家也得在屏幕前坐整整 70 天才看得完。這麼多的代碼,每次編譯,還得 32 臺機器、運行 48 個小時才能完成。

曾經有一次,項目組的一位開發人員負責檢查右鍵單擊界面為什麼會導致應用程序卡死這麼一個 Bug。經過幾天的耐心檢查後,他發現其實這並不是一個 Bug,只是菜單彈出速度比較慢,彈出一次大約需要 45 分鐘。

為這個項目提供數據庫的企業也沒能撐到這個法國政府項目成功的那一天——數據庫公司先倒閉了。但是,這個項目又寫死在了這個數據庫上,所以也只能就這麼繼續用下去。

此外,公司還不斷的解僱人。遲到一分鐘?會被解僱!穿短褲上班?會被解僱!最後留下的項目經理比團隊成員還多,55 名項目成員之中有 20 名開發者和 35 名經理。也就是說兩個項目經理才能分到一位程序員來給他幹活兒。

這樣一個項目,是怎麼被“煉”出來的?

選擇了超難學習的 C++ 語言來實現項目

直到現在很多人還是覺得 C++ 是種好語言,是軟件開發的理想工具選項。

但是單從複雜性角度來看,C++ 可能是世界上最差勁的計算機語言之一。

這種語言最初由一個人,或者最多是一小撮人設計而成。多年以來,隨著 C++ 語言的應用範圍不斷增長,最終出現了“按委員會導向進行設計”的可怕制度。CORBA 就是這麼來的。

如果大家用過 C++,一定了解這個語言需要長時間的學習和不斷的練習才能被掌握。你甚至需要做無數個微小且毫無意義的練手項目。而且很有可能永遠弄不明白它是怎麼編譯出來的。以至於它的創造者 Stroustrup 都承認自己沒有完全搞清楚這種語言。

在《高效 C++(Effective C++)》中,Scott Meyers 警告稱 C++ 中包含多種子語言。他列舉了 C 語言、Object-Oriented C、Templates 以及 STL,但如果仔細觀察,大家會發現 C++ 中包含的風格基本上跟編譯器選項的數量一樣多。

600 萬行代碼!計劃兩年結果做了十二年,直到負責人被丟進監獄

把這個數字乘以平臺數量,乘以編程規則與建議數量,再乘以活躍程序員的數量,就能得出整個社群的總體規模。最重要的是 ISO 委員會還會不時發佈新版本來進一步強化這種複雜性。我接觸過的 C++ 大師們基本有個共性,就是他們承認自己只能弄明白 C++ 語言中大概 90% 的部分,這個比例已經足夠讓他們名留青史了。

使用沒經驗的 C++ 程序員

這個項目開始的時候,政府方面先期支付了幾百萬歐元,開發計劃在兩到三年之內完成。公司聘請了幾位 C++ 軟件專家來推動這個工作。隨著資金的逐步落實,每 3 個月左右就會提升一次團隊規模。

由於採用的是 C++ 語言,而每個人對 C++ 的理解程度又都不一樣,某些問題有時候只能由其中一位專家負責解決。也就是說,如果只有一名程序員有能力維護項目中的某個高難度部分,但他離職了,就沒人能讀完或者理解他的代碼,那麼這部分就沒法維護了。

這個項目進行七年之後仍然沒能達到足以交付的水平,公司需要每天支付數千歐元的罰款。管理層最終決定降低成本並解僱所有具備開發經驗的員工,轉而招聘了一批沒有任何軟件工程經歷的新手。

那陣子,很多團隊成員的桌上都放著一本《C++ 傻瓜入門》。

600 萬行代碼!計劃兩年結果做了十二年,直到負責人被丟進監獄

悲催的是,對於項目中的新手來說,他們沒有能力消化 C++ 語言的極高複雜性。而且這些人用在學習語言及編譯器方面的時間,要遠遠多於開發實際成果的時間。

十年之後,考慮到項目的災難性現狀,公司的中層管理者決定再聘請一批有經驗的軟件工程人員幫助項目重回正軌。

版本不兼容

除複雜性外,C++ 還存在二進制兼容性(ABI)方面的問題。在對象文件內對 C++ 對象進行命名的具體方式實現標準化之前,我們根本無法將兩個不同編譯器產生的兩個對象進行相互鏈接。

對於庫供應商來說,這意味著我們必須直接發佈源代碼。而一旦以源代碼的形式集成第三方庫,就意味著我們必須引入所有必要的編譯環境——這些環境可能與當前環境兼容,也可能不兼容。這樣,工作的重點就從開發實際功能,變成了集成一套外部庫,然後弄清楚該如何對該庫進行編譯。

雖然新版本已經解決了問題,但時至今日生產環境中仍存在大量舊系統。而且由於二進制兼容性問題,這些陳舊系統一直無法與 C++ 編譯器良好對接。要想徹底消除這個問題,可能得等到幾十年之後了。

有些人可能會說:“如果 C++ 真那麼垃圾,為什麼還有那麼多人在用?”要知道,這個項目開始於十年前,除了 C++ 沒別的可供選擇呀。現在的大多數軟件工程師都不會這樣故意給自己找麻煩。

根據現在 Slashdhot 上發佈的 C++ 相關內容來看,躲著 C++ 走已經基本成為一種共識。

瘋狂的版本控制

這個項目進行了好幾年,團隊裡終於有人想到應該使用版本控制工具。最初選擇的版本控制工具沒能起效,所以大家還不斷的變更管理工具。每一次變更,都導致原有記錄徹底丟失。最終選擇的是一款真正災難級的來自瑞典的圖形用戶界面。

項目組還專門建立了一支有四名成員的團隊,致力於解決版本控制軟件的基本維護工作,其中包括:

  • 首先提交申請,與版本控制團隊約定溝通時間,整個批准週期大概是一個禮拜。
  • 沒有中層管理的授權,不得編輯文件。員工必須事先上報自己想要編輯的文件,而後發送正式的審批申請,申請會被遞交至版本控制小組,他們可能會在接下來的幾天內實際執行。
  • 對代碼的每一次修改都會創造出新的分支,所以必須得想辦法合併並回收所有修改內容。由於存儲有大量文件,所以各位可能覺得不會同時有兩個人在修改同一個文件,對吧?但事實證明,大部分修改都集中在大約 100 個文件身上。
  • 更新過程同樣非常痛苦:提交的代碼將首先接受自動 bug 檢測軟件的審查,而後再由中層管理進行人工審查。可以想見,緩慢的審查速度導致 bug 的產生速度比清理速度快得多。認真查看已經報備的 bug,大家會發現每一次 bug 修復都會帶來兩倍的新增 bug。
  • 版本分配方式簡單而粗暴:舊軟件是第 1 版,目前的軟件是第 2 版,未來的軟件是第 3 版。實際上,根本沒人知道最終交付給客戶的會是第幾版。

終於有一天,項目正式交付了——而且這個時間已經不是當初商定好的時間了。在項目截止的那天,他們交給客戶的實際是一張包含安裝說明的空白 CD,因為到這時全部開發結果已經不可能在幾周之內完成 build。客戶發現了其中的貓膩,並正式發起訴訟,公司就趕緊把去年的舊版本再交上去,而且絲毫不打算掩飾下。

隨意解僱員工

大型企業所代表的不只是沉重的人員結構負擔和金字塔上面的複雜體系,其中更存在著無數所謂中層管理人員——他們專門負責收拾基層員工,這就是他們的全部工作內容。從中層管理者向新人介紹工作內容的那一刻開始,影響就已經出現了——他們只知道下命令,不理會任何底層反饋。

有很多極端的例子:

  • 早上九點到單位,一分鐘也不能遲到。有一天,有位經理站在大門口,每位遲到的員工、哪怕只遲到了一分鐘,都會被當場開除——其中包括幾名經理以及銷售人員。
  • 咖啡機每隔幾天就會出毛病。這顯然是人為搞出來的,可能管理者們認為總喝咖啡也影響工作效率。畢竟省下這段時間,程序員完全可以多碼幾行代碼。
  • 廁所從來打掃不乾淨,看著讓人噁心。這可能是為了提高生產效率:減少待在洗手間裡的時間,就能讓員工拿出更多時間幹活。

很多人不相信上班遲到一分鐘就會被當場開除,但這就是事實。因為請了外包公司,所以企業可以隨時撕毀合同,這也是外包公司的意義所在。曾經有一家外包公司的員工被解僱,法院方面用了兩年時間進行調查判決,最終只獲得 3 萬塊的賠償。相信很多朋友都覺得這麼點錢不值得耗費巨量的時間心力,而且大多數人甚至不會提起訴訟。

哪怕是直接跟甲方簽了合同,情況也好不到哪去。公司可以因重大過錯為由把你當場開除,然後等待幾年的漫長調查再跟你出庭對質。但面臨失業壓力的可是我們自己,誰願意拿出兩年時間跟前任僱主沒完沒了地扯皮?

這家企業,還曾經以穿短褲上班為由解僱員工。這位員工選擇訴訟併成功勝訴,但公司一方最終還是把禁止穿短褲上班寫進了制度。

不斷的解僱導致新人的平均留存時長僅為 3 個月,這還是因為法國法律規定員工至少要待滿 3 個月才能被公司解僱。

最後剩下的項目經理比團隊成員還多,55 名團隊成員之中有 20 名開發者,和 35 名經理。也就是說兩個項目經理才能分到一位程序員來給他幹活兒。

經理們不斷組織各種會議,不斷髮布內容完全相同的 PPT 演示資料,而開發者們則在寬敞的開放式辦公區內聊天打發時間。這幫經理也都沒什麼軟件工程方面的經驗,技術水平低下。經理們對互聯網沒什麼瞭解,最多隻聽說過色情網站。聽到他們討論互聯網,員工也只能保持尷尬而不失禮貌的微笑。

官僚的管理方法

因為不斷的隨意解僱員工,也沒人敢說個“不”字,最終慣壞了這批高層領導,導致整個企業的管理作風極其官僚:

在現場露個臉,比處理實際工作更重要

工作到底做成個什麼樣子,往往沒人關心——但是,你絕對不能遲到、不能早退、不能不參加會議。正常下班時間之後,你甚至沒什麼正事可做,但你得在那待著,跟同事聊聊天、喝喝茶、上上網。這些都行,但不許回家,否則你就趕不上下一波升職加薪。這裡的基本思路是,你應該把自己的生命奉獻給公司。放棄家庭生活,最好能不拿薪水——無論你前一天加班加點趕出多少工作,第二天都一定不能遲到。

上報的內容不重要,但文本格式必須拿捏得死死的

作為一名員工,你辛辛苦苦完成了一份報告,自認為這份報告內容翔實、建議中肯。但是,領導首先看的不是內容,是文本格式是否正確。如果公司徽標顏色不對或者 Word 文檔的格式沒按要求調整,那一切肯定被打回重來。

電腦一水的微軟標配

在這裡,每個人都用 Windows,通過 IE 瀏覽網頁,用 Exchange 發送郵件,使用 Word 編輯文檔。如果文檔裡的條目數量不超過 10 條,請把它做成 PPT。10 到 20 條之間,那就是 Word 格式。如果條目更多,只能用 Excel 電子表格。IETF 和 RFC?那不是開源的東西嗎?我們可不用那種“沒版權”的東西。

Java 是唯一的語言,XML 拯救一切

其他編程語言都是給麻省理工那幫科學家準備的。我們只用行業中最主流的語言選項。如果其他人都在用,那肯定不會有錯。

花錢就是為了讓程序員寫代碼的

軟件工程就是把簡單的事情複雜化——本質上不就是由廉價勞動力在那寫點代碼嗎?要開發軟件,需要的就只有頁面和代碼頁,這些頁面必須是純 ASCII 文件。程序員(或者叫碼農)按代碼行數計算報酬,代碼行的生產跟編碼器數據 / 編碼耗費的時長保持線性比例關係。總而言之,花錢就是為了讓程序員寫代碼的,其他事情你們不要摻和。

你知道就行,別往下傳

你得把自己掌握的一切有價值信息報告給上級,但千萬不能透露給基層員工。最理想的狀態,就是每名員工都整天坐在自己的計算機前面編寫代碼,完全不質疑或者挑戰現有執行決策。

人力資源部門比人力資源本身更重要

人力資源是種可以犧牲的素材。在危機時刻,公司可以隨時剔除某些個體,再快速招聘新的人員。但是,人力資源部門本身卻不可替代——他們掌握著招聘與解僱的生殺大權,千萬別得罪這幫人。

小結

現實中,有著官僚習氣的企業要遠比靈活有趣的公司數量多得多。大家不妨對號入座思考一下,一旦你發現你的企業或你的項目有這篇文章裡提到的問題,就不要抱以希望了,它已經沒救了,趕緊撤吧!


關注我並轉發此篇文章,私信我“領取資料”,即可免費獲得InfoQ價值4999元迷你書!


分享到:


相關文章: