調試代碼是一種樂趣

          近來連續調試了好幾天的代碼,樂趣無窮,:),在純凈的人和機器對話的時間中,充分的和機器不斷的交流,最終共同實現功能,和同事說:“我喜愛調試代碼勝過了寫代碼”,怎么說呢,我覺得調試代碼能夠充分讓你將所掌握的知識發揮出來,考察自己解決問題的能力以及學習知識的能力,在這篇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、操作系統、硬件,實在不行的話,還得臨時學習下這些知識,這樣才能在短時間內解決,因此想來想去,越來越覺得如果在面試的時候讓面試者現場調試段程序貌似還是挺靠譜的,更有助于全方位的考察,貌似只有很少數的幾家公司會這么干,當然,這有客觀條件的原因,但要克服貌似也不是很難。

          posted on 2008-11-18 23:49 BlueDavy 閱讀(6303) 評論(4)  編輯  收藏 所屬分類: Java

          評論

          # re: 調試代碼是一種樂趣 2008-11-19 01:44 Oasis Feng

          如果是調試寫的比較爛的代碼,那恐怕就很難體會到樂趣了。只有編碼中充分考慮了調試需求,并且對執行期異常有高度前瞻性的日志才能創造一種充滿樂趣的代碼調試體驗。

          關于并發,我盡量不在自己寫的代碼中引入過多需要考慮并發的處理和機制,理想的情況是讓基礎庫或編程框架為你代勞那些并發需要周全考慮的事情。

          程序依賴的問題其實還是涉及到編碼中的一條準則:模塊邊界的不信任原則,尤其針對協作開發。無論是集成測試和是運行期檢查,只有以這個原則出發完善必要的調試輔助工作,才有助于快速準確的定位問題的直接源頭。  回復  更多評論   

          # re: 調試代碼是一種樂趣 2008-11-24 11:43 brokendoor

          看來 BlueDavy 同學最近的生活悠閑了,開始發掘生活和工作中細微之處的樂趣。

          幫著閑扯幾句:
          并發是這世界的本源,人腦也是并發的,機器比較笨,讓人腦模擬機器的笨并發,自然是沒辦法了。

          所以,還是要靠人腦Debug,而不是機器。  回復  更多評論   

          # re: 調試代碼是一種樂趣[未登錄] 2008-12-18 17:52 null

          用記事本也需要debug的,沒聽說過jdb???  回復  更多評論   

          # re: 調試代碼是一種樂趣 2008-12-22 20:45 zhuxin

          因為所做課題的關系看了你寫的大作《OSGi實踐》,并跟蹤到了你的博客,看了你的很多文章,感覺你知識面很廣,特別有奉獻精神。非常感謝你的分享和付出。
          你的好幾篇文章,都很有趣,讓人覺得你很年輕,也讓我對以后的工作有了更多的期待~  回復  更多評論   

          公告

           









          feedsky
          抓蝦
          google reader
          鮮果

          導航

          <2008年11月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          統計

          隨筆分類

          隨筆檔案

          文章檔案

          Blogger's

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 高淳县| 海原县| 宝清县| 扶风县| 宽城| 中牟县| 睢宁县| 崇左市| 台湾省| 敦煌市| 大安市| 平南县| 拉萨市| 新余市| 鲁山县| 垫江县| 惠州市| 阳朔县| 芷江| 祥云县| 百色市| 平度市| 海兴县| 昌吉市| 鲁甸县| 兰西县| 交城县| 洛川县| 如东县| 阜康市| 资溪县| 桓台县| 罗甸县| 黑龙江省| 五家渠市| 宁武县| 克东县| 乐陵市| 榕江县| 咸阳市| 怀远县|