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

更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
