http://blog.gkong.com/more.asp?name=linkman&id=27854
我不知道,自己現在還算不算一個程序員。如果還算程序員的話,我肯定不是那種絕頂聰明的程序員。
我不是一個聰明的程序員,不能在鍵盤上手指翻飛,靈光似劍,一日千行,閉目成章。大師的高度,遠非我能指望,我會犯很多錯誤,只是一個普通的程序員。
所以,對于編程,我是一個悲觀主義者。
我不相信,所編寫的程序能夠一次編譯通過;也不相信,能在家里將程序的所有錯誤都找出,而不需要出差現場;更不相信,我的程序能夠在不同的環境下,對各種異常,都處理得非常完美;尤不相信,我的程序沒有任何內存丟失,可以連續運行一周。
我本來不是一個悲觀主義者,曾經的我,是那么激揚那么狂妄,只是一次次被打擊,讓我越來越務實,越來越冷靜,越來越清醒地看待自己。隨著歲月的增長,我編程的次數已越來越少,但是,我的悲觀主義思想卻越來越濃。
一打開程序,我便想到,因為軟件出錯,而不得不給用戶寫檢討;便想到,因為每月死機一次,客戶對我大發雷霆;便想到,因為產品質量問題,而陪客戶喝酒,連飲七大瓶啤酒。
那七瓶要命的啤酒,依然不能讓客戶回心轉意,于是,我成了一個悲觀程序員。
我是悲觀主義程序員,好在還有五件武器。
第一件武器:斷言(ASSERT);
我希望,任何調用我的模塊的程序,都能按照希望的參數格式和調用方法,正確地調用我的模塊。因此,在我所編寫的每一個模塊內,都會大量地使用斷言(ASSERT),在模塊中加上了斷言,我便相信,程序模塊有了一個一個相對真實的調用環意,便有了一種虛幻的安全感。
第二件武器:靜態代碼檢測工具,如PC-lint,有時也使用編譯器的最嚴格的編譯級別;
我從不認為,自己是一個對C/C++/VC等,都非常熟悉的程序員,經常會不小心使用一些不正常的語法,或是不太考慮字段的邊界,因此,在程序編到一定的階段,都會采用pc-lint,對我所編寫的程序,進行嚴格的編譯檢查。
第三件武器:動態代碼檢測工具,如boundcheck;
對于C/C++程序員而言,最大的痛苦就是內存泄漏,或其它資源泄漏了,我對內存泄漏有天生的恐懼,也經常在內存丟失方面犯錯誤,因此,在產品發布給用戶前,一定會采用動態代碼檢測工具,進行一次徹底的測試。
第四件武器:單元測試工具,如cppunit;
我沒有足夠的自信,認為自己能夠很好地駕馭多個模塊的大型程序,也不相信自己寫過的、超過50行的程序會沒有問題,因此,我會盡量引入單元測試,對每一個重要的函數或模塊進行地毯式單元測試,當看到那一遍測試通過的綠色,才能夠安心地回家睡覺。
第五件武器:調試信息;
我相信,我所編寫的所有程序,都不可能一次成功,即便再認真地調試檢查,再多地廠內工作,在現場還是免不了會出問題。因為,不可能在家里模擬現場所有的情況,也不能夠對各種異常情況進行完整地猜測。因此,在我所編寫的很多程序中,特別是與監控有關的、需要長期、連續運行的程序,都會加上盡可能多的調試信息。
在程序中加上調試信息,是我最后的稻草,有了它,我終于敢將產品戰戰兢兢地交給客戶。
那么,調試信息應該記錄哪些內容?我想說的是,調試信息應該能夠記錄現場所有的信息,包括:
程序的啟停狀態;
調用它人程序的邊界參數;
被它人調用的程序的邊界參數;
與外部環境的邊界,包括操作系統、文件系統、硬件、數據庫等;
與網絡交互的兩端邊界;
重要模塊的被調用參數;
模塊內的重要過程的當前參數;
有了這些調試信息,我便可以不出差了,當現場發生了事情時,我的第一反應便是要求查看這些調試信息。
今天一位朋友問我,你如何保證你的程序能夠穩定,我告訴他:我有五件武器。
寶刀配英雄,現在我已很少編寫程序了,這些武器,就送給戰斗在第一線的程序員吧,也許你們現在不覺得它們有多重要,但總有一天,你們會自覺地將它們帶在身邊的。