閱讀680 返回首頁    go 阿裏雲 go 技術社區[雲棲]


我在微軟亞洲研究院生活中所接觸的語言

自上次《回首往事:十八年的語言分支》一文後,全民編程計劃也算是正式啟動開來,其實前幾次的文章(詳見底部的推薦文章)確實為我們分享出了很多的道理。從中我們看到了語言的“叛逆思想”、從中我們對一些語言有了更深入的認知、從中我們也能體會到身為程序員的各種生活。

肖伯納有句名言是這麼說的‘人生不是一支短短的蠟燭,而是一支暫時由我們拿著的火炬。我們一定要把它燃得十分光明燦爛,然後交給下一代的人們’。我們在之前的文章提到過,每個人的經曆本身就一個“瑰寶”,把這些經曆分享出來可以讓別人得到很多的啟示。這次,51CTO的記者邀請到了微軟亞洲研究院研發工程師陳梓瀚陳老師來分享一下他在微軟生活中的所接觸的語言。我們來看一下陳老師能為我們帶來什麼樣“瑰寶”。(他的博客園:https://home.cnblogs.com/u/geniusvczh/

“初品編程語言”

當每個人第一次接觸編程語言時,都會產生或多或少的感觸,這很正常,也就是我們常說的第一印象。而我第一次知道有編程這回事時,是在廣東汕頭華僑中學念初二的時候學校開的課,剛好是這個世紀的第一年。當時學校發了一本前半本QB後半本VB5的教材,書裏麵有代碼,就算是我第一個接觸到的代碼吧。當時的感覺就是:“真是直觀啊。”

再後來我學習編程的過程中,我很少看別人的代碼。一個功能的實現往往有很多種,就像一個方程的有很多個解法一樣——盡管最後答案隻有一個。我覺得知道一個具體問題的解往往是沒什麼太大的意義的,雖然這是初期重要的積累過程,但過了這個階段,再糾結這些問題已經對自己的成長沒有什麼好處了。

在我基本上能用VB表達出自己的想法之後,我就差不多不看代碼,而是隻看各種原理和API(或類庫,以下省略)手冊了。盡管當時的代碼還很爛,但是隻要不斷地寫,變好隻是時間問題。相比之下積累原理和API是更加重要的。

API的掌握

當一個編程人員,經曆了從無到有的過程後,如果他對於編程產生了興趣,他一定希望能夠不斷進步,達到一個又一個新的高度,我亦如是。

又過了一個階段後,讓我覺得API也變成一件不太重要的事情了,因為學習一個API實在是太簡單了。你所需要知道的就是這些東西的存在,就跟看算法導論的時候知道有那麼些算法每個算法的好處在哪就夠了,等到真的需要了可以去查。當然如果你根本不知道這個算法,那也是不行的——API也是如此。等到學習API的時間已經短到可以忽略的時候,一般就是通過看博客文章微博等方法來知道這些世界上存在很多解決什麼事情的API,這些API可能也是屬於你從來都沒用過的語言的,不過沒關係,先放著。

在這段時間裏。有空的時候我就不去具體研究每個API的細節了,而是去積累原理。這裏所說的原理指的是類似數據結構背後的數學模型啊,或者是編譯原理啊,或者做渲染的時候的各種計算方法啊,或者是設計一個語言的語法的時候需要掌握的一些譬如類型係統之類的知識等等。

當然想manage一個API/類庫也是需要花上那麼一段時間的。但是原理積累的足夠多之後,看到一個新的東西,往往可以猜出他API背後的一些東西。隻要這個API的作者也是靠譜的,那“英雄所見略同”的事情便時有發生。這就是為什麼到了這個階段之後掌握一個API是很快的,因為如果讓你來設計他,那你大概也會設計出差不多的東西。所以這樣的技巧就可以大大提升你學習一個新的API的速度,用到哪學到哪,這就仿佛你一開始就掌握得很好。還記得去年,一個在Office部門當過Architect的同事意味深長的跟我說“Architecture is patterns”的內容。正如古人所說,優秀的數學家在理論之間看到了相似,而卓越的數學家在相似之間看到了相似。我想就是這個道理吧。

雖然語法啊、API啊、類庫啊、原理啊、架構有很多,而且中間千差萬別,但是總的來說掌握他們有兩件事情要做。第一件事情就是要知道他們。你可以掌握的不好,你可以完全不去試一試,這沒有關係,但是你至少需要知道他好在哪。第二件事情就是要從中看到相似。再說下去估計就變成玄學了,所以就此打住吧,言歸正傳,接下來讓我說說在微軟接觸到的一些語言吧。

我的微軟生活

記得我從實習開始就是在微軟裏度過的,當時做的是Visual Studio相關的東西,後來轉正的時候去了SQL Server,再後來就到了現在所在的MSRA了。

盡管這三個部門做的東西差距很大,但是選擇的方法都是一樣的——盡量用C#,不行再說。這也不是公司非得推廣C#不可,而是因為C#能做【而且能做好】的事情實在太多了,非得用C++才能做得好的事情已經越來越少了。當然或許Windows組不是這麼看的,他們覺得WPF和XAML設計得好,就做了一個native版本的輪子來當Metro UI用,還給VC++搞了一個/CX,不過至少在我呆過的地方都更喜歡C#。

至於C#是不是真的那麼神奇,我隻能說現在像我們的基礎設施,譬如Azure和VS等,C#占的分量都遠遠超過C++的。隻要不是特別計算密集型的東西,或者對資源的控製不用斤斤計較的東西,用不用C++的意義已經不大了。其實有些時候多買些機器要比花時間把程序在一些角落裏寫得好要節省更多的成本,當然前提也是需要有的——得先掌握寫scalable程序的方法。

當然這並不阻止我在不工作的時候還繼續研究C++的東西。我在上班的時候寫公司的代碼,下了班開始寫自己的代碼,其實自己研究項目的難度其實往往要更大,因為自己搞東西不在乎成本,搞不出來可以拖,慢慢研究會了再搞。盡管在微軟內部也是差不多的,但是項目畢竟還是有期限的,事情不能做得太天馬行空。

我所染指的語言

談到語言,就不得不提到項目,項目確實是我們在工作中成長的重要因素。每個項目都有自己最合適的語言,隻要政策允許,我都會盡量選擇最合適的那門語言去學。所以這不是一個選擇的問題,一個項目不是你用不同的方法去“選擇”一門語言,最適合的語言就會變的。這就跟數學定理一樣,一直在那裏,隻有你發現和沒發現的區別。

很多新人認為編程語言的選擇是否會對未來的職業規劃出現影響,至少對我來說,我認為應該是不太會。因為學習一個語言需要花很長時間的這個階段已經過了,為我在讀書的時候的主題是做編譯器,所以各種各樣奇葩的語義結構基本上都見過了,所以當接觸一門新語言的時候,就會跟上文所提到的一樣產生各種“英雄所見略同”的感覺。當然有一些語言的設計者對一致性這種重要的特點是沒有追求的——譬如說go,盡管他是Google做的,但這並不阻止這門語言看起來就像很多個補丁黏在一起。

在微軟的生活中我重點染指的語言大概有VB、Delphi(前麵這兩個估計在也不會用它了)、C++、C#、F#、Haskell和Prolog。剩下的其它語言,絕大多數都跳不出這幾門語言所能覆蓋的範圍。此後接觸一門新語言的重點就是收集和體驗他的一些最佳實踐,所以已經不是什麼重要的問題了。

其實還有一些其他的語言,例如Go啊,Rust啊,Scala啊,Java啊,Prolog啊,Erlang啊,Perl啊,Lisp啊,BrainFuck啊,JavaScript啊,objc什麼的,還有很多叫不上名字的東西,我都會去看。有些語言還在別人那裏很流行,至少我現在還用不上。我會去看的原因有兩個,第一個就是說不定將來要麵臨“選擇”所以知道的越多越好,另一個就是現在我的興趣好保留在如何設計一門好語言,如何寫一個好的library上麵,所以開眼界是很重要的。

當然在這裏我並不是提倡語言無用論,我提倡的是,語言有很多,而且不同的項目最適合的語言是千差萬別的。所以千萬不要試圖去相信一個語言是銀彈(最近迷信C語言的風氣又再一次上來了),我們所需要做的事,把它們統統都學會,那這樣選擇也就變成一件容易的事情了。而且大項目裏麵的小項目用不同的語言來寫這種事情是很常見的,不能回避。

接觸過這麼多的語言後,必定會有一個相互之間的比較,也會產生出每個人心中最傾心的一種編程語言,那麼你猜我最傾心的編程語言回是什麼呢?你肯定猜不到。

我最傾心的Haskell!

之所以上麵我會說你想不到,是因為讓我最傾心的語言是Haskell,你沒看錯,的確是Haskell。就像我《伴隨我成長的編程書》所提到的一樣,我是從Haskell開始才知道掌握程序語言相關的理論是多麼的重要。當我逐漸把Monad啊、CPS變換這些看起來跟寫代碼沒什麼關係的知識都學會了之後,遇到一個所謂“多範式語言”(特別是C++和C#)的時候,在一個程序的不同的部分使用不同的範式來提高開發效率和可維護性(主要是通過違反多少次DRY原則來衡量的)的這種事情已經不再是一個問題了。

可以說沒有Haskell,我就不會知道這個世界上還有lambda calculus,還有類型係統,還有各種各樣美妙的知識。盡管對於我喜歡寫的大部分程序講Haskell都不是最好的語言,但是這並不妨礙我喜歡Haskell。Haskell讓我對其它語言掌握得更好,特別是C++。

與Haskell相似的東西除了C++的模板以外,我再也找不出別的可以相提並論的語言了。隻有這兩個東西讓我感受到編程語言的魅力。隨著硬件越來越牛,將來取勝的程序語言,我在這裏鬥膽做一下預測,肯定包含兩個特征:

1、語言表達能力強,噪音少,各種庫一致性高。

2、語言本身要容易分析(指語義上的),這樣才能不需要太過於複雜的過程(譬如說分析指針內容的別名這種亂七八糟的事情)也可以產生出很好的代碼。

盡管最後的贏家可能不是Haskell,但估計也是差不多的東西。那種不僅學起來難,坑多,而且還很難分析的語言——首當其衝的是C語言——估計會跟Java一樣因為有大量的遺留程序而得以保存,但遲早會被邊緣化的。不過我想這個時間還很長,因為如何把Haskell編譯的更好的這些相關技術還有待研究。

這麼說可能有點抽象。如果想理解這方麵的東西的話,我推薦一個視頻教程集合Channel9:https://channel9.msdn.com。去上麵找我敬仰的Erik Meijer關於Haskell、Linq和Reactive Programming等相關內容的東西去看。看懂了之後,就可以把將其他語言的優點強加在自己喜歡的語言上的這件事情,做得更加得心應手了。正如《Monadic Parser Combinators using C# 3.0》這篇文章所施展的技巧一樣,當你看著LINQ的代碼,眼睛裏的不是LINQ,而是CPS變換的時候,你可以把Parser也寫成跟LINQ一樣的東西。

也許這對大部分人可能沒什麼用。因為我不管做什麼東西,主要的業務還是做Library,所以關注點也好,但跟做App的人的區別還是相當大的。所以盡管有些人覺得“Monad都是些什麼亂七八糟的東西反正我學了也不能讓我漲工資也不能讓我這個項目的加班時間更少”,至少對於我來說,是很有意義的。

全世界編程語言數不勝數,總有一個是你喜歡的,也總有一個語言是你聽都沒聽過的,那麼你會想,為什麼會有這麼多的編程語言呢?有些語言真的有存在的意義嗎?

我是如何看待如此之多的語言

很多人認為之所以有這麼多編程語言,有工作的需要,但也有一部分是因為每個編程語言都有一些缺點,所以需要另一種語言來進行完善。但是我覺得這種說法有一種“語言都是衝著成為銀彈去的”的這個觀點在裏麵。其實這樣說是不合適的,譬如說SQL語言,雖然說SQL已經越來越像通用語言了,但是你也隻會拿它來操作數據庫,的同時你也不會選擇其他語言來操作一個數據庫。

另一個例子就是Shader語言了,Shader語言是用來操作顯卡渲染圖形的。做渲染一定會用Shader,而Shader也隻會用來做渲染。盡管現在有什麼GPGPL的概念,但是隻要一涉及到通用計算,大家就不會傾向於選擇DSL,在我們的日常開發裏麵,DSL往往充當一個更加重要的位置。因此我們就有業界良心NVidia公司的作品CUDA,還有VC++2012的一個更強大的實現C++AMP了。

其實還是跟上麵所強調的一樣,每一個項目都有自己的最好的語言。所以答案很明顯,之所以語言這麼多,除了作者閑到非要做一個編譯器來玩一玩的這種事情(譬如說我,不過我的語言都坑了,有些人的語言就沒坑,譬如說ruby之父鬆本行弘)以外,最重要的原因就是,項目之間的差距太大,所以對語言的要求的區別也很大。一個語言不可能同時滿足這麼多相差很大的要求,所以就有很多個語言長出來了。因果關係不能顛倒。

既然有這麼多的語言,那必定市場上就會出現各種語言從入門到精通的書籍,在我的《伴隨我成長的編程書》一文中已經分享了很多自己在實際開發中看過並覺得比較好的書籍,下麵我會說說我在實際開發中認為比較好的工具。

推薦完書後我們在談談工具

說道最喜歡的工具,那麼首當其衝的當然是Visual Studio。盡管我很喜歡搞那些平台無關的東西(這並不意味著我喜歡跨平台),但是我毫不否認一個稱手的工具是相當重要的。IDE對我的重要性已經高到我會為我的語言寫IDE的這種程度了。盡管我現在寫的還不好,所以在可以預見的時間裏麵我還將繼續研究這個事情。別的就不說了,VS寫ASP.NET MVC4程序的時候,在一個Razor模板文件裏麵充滿了JavaScript、C#、Html和CSS四種語言。令我感到驚訝的事,盡管這四種語言你揉在一起寫,但是Visual Studio的IntelliSense精準而且好用到那四種語言仿佛就是一種。我無法想象要是讓我用不帶IntelliSense和Debugger的編輯器來搞這些事情那是個什麼樣子。

當然VS也並不是總是可以完成我想要完成的內容。我有一次還是掉了坑的,就是在我寫GacUI(www.gaclib.net)的時候,我給我的類都加上了XML注釋,結果發現沒有一個工具可以讓我用XML注釋來給Native C++程序產生文檔。微軟的這方麵工具都是針對.Net(包括C++/CLI)的。所幸的是,VS還是給了我一個讀PDB文件的API,盡管藏得很深,但還是Public API。因此我最後選擇通過把PDB和XML注釋編譯出來的一個XML文件拿來join的方法,自己搞定了這件事情。

還有一個我想提到的是,我們都知道因為C語言的宏實在是坑太多了,於是Boost.PP應運而生。但是Boost.PP因為是建立在宏上麵的,因此坑也很多,我在大三那一年耗盡了心血都沒辦法把他掌握到一個可以再複雜情況下安全使用的地步,一怒之下,開發了fpmacro(gac.codeplex.com的項目裏麵就有,那些擴展名為fpm的文件就是)。fpmacro長得跟宏差不多,但是它是一門嚴謹的語言,語法是經過精心設計的,專門用來寫隻能用複雜的邏輯才能產生你的不想人肉寫的C++代碼。至於我為什麼會需要這麼一個工具,是因為我經常需要產生跟std::function一樣風格的大量三角形特化。

這個故事告訴我們,能自己寫工具,才是終極的解決辦法。

全民編程

51CTO記者寄語:在語言這塊,每個人跟每個人了解的各有差異,而陳老師在微軟的成長,更是讓他發現了他“獨愛”的編程語言,本文中他對於Haskell的講述更是讓我們看到了這門很多人並沒有在意的語言它的亮點,並且我們也應該深思一下,自己每天運用的代碼是否自己真的了解其原理和機製呢?還隻是一種熟能生巧的習慣呢?

網友朋友們,你們又將會有什麼樣的編成生活要講述給我們呢?亦或是又會有什麼樣的語言見解給我們分享呢?這些都會是我們所期待的,就讓我們行動起來,一起來參與全民編程吧!


最後更新:2017-04-03 19:06:50

  上一篇:go GRUB Customizer配置Ubuntu開機菜單
  下一篇:go Hadoop集群中hosts文件配置問題