中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
一位編程老手13年來處理棘手bug的18個心得

作者簡介:Henrik Warne是瑞典斯德哥爾摩的一名軟件開發(fā)員。從事編程行業(yè)已有20多個年頭,現(xiàn)在仍熱愛編程。目前,他是TriOptima公司的開發(fā)員,負責為財務風險管理系統(tǒng)開發(fā)軟件。之前,他在Symsoft從事移動通訊系統(tǒng)的開發(fā)。更早些,在愛立信為移動交換系統(tǒng)開發(fā)軟件,并在一家小型初創(chuàng)公司待過,為VoIP開發(fā)嵌入式系統(tǒng)。主要從事開發(fā)員的工作,不過也做過幾年的系統(tǒng)測試員和支持工程師。


我在《從你的bug總結經(jīng)驗教訓》一文中寫道,我一直在如何跟蹤遇到的最有意思的bug。我最近回顧了全部194個bug(時間跨度達13年),看看從中學到了什么經(jīng)驗教訓。下面是最重要的幾個經(jīng)驗教訓,分為編碼、測試和調試這三大類:


編碼


這些是在過去給我?guī)砑謆ug的所有問題:


1. 事件順序:處理事件時,很有必要提出下列問題:事件是否可以以一種不同的順序到達?如果我們從來沒有收到該事件,會怎樣?如果該事件連續(xù)出現(xiàn)兩次,又會怎樣?即使通常情況下這永遠不會出現(xiàn),但系統(tǒng)(或交互系統(tǒng))的其他部分中的bug可能會導致這出現(xiàn)。


2. 處理太早:這是上述“事件順序”的一種特殊情況,不過它已引起了一些棘手的bug,所以它自成一類。比如說,如果信令消息接收太早,在配置和啟動過程完成之前接收,許多奇怪的行為就會出現(xiàn)。另一個例子:當某個網(wǎng)絡連接還沒有被列入空閑列表就被標為斷開。調試這個問題時,我們總是假設它在處于空閑列表時被設為斷開(但為什么它又沒有從列表上撤下?)。沒考慮到有時動作發(fā)生太早要怪我們沒想到。


3. 隱蔽故障:一些跟蹤起來最棘手的bug(一方面)是由出現(xiàn)隱蔽故障、繼續(xù)執(zhí)行而不是給出錯誤的代碼引起的。比如說,系統(tǒng)調用(比如綁定)返回未加檢查的錯誤代碼。另一個例子:遇到錯誤元素后,直接返回而不是給出錯誤的解析代碼。調用在故障狀態(tài)下繼續(xù)持續(xù)一段時間,這大大加大了調試的難度。最好一旦檢測到故障情況,就返回錯誤。


4. if語句:有幾個條件的if語句給我?guī)砹嗽S多bug。即使if語句概念上很簡單,有多個條件需要跟蹤時,它們也很容易搞錯。如今我試著重寫代碼,力求更簡單,避免要處理復雜的if語句。


5. Else:有幾個bug是沒有適當考慮如果條件為假會發(fā)生什么而引起的。幾乎無一例外的是,每個if語句應該有一個else部分。此外,如果你在if語句的一個分支中設置了某個變量,可能應該在另一個分支也要設置該變量。與此相關的是標志(flag)被設定的情況。僅僅添加設定標志的條件很容易,但是容易忘了添加應該重新設定標志的條件。任由永久性設定的標志留在那里可能會在將來導致bug。


6. 不斷變化的假設:一開始最難預防的許多bug是由不斷變化的假設引起的。比如說,一開始,可能每天只有一個客戶事件。然后,按照這種假設編寫了許多代碼。后來某個時候,設計發(fā)生了變化,允許每天有多個客戶事件。出現(xiàn)這種情況后,就很難改變受到新設計影響的所有情況。很容易找到顯式依賴該變化的所有項,但是難就難在,找到隱式依賴舊設計的所有情況。比如說,可能有代碼讀取某一天的所有客戶事件。隱式的假設可能是,結果集從不大于客戶數(shù)量。我沒有好的辦法可以預防這類問題,歡迎讀者建議。


7. 日志:深入了解程序執(zhí)行的任務至關重要,尤其是邏輯很復雜時。務必要添加足夠多(但是別太多)的日志,那樣你就能弄清楚為什么程序在執(zhí)行它執(zhí)行的任務。如果一切正常,日志并不重要,但是一旦出現(xiàn)了問題(這不可避免),你會很高興添加了適當?shù)娜罩居涗?。?/p>


測試


作為一名開發(fā)者,除非進行了測試,否則我不會說搞完了一項功能。至少,這意味著每一行新代碼或更改后的代碼至少執(zhí)行了一次。此外,單元測試或功能測試也很好,但還不夠。新功能還必須在類似生產環(huán)境的環(huán)境下加以測試和探究。唯有如此,我才可以說搞完了一項功能。下面是bug在測試方面給予我的一些重要的經(jīng)驗教訓:


8. 零和空:務必要以零和空(合適的情況下)來進行測試。對于字符串而言,這意味著既指長度為零的字符串,又指內容為空的字符串。另一個例子:在發(fā)送任何數(shù)據(jù)(零字節(jié))之前,測試TCP連接的斷開。沒有使用這些組合來測試是bug悄然出現(xiàn)的頭號原因,我在測試時是原本可以發(fā)現(xiàn)這些bug的。


9. 添加和刪除:新功能常常需要能夠為系統(tǒng)添加新配置,比如說用于電話號碼翻譯的新配置文件。所以測試它切實可行、以便添加新的配置文件很自然不過。然而,我發(fā)現(xiàn)很容易忘了還要測試配置文件的刪除。


10. 錯誤處理:處理錯誤的代碼常常很難測試。最好由自動測試來檢查錯誤處理代碼,但有時這不可能。這種情況下,我有時采用的一招就是,臨時修改代碼,讓錯誤處理代碼運行。要做到這一點,最容易的方法就是反轉if語句,比如說將if語句由error_count > 0反轉為error_count == 0。另一個例子是誤拼數(shù)據(jù)庫列名,讓所需的錯誤處理代碼運行。


11. 隨機性輸入:常??梢园l(fā)現(xiàn)bug的一種測試方法就是使用隨機性輸入。比如說,H.323協(xié)議的ASN.1解碼可處理二進制數(shù)據(jù)。通過發(fā)送有待解碼的隨機性字節(jié),我們發(fā)現(xiàn)了解碼器中的幾個bug。另一個例子是使用測試調用生成腳本,其中調用持續(xù)時間、回復延遲、第一方掛斷等都是隨機生成的內容。這些測試腳本暴露了無數(shù)bug,尤其是接踵而至的事件引起的干擾。


12. 檢查什么不該發(fā)生:測試常常包括檢查所需的動作已發(fā)生。但它很容易忽視相反的情況――檢查不該發(fā)生的動作確實沒有發(fā)生。


13. 自行編寫工具:我通常構建自己的小工具,好讓測試更容易。比如說,我在處理面向VoIP的SIP協(xié)議時,寫了一個小腳本,就返回我所需要的頭和值。有了這個工具,許多個別情況測試起來很容易。另一個例子是可以進行API調用的命令行工具。通過從小處著手,然后根據(jù)需要逐步添加功能,我最后開發(fā)出了非常實用的工具。自行編寫工具的好處就是,我獲得了所需的那種功能。


不過根本不可能在測試中發(fā)現(xiàn)所有bug,有一回,我改變了由兩部分組成的處理關聯(lián)號碼的機制:路由地址前綴(始終一樣),以及從000到999的動態(tài)分配號碼。問題是,查找關聯(lián)時,動態(tài)分配號碼的第一位數(shù)字在查詢地址表之前就被誤刪除了。所以,不是尋找637之類的號碼,你尋找的是37,而這個號碼不在表中。這意味著,它一直尋找到100,所以前100個調用正常,而之余的所有900個調用失效。所以除非我在重新啟動之前測試了100多次,否則在測試時發(fā)現(xiàn)不了這個問題。


調試


14. 討論:在過去對我?guī)椭畲蟮恼{試方法就是與同事討論問題。我常常只要向同事描述問題,就足以認識到問題是什么。此外,即使同事不是很熟悉相應代碼,常常也能給出好主意,表明哪里可能有問題。我在處理最棘手的bug時,與同事討論這一招來得尤其管用。


15. 密切關注:調試某個問題花很長時間時,常常是由于我做了錯誤的假設。比如說,我以為問題出現(xiàn)在某個方法中,而實際上這個問題根本不會出現(xiàn)在這個方法中?;蛘邟伋龅漠惓2⒉皇俏壹僭O的那個異常?;蛘呶乙詾樵谶\行軟件的最新版本,實際上運行的是舊版本。因此,一定要核實這些細節(jié),而不是犯想當然的毛病。很容易看見預期看見的問題,而不是實際擺在那里的問題。


16. 最近的變化:過去可以運行的代碼現(xiàn)在無法運行時,這常常是最后一個變更的對象引起的。有一回,最近變化的對象只是日志,但是日志中的錯誤引起了更大的問題。為了讓諸如此類的回歸更容易找到,有必要在不同的提交代碼中實行不同的變更,并且要清楚說明變更。


17. 相信用戶:有時候用戶報告問題時,我的本能反應是“這不可能。他們肯定是哪里弄錯了。”但是我已學會了擯棄這樣的反應。結果往往證明,用戶報告的正是實際發(fā)生的問題。所以如今,我對用戶報告的問題信以為真。當然,我仍反復核查各方面已正確設定。但是我碰過好多情況下,之所以發(fā)生奇怪的問題,是由于不同尋常的配置或意料之外的使用,而我默認的假設是,它們是正確的,程序是錯誤的。


18. 測試修正版:bug的修正版準備就緒后,它必須進行測試。先在沒有修正版的情況下運行代碼,觀察bug。然后打上修正版,重復測試用例。現(xiàn)在,錯誤行為應該消失。遵照這些步驟可以確保它其實是個bug,確保修正版確實解決了問題。這很簡單,又必不可少。


其他意見


這13年來我一直在跟蹤我遇到的最棘手的bug,這期間發(fā)生了很大的變化。我開發(fā)過一個小型嵌入式系統(tǒng)、一個大型電信系統(tǒng)以及一個基于Web的系統(tǒng)。我用C 、Ruby、Java和Python編寫過代碼。我用C 編碼時期的幾類bug已完全消失,比如堆棧溢出、內存損壞、字符串問題以及某些形式的內存泄漏。

我遇到的其他問題(比如循環(huán)錯誤和個別情況)少了很多,那是由于我一直對更多的邏輯進行單元測試。但是,這并不意味著沒有bug,還是有bug。這篇文章總結的經(jīng)驗教訓幫助我在編碼、測試和調試這三個階段盡量減小破壞。要是你在預防或查找bug方面有什么其他的實用技巧或方法,歡迎留言交流。



本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
修復每個 bug 后都要問這 3 個問題
10+年程序員總結的20+條經(jīng)驗教訓
13 年的 Bug 調試經(jīng)驗總結 – 碼農網(wǎng)
快速發(fā)現(xiàn)bug ,用起來非常爽的七個神仙調試工具
編程時幫你減少Bug的八種方式
程序員面試之道(《程序員面試筆試寶典》)之快樂編程的好習慣有哪些?
更多類似文章 >>
生活服務
熱點新聞
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服