好久沒有寫博客,一方面因為工作太忙,另一方面是因為沒有發現什么好寫的。可是后來發現沒什么好寫的原因其實也是因為工作太忙了。忙得不正常,所以沒有很多時間和精力來研究和欣賞自己喜歡的東西了。
我在一家叫做 Coverity 的公司工作,我住在三藩市(San Francisco)。Coverity 是一個奇怪的公司,三藩市是一個奇怪的城市。
Coverity 制造一種叫做“靜態分析”(static analysis)的軟件。這種軟件可以在不運行程序的情況下,經過對代碼的分析,自動的找到程序里面可能出現的問題。這有點像我之前給 Google 做的那個 Python 分析器,只不過針對另外的語言(C,C++ 和 Java 等),分析的側重點不同,能處理代碼的規模也貌似大一些。還有就是這么多年了,久經沙場考驗了。
Coverity 具有世界上最先進的一些技術,所以麻雀雖小,卻讓很多人離不開它。恐怕很少有人知道,這小小的公司的忠實客戶,包括了一系列的大拿:美國宇航局, 波音, 洛克希德馬丁,雷神(Raytheon),BAE Systems,豐田,歐洲原子能中心(CERN)…… 貌似幾乎所有對代碼質量不敢有絲毫差錯,又不得不用像 C++ 這樣毛病眾多的語言的公司,都購買了 Coverity 的產品。比如最近的火星好奇者號上的所有200多萬行代碼,都經過了 Coverity 的靜態分析。當然,如此精密的設備不可能光靠 Coverity 查一下錯就能確保萬無一失,它必須依靠很多其它的技術,但 Coverity 確實是這些東西的開發過程里面比較重要的部分。
我必須承認,Coverity 給了我足夠的啟發,甚至間接的讓我發現了自己之前做的 Python 靜態分析里面存在的一些問題。Coverity 的產品在大規模的代碼上面的成功,也讓我意識到了自己在 Python 分析器里的一些突發奇想的設計的正確性和價值。如果我現在做一個新的 Python 分析器,它將比原來的精確和高效(也可以推廣到其它語言比如 JavaScript)。我也清楚的看到,Coverity 自發研制的一些“不大嚴謹”的做法,其實比程序語言領域里面一些看似高深的“邏輯”還要“正確”。這些微妙的“提示信息”,讓我把多個領域的知識串通了起來。所以我覺得跟這公司還有點臭味相投,加入 Coverity 也是不枉此行的。
然而我也發現,Coverity 缺少我擁有的程序語言理論知識。絕大部分的 Coverity 工程師沒有系統的學習過 lambda calculus 和函數式編程。在我的 Python 分析器中,其實包含了 Coverity 還沒有的技術。Python 的靜態分析本來就比 C++ 和 Java 之類的難,然而我的實現卻異常的簡單。這些微妙的技術,貌似很多人都可以說他“會做”,但是他們卻很難把它做對。這就像“CPS 轉換”一樣,很多人都說他會做,可是真正做對的只有極少數人(我是其中之一)。這些技術源自于我對程序語言本質的理解,源自于 Dan Friedman, Kent Dybvig 和 Amr Sabry 等老師的教誨,也源自于我自己辛勤的實驗,實驗,再實驗…… 在我簡短而優雅的代碼中,包含了許多人需要花費好幾倍的代碼長度才能達到的目標。所以雖然 Coverity 的工程師們技術實力很強,但在代碼的簡單程度和對程序語言語義的理解上,真的很難達到我的程度。
這就是為什么我經常能夠一眼就看出 Coverity 產品里存在的問題,并且很快的修正錯誤。舉一個簡單的例子,有一天我修改了一行代碼,使得產品在某些 benchmark 上的內存使用量減少了一半。我為什么可以做到這一點呢?因為在我的 Python 分析器里,這個問題是從一開頭就不存在的。它源自于一種幼稚的解釋器寫法,有點像 GoF 的《Design Patterns》里的那種。Coverity 的代碼里面有好些類似的問題,都是我自己根本不可能犯的錯誤,我都沒有機會給他們改進。我不是想貶低同事們的水平,他們都是 Stanford, Berkeley 等學校畢業的高手,可是我也很清楚自己的技術地位。
所以我就經常發現這樣的麻煩事:我順手改掉了一個自認為很顯然的問題,或者一個我根本不會犯的錯誤,然后就發現有大批的測試需要被修改,我也會被要求寫出“regression test”,用以防止同樣的錯誤再次發生。某些同事對于測試的戰戰兢兢的態度,其實跟我當年在 Google 實習的時候沒有什么兩樣。看到這里的問題了嗎?這些我“根本”不會犯的錯誤,幾分鐘時間順手就改掉了,但是我卻要花成天的工夫去修改和創建測試,防止它“再次”發生。我不得不說,在這些測試上所花費的工夫,占用了比我修改代碼多好幾倍,甚至幾十倍的工夫!
想想這六個月以來我干了些什么,再比較一下在 Google 實習的那六個月獨自從頭做出來的東西,我發現自己簡直什么也沒有干。這就是我不喜歡“測試驅動開發”(TDD)的原因。在 Google 的六個月里,我無視同事對于測試的要求,從無到有的做出了如此精密的系統,一個測試都沒有寫照樣做得好,為什么呢?因為我的代碼非常的簡單清晰,我隨時都可以把它們完整的呈現在頭腦里面,從而讓“心靈之眼”可以看到可能出現的錯誤。也許這就是所謂的“邏輯思維”。
對測試過分依賴的人,往往不具有這樣的思維能力。他們不能夠看到代碼最簡單的本質,所以需要做很多試探,以求達到“近似解”。為了不至于偏差很多,就寫很多測試,用以捕捉和防止每一次的錯誤。這就像一個初學畫畫的人,一點一點的描,用橡皮反復的擦,可總也抓不住事物的精髓。這些人對“錯誤”的記憶能力特別強,往往深入的追究一塊代碼是“如何”錯的,“為什么”是錯的,下次如何才能不犯同樣的錯誤。
然而我卻沒法記住之前的代碼是如何錯的,我也不想知道為什么它是錯的,我只記得“正確”的代碼是什么樣子。錯誤的方式有千萬種,可是正確的卻往往只有一個。把腦力浪費在記憶錯誤的東西,這就是為什么很多人不能寫出真正優美而正確的代碼。我受到的訓練讓我可以直接得到正確的結果,所以測試對于我來說分量沒有那么重。當我的代碼需要大量的測試才能確保正確的時候,那就是它該被推翻重寫的時候。所以我的代碼往往沒有任何補丁和變通,可以說是無懈可擊。這就像是一個真正會畫畫的人,他閉目沉思,然后一氣呵成。當然,優美的代碼并不是一蹴而就的,有的代碼被我推翻重來幾十次才最后成功,但我最后的代碼不留下絲毫錯誤的痕跡。所以我覺得,看一個程序員的水平,不要看他留下來多少行代碼,而要看他刪掉了多少行。
我覺得做 Coverity 的工程師真累。這種累不止在于以上的技術層面的繁瑣,而且在于管理層對工程師的缺乏尊重以及不必要的壓力。這讓我在受到了足夠的“啟發”之后,開始懷疑是否還有繼續為它工作的價值。對于公司管理,以及對于 IT 行業總體的看法,我還是以后再講吧。
-
Google
+關注
關注
5文章
1788瀏覽量
58686 -
工程師
+關注
關注
59文章
1589瀏覽量
69233 -
代碼
+關注
關注
30文章
4888瀏覽量
70274
發布評論請先 登錄

如何成為一名合格的KaihongOS南向驅動開發工程師
如何成為一名合格的KaihongOS北向應用開發工程師
如何成為一名嵌入式軟件工程師?

一名硬件工程師的獨白:我們為何總在"用愛發電"?
嵌入式軟件工程師就業好不好?
月薪 3 萬的嵌入式工程師都在用,串口屏到底神在哪?

如何成為一名合格的南向驅動開發工程師
如何成為一名合格的北向應用開發工程師



Victor Labián Carro:以好奇心成就 RISC-V 職業成功之路

評論