1. 程式人生 > >程式設計師除錯能力提升

程式設計師除錯能力提升

糾錯前先思考:

  在我加入貝爾實驗室一年多後,Gerard Holzmann設計了一個很小的交換式製圖語言,我開始和Ken Thompson一起在開發針對這種語言的即時編譯器上做結對程式設計。我打字比較快,所以我坐在電腦前,Ken站在我身後看我程式設計。我們開發的很快,但經常會遇到問題,而且可以看出來出錯了——畢竟這是一個圖形化的程式語言。當程式出錯時,我本能的一頭扎進問題,檢查報錯跟蹤資訊,新增除錯列印語句,啟動偵錯程式,等等,但Ken只是站在那思考,完全不理會我也不檢視我們寫的出問題的程式碼。一段時間後我發現一個規律,Ken經常會比我先找到問題出在什麼地方,而且會突然的喊一嗓子,“我知道什麼地方的問題了。”每次他的判斷都很準確。我認識到,Ken已經在腦海裡構建了程式碼的模型,當有問題出現時,那是他腦子裡的模型出了問題。在思考為什麼會發生這些錯誤時,他能憑直覺找到模型中什麼地方不對或發現寫的程式碼跟這個模式什麼地方有出入。

  Ken教會了我一個極其重要的習慣:糾錯前先思考。如果你一頭扎進問題中,你可能只解決了當前出現問題的程式碼,但如果你先思考這個錯誤,這個bug是怎麼引入的?你通常發現和糾正一個更高層次的問題,進而改進了系統設計,防止了更多bug的出現。

  我認識到這種程式設計思考模式非常的重要。有些人痴迷於一行行的、使用各種工具來除錯所有的東西。但我現在相信,思考——不看程式碼的思考——是最好的除錯途徑,因為它能讓你開發出更好的軟體。

程式設計師除錯能力和相關書籍:

  在軟體行業中,個人覺得每個Coder、Leader(那些當了Leader以後就不需要Code的除外)都應該除了具有良好的編碼能力以外,最為主要的就是Debug的能力要堅實。千萬不要告訴我Debug工作是Tester和QA的事情,首先你要認識到Debug的能力是一個並不簡單的能力,能幫助你提高你的開發能力,加快開發速度,節約開發成本;其次你更應該知道,你所掌握的Debug的能力和技術並不可能搶去Tester或者QA的飯碗,他們做的工作更仔細、全面,更富有創造力。由於本人數年來一直使用VC6,所以下面使用的觀點和相關的描述都是從VC出發的,肯定有所偏頗、錯誤之處,還望各位看官不吝嗇地指出,本人定虛心接受,共同討論,共同學習,共同進步。個人覺得Debug能力包括以下三個個方面:

1、良好的編碼習慣,良好的邏輯結構能力,對Bug的預見能力。一個成熟的程式設計師,應該有一個良好的程式設計習慣,不僅需要有良好的編碼格式規範,更為需要的是對於程式中的邏輯實現時候有一種良好的結構。程式設計其實就是資料和邏輯的集合,資料的處理較為簡單,或者說是需要的邏輯思維能力比較少,當演算法邏輯要在資料上實現的時候,同一種邏輯,讓不同的程式設計師來實現可能有各種各樣的不同實現結構,從這個角度來說,這裡所說的“良好的編碼習慣”就應該指的是對於邏輯實現時候使用的良好的程式設計結構,一個好的程式設計結構應該是能預防錯誤的發生,對錯誤的預見和錯誤出現以後的錯誤處理與異常處理的良好安排。也許有人說這不好辦嗎?每個邏輯判斷的地方新增條件判斷或者異常處理不就行了?個人覺得不是那麼回事,過多的if、assert、ASSERT等語句或者是巨集,尤其是並列的if語句需要耗費很多判斷、執行的時間,對於一個子程式(函式),尤其是呼叫頻率比較頻繁的子程式(函式),一次浪費了一點點時間,多次、頻繁地呼叫浪費的時候就顯得可觀了,所以並不是if語句使用的多,程式出錯的可能性就小,過猶不及!如果確實需要使用多個if語句進行條件判斷,最好能使用巢狀的if語句,逐步的縮小判斷範圍,這樣消耗的時間要比並列的if語句要小,還要注意的是if語句的條件判斷也不是萬能的;assert、ASSERT等判斷巨集也不是萬能的,它會造成Debug和Release版本在響應速度和最終的編譯結果的不同,對於一些關注於效能、響應速度的程式,所造成的影響是不可忽視的。不過開發過程中的除錯階段倒是提倡使用這些巨集來發現演算法錯誤和不足。另外對於異常處理段的使用,個人覺得能不用異常處理的地方儘量不要使用異常處理,除非當某個錯誤發生以後導致程式不能繼續執行或者是崩潰的時候才使用異常,有時候你能使用異常處理,將發生錯誤的程式繼續執行下去,但是可能產生的最後結果並不是客戶所需要或者是期望的,這樣就容易讓客戶產生質疑:你是不是在程式中做了什麼手腳?這也讓你失去了獲得Bug發生的前提狀況資訊,從而失去了一次修改Bug的機會,所以說有時候當程式發生錯誤時,僅僅彈出一個MessageBox提示一些資訊,然後關閉程式,也不失為一個好的辦法。

2、編碼過程中的除錯跟蹤和錯誤定位能力。這個能力主要就是在開發過程中,當自己在Build程式,Run起來以後,竟然發生了Bug或者是Memory Leak,這時候就需要你使用各種工具進行除錯跟蹤了。首先你要相信VC不僅是一個很好的IDE,也是一個很好的Debug工具,其提供的呼叫棧、條件斷點、資料斷點、反彙編等工具足夠強大,足夠應付平常的Bug,但是現在很多的程式設計師,包括一些自稱為老程式設計師的也未必能很好的使用這些工具,尤其是條件斷點和資料斷點(在下面介紹的第二本書中有詳細的使用說明)。當VC不能滿足你的要求的時候你就需要使用其他的工具了,例如:SmartChecker,BoundChecker,Purify,SoftICE等等了。從這個角度來說,這裡的“除錯跟蹤能力”不僅是程式設計師對Bug的定位能力,更為主要的還是對於除錯工具的掌握、使用的能力。“磨刀不誤砍柴工”,在開發之前或者開發閒暇時,好好的研究一下一些開發、除錯工具不愧為一種好的提升這種能力的好辦法。能靜下心來思考一下這些工具的工作原理就更好了,這樣不僅能幫助你在程式設計的時候預見Bug,並且對你提高你的程式設計技巧也會有所幫助。例如VC中的程式在Debug模式下為什麼能發現數組訪問越界?這是因為在Debug模式下,在分配陣列所佔用的記憶體時候,編譯器在陣列記憶體的兩端分別加入了一個位元組的越界判斷記憶體。這也就是為什麼很多的MFC程式在使用自定義訊息的時候在Debug模式下沒有錯誤而在Release模式下發生錯誤的原因了。這裡我還想說一說我最喜歡做的兩種除錯方法:當Bug出現的時候,首先確定Bug的位置,然後:A、註釋掉可能導致Bug的段落,在需要取得資料值的地方直接提供一個合理的值,然後看看程式是否能正確執行,如此迴圈往復,逐步縮小範圍,最終找出Bug所在;B、如果Bug被定位在一個小的功能、子程式或者函式中,可以使用新建一個Test工程,在一個完全“乾淨”的環境下,對此功能、子程式或者函式進行測試,找出Bug所在。此節最後我想說的就是利用你的網路。當一個Bug出現時,你也許感到茫然,也許感到無從下手,這時候你就可以利用的你網路資源,使用強大的搜尋引擎(比如Google、Baidu等等),輸入相關的錯誤提示資訊,也許搜尋到類似問題的網頁,也許別人也遇到過同樣或者同類的問題,其他人所提供的答案就是你所需要的,或者能給你以提示、啟發的!

3、對事後發生的Bug能有良好的感知能力。當一個Bug出現的時候,優秀的程式設計師能根據Bug發生的前提和Bug發生的時間點、程式中的位置,很好的感知到Bug可能發生在哪一個函式或者哪幾個函式中,是什麼情況導致Bug的出現的,並且能夠很快的定位錯誤並Fix這個錯誤。這種能力使用的地方往往是程式已經Release了,已經被客戶使用了,在使用的過程中發生了Bug,客戶向你“傾訴”時。那麼怎麼才能有這樣的能力呢?也許很多的這種能力都是在你不斷的摔倒,被經理P了N次以後,所積累起來的經驗,所以說這也是一種痛苦以後所獲得的快樂的能力,它需要你對自己所做的軟體產品的結構、執行條件、執行原理和相關的涉及部分有很好的理解、掌握。有的時候多在網站上看看別人的經歷也能有所收穫。

  在以上的三種能力中,第一種能力主要在於態度和思維能力,後兩種則偏向於學習能力和經驗的積累;個人覺得第一種最為重要,所謂的“態度決定一切”嘛,呵呵。

最後向你推薦幾本關於除錯的書籍:

1、《Writing Clean Code——Microsoft Techniques for Developing Bug-free C Programs》(中文版譯作《程式設計精粹——Microsoft編寫優質無錯C程式祕訣》或者叫做《零錯誤程式》)——這是一本出版很早的書,現在也許在書店中都看不到了,但是你要相信此書的作者Steve Maguire(曾是Microsoft資深的程式設計師,參加了Excel在多個平臺下的開發和移植工作)所提供的許多防錯、排錯、測試的準則還是能讓人從中獲益非淺的。作者將每章的要點都和自己實際工作經歷相結合,提供了翔實的例子和相關程式碼,使用的語言更是幽默風趣,讓人讀起來不會感覺晦澀難懂,尤其是每章結束部分提供的練習和思考題更是貼合實際,發人深省。也就是這些原因才使得這本書經久不衰,一直為廣大程式所喜愛,所廣泛地討論。至今尚未能見到能與之相媲美的書籍。網上所流傳的林銳博士所著的《高質量C++程式設計指南》和《軟體工程思想》在深度和廣度上與之相比也顯得遜色不少!

2、《Debugging Windows Programs》(中文版譯作《Windows程式除錯》,中國電力出版社出版)——這是一本現在在書店很為流行的一本書。此書使用的語言比較樸實、易懂,也許是譯者精心處理的結果,敘述習慣比較符合國人口味。這本書主要包含除錯策略、除錯工具、除錯技術三部分,本書主要介紹的是在VC這個IDE、編譯器下開發程式所應有的一些技術。看完此書你肯定會更為深入的瞭解MFC,瞭解結構化異常和C++異常的區別和聯絡,瞭解怎麼除錯多執行緒程式,怎麼除錯COM程式,怎麼除錯記憶體,怎麼除錯繪圖程式等等。不管你是自認為有多年的開發經驗的開發高手,還是剛剛入門的初學者,相信只要你耐心的看完此書,你一定會和我一樣深深的感嘆一句:原來VC的除錯功能這麼強大!如果早點看到這本書就好了!

3、《Debugging Applications》(本人尚未見到中文版)——這本書主要介紹的是VC和VB的除錯,其中VC的除錯佔到70%-80%左右。本書也分為三部分:Debug的形式,強有力的Debug,Debug的工具和技術。其中有部分內容和上一本書所說的相同。但是這本書還是提供了很多新的東西:介紹了遠端除錯,提供了一些新的工具使用例子的說明,介紹了更多的底層的東西,甚至涉及彙編的相關資訊的閱讀和理解。在閱讀了上一本書以後,如果你還想提高,這本書是你不錯的選擇。

第一本書主要就是培養大家第一種Debug能力的,後兩本書是培養大家第二種Debug能力的,對於第三種能力主要還是要靠經驗的積累。

我現在就看到這三本書是比較好的書,如果你覺得有其他的比較好的相關書籍或者相關資訊請告知我。在肯定這幾本書對你的開發過程會有所幫助的前提下,另外我想說的就是即使你看了這幾本書你也不會編寫出完全沒有Bug的程式,畢竟Bug的種類和發生的情況實在是有很多的客觀和主觀因素,不可能完全杜絕。程式設計是一門實踐性很強的工作,唯有在工作、實踐過程中總結教訓,總結經驗才能不斷提高。祝大家在獲得知識,積累經驗的過程中少走彎路,大踏步的前進!!!