調(diào)試代碼是一種樂趣
調(diào)試代碼是一種編碼所需的基本能力,相信沒有多少人寫出來的代碼能夠是沒有bug的,雖然傳聞是有過這樣的人,因此普通的我們只能通過調(diào)試代碼來查找和修復(fù)代碼中的問題,需要調(diào)試代碼的場景有很多種,在這些場景中,也會有很多種不同的調(diào)試技巧可采用。
最典型的需要調(diào)試代碼的場景是單元測試的場景,在單元測試時會碰到代碼的執(zhí)行不符合預(yù)期或拋出意料外的異常,在碰到拋出意料外的異常時,通常現(xiàn)在的高級語言都會提示是由于哪行代碼造成的異常,于是首先的做法都是去看看對應(yīng)的那行代碼是什么個狀況,然后評估大概是什么原因造成的,如果在這種推測情況下無法判斷問題在哪了的話,在沒有支持程序調(diào)試時,通常只能是在原始代碼中輸出一堆的信息到console,例如java中就是System.out.println或System.out.err,于是運行,看看console中一堆的信息,然后慢慢的來推測問題,當(dāng)然,這也是一種可選的方案,甚至在某些場景中是一種不錯的方案,但在各種IDE支持程序調(diào)試后,更多的時候調(diào)試都可以通過IDE來進行,發(fā)明這個的人真的太偉大了,雖然我不知道是誰,但是還是想膜拜下的,:),有些看似很小的功能,往往非常的重要,于是現(xiàn)在的我們可以幸福的設(shè)個斷點,然后開始逐行跟蹤、跳行跟蹤、跟蹤進入函數(shù)內(nèi)部、跳出函數(shù)、跟蹤變量甚至修改變量等等N多種的方式幸福的調(diào)試著代碼,看著代碼在運行時的狀態(tài),很容易的就讓我們發(fā)現(xiàn)代碼中的問題,這個絕對是節(jié)省了非常非常多的時間,所以我說我很佩服那些號稱用記事本寫代碼的高手們,難道他們的代碼都是零bug的?要么就是出了bug后也可以一眼判定問題所在的?那實在太強了點,對于這樣的高手,確實可以不需要IDE這種現(xiàn)代化的武器,對于我而言,用記事本寫就像停留在原始時代,而IDE差不多應(yīng)該到帝王時代了,:),開玩笑,調(diào)侃下用記事本寫代碼的高手而言,這是單元測試中的場景和通常采用的技巧。
還有需要調(diào)試的場景通常會是集成測試場景,通常,集成測試會復(fù)雜很多,于是要用到的調(diào)試技巧會復(fù)雜一些,就像下面這樣的兩種場景:
1、并發(fā)程序
并發(fā)程序向來就是最最復(fù)雜的,沒有人能知道在運行時到底是怎么個執(zhí)行順序,否則就不叫并發(fā)了,:),于是,在并發(fā)程序中,N多種人腦無法想象的復(fù)雜場景就出現(xiàn)了,畢竟人腦的思考應(yīng)該不支持并發(fā)的吧,至少我的貌似支持不了,也許是我笨,呵呵,而且通常并發(fā)程序中的錯誤是不一定能每次都重現(xiàn)的,這是最麻煩的,至于借助IDE調(diào)試,同樣是不行的,因為并發(fā)程序由于斷點的進入可能完全被打亂,于是,對于并發(fā)程序,通常能采用的方法,比較靠譜的方法,我覺得還是打日志,當(dāng)然,你可以選擇繼續(xù)System.out.println、System.out.err,或者采用更加高級和優(yōu)雅點的log.debug這樣的方法,然后就看著時間戳來慢慢的運用自己的大腦來思考復(fù)雜的并發(fā)的問題,:),這絕對是一種挑戰(zhàn),但因此也會帶來充分的樂趣,于是慢慢的享受這個過程吧。
多說一句,還好現(xiàn)在java有了更高精度的時間戳:System.nanoTime,用System.currentTimeInMills根本就沒法分析并發(fā)程序,因為它的精度不夠。
2、所依賴的程序有問題
這種場景嘛,相對而言就復(fù)雜很多了,因為通常這個時候能做的多數(shù)是通知所依賴的程序方去查找問題,但如果手頭有所依賴的程序的代碼的話,多數(shù)可以采取跟入其源碼的方式,盡管不一定能修復(fù)其源碼,但對于查找出問題還是會提供很大的幫助,例如跟蹤框架代碼、jdk代碼等等,對于訪問的遠程程序而言,則不太相同,java嘛,還好,可以支持遠程調(diào)試,我相信現(xiàn)在的大部分語言都支持的,遠程調(diào)試那是相當(dāng)?shù)闹匾剑谑俏覀兙涂梢栽诒镜卣{(diào)試著遠程某臺服務(wù)器上執(zhí)行時的bug,:),偷著樂吧。
最后一種最痛苦的大家最想調(diào)試的場景,就莫過于生產(chǎn)環(huán)境了,估計有N多人都想直接在生產(chǎn)環(huán)境中調(diào)試,看看生產(chǎn)環(huán)境中的問題是怎么產(chǎn)生的,但生產(chǎn)環(huán)境嘛,是不太可能拿來調(diào)試玩的,而有些時候線下要模擬也不是什么簡單的事,說到這,又要天馬行空的瞎扯下了,記得在云風(fēng)的blog上以前有寫過一篇游戲中對于出錯場景的記錄以及回放的功能,這功能聽著是相當(dāng)?shù)膸浹剑茫^續(xù)回到正題,在自己的代碼還沒有如此強大的錯誤記錄和回放功能時,也許能做的選擇就是在代碼中多寫一點log.debug了,在生產(chǎn)環(huán)境有問題時,則打開相應(yīng)的日志的debug項,然后繼續(xù)靠人肉分析了,這個時候還是體現(xiàn)了log.debug的強大作用滴,根據(jù)這點可以看出,在代碼中還是有必要寫些合適的log.debug的,除了為了自己外,對于其他使用的人調(diào)試bug也是可以給予很大的幫助的。
嗯,沒想到稍微扯了下,也寫了不少,從這稍微寫的內(nèi)容中,其實也能看出,調(diào)試可不是鬧著玩的事,絕對需要相當(dāng)完整的知識體系,這也難怪張銀奎的《軟件調(diào)試》寫了三年,而且那么的厚,看來還是值得看看的,:),小廣告,大家別在意。
而且這里還沒說到,通常需要調(diào)試的時候,多數(shù)都是出問題的時候,那么這個時候還會面臨很大的壓力,怎么樣在緊急的時間內(nèi)還冷靜的做好人肉分析的工作,這可是相當(dāng)?shù)目简灴箟耗芰Α⒓夹g(shù)基本功、邏輯分析能力和學(xué)習(xí)能力的過程,想想,要能在短時間內(nèi)查出問題的原因,通常需要對代碼運行的場景做出冷靜的分析,進而需要具備從頭到尾的知識,例如所采用的框架、java包、甚至到JVM、操作系統(tǒng)、硬件,實在不行的話,還得臨時學(xué)習(xí)下這些知識,這樣才能在短時間內(nèi)解決,因此想來想去,越來越覺得如果在面試的時候讓面試者現(xiàn)場調(diào)試段程序貌似還是挺靠譜的,更有助于全方位的考察,貌似只有很少數(shù)的幾家公司會這么干,當(dāng)然,這有客觀條件的原因,但要克服貌似也不是很難。
posted on 2008-11-18 23:49 BlueDavy 閱讀(6304) 評論(4) 編輯 收藏 所屬分類: Java