讀《編程匠藝—編寫卓越的代碼》:錯(cuò)誤

(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è)表示成功或失敗的值形纺。如使用布爾型返回值TRUEFALSE 丘侠。
  • 一種更高級的方法是列舉出所有可能的退出狀態(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)

異常安全

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柱徙,一起剝皮案震驚了整個(gè)濱河市缓屠,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌护侮,老刑警劉巖敌完,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異羊初,居然都是意外死亡滨溉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門长赞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晦攒,“玉大人,你說我怎么就攤上這事得哆「眨” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵贩据,是天一觀的道長伐脖。 經(jīng)常有香客問我,道長乐设,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任绎巨,我火速辦了婚禮近尚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘场勤。我一直安慰自己戈锻,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布和媳。 她就那樣靜靜地躺著格遭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪留瞳。 梳的紋絲不亂的頭發(fā)上拒迅,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼璧微。 笑死作箍,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的前硫。 我是一名探鬼主播胞得,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼屹电!你這毒婦竟也來了阶剑?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤危号,失蹤者是張志新(化名)和其女友劉穎牧愁,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體葱色,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡递宅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了苍狰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片办龄。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖淋昭,靈堂內(nèi)的尸體忽然破棺而出俐填,到底是詐尸還是另有隱情,我是刑警寧澤翔忽,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布英融,位于F島的核電站,受9級特大地震影響歇式,放射性物質(zhì)發(fā)生泄漏驶悟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一材失、第九天 我趴在偏房一處隱蔽的房頂上張望痕鳍。 院中可真熱鬧,春花似錦龙巨、人聲如沸笼呆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽诗赌。三九已至,卻和暖如春秸弛,著一層夾襖步出監(jiān)牢的瞬間铭若,已是汗流浹背洪碳。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奥喻,地道東北人偶宫。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像环鲤,于是被迫代替她去往敵國和親纯趋。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 2016年國慶假期終于把此書過完,整理筆記和體會于此西剥。 關(guān)于書名 書名源于俄羅斯的演員斯坦尼斯拉夫斯基創(chuàng)作的《演員...
    李劍飛的簡書閱讀 7,251評論 2 65
  • 公司成立了圖書一角痹栖,每個(gè)同事都從家?guī)Я藭:髞砦野l(fā)現(xiàn)一個(gè)事實(shí)瞭空,這些書本揪阿,不同的是書名,相同的是封皮內(nèi)容都很新咆畏。其實(shí)...
    艾婷婷閱讀 509評論 0 3
  • 連續(xù)靈修經(jīng)文第34天 【伯2:6】耶和華對撒但說:“他在你手中南捂,只要存留他的性命【烧遥” 《感動(dòng)》一切都在神的手中溺健,生...
    報(bào)佳音閱讀 287評論 0 0
  • 先把qq的zip包放在downloads根目錄下面(必須放在該目錄下)sudo apt-get updatesud...
    吧啦啦小湯圓閱讀 337評論 0 0
  • 獻(xiàn)計(jì)七,結(jié)果:袁紹未采納钮蛛。 以下是《獻(xiàn)帝傳》中的記載: 紹將濟(jì)河鞭缭,沮授諫曰:“勝負(fù)變化,不可不詳魏颓。今宜留屯延津岭辣,分...
    椒鄉(xiāng)書生閱讀 608評論 0 2