那些年 我追過的語言

陳天發表於2014-03-14

  程式君也年輕過,年輕的代價就是盲目追隨。

  從MS-DOS6.0開始,程式君就是微軟的狂熱擁躉。

  這種狂熱自win95走上高潮(有誰還記得win95光碟裡帶的Good Times的MV,請舉手),歷經《未來之路》,windows2000,最後在dotnet釋出後到達頂峰。

  那段時間,只要微軟反對的,就是我反對的。

<embed>

WIN95光碟上的這首老歌,不知道你聽過沒有

  不喜歡Netscape Navigator,只因為IE;詛咒過SUN,對Java深惡痛絕,因為NC是PC的死敵,SUN妄圖革微軟的命;使用Visual Basic,啃MFC,不為別的,就因為powered by Microsoft。

  但VB功能太弱(其實還是我水平太差),MFC太亂,以至於大二時,我在給人打工做軟體的時候無奈地選擇了Delphi。

  雖然不怎麼喜歡嚴謹的pascal,但Delphi有讓我不得不用的理由。用它寫程式碼清新明快,效率上甩了笨重的MFC幾條街,速度上讓VB相形見拙。在那個Wake On LAN才興起不久的年代,我用dephi做的印象最深刻的一個小feature,是通過一臺電腦開啟(或者關閉)區域網內幾十臺電腦。看著自己的軟體能『神奇』地喚醒機房裡的一群電腦,別提多自豪了。

  在我上大學的期間,做客戶端軟體(或者C/S結構的軟體)雖然能賺錢,但已經漸漸不酷了,ASP的出現,讓我的興趣移師到web(那時時髦的叫法是:B/S)。ChinaRen的崛起讓我萌生了做自己的班級主頁的想法,但做出來的東西只能躺在硬碟上,在參加比賽的時候演示兩下 —— 那時幾乎沒有免費的提供MSSQL的伺服器,而我做的『網站』,無一不基於MSSQL或者其簡化版。我像一隻把頭埋在沙子裡的鴕鳥,把自己限制在自己構築的程式世界。

  後來DotNet帶著微軟的萬千寵愛出爐,我第一時間接受了它。我一邊玩著C#程式碼,一邊繼續無視如日中天的Java 2及NB哄哄的J2EE。C#很迷人,一下子讓我有種想要扔掉delphi的趕腳,但無奈dotnet framework太大(而且相對較慢,當時),還在使用賽揚的客戶無法接受。

  程式設計師在世最痛苦的莫過於最愛的語言(C#)賺不了錢,不喜歡的語言(Pascal)卻為你解決生計問題。

  C#無法在我的兼職生涯中施展拳腳,只能作為又一個參賽語言或者研究院語言,被我拿著招搖撞騙(那時講dotnet就好比現在的雲端計算,大資料,很容易把不懂的人侃暈),寫著連我自己也不相信的虛擬企業資訊整合系統,混各種核心期刊論文。

  畢業後,本來想找份C#相關的工作,卻陰差陽錯地做了通訊領域,讓C取代C#,成了我的主流語言。大學時我的C也就是個習題水平,做過最難的習題不過實現inode模擬一個簡單的unix檔案系統,然後提供幾個shell命令能建立目錄,建立和修改檔案。到了工作崗位,socket,timer,hash table,ring才真正走出教科書;而伴隨著通訊領域的工作,Linux則正式走入我的生活。

  認識到了linux的強大和從骨子裡透出來的美感,我從此與微軟的技術漸行漸遠,也離開了混跡多年的codeproject。

  寫C的日子是枯燥的,尤其是用C寫protocol。完整寫過的IGMPv3,大部分程式碼幾乎都是不用太動腦子的從協議語言到C的翻譯。

  那兩年正是網際網路方興未艾的時候。google正飛速發展,百度從新浪的搜尋提供商(2B)開始尋求面向大眾(2C),3721是瀏覽器的標配,而mediaWiki也隨著wikipedia的走紅而走紅。寫出mediaWiki的php,成了我閒暇研究的物件。那時LAMP開始成為時髦詞彙,WAMP/Apache Friends為還在使用windows的人們上提供全套網際網路開發環境。

  後來我在做一個自動化測試系統時感受到了php的力不從心 —— 我缺一門好的膠水語言,在web和system間遊刃。正巧坊間一直流傳『真正的程式設計師用C,聰明的程式設計師用python』的偈子,於是我又學習了python。這下拼圖完成了:我用php在前端接受使用者提交的任務,用python讀出任務,從clearcase中checkout對應的全套路由器程式碼,編譯出image,然後使用pyserial(一個串列埠庫,可以連路由器的串列埠)和pyexpect(expect的python封裝)連上測試環境中的路由器載入編好的image,然後呼叫測試團隊提供的自動測試指令碼測試。

  那時沒有rabbitMQ這樣的殺器,php和python之間的任務同步做得很土:php把任務插入到資料庫,python程式死迴圈每30s從資料庫中讀任務。

  後來我換到了現在所在的外企,很快在同事的推薦下小試了一陣QT,QT的slot和signal做得真心漂亮 —— 可惜那時客戶端軟體徹底從我的技能清單裡被移除,我也就沒有繼續在QT上發力。

  那段時間,C讓我餬口,php讓我保持和web的連線,而python,一直是我做各種小工具的最愛。

  期間玩過drupal,symfony。看symfony的作者的screencast,才知道有種開發神器叫TextMate,有個程式設計師的電腦叫macbook。

  symfony對我而言是個很好的佈道師,它讓我認識了Ruby on Rails和django(源自symfony和二者的對比)。

  它的一個聯絡專案jobeet還為我日後為創業專案起名提供了思路 —— 對,toureet就是這麼出來的,而且07年前後這個名字就橫亙在我的腦海。這不算個很接地氣的名字,但就像初戀一樣讓人揮之不去。

  知道了Ruby on Rails後,我才意識到如今已經是RoR橫掃一切的時代,幾乎是個創業公司就在用RoR。JavaEye的Robin稱自己幾天就搭了JavaEye出來,我雖然不怎麼混JavaEye,但這還是大大刺激了我一下,讓我對Robin和RoR好頓膜拜。

  但那時RoR內部分裂了有一段時間,社群正在開始思考如何讓分裂的兩個分支摒棄前嫌,在RoR3.0大一統。這讓我好生鬱悶:究竟是等還是不等那遙遙無期的RoR3?畢竟,之前symfony2已經狠狠地擺了我一道 —— 我在1.x上寫的程式碼在2裡無法執行,而且2的改動之大讓我一時間無法適應。如果現在入手學習RoR2.x,會不會重蹈覆轍?

  兩權相害取其輕,我最終選擇了django。

  然後機緣巧合加各種必然,我走向了創業之路。

  等我『畢』業時,我已經算是django和javascript的熟手。

  javascript是個很有意思的存在。我大概在2000年左右抄(對,抄的)的第一段js是一個問候的程式碼,大致是檢查當前時間,然後提供不同的問候語。很傻很天真。

  那時的javascript惡名遠揚。除了好玩,沒人嚴肅看待它。

  直到幾年後prototype.js和http://script.aculo.us出現(誰還記得你們呢?sigh),javascript才開始自我正名。

  然後是神一樣的jquery。

  接下來羽翼豐滿的javascript開始玩MVC,代表作是backbone.js。

  還玩函數語言程式設計,如underscore.js。

  總之到我創業時,javascript的生態圈已經無比繁榮。途客圈的第一個產品的計劃編輯器使用了backbone.js,第二個產品前端全面採用ember.js,而且用coffeescript撰寫。

  我寫了個makefile把所有的coffeescript整合編譯打包。

  我好像沒提makefile吧?程式設計師最好會makefile,減輕很多事務性工作。

  然後javascript在V8的基礎上開啟了nodejs時代,nodejs讓javascript登堂入室,成為後端的一股勁旅。

  從此前端工程師開始屌絲逆襲,成了香餑餑。會Python的不見得敢寫前端程式碼,但會javascript的已經在後端開疆拓土。

  笨重的XML此時已經向JSON讓路,前後兩端的資料通訊被javascript把持。

  mongodb的出現進一步助長了javascript的氣焰 —— 連資料庫都是JSON(BSON)儲存,javascript作為儲存過程(這麼說好理解些),javascript還有什麼不可以?

  幾乎在一兩年間,LAMP改朝換代成了MEAN(MongoDB,Express,Angular,Nodejs/Nginx),nodejs大有當初RoR橫掃一切之勢。

  構建在nodejs上,提倡react的meteor.js向整個網際網路颳了一陣清風 —— 原來網站的程式碼還能這麼輕巧地讓一切動起來!草草學習後,花了幾個晚上,我寫了teamspark,成為了途客圈團隊內部的標準溝通工具。

  可惜不知怎麼的,meteor.js的發展在0.6之後似乎漸漸受到瓶頸,打下的良好使用者和市場基礎在這兩年的緩慢更迭中一點點被消磨。

  後來我從網際網路回到了通訊領域,趁著一段難得的清閒,好好研究了下concurrency。concurrency自然少不了Joe Amstrong的erlang。erlang相對於我理解的那些語言,有點不食人間煙火的意味。

  在erlang身上我貪婪地攫取了很多知識。erlang適應起來很難,尤其你想表達 x=x+1時會感覺那麼地痛苦與無助。我頗花了一些時間才搞明白 atoi() 在erlang中究竟怎麼實現。

  儘管我尚未用erlang寫過什麼像樣的系統,但它對我思想的衝擊是巨大的。erlang告訴我actor model(其實最早是松本行弘),讓我見識了immutable的威力,和如何優雅地scale out。我興奮地寫下了:Why should C programmers learn Erlang?。之後,又深入研究了STM(Software Transactional Memory)等其它concurrency手段(在此時認識了clojure)。

  最終,我從erlang延伸到了go。go是門優點與缺點同樣突出的語言。本來我正是把它當作一個帶併發支援的"modern C"來看的,但深入下去後發現,go和C是兩個世界的人。go只能在某些場景下替換C,但無法取代C。soft realtime是個魔咒,把幾乎一切有GC支援的語言擋在了C的另一側。現在看來,也許只有rust能從理論上取代c/c++。

  go已經發展到1.2版本,但依舊任重道遠。首先,它的編譯速度比宣稱的慢不少,執行速度更是比C差了不少,很多場景下(尤其GC相關),要比JVM下的語言(如scala)差。

  go也有不少bug,連我都能發現一個嚴重的導致可執行檔案好幾百兆的問題(沒處理好bss段)。

  但go精巧的語法,簡潔的思想,語言內建的併發支援,讓它還是我不斷學習的物件。

  人的精力畢竟是有限的。很多語言看了看思想,寫了寫簡單的例子(上百行程式碼)就擱在一邊了。在此鳴謝:ruby,elixir,io,emacslisp,scala,nimrod,rust,clojure,lua,我從你們那裡吸收了不少有意思的知識,卻淺嘗輒止,沒有深入和你們互動下去。

  也許你會問:一門語言究竟多久能掌握?

  學精一門語言,也許需要花上三五年的功夫,也許還要更長。

  但學精了一門語言後,學第二門一週也就該能入門了(erlang, haskell, lisp除外)。

  現在我不再會對某個公司的技術有特殊的偏見。我擁抱一切能提高生產力的技術。

  也許你會問:學那麼多語言有什麼用?

  如果用來養活自己,一門學精了就足夠。其它的沒什麼用,也就消遣消遣。我看中語言背後的思想,會比較用不同語言開發的樂趣。另外,當你喜愛的語言新增了新的特性(或者你用到了某個高階特性),你可以一下子就想到了背後的邏輯:啊,原來這是xxx的思想。於是,你對這兩門語言的掌握又加深了一層。

  我目前最大的遺憾,是沒有靜下心來好好看看java。

  雖說對技術沒有偏見,但我依然痛恨噁心的IE6/7;同時,我打心底喜歡一樣東西:MAC。

  如果說對程式設計師有什麼忠告,那就是:Every programmer should use MAC。

  $ brew install nimrod

  願每個程式設計師都成為人生的好獵手!^_^

  作者 - 陳天

相關文章