John Carmack談軟件工程中藝術與科學

雖然我不是個遊戲超級玩家,但卻是因喜歡遊戲而開始學習編程的(特別是圖像渲染算法)。所以當我看到John Carmack在2012 Quake­Con上的發言時,我覺得自己該聽聽,學習遊戲設計以及開發相關的知識。

不過我所聽到的是一個黑客在談論他的最近感悟——軟件工程事實上是一門社會科學。其中的大約10分鐘,他涉及到了人性的各個方面,比如開發人員犯的錯誤,編程語言設計,靜態分析,代碼評審,開發人員培訓,成本/收益分析。文中強調的部分是我加的(文字爲我轉錄,如有錯誤,還請海涵)。


在嘗試讓遊戲跑得更快(我們的主要發展方向)的過程中,我們犯了不少《Doom 4》中已有的錯誤。其中的一些顯然無法改變,但迫於提速的願景,不得不做。

因爲這些行不通,你懂的,兩個遊戲相隔了6年。

在軟件開發方面,你們或許知道一件有趣的事,那是一個對我的訪談。那個訪談中我提到我是如何學習到那麼多知識的,不過與一年前相比,現在我是個更好的開發者,當時主持人對此很是驚訝。你知道經過了20年,經歷了所有的一切,最終一切都浮出水面。關於軟件開發我確實學習到很多,既包括個人技能,也包括更多的關注團隊積極性的一面。

而後者是過去多年來我所忽視的,因爲過去我把自己標榜爲一個軟件工程的科學家,處理一些抽象、證明、正確相關的事情,真的很酷。

事實上在計算機科學中,真正屬於科學的唯一事情就是算法,優化屬於工程範疇。但是那些沒有一直開發算法的人,大部分的時間都花在編程上。我們中確實有少數程序員在做一些優化以及挑選算法,但是90%以上的程序員在編寫程序,只是爲了實現一些功能。當我開始審視這一切時,發現工作中的絕大部分沒有科學、工程、正確的一面。或許,其中某個程序員會說,他做了很多的巧妙編程工作,實現了一些功能。我們喜歡把自己想象成聰明的工程師,用正確的方式去開發好軟件。但隨着我觀察的越來越多,發現這根本不是事實。

除了那些能夠評估的東西,我們用來評估和重現的工具纔是科學的精華所在,有了它們,才能評估、重現,做出預測並測試驗證。我們會在做優化和算法時涉及,但所有其它事,跟科學無關。程序員之間的交流,甚至於與不同時期的自己交流。我們談論函數式編程,lambda演算,monads,這些想想就很美,但對你在軟件工程方面做的事情沒有任何影響,這些僅僅是最佳實踐而已,一些總結好的做法,但只是在阻止人們犯某些類型錯誤的時候它們纔有意義。純函數式的,用最嚴苛的科學的視角寫出來的代碼,最後還是會轉化爲彙編語言,事實上你也可以用諸如BASIC或者其它任何語言來實現。

另一件對我有啓發意義的事情是大兒子開始學編程。我確實搖擺過是否應該讓一個7歲的孩子學習Haskell,最終決定不要,我不認爲自己是一個足夠出色Haskell程序員以至於願意去指導別人。當我思考人們到底如何開始從零學編程時,我豁然開朗,意識到我們從軟件工程社區獲取瞭如此之多,事實上是一些構建在一個核心基礎之上的由多層組件組成。當你回退到結構化編程,不論while循環,還是for循環,在底層,你如何解釋編程,計算機做些什麼,最終都會歸於流程圖(flow chart)。這種條件執行這個,否則執行那個。甚至嘗試解釋在一個地方到底是應該用for循環還是while循環時,這僅僅關乎慣例,一個解決人們經常犯的錯誤的慣例。但是它們不是計算機在做些什麼的核心。這些只是人們根據以往經驗總結的讓你少犯錯誤的方式。

另外一件嚴峻的事情是,程序員一直在不斷的犯錯。我去年談論了很多關於靜態分析方面的工作,並嘗試靜態分析我們的所有代碼,希望它們都能夠順利通過,可惜掃出了數以千計的錯誤。其中一些問題,我的同伴們確實是Bug,並保證下次不會再犯,這種感覺不錯。如果一些錯誤沒有從語法上阻止,就可能發生。那正是我投入如此多精力到靜態分析上的原因之一。我希望能夠開啓更多嚴格的語言限制,因爲我們一直在犯錯

最近我開始做的一件事情是code review,查看每日提交的代碼,找出一些典型的錯誤案例,給team成員講講。標註出一小段代碼,說這是個靜態分析工具掃出的Bug,推薦這樣的寫法,更簡單清晰,也不容易犯錯,剛開始時有些成員對這種公開文化有些反感,不過我覺得大家現在都接受這樣的做法了。但有個問題,我看看大家都做了什麼就會花費很多的時間,更別說逐一review。能夠指出組內其他成員犯的錯,並告訴大家當心類似的問題,那纔是真正的價值所在。只要組員都接受這件事,就是有積極意義的。

當你在爭論譬如是否應該在函數的參數之前加上const關鍵字時,想象一下會發生什麼。這些很難客觀地給出結論,大多數這種情況,我們稱之爲緩存失效,要耗費很大的精力來做說服工作。如果一個結論很客觀,顯而易見,就不會起爭論。但是其它的很多事情涉及的只是代碼風格問題,你或許會說,根據多年的經驗,這會導致種種錯誤,但是很多人會回答說,我從來沒有看到那種錯誤,對於我來說那不是問題,我從來沒有犯過那種錯。這個時候能夠演示錯誤很重要,看,就是這個問題導致的錯誤。

隨着這些事情我做的越來越多,並思考相關的問題,我覺得這些不是科學,而是解決人類弱點的過程,我希望有更好的辦法來處理。我們都希望成爲更好的程序員,開發出更好的產品,把工作做得更好,但是事實歸結爲去訓練數十個人按一致的風格做事情。組內成員有進有出,不斷更迭,新人進來,看着代碼庫,不瞭解慣例規則。有更好,也有更壞的方式做事情,不過這真的很難衡量。

這些是我正在花更多的時間關注的事。我閱讀了NASA的軟件工程報告,在大量資料中並沒有找到任何有價值的東西。真正有價值的是自動化——無需人工參與,自動評估。我覺得那纔是越來越大的項目的最終歸宿。現在我們開發的一些項目代碼量非常驚人。回頭看看NASA的報告,他們認爲3,4百萬行代碼是大項目。現在我們的遊戲引擎的代碼量遠遠超過那個數字。這樣來評估遊戲引擎很有意思,它比送人類到月球上並返回,控制宇宙飛船,操作太空艙,維護空間站還要更復雜,所有這些巨型項目都沒有市面上的任何主要遊戲引擎複雜。

我的答案並非到此爲止。使用NASA風格的開發流程,他們能夠交付Bug率非常低的產品,但這建立在極低的生產力基礎上。你能夠做的一件事情是,分析成本/收益比值,你會說自己能開發出很棒的產品,但推出實在是太晚了。或者我們可以做得很快,領先市場,不過可能做得不大精細,不過我們會讓一些很酷的功能儘快推出。這是一個典型的例子,合適的工具,處理合適的任務。現實中發生的是,你會很快推出很酷的產品,但會在多年內忍受它的折磨(譯者注,猜測是指維護產品)。而在這方面我覺得我們做的不是很好。

我們知道有些代碼將會維護十年,我告訴同事這是個好機會——你寫的代碼,並未與特定的遊戲強相關,或許會活躍10年,會有數以百計的程序員閱讀、參考、調用它,責任重大。在軟件的API設計層有很多問題,找出它們是項藝術,需要技藝精湛的工匠。我希望以後能夠有更多關於軟件工程藝術的內容與大家分享,我正投入很多精力鑽研其中。


原文鏈接:John Carmack discusses the art and science of software engineering
譯者:李榮,搬磚碼農一枚,喜歡搬磚,喜歡設計,代碼潔癖患者,個人博客: http://blog.csdn.net/kimylrong/

發佈了76 篇原創文章 · 獲贊 535 · 訪問量 95萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章