天天看點

浮躁世界,我思考

1. (一)

又是一個悶熱的周六,灰霾就像粘在天空一樣,依舊籠罩着這個城市。帶着小寶,我們三人遊蕩在藍色港灣的兒童城中,為小家夥的未來打算着。老婆和丈母 娘穿梭于一個又一個玩具店,而我,因為推着童車,不便走來走去,就帶着小寶靜靜地欣賞樓下冰場裡玩耍的孩子們。很快,我們的注意力就被冰場上兩個正在進行 對抗訓練的小男孩吸引住了。小寶快樂地随着冰球轉動脖子,雙眼緊緊地捕捉着黑色的冰球,不時發出愉悅的『喝彩』;而我,默默地看着兩位『男子漢』一次次跌 倒,又一次次爬起,對抗雖然異常激烈,但任何一方都沒有髒動作,這足以讓真正的冰球賽場上的成年人汗顔。

連日來,對環法自行車賽興奮劑醜聞的追蹤報道,讓曾經的英雄們紛紛落馬。成人世界裡,人們對于名利的渴望,對成功的追逐已經遠遠超出了能力或是道德 的底線。我們不得不承認,這個世界正變得越來越浮躁。會爬的恨不得立即會走,踉踉跄跄走着的,又恨不得能撒腿就跑。前兩天我在卓越亞馬遜上随便查了查『小 時學會』和『天學會』,結果發現分别有65條和157條結果之多。『Java程式設計24小時輕松掌握 』,『21天學會javascript』,『30天學會Visual C++』,...看着那列出的一大堆需要花很大力氣學習和使用的語言,我不得不感慨這種浮躁已經無處不在。

小寶還在咯咯地樂。那種發自内心的,如雪花般潔淨的快樂讓我由衷地羨慕。如果不是上周日LP跟我嚴肅地讨論了一下在未來我如何更好地履行父親的責任,此刻(周六的下午)我應該端坐在辦公室裡思考某段代碼該如何去寫,而不是在這樣一個放松的環境下,任由我的思想翺翔。

我們讨論的結果是,一周裡大禮拜我能不去公司工作就不去,并且工作日最好有兩天趕在七點前回到家,這樣,可以大大增加我在家中陪伴小寶的時間,提升 她對『父親』這個角色的認知。在北京這樣一個擁擠到幾乎處于崩潰邊緣的城市,以公司到我家長達三十五公裡的距離來算,晚上七點前回到家就意味着至少提前兩 個從公司出發,還得祈求一路上 1)沒有事故(小機率事件),2)沒有管制,3)沒有幽靈堵車。兩個小時的車程對很多北京人來說還在忍受的極限内,但對我來說,開車上/下班的時間超過一 小時我就已經渾身難受,更遑論兩小時這一讓人絕望的數字。是以,我決定在提前回家的那兩天搭乘地鐵,這樣,隻消花一個半小時,我就能回到家中;而且,在地 鐵裡,我可以暫時遠離代碼和網際網路,翻幾十頁和技術毫不相幹的書。巧的是,上周不開車的兩天上下班時間裡,我翻的書是《長日留痕》——一本我買了很久,翻 了幾次卻都沒看進去的小說。史蒂文斯先生,書中的主人公,利用一次旅行的機會回顧了他漫長的管家生涯。在整部書中,他始終在回憶過去的人生,并且不斷地探 讨一個嚴肅的問題:一位傑出的男管家究竟是什麼樣子的?

感謝這本書,讓我開始嚴肅地回顧我自己的職業生涯。這思考斷斷續續遊走了好幾天,很多時候幹脆藏身在潛意識中,以至于每每我工作累了,對着窗外中關村東路和成府路交叉的路口發呆時,它就會蹦出來,讓我暫時從繁重的工作中解脫出來,在回憶中盡情徜徉。

2. (二)

教練一聲哨響,把我暫時拉回。此時此刻,兩個小家夥開始了一攻一守的對抗,場面也變得好玩起來——兩個小愣頭青從場地的兩端以幾乎相同的路線滑向中 圈,砰的一聲,重重地撞到了一起,一同倒地。教練上前,把攻方的小家夥拉到一旁耳語幾句,并比劃了幾下,随即恢複了比賽。兩人從場地的兩頭快步沖向中圈, 守方将重心控制地很低,高速滑動中,目不轉睛地盯着冰球。就在兩人要接觸的一刹那,攻方一個急停,然後迅速切向斜前方。由于撲得太猛,守方來不及調整,無 奈讓攻方輕松繞過自己,打進一球。不知是看懂了比賽,還是單純開心,小寶揮舞着雙手,發出歡暢的尖叫聲。

這就是教練的作用。他們告訴你什麼是基本功,如何應對局勢,以及一名優秀的球員應該具備什麼素養。在一個人職業生涯的早期,一位好的導師比什麼都重要。一晃我的程式員生涯已經過去了十年,在這十年裡,我一直在不斷探索一位優秀的程式員究竟該具備什麼素養,如果當時有個教練能給予我指導,給予我探索的方向,那該多好啊。

可惜沒有。軟體行業沒有教練,也沒有拜師學藝的傳統。也許曾經有,但自從程式員從手工藝人變成了工程師,教練或者師傅就不再重要。你基本不需要像手 工藝人那樣具備從無到有做出點什麼的技術,你需要的僅僅是解決某個或者某些特定問題的能力 —— 某種意義上說,這和流水線上的勞工并無二異。這也導緻了那些速成的圖書的暢銷,因為它們試圖讓你學習到的是如何完成任務,而非如何程式設計。當然,網際網路正在粉碎這一切,程式員似乎又在回歸手工藝人的傳統,這很好。

雖然沒有教練,但每個軟體公司基本都會為新員工指定一名資深的同僚提供『象征』意義上的 "mentor"。我說『象征意義』,并不是否定mentor的作用,而是說這些mentor并非職業化的mentor,『傳道授業解惑』的為師之 道,mentor們勉強在解惑上提供了些許幫助。當然,對于公司來說,mentor最重要的作用是成為一個榜樣(Role Model),通過他們的工作态度,工作習慣,工作能力,對新員工,尤其是處在職業生涯早期的員工産生潛移默化的影響。

我職業生涯起始的公司是神州數位網絡公司(DCN)。如果将google或者twitter定義為『優秀』公司,那麼,DCN顯然處在平庸公司的行 列。好在DCN繼承了老聯想的底子,還有一批有理想的做系統的牛人。Z君就是這樣一個人。碰巧我被分在了他所在的團隊。當我把『一位優秀的程式員究竟該具 備什麼素養』這樣的問題抛給我的mentor,即将離職的X君時,他讓我多看,多學Z君。之後,有意無意地,我都會多去勞煩Z君,他總會抛開手頭的事,爽 快地為我答疑。為了解決某個問題,他經常工作到深夜;跟他讨論代碼如果沒揪到根上他絕不善罷甘休。拿code review來說,當你看到一堆邏輯上無比正确但寫作上WTF的代碼時,即使想罵娘,但屈服于release的壓力或人情世故,你總會妥協。但Z君不太會 妥協。他會笑眯眯地,毫不留情地指出你代碼上十多處毛病,讓你整改。很多人認為代碼邏輯對了就足夠,但Z君期待代碼(算法)在時間空間上的合理(和諧), 以及是否做到了SoC。工作之外,他又是個吊兒郎當的人,經常爆發出的爽朗的笑聲,渾身濃重的煙味,讓你即使在很遠的地方,也能感受到他獨特的氣場。

從Z君身上,我找到了一直追尋的問題的第一個答案:

真心喜愛你所做的事情。

真心喜愛你所做的事情。之是以斟酌出這個句子,是因為我覺得諸如『敬業』,『有韌勁』,『鑽研』,『愛學習』等詞語或多或少都被它涵蓋,或者說,是它的自然而然的結果。

那時對我而言,『真心喜愛』就意味着每天超過12個小時泡在公司裡努力搞明白遇見的每一個技術問題。很快,我搞透了OSPF,填補了X君走後OSPF上的空缺,之後又獨立開發了IGMv3,SNTP,接着完成了極其重要的linux 2.4 kernel的移植。

3. (三)

由于工作的原因,我逐漸與另一個團隊的S君打交道很多。S君興趣很廣,他幫着公司内部搭建了團隊的wiki,使得資訊的交流,知識的分享大大地系統 化。以前我們知識的交流以郵件為主,這很被動,當下有用的,還是無用的知識,都一股腦成了一封封亟待打開的郵件。打開看吧,浪費時間;不打開吧,以後需要 時都不知道自己的郵箱裡還有這麼份東西。在S君的推廣和維護下,團隊的wiki大大提高了大家擷取知識的效率。

從S君那裡得知,他使用了一個叫mediawiki(wikipedia使用的軟體)的開源軟體。我開始把玩mediawiki,進一步,我接觸了 LAMP,并且逐漸意識到像linux,Mediawiki這樣的開源軟體的重要性。如果說林則徐魏源是近代中國開眼看世界的第一人,那麼他也許是DCN 内部擁抱更廣闊的世界的第一人。做system的,很少關注application的動向,有種天朝藐視番邦的傲嬌;而做application的,則放 低姿态謙卑地注視着system的變化。現在随便拉一個做路由器的人,你問問他對web application的看法,十有八九還停留在對LAMP的認知上;而做web application的人已經把觸角伸向了user space data plane。究其原因,是做system越做越掌控一切,傾向于封閉;而做application越做越依賴生态圈,是以擁抱開放。

S君讓我認識到了開源的力量和開放的社群的偉大之處。懷着對mediawiki的敬畏,我開始學習PHP,進而在他的影響下,學習據說是『聰明的程式員』使用的Python。我想我已經是『真正的程式員』了,如果能成為『聰明的程式員』,何樂而不為?

在這個過程中,我找到了第二個答案:

擁抱開源和自由軟體,擁抱社群。

大學期間,我曾經是一個堅定的微軟主義者:凡是微軟推出的,我都擁護;凡是微軟反對的,我都反對。直到畢業時,我還天真的認為C#就是我們這代程式 員的終極武器。S君及時把我從這種盲從中拉了出來,讓我看到了一個不一樣的世界。現在棱鏡門事件的熱度在漸漸褪去,但是,它讓人們開始意識到 Richard Stallman的思想的重要性:開源軟體關乎着人類的自由。遺憾的是(也許我不該這麼評價),我的兩任雇主,對開源軟體的貢獻要遠小于其索取。

PHP和Python對于我所做的開發任務似乎毫無幫助,學習它們地目的是為了了解更廣闊的世界,了解為什麼最流行的軟體會被用這樣的語言開發出 來。為了更好的實踐我的所學,我用PHP和Python做了一個工具:開發人員可以通過一個PHP撰寫的web頁面送出一項測試任務,背景的python 腳本拿到這個任務後會拉下指定版本的代碼,編譯,并将編譯好的image傳到直連的交換機上,然後開始運作測試團隊提供的regression腳本。我的 工具帶來的效率的提升引起了老闆的重視,我被準許使用一台PC和兩台交換機,組成一個完整的環境,供開發團隊踐行CI(Continuous Integration)。

在這個過程中,我發現了第三個答案:

能夠通過自身所掌握的技術,不斷提高自己和團隊的效率。

容我再解釋兩句。一個真正的程式員,在那些每天重複低效的幹活方式展現在你面前時,很難抑制住利用自己的技能做點什麼改變現狀的心情。工作中(當然 生活中也是),這樣的低效比比皆是。比如說從X系統中定期導出一些資料到excel中做報表,比如說一級一級收集weekly report進行工作彙總。

這種低效在我工作過的第二家公司,Juniper,也廣泛存在。

回顧我目前的整個職業履曆,我在DCN工作了兩年零兩個月,在Juniper China R&D(CNRD)工作了五年半,在途客圈作為創始人和CTO工作了兩年,然後回到Juniper CNRD工作至今。是以,作為雇員,我總共就工作過兩家公司,是以,是否每家軟體公司都存在類似的低效,我不得而知。但我覺得,工作中的低效場景無處不 在,問題在于有沒有被發現,發現後值不值得為此做點什麼。

4. (四)

冰球場上的對抗結束了,小家夥們離場休息去了。我松開手上的童車腕帶,把腦袋湊過去,輕喚小寶的名字。小寶顯然還全神貫注于冰場,被我這突然的舉動 吓了一跳。當她惶恐地轉過頭來看到是我,便放下心來,微微笑了笑,又回過頭去欣賞冰場上的運動。循着她的目光,我看到冰場上一個也就六七歲大的小女孩一個 人在認真地練習花滑。她的動作如此純熟,姿态那麼優美,讓你幾乎忘了她的年齡。我想,她大概這麼練了有很長一段時間了吧。

看到這裡我不禁想起在Juniper曾經跟Y君讨論過我們招人的準則。我不解為何我們不給年輕員工,甚至應屆畢業生一些機會。Y君認為我們需要的是 專家,而某個領域的專家,根據研究,需要經過10000個小時的培養。我算了一下,假使每周四十個小時,一年五十周撲在某個或者某些特定的領域,那麼,五 年的時間就可以造就一個專家。這也是為何很多公司對于senior的職位,都要求至少五至七年的相關工作經驗。但現實是,在面試中,很多五年,甚至十年工 作經驗的人都未必對得起自己逝去的年華。我曾經遇見過一個工作了8年之久的程式員,在提供了vim,gcc等編輯編譯環境的情況下,連一個非常簡單的連結清單 操作的程式都無法正确完成。這是怎麼回事?

我查了查"10,000 hour rule"的原文,是這麼說的 —— "it takes approximately 10000 hours of deliberate practice to master a skill"。

問題出在了"deliberate practice"上。

何謂"deliberate practice"?鋼琴考級有九個等級,每個等級都有要求的技法和曲譜。這是一系列刻意設計的練習,每一個級别都比上一個難度大一些,但經過努力還是可 以掌握的。當你對車爾尼駕輕就熟後,可以嘗試一點巴赫,也許也可以是貝多芬,但絕不能倒着來,也不能跳着來。跳着來意味着你目前的水準和期望的結果之間的 鴻溝太大,也許已經超過了單憑努力就可以到達的境地。

可惜軟體行業鮮有這樣的"deliberate practice",學校和教育訓練機構也沒有類似的體系。是以這個社會能夠批量造就鋼琴9級獲得者,卻無法批量培養出合格的程式員。很多擁有五年工作經驗的 人,折合成有效的經驗,也許就隻剩一年,剩下的四年隻不過在重複自己第一年的收獲。這就好比一個人掌握了車爾尼《鋼琴簡易練習曲》後,還在刻苦反複練習相 同的内容,即使練到脫離曲譜信手拈來,又有何用?

想想我們的境地,挺悲慘的。沒有合适的導師指引方向,沒有成型的體系來培養專家。但是我們還得不斷地學習,不斷地更新知識。對于那些還尚未『開竅』的程式員來說,職業生涯就像《富爸爸窮爸爸》所謂的老鼠賽跑,在蹉跎中耗盡光陰。

是以自我救贖的最好方法就是不斷地給自己增加挑戰,讓自己脫離舒适區域。具體方法是:用那些剛好超過自己能力的任務挑戰自己,build(嘗試) - measure(分析) - learn(學習總結)。然後不斷重複。這是lean startup一書中建議的精益創業模式,同樣也适用于這個場合。

不要去看那些多少小時或者多少天就能掌握XYZ的書。生命苦短,多讀讀大師的著作和文章,他們能讓你跨越到新的台階;多寫代碼,多寫能讓你有征服感的代碼。

這就是我找尋到的第四個答案:

不斷跳出舒适區,有目的地挑戰自己。

讓我倍感欣慰的是,在Juniper的這五年半時間裡,公司提供了各種機會讓我在三個不同的team裡學習和掌握data plane,kernel,以及application。托L君rellocate到US的福,我還有機會lead一支團隊,來踐行我在 leadership上所學的理論知識。

冰場裡依舊人聲鼎沸。怕寒氣把小寶凍着,我不敢在此過度停留,我把車推着往裡靠了靠,坐在一張椅子上稍稍休息。小寶舉着雙手似乎在抗議,但當她發現從她坐着的角度依舊能看到冰場的一角時,就漸漸安靜下來,雙手自然搭在童車的護欄上。

說來好笑,就在我離開Juniper的前夕,L君主持了一場小規模的英文演講訓練,以此來提高manager們用英文當衆發言的能力。我的主題就 是"Move yourself out of comfort zone"。後來偶然的機會,我遇到了同樣也離開Juniper的L君,他說他那時就感到我要離開。我問為什麼。『因為CNRD對你而言已經成為一個 confort zone,你隻需不犯錯誤,靜靜等待,就能一點點向上爬,而這又和你的性格,尤其是你的演講傳達出來的感覺不同。』L君回答道。

想想也真是。我的性格裡流淌着不安分的血液,它源自我的父親。一九九三年,父親隻身前往海南和廣東,像那個時代的所有朝氣蓬勃的年輕人一樣,希望能 夠在改革開放的最前沿,尋找工作機會,潇灑走一回。和其他人不同的是,父親當時已接近不惑之年,有家有口,還捧着醫生這樣一個金飯碗。如今我已過而立,晉 升為爺爺的父親年逾古稀,在這個本該安享天年的時刻,仍然奮鬥在第一線,業餘時間還以編者的身份出了個人的第一部書,同時正在緊張地編撰第二部。父親就是 我的榜樣,能夠全面超越他是我的一大理想(當然這也是一個達爾文主義者必須做到的,總不能一代更比一代差吧^_^),可惜至今我還未能完成這一理想。

5. (五)

A language that doesn't affect the way you think about programming, is not worth knowing.  - Alan Perlis

離開Juniper,我選擇了創業,建立了途客圈。那是一段奇妙的旅程,一段讓我成熟很多的征途。有史以來第一次,我寫軟體,不是為了我的雇主,我 的payroll,而是為了我的夢想。雖然這段旅程僅僅走了兩年我就不得不因為一些個人的原因選擇了自我放逐,但這兩年,如喬幫主所言,是我開始去連接配接那 一個個"disconnected dots"。我的程式設計水準開始極大地發展,我的軟體開發思想在不斷走向成熟,我越來越覺得自己像是一個真正的程式員了。

重要的是,我開始學習新的語言了。你也許注意到,自從從DCN學習了PHP和Python後,在Juniper我就不再學習新的語言了,部分原因是 我在夯實我這兩門語言的水準,尤其是Python的水準,但更關鍵的原因是我開始固步自封了。C讓我成為真正的程式員,Python讓我成為聰明的程式 員,我似乎找不到繼續學習新語言的理由。

但是,創業改變了這一切。我不得不學習javascript,因為這是用戶端唯一的标準。盡管在十多年前我就接觸了javascript,并用它做 過一些效果,但那時對javascript的使用,與其說是使用,不如說是誤用。在途客圈,我才真正重新認識這門prototype based language。另外,為了權衡究竟什麼樣的架構更利于未來的發展,我花了很多功夫深入了解ruby,在ruby和python之間進行對比。通過《松 本行弘的程式世界》,我了解了設計ruby時的很多思想。盡管途客圈最終選擇了python/django,但這是一次非常有益的對比和思考,它讓我進一 步找到了第五個答案:

學通超過一種程式設計語言,了解盡可能多的程式設計語言及其優劣,知道解決某個問題的可能的最佳路徑。

注意學通和學會是兩個概念。學會意味着你能夠使用這門語言,會寫程式,而學通則意味着更多:

  • 了解語言被建立之出的動機,深刻了解語言背後的思想。
  • 掌握如何線上調試(online debugging)和事後分析(coredump analysis)。
  • 掌握語言外延/周邊的技術。如JVM之于java,OS/CPU EABI之于C。
  • 掌握如何提升關鍵代碼的效率,如何能夠擴充語言的能力。如NIF之于Erlang。

很多在履歷中号稱精通C的人不知道malloc背後都發生了什麼,精通Python的人卻無法用meta programming寫出幹淨漂亮的代碼。這樣的精通其實也就是勉強學會。

按照這個标準,摸爬滾打了十年後,我在C語言上勉強算學通,Python和Javascript隻能說學會,Erlang/Ruby剛算了解。

容我再解釋一下為何要了解盡可能多的程式設計語言極其優劣。比如說新開發的軟體并發模式要采用STM(Software Transactional Memory),如果在技術選型前,你知道clojure在語言層面,haskell在GHC層面實作了STM,那麼,你的選擇可能不會局限于你之前所用 的語言。

6. (六)

總而言之,現在完全不可能讓時鐘倒轉了。你不能永遠總是對過去也許會發生的事耿耿于懷。你應該認識到你與大多數人一樣地過得很好,或許還要好得多,那就應該心滿意足了。  - 《長日留痕》
Life is short, [the] craft long, opportunity fleeting, experiment treacherous, judgment difficult.  - Hippocrates

也許是之前的凝視耗費了太多的精力,小寶開始打着哈欠揉眼睛。她回過頭來,張開雙臂,滿眼期待地望着我。我知道,小家夥想要抱抱了。

十年前我根本無法想象十年後我能如此幸運而又意外地擁有她,正如十年後我無法預料她會變成什麼樣子。我可以為我的職業生涯,還有她的人生 做"deliberate"的打算,但我無法控制結果。過去的十年,我遇到了很多很多十字路口。就像《長日留痕》裡說的那樣,『你不能永遠總是對過去也許 會發生的事耿耿于懷』。重要的是,我做出了選擇。我很高興我的人生經曆與大多數人一樣豐富,或許還要豐富得多,我很高興我有很多很多故事講給我的孩子聽。

哦,忘了說另外一個答案,也就是第六個 —— 當然,僅僅對非英語母語的人有效:

能用英文自如地閱讀,寫作和交流。

一位優秀的程式員究竟該具備什麼素養?

在用了近8年的vim之後,我決定,嘗試emacs。