跟朋友吃著飯,說接下來看個什么電影去呢。看著四月份的爛片列表無語,居然五十度灰還在放。他笑了起來,說他媽七十歲生日那天自己去看了五十度灰。看完,用一句臺詞總結,what the,哈哈。思路(渾身肌膚都)需要捋的時候,為什么被別人捋不是虐心是享受呢,因為能激發一點想象力吧。
他問,“五十度灰什么意思?”
“無非一層層把過去的遭遇剝出來。” 我想了一想。
對軟件工程的發展有二十幾年的感覺,也積攢了一些程序員的經驗,開篇的調戲是為了防止后面沒激情。(You know, I noticed my male colleagues write "0xBABE" "0xDEAD" when they initialize byte arrays. Subconsciousness... what a lonely profession.)
我父親是水文領域的計算機專家,因此我小的時候接觸計算機非常早,幾歲的時候就用過打孔的紙帶,八進制的。但是接受了他的理論,計算機只是工具,為各個專業所用,反倒沒報計算機系。因為我喜歡物理討厭化學所以最后選了材料科學,比計算機或電子工程更好申請獎學金,因為出國是早就定好的目標,可以開闊視野。最后在美國讀金屬材料不好找工作,趕上 2000 年的泡沫又轉回到計算機。
入行具體做網絡通信,而且先是個偏門,control network,2000 年在做智能家居的東西,在 JavaOne 上發布一個 demo,移動端是 Palm Pilot。后來做智能大廈 building automation, PC 端的東西。再后來回到 data network,Ethernet AV streaming 的固件。最后八個月轉領域做了 flash controller firmware。這幾次轉換相當于三個處女期(通常是一個月),幾乎都是愉悅壓不倒痛。以IT業的節奏,程序員一輩子只當一次處女恐怕難求。
現在還清楚記得第一個月上班天天沮喪,跟的高級工程師在 port 一個幾十萬行的 C++ 產品去 WindRiver 的新版。不寫新 code,porting existing code 貌似簡單。CS grad,編譯總會吧。沒想到編譯出的錯,dah,以zillions 計,一個月都沒解決干凈。還記得有些人注釋寫//不是/* */。"Son of bitch!"他氣得沖出辦公室找那些人算帳去了。這就是為什么以前要寫 portable C 的規范,現在的 compiler 哪個不能處理這個,lol。除了這些低級問題,還有 WR 的問題,我又不熟悉本公司的代碼,又不敢亂改,又不是時時逮到人能問,只能沒日沒夜加班砸時間熬。最后老板看出來老工程師一沒好好帶,二也不適合新手做,把我抽出來做 Java 小項目。相關的codebase 小,入手就快(Size matters,帶新人的程序員切記)。Port 一部分 C++ 去 Java,還有的用 JNl 調用。這個非常好,讓我熟悉了兩種語言的 mapping。而且 Java API 是多么的好查找好調試,呵呵,以至于迄今我對 C++ 過敏,能寫 Java 和 C 就不寫 C++。(電影里怕她第一次對鞭子過敏的有木有。)當然 C++ 是Windows 時代 desktop shrink wrap software 的首選,和 visual studio 還是很好用的。我老板做得非常好的幾點是,看到我加班就說,“回家,加班太多了做不長久”。而我 Java 這邊一做出點東西大加贊揚。每周固定時間1-on-1,聊完了工作聊別的。我后來因為個人原因跳槽,他二話不說要 match 下一家的工資。所以離職很久了我仍然給他寄圣誕卡。
在這家公司做 OSGi 的實現,G 是 Gateway,for networking,跟 Eclipse 本來八竿子打不著。不得不服美國技術思路流通塊,好的思路拿來用,原來的項目死了,用得成功的反而更有名。Eclipse 第一次設計大轉型后,基于 microkernel 加插件的 OSGi 構架。Eclipse 已經很復雜化了,畢竟是 IBM 的班底再開源的。IBM 的哪個產品都有點航空母艦狀。我們做的比較 micro,硬件盒子基于 Linux 的,Insignia 的 JVM。我經歷了 J2ME 的誕生,想當然 JVM 可以在任何硬件上跑。(今年和移動端開發觸電,what the,Android 和 iOS 是兩套?同樣的活,干兩遍。Give me a break.)
后來換了個公司,又趕上內部 reorg,有兩個組選擇,去做 PC tools,雖然是配角,老板很 nice,同事全是美女,至少還是 PC software,熟悉。另一組是 firmware,全是男同事,老板也比較硬,問題是,我沒做過firmware。但這是核心部門,正缺人,裁人的風險小。去吧,要養家糊口呢。一上來,當測試,firmware 部門原沒有專人測試。(犯了 Joel Spolsky 的軟件開發十誡之一)呵呵,測試其實是對新人的一個好安排。除了一條,沒有測試文檔,這就把原本簡單溫柔的工作性質變了。我既要看 IEEE specs,印出來幾大本一尺高,又要看code 實現。還好跟 control networks 是相鄰領域的,只是 packet format,flow 變了。當時 firmware 組在五樓,沒位置了,我新來坐四樓,反而和 DSP 組的人一起吃飯聊天多些。每天 Email 樓上的問問題。有一天我忘了是問什么小事了,結果引動牛人下樓來大罵,能不能少問這種問題,這都不會還做什么做啊。隔壁 DSP 的人都動容,這是怎么了。(天天吃飯的同事是不會這樣對你的,小笨我沒盡早去打理啊。)情緒上的反胃靠加班壓制,別人不就是嫌我慢嗎。有一天很晚了,人家下樓來看到我,臉色就和緩多了。我說 audio test sample 那首歌真好聽,尤其在公司清凈無人的時候。“哦,Forever at Your Feet。那是我特別的歌。”(歌后面是有故事的喔。)結果兩年后他離職的時候,組里就我哭得眼圈紅紅。他說,他在那工作三年,能得了兩個人的眼淚,也值了。他走以后,我們的產品和 Apple, Broadcom, Harman, LabX 做兼容測試的時候,老美喜歡放搖滾,我們總放這一首有點凄涼的歌。凄涼到最后,一連走了7個人。我試圖向上進言,未果。現在發現,當牛人的付出不得承認并且被錯誤對待時,一走會走一片的,眾人都會心有戚戚焉。
我最后一個走的。Flash controller 公司熱的時候不好招人,做過 disk controller 的上,單跟 firmware 沾邊的也上,像我這樣的。(跟現在移動端招人像不像?火線上崗。)第一天老板講話極快,后來知道了他是 brilliant engineer, (慢一點會減少痛,好嗎), 二十分鐘入職培訓講完了。派我邊看 code 邊 fix bug,這是培訓新人的正常方式,正舒口氣。兩天后,不好了,是個 timing related bug,有時出有時不出。這個也會做,多 run,想辦法讓它一直出。但和 networking test 傳包解析包結果立得不同的是,flash 很多 test case 是反復讀寫,有隨機性。我要用的特殊 case 要 run 2-4 小時。百般造簡單 case 的嘗試不成功,這就去了一個多星期了。老板說,還是用原 case,事后證明他的方向是對的。兩個星期的時候,我看到 code 里有一個 switch case 沒有 break, falls through,是一個state machine,注釋不太多。試吧,加上 break, pass, 拿掉,fail。特別小心地把全體功能性 test run 一遍,至少沒有 break 別的東西,夜里興奮地 check in the fix。第二天被老板 revert。? 解釋是需要 fall through,這只證明是 timing bug。跟 chip designer 談談?那人已經離職了,跟接替的人也沒套出什么來。繼續折騰不同時間點的 build,娘啊,一天只能 test 幾版,SVN commit 每天都是幾十個,好不容易得出另一個 hint, 兩個月前 fork 的某個 branch passes, the trunk fails. 這就是時不時 branch 要承受的痛. 在source control 里 branch 一下很容易,就按這個客戶的需求改一點交出去,快啊,不影響別的功能開發。(容易的快感要抑制,才會爽得久一點。)那就死磕兩邊的 diff 吧,特別多,肯定先注意 functional changes,不會去看那些 printf。每天 6 點一睜眼就 VPN 看 lab 里前一天的 test 有沒有結果,然后再 run 上一個,9 點人到公司能看結果,晚上 8、9 點離開公司時 run 一個,睡覺前還能再 run 一個。(不是程序員的人看 Imitation game 會對這種跟機器打交道的孤獨、挫折和堅韌有切身之感嗎?)最后讓人淚奔的結果出來了。Pass 的 branch 里有幾句 logging (類似printf),在 trunk 里被注釋掉了,影響了 timing。將近一個月過去了,兩周一版的 release 趕上了第二個。我頗有點抬不起頭來,一個 bug 花了這么久。多數 team members 和老板都比我年輕,平常也不叫我一起吃飯,真不是一個好的開頭。
幾個月后,我決定辭職學中醫去,不想做新項目了,老板讓我把 codebase 重整一下,因為每個新項目都是 clone the old codebase then modify。如果每個新人進來都像我那么掙扎,公司損失大了。(真是哪壺不開提哪壺。)Refactor 絕對是個吃力不討好的事,同事不歡迎,極大影響進度,出錯的風險大,程序員也不愿意報績效時沒有具體實現新功能。我很愉快地同意了,和各方溝通,把 C 文件拆分,模塊化,解決混亂的 dependency問題。C 寫好了不比 C++ 封裝得差,效率不用講了。過程中用了幾個 eval 版 static analysis tools, 包括 coverity (后來認識王垠的時候才知道是他做過的產品). 最后因為 dev seat 實在是貴,不能讓 50 個人全裝,選擇讓一個負責程序員來管理,不太理想,但絕對強似于無。這些 code analysis tool 應該在每個程序員加新 code 前時不時 run 的。
最后跟老板 exit interview,他才講,我后來一次做的一個功能讓他知道我的水平。(經理們,員工的士氣要隨時鼓舞,不要等到他辭職。不給足小興奮會讓人變性冷淡,一樣的道理。)一個韓國工程師做了幾個月的一塊,怎么都有 bug 通不過。我三四天就做好了。當時我一看那一堆 code 散在好幾個文件里,思路也奇怪,就干脆刪了,照著 SATA spec 重寫。Spec 就是告訴 implementer 和 tester 有哪些 case,怎么處理等等。哪像我第一次遭遇的 bug 是一大片混沌,無章可循,而且我除了被告知公司的 flash 裝在 iPhone5 里面,flash 怎么 work的自己去搞定吧。但是另一位年紀大的韓國同事很有心,收集文檔在 wiki 上,平常看他說話做事不是那么靈光,在組里地位也一般,但在幫助新人上功勞是很大的。這就是 team building 的藝術,經理要掌握好。
好了,總結下虐心一二三。不要讓處女程序員情感上落單,也不要一上來就用鞭子和手銬,大項目的不要,穩定性 bug 的不要,要 sit together, eat together, take it slowly, do it the regular way。拿王垠在Google做 Intern 的經歷來舉例,他不是正常人,也不是 virgin,還落下了后遺癥不是嗎。:P