tft每日頭條

 > 圖文

 > bug為什麼是程序bug

bug為什麼是程序bug

圖文 更新时间:2025-02-05 17:46:08

bug為什麼是程序bug?bug的本意是指昆蟲、小蟲、損壞、缺陷等意思,在互聯網時代還有一種引申意義,用來形容某人/物超乎想象的厲害,那簡直就是開挂的人生,系統的bug,我來為大家科普一下關于bug為什麼是程序bug?以下内容希望對你有幫助!

bug為什麼是程序bug(程序員與BugBug與Debug的含義)1

bug為什麼是程序bug

bug的本意是指昆蟲、小蟲、損壞、缺陷等意思,在互聯網時代還有一種引申意義,用來形容某人/物超乎想象的厲害,那簡直就是開挂的人生,系統的bug!

一般地,在碼農的世界裡,bug是在電腦系統或程序代碼中隐藏着的一些未被發現的缺陷或問題,可以簡稱為程序缺陷。從廣義上看,還包括軟件需要改進的細節、或與需求文檔存在差異的功能實現等等。

bug 是如何與程序缺陷聯系起來的呢?

Bug的由來

時光回溯到一台計算機可以裝滿整個房間的時代,大約在1945年9月9日,Grace Hopper發現了Harvard Mark II 計算機的第一個bug。Grace Hopper是數據處理方面的專家,在1952年為UNIVAC開發了第一個編譯器,能夠把人讀得懂的高級語言翻譯成計算機能夠識别的機器語言。

那一天,Grace Hopper對Harvard Mark II設置好的17000個繼電器進行編程後,技術人員正在進行整機運行,它突然停止了工作。于是他們爬上去找原因,發現這台巨大的計算機内部一組繼電器的觸點之間有一隻飛蛾,這顯然是由于飛蛾受光和熱的吸引,飛到了觸點上,然後被高電壓擊死。死去的飛蛾被夾扁在觸點中間,從而“卡”住了機器的運行。

所以在報告中,Grace Hopper用膠條貼上飛蛾,并用“bug”來表示“一個在電腦程序裡的錯誤”。後來,人們在電腦系統或程序代碼中隐藏着的那些未被發現的缺陷或問題,也叫“bug”,同時 把排除程序故障叫DEBUG,這一“稱呼”成為計算機領域的專業術語。

BUG和DEBUG的中文譯為“缺陷”和“調試”。“缺陷”可能更反映事物的本質,因為“bug”是從外面爬進去的,并非程序本身有問題。而程序本身存在的問題,是程序原來就具有的。

程序代碼中Bug的産生原因

一般地,在程序設計中的術語, Bug是在軟件運行中因為程序代碼本身有錯誤而造成的功能不正常、體驗不佳、數據丢失、非正常中斷、死機等現象。

Bug 的産生原因多種多樣,千奇百怪,例如:

改錯了文件

改對了文件,但放錯了位置,或者根本忘了保存

改對了文件但沒有重新編譯

認為把那個條件變量開啟/關閉了,但實際上弄反了

運行了錯誤的版本

改正了問題,但忘了提交

改正了問題,也提交了,但其他代碼都依賴于之前有問題的版本

......

軟件系統是一個豐富多彩的世界,總有Bug在裡面飛來飛去。任何軟件在發布時都不可能是絕對的零Bug,因為誰都不敢保證,自己寫的代碼沒有任何問題。

bug的生命周期和分類

實際上, bug的生命周期可能是這樣的:

産生-->被發現-->被解決或者變成了另一個bug。

但是從軟件工程尤其是QA的角度看,任何一個bug的一般生命周期包括這樣幾個階段:

新建-->指派-->已解決-->待驗-->關閉

如果等待檢驗的bug在驗證時沒有解決好,則需要重新打開bug,開啟循環并繼續指派。

由于bug衆多,我們在fix bug的時候往往本着要事優先的原則,處理那些影響較大的bug,這需要根據bug 的嚴重程度分類,例如:critical,major,minor,de-effeicency,也就是所謂的P0/P1/P2/P3, 當然粒度也可以分得更細或者粗一點。

根據不同視角,可以對bug有不同的分類,根據bug 所影響的領域分類,QA的測試領域可以參見《程序員眼中的測試》。

另外,bug的數量往往被用來作為衡量軟件質量的一個指标。在CMM中規定的軟件質量标準如下(Bug個數/千行源代碼):

CMM1級 11.95

CMM2級 5.52

CMM3級 2.39

CMM4級 0.92

CMM5級 0.32

因此,我們往往會在生産bug 和 debug中徘徊,寫代碼的時間與排錯時間的比例有時會高達2:8。既然debug 是我們工作生涯中不可或缺的組成部分,容易混淆的是,debug 盡管在更多時候是一個過程,但有時候指的是一個程序——debugger。

Debugger是個程序

Debugger為一種調試軟件,工程師或程序員可以用來驗證算法。在一般的硬件設備上,都有着專門用于debug 的接口,在不太遙遠的DOS世界裡,一行debug 命令可以起到讓操作系統初始化的效果。

在windows平台上,WinDbg是微軟發布的一款相當優秀的源碼級(source-level)調試工具,可以用于Kernel模式調試和用戶模式調試,還可以調試Dump文件。

在Linux平台上,一般使用GDB,又稱GNU調試器,是用來幫助調試程序的工具。gdb的主要功能如下:

    啟動程序,可以按照自定義要求随心所欲的運行程序。

    可讓被調試的程序在指定設置的斷點處停住。(斷點可以是條件表達式)

    當程序被停住時,可以檢查此時程序代碼中所發生的事。

    還可以改變程序代碼,修正一個BUG産生的影響從而測試其他BUG。

很多跨平台的編程語言都一般會有各自的Debugger。PHP的調試方法最基本的是echo或者var_dump。還有就是使用zend debug 或者Xdebug的調試插件。

pdb是 The Python Debugger 的縮寫,是Python标準庫的一個模塊。pdb模塊規定了一個Python程序交互式源代碼調試器,支持在設置斷點(包括條件斷點),也支持源碼級單步調試,支持棧幀監視,支持源代碼列出,支持任意棧幀上下文的随機Python代碼估值。它還支持事後調試,并且能在程序控制下被調用。

例如:

>>> import pdb >>> import mymodule >>> pdb.run('myfoo.test()') >>>

也可以命令行調用 python -m pdb myfoo.py 。

總之,Debugger是我們在單機debug中非常重要的工具。但是,對于分布式系統而言,這些debugger 都有着很大的局限,雖然也有一些debugger工具,但多是面向特定系統的。

那麼分布式系統的debug 主要依賴什麼呢?日志。關于日志的重要性,可以參考《全棧必備 Log日志》。

Debug的原則

不論是單機上的應用,還是分布式系統,debug是遵循問題隔離的原則,便于定位問題。

問題隔離可能是所有debug中最強大的核心原則. 問題是否可重現是非常重要的。如果不能重現這個問題的産生方式, 解決起來會變得異常困難。問題隔離使我們擁有了控制變量。

從空間隔離上看,程序代碼中具有不同的庫或者框架, 并且可以包含許多同事的提交, 其中, 可能有一些已經不再在這個代碼庫上工作了。問題隔離有助于消除問題的非必要部分, 以便專注于一個解決方案. 問題隔離的目的是弄清楚是發生沖突的根本原因,了解是否存在競争條件。

從時間隔離上看,避免一次性的大量修改,越少改動代碼越好,這樣有助于發現問題。連續反饋的一緻性結果越多, bug的跟蹤就越容易。所以在調試時, 盡量不要安裝任何新的軟件或組件, 或者引入新的依賴。如果發現每次靜态輸入卻返回了不同的錯誤, 應該馬上提高警惕, 并且全力解決它。

Debug 時的一些雕蟲小技

通過二分法去定位問題是Debug的一般方法,即便如此,面對各種不同的編程語言,還有千姿百态的軟件系統,我們很難有高效快速的通用方法。

但是, 有一些debug時的關注點,可以看作雕蟲小技。

1.環境檢查

複現一個Bug,一般從環境檢查開始。從底層到應用層逐層檢查,要耐心确認。同時,關注幫助文檔、手冊或數據表,關注工作目錄或者運行環境的路徑。

2. 日志檢查

不要害怕被大量的調試日志,看起來很吓人,但實際上是來幫忙的。大多數時候它會告訴我們真正的問題是什麼和在哪裡!在25年前,debug C 語言程序的時候,自己好像隻能依賴printf來定位問題。

根據日志思考:什麼導緻了這個錯誤?錯誤是如何觸發的?...

3. 代碼核查

先看看拼寫錯誤吧,typo 或者簡單的語法疏忽有時不易發現。有時候括弧或者大括弧的幸運碰撞,有時候context成了content,fetch成了fecth,如果對自己的代碼熟視無睹,可以讓别人幫着看一眼。

同樣,“以終為始”,先檢查是否接收了正确的數據類型,一般的防禦式編程都可以看到接收的參數或數據。如果接收方合乎預期,跟随調用鍊的腳步,看調用者的函數,一步一步逼近bug的所在地。

如果定位到了函數,尤其是那些執行的叠代方法(尤其如for、while、do等循環處理),嘗試在console上顯示一步一步地執行結果。

4. 定向驗證

對指定的函數或者邏輯輸入固定的數據,或者執行固定的代碼來做定向驗證,可以是正向的,也可以是逆向的。

如果增加了大量輸入還看不到所需輸出的話,需要确認一下這些代碼真的在執行嗎?雖然有了條件語句(如if,switch等),但實際上執行的是在這裡麼?在條件語句中注入簡單的代碼,比如打印一個簡單的“hello world”,可以幫助您看到程序執行的流程。

當然了,如果有完整一點的單元測試,往往方便的多。

5. 注釋代碼

如果對于bug發生的邏輯模塊位置遲遲不能定位,往往還要回歸到通過二分法定位。逐行注釋代碼的方法可能是可行的,但不是最有效的方法。如果對問題所在沒有什麼想法的話,這可能是一條必經之路。

6. 手畫流程

“好腦子不讓爛筆頭”,有時候,我們需要一支筆和一張紙,就可以從所有的技術細節中解放出來,就能從視覺上看到事情是如何運作的,把邏輯流程畫出來能夠幫助我們梳理和定位代碼邏輯上的問題。這有點兒像反向工程,尤其對于那些不熟悉的代碼,閱讀代碼并畫出流程會提供較大的幫助。

随筆結語

“Zero Bug” 可能是程序員追求的目标,但現實中存在着較大的困難。程序員的日常離不開debug,寬泛一點說是trouble shooting(故障排除)。故障排除在很多時候依賴于經驗,反複實踐幾乎是不二法門,但是,我們可以通過歸納總結自己的經驗形成一個“心智模型”,可能是樹狀的,也可能是金字塔結構,也就是所謂的“套路”。

我們都有一個共同的夢想——成為更棒的程序員,但是如何做?如何學習和精進自己的技術?如何做業務分析和架構設計?如何做技術管理?本書就廣大程序員都很關注的問題提供一些思路和方法。

今天我給大家總結出來一份c/c Linux後台服務器開發架構師成長路線圖。需要視頻學習的朋友可以後台私信【架構】獲取

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关圖文资讯推荐

热门圖文资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved