本節書摘來自華章出版社《effective debugging:軟體和系統調試的66個有效方法》一書中的第1章,第1.2節,作[希]迪歐米迪斯·斯賓奈裡斯(diomidis spinellis),更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視
現在很少有哪個工作場所不能上網,如果在一個無法上網的地方開發程式,那我的效率會很低。遇到代碼錯誤的時候,我們應該上網搜尋,或者與同僚一起尋找解決辦法。
有一個相當有效的搜尋技巧,是把由第三方元件所給出的錯誤消息打上雙引号,并将其粘貼到浏覽器的搜尋框裡面。把待搜尋的内容放在一對雙引号中,意思是要告訴搜尋引擎:隻搜尋與該内容精确比對的頁面。這樣做可以使搜尋結果更加準确。還有一個很有用的技巧,是把與錯誤有關的程式庫或中間件的名稱、對應的類名或方法名,以及所傳回的錯誤代碼,也一并放在搜尋框裡面。要查找的函數名稱越罕見,搜尋到的結果也就越确切,例如,搜尋plgblt所得到的結果,要比搜尋bitblt好得多。此外,我們也應該試着搜尋意思相近的詞,例如,除了搜尋“hangs”(挂起),還可以搜尋“freezes”(當機),除了搜尋“disabled”(禁用),還可以搜尋“grayed”(變灰)。
要想解決一些與api調用有關的難題,我們通常可以觀察其他人是如何使用這些api的。我們可以看看開源軟體如何使用某個函數,如何對傳給該函數的參數進行初始化,以及如何解讀函數所傳回的結果。在這種情況下,專門用來搜尋代碼的引擎(如black duck open hub code search),要比google那樣的通用引擎更好。例如,如果在這個搜尋引擎裡面查找mktime,并且隻看與某個項目有關的代碼,而過濾掉程式庫的聲明及定義,那我們就會發現下面這樣的代碼片段:
通過上述代碼片段,我們可以看出:mktime函數與localtime函數有所不同,它要求傳入的年份必須是完整的數值,而不是距離1900年的偏移量,而且它的月份是從1開始計算的。這兩個地方經常會出錯,對于那些沒有仔細閱讀函數文檔的人來說,更是容易在調用時傳入錯誤的參數。
在檢視由搜尋引擎所給出的結果時,我們要注意這些結果是從哪個網站抓取到的。stackexchange旗下的網站(如stack overflow)通過很多措施來鼓勵使用者進行有效的交流,是以,在由搜尋引擎所給出的結果中,有很多比較切題的讨論及答案都來自這個系列的網站。在浏覽stack overflow上面的答案時,不僅要看提問者所接受的那個回答,而且還要看看其他那些贊同數量比較高的回答。除了答案的正文,我們還可以關注答案下面的評論,因為很多人都會通過評論的方式來給出新的消息,例如,有人會在評論中告訴大家,自己發現了一個可以避免錯誤的新辦法。
如果你把自己精心構造的關鍵詞放入搜尋引擎之後,并沒有得到有用的結果,那麼或許意味着你找錯了目标。對于常見的程式庫與軟體來說,你不太可能成為第一個遭遇某問題的人,是以,如果在網上找不到類似的描述,那可能說明你對問題的判斷發生了偏差。例如,你本來以為程式崩潰的原因是某個api函數的實作有bug,但實際上卻是傳入的日期有誤。
如果網上找不到答案,那你可以在stack overflow網站提問,把自己所面對的問題描述出來,然而,這需要花一定的時間來建構一個簡單、自足且正确的範例(sscce)。凡是在論壇發問,都應該遵循該sscce原則,也就是要給出一個其他人可以直接複制、粘貼并編譯的例子,使得他們能夠看到你所經曆的問題(參見第10條)。對于某些程式設計語言來說,甚至可以把範例代碼嵌入sourcelair或jsfiddle這樣的線上ide,令大家能夠在網上直接看到運作效果。sscce.org網站詳細解釋了應該怎樣針對具體的語言和技術來構造良好的範例。eric raymond所寫的文章《how to ask questions the smart way》也與這個話題有關,值得一讀。
筆者發現:隻要我能夠恰當地描述問題,并且附上合适的範例,那麼該問題的解決方案通常就會自然地浮現出來。就算我自己找不到答案,這樣的問題也可以吸引一些懂行的人過來進行試驗,他們或許能找到辦法。
如果你所遇到的問題在某種程度上與開源的軟體庫或程式有關,而且你認為它們的代碼中很可能有bug,那麼可以聯系其開發者。常見的做法應該是通路那個開源項目的bug追蹤系統,并在上面送出一項事務。送出的時候,也應該首先確定其他人沒有報告過類似的bug,并且要把重制該問題的詳細步驟準确地寫進去。如果那款軟體沒有bug追蹤系統,那你可以給它的作者發郵件,郵件要寫得相當謹慎,措辭要得體、語氣要謙和,因為大部分開源軟體的開發者都不是你的雇工。
要點
把錯誤消息打上雙引号,以便在網上準确地進行搜尋。
認真檢視stackexchange系列網站上面的回答。
如果上述兩種辦法都不見效,那你可以自己提問或送出事務。