(J.Robert Oppenheimer):
我們知道呐籽,避免犯錯(cuò)誤的唯一辦法就是找出錯(cuò)誤羽利,而找出錯(cuò)誤的唯一辦法就是要有自由提出問題的權(quán)利
在生命中某個(gè)時(shí)刻榛做,每個(gè)人都會有這樣的感悟:世界并不按你的期望運(yùn)轉(zhuǎn)券勺。
錯(cuò)誤是不可避免的檀蹋,我們可以做的是:當(dāng)糟糕的事情發(fā)生了松申,我們就來處理它。
一俯逾、錯(cuò)誤從何而來
奧斯卡.王爾德(Oscar Wilde)
卜人之卜贸桶,乃當(dāng)世之圣明
幾乎任何操作都會帶來意想不到的結(jié)果,這種結(jié)果與有缺陷的程序中的bug是不同的纱昧,因?yàn)殄e(cuò)誤的發(fā)生是可預(yù)見的刨啸。例如,你想打開的數(shù)據(jù)庫可能被刪除识脆,磁盤空間隨時(shí)可能被用完设联,或你訪問的Web服務(wù)目前不可用。
如果你不編寫代碼處理這些錯(cuò)誤情況灼捂,肯定會遇到bug离例;但如果錯(cuò)誤發(fā)生的概率極小,它可能是一個(gè)無足輕重的bug悉稠。
錯(cuò)誤發(fā)生的原因可能有幾千種宫蛆,總體可歸類為三種:
用戶錯(cuò)誤
野蠻的用戶粗暴地對待你心愛的程序。也許提供了錯(cuò)誤的輸入,也許是進(jìn)行一次完全荒謬的操作耀盗。程序員錯(cuò)誤
用戶按下正確的按鈕想虎,但代碼崩潰了。這是bug引起的叛拷,是程序員引入的代碼缺陷舌厨。未處理的錯(cuò)誤會引起bug,bug會導(dǎo)致更多的錯(cuò)誤忿薇。意外情況
用戶按下的按鈕正確裙椭,程序員也沒犯錯(cuò)誤,它是來自命運(yùn)之神的捉弄署浩。
也許是網(wǎng)絡(luò)連接失敗了揉燃,也許是打印機(jī)墨水用完了,或者是硬盤空間沒有剩余了筋栋。
二炊汤、錯(cuò)誤報(bào)告機(jī)制
在編寫代碼時(shí),我們需要定義良好的策略應(yīng)付哪些可能出現(xiàn)的問題二汛⌒稣福可以在檢測到錯(cuò)誤時(shí)彈出一個(gè)消息框來通知用戶,也可以在中間層代碼檢測到錯(cuò)誤時(shí)向客戶端代碼自動(dòng)發(fā)送信號肴颊。不管如何,都應(yīng)該有人或代碼負(fù)責(zé)確認(rèn)錯(cuò)誤和對錯(cuò)誤作出反應(yīng)渣磷。
1. 不報(bào)告
- 最簡單的錯(cuò)誤報(bào)告機(jī)制就是不為錯(cuò)誤報(bào)告操心婿着。但你的程序可能以一種可以預(yù)知的方式運(yùn)行,甚至崩潰醋界。
- 還有一種忽略錯(cuò)誤的做法竟宋,遇到問題立即中止程序。
2. 返回值
- 第二種簡單的機(jī)制是從函數(shù)返回一個(gè)表示成功或失敗的值形纺。如使用布爾型返回值
TRUE
或FALSE
丘侠。 - 一種更高級的方法是列舉出所有可能的退出狀態(tài),并返回一個(gè)相應(yīng)的原因代碼逐样。其中一個(gè)值代表成功蜗字,其他的值分別代表許多不同的異常終止情況。
-
int count()
向下遍歷一個(gè)鏈接的列表并返回其元素個(gè)數(shù)脂新,它如何報(bào)告列表的結(jié)構(gòu)已被破壞呢挪捕?
(a).返回一個(gè)復(fù)合數(shù)據(jù)類型(或元組),其中包含返回值和一個(gè)錯(cuò)誤代碼争便。在類C語言中级零,這種方法相當(dāng)笨拙并很少見。
(b).通過一個(gè)函數(shù)參數(shù)返回錯(cuò)誤代碼滞乙。在C++和.NET中奏纪,這種參數(shù)常通過引用來傳遞鉴嗤;在C語言中,通過指針來控制對變量的訪問序调。
(c). 預(yù)留一些返回值來表示各種故障醉锅。可以指定count()
返回負(fù)數(shù)表示錯(cuò)誤原因代碼炕置。
3. 錯(cuò)誤狀態(tài)變量
- 函數(shù)將設(shè)置一個(gè)共享的全局錯(cuò)誤變量荣挨,而不是返回一個(gè)原因代碼。在調(diào)用函數(shù)之后朴摊,通過查看狀態(tài)變量來確定函數(shù)是否成功的完成默垄。
- C語言標(biāo)準(zhǔn)庫通過errno變量應(yīng)用該技術(shù)。 但不是所有的C語言標(biāo)準(zhǔn)庫函數(shù)都使用errno甚纲,不能保證前后一致口锭,并且使用任何標(biāo)準(zhǔn)庫功能之前,都必須先清除errno介杆。
- 共享全局變量會帶來線程安全問題鹃操。
4. 異常
異常是一種管理錯(cuò)誤的語言工具;不是所有的語言都支持異常春哨。
異常有助于將正常的執(zhí)行流程和異常情況(當(dāng)某個(gè)函數(shù)失敗并且不能按計(jì)劃完成其功能時(shí))區(qū)分開荆隘。
當(dāng)你的代碼遇到一個(gè)它無法處理的問題時(shí),程序會停止運(yùn)行赴背,并拋出一個(gè)異常(一個(gè)代表錯(cuò)誤的對象)椰拒。在調(diào)用堆棧中向后退,直到找到一段異常處理代碼凰荚。
根據(jù)處理異常之后程序運(yùn)行情況燃观,操作模式分為:
(a) 終止模式
程序在捕獲【異常的處理程序執(zhí)行完畢】之后繼續(xù)執(zhí)行。C++便瑟、.NET和Java語言都采用此種模式缆毁。
(b) 恢復(fù)模式
程序重新從異常出現(xiàn)的地方恢復(fù)執(zhí)行。
5. 信號
三到涂、檢查錯(cuò)誤
四脊框、處理錯(cuò)誤
伏爾泰(Voltaire)
熱愛真理,寬恕錯(cuò)誤
五养盗、代碼示例
六缚陷、是地獄浮現(xiàn)
七、管理程序錯(cuò)誤
下面是一些對于管理程序錯(cuò)誤的出現(xiàn)往核、檢測和處理的主要考慮因素:
避免可以造成錯(cuò)誤的事情箫爷。例如通過預(yù)先保留足夠的資源來避免資源分配錯(cuò)誤。
定義程序或例程在不正常環(huán)境下的預(yù)期行為
清晰地定義哪個(gè)組件負(fù)責(zé)處理哪個(gè)錯(cuò)誤
檢查你的編程實(shí)踐
總結(jié)
本杰明.富蘭克林(Benjamin Franklin):
人總會犯錯(cuò),悔過就是圣人虎锚,堅(jiān)持就是惡魔
處理錯(cuò)誤和故障是一項(xiàng)艱苦的工作硫痰,它使編程陷入現(xiàn)實(shí)世界具體細(xì)節(jié)的泥沼中。然后窜护,它絕對非常重要效斑,因?yàn)槟闼帉懙拇a由90%是用來處理異常情況的。
內(nèi)容相關(guān)
異常安全