為啥程式會有bug?
如果這是第二次看到我的文章,歡迎右側掃碼訂閱我喲~ ?
本文長度為 4818字 ,建議閱讀 13 分鐘。
堅持原創,每一篇都是用心之作~
這是一篇半娛樂性的吐槽文章,權當給廣大技術人員解解悶:)。
哈哈哈,然後我要開始講一個經常在發生的事實了。( 程式設計師們可能會感到一些不適 )
99.999999999%做技術的都會被問到或者被吐槽到:“你的程式怎麼又出bug了!”
▲圖片來源於網路,版權歸原作者所有
反正,我作為程式設計師的內心世界是:如同一萬隻草n馬飛奔而過,難以壓抑內心的激動,每次都差點忍不住想說“你寫篇幾百字的作文還有錯別字呢,我碼個幾萬行的程式碼還不允許出錯了?“
可能同樣是做技術的你此時在不斷點頭,哈哈。
但是這麼講畢竟也緩解不了矛盾,我們還是得擺事實講道理不是?
啥都不怕,就怕程式設計師有文化!
所以,Z哥想來帶你好好分析一下這個事情,當你再遇到這個情況的時候,可以拿這些觀點來反駁( 不是做技術的也可以瞭解下程式設計師的難處,誰沒個難處呢,多多包容 )
什麼是Bug
任何一個「問題」的產生,本身是沒有好壞之分的,但是為什麼會有的就不被care,甚至還會很喜歡,而有的會被吐槽呢?根本原因是因為產生了利益損失。
比如年前拼多多出問題送了很多無門檻券。
作為一個使用者,自然很喜歡,誇你誇到飛起,怎麼會吐槽你呢。但是作為利益損失方,必然破口大罵,害我傾家蕩產!
所以, 如果沒有產生利益損失,我想其他人也不會來找你吐槽 。
但是「問題」就等於「bug」嗎?我認為並不是, 「問題」不等於「 bug」 。
因為程式設計師的職責是什麼?拿造房子來比喻的話,我認為最核心的工作真的和“搬磚”(非貶義詞)無異,就是根據設計師(產品經理)設計好的設計圖砌磚(編碼),建成和設計 圖 上一模一樣的建築。
所以,如果一個東西造出來與設計不符,那麼它可以說是bug或者缺陷(缺斤少兩不完整)。否則,並不是bug,但可以被稱之為「漏洞」(完全沒考慮到的),表示不在預料之內的情況。
之前看到過一個形象的比喻: 你家裡的窗可以從外面開啟,那叫漏洞。你家裡的窗打不開,那叫bug 。
但是要承認,bug是必然存在的。為什麼?它是如何出現的呢?
Bug是如何出現的
正如前面所說,程式設計師做的是“造房子”的事情。這件事完整的步驟分為3步。
-
與產品經理討論並確定功能(確定一個可以實現的設計圖)
-
將每個單獨的元件抽象出來(確定施工方案)
-
將相關的元件實現並進行組合,完成建設(帶上材料開始施工)
第一步,“與產品經理討論並確定功能”主要是溝通,靠“看”和“理解” 。
但是溝通本身是一個有損耗的過程,特別是在職責非常明確的組織中,產品經理啪啦啪啦講了很多,到實際做的時候你必然還是會去翻閱需求原型、需求文件之類的重新理解一下。這個時候就是一個非常危險的時期。
比如像下面這個的答案是什麼?
▲圖片來源於網路,版權歸原作者所有
答案是17?不對。
我猜你可能沒注意到這些地方。
▲圖片來源於網路,版權歸原作者所有
為了讓你有深刻的印象,這個舉例可能比較刻意和誇張一些,但是我想在你的身邊,由於沒注意到或者理解有誤的現象肯定很常見。
溝通是相互的,這鍋只讓程式設計師背的話的確太委屈了點。
第二步,“將每個單獨的元件抽象出來”這主要是一個人抽象能力的體現 。
但是抽象是啥?抽象是“透過現象看到本質”的能力,這個能力理論上是可以無限增長的。隨著你對相關資訊的掌握越多,這個能力會越強,會無限趨近於100%,但永遠不會真正達到100%,因為沒人知道怎麼才算100%。
所以,當你具備的資訊沒那麼多的時候,是不是就抽象的不是那麼合理?不合理會導致什麼?雖然不會直接產生bug,但是會更容易產生bug。但是人不都是需要經歷這麼一個成長的過程麼?
可以說,精通一項能力的背後都是踩著無數的bug過來的。要麼在來這個組織之前已經踩過了,要麼在這個組織裡踩。因此,前者的薪資也比後者高。
所以, 如果過分苛求沒有bug,等於是在扼殺每個人成長的機會,並且在透支未來的可能性 。人會變得非常保守、不敢嘗試新事物。
但是外部環境在不斷變化,新事物總會被動的需要去接納(技術的更新越來越快,趨勢不可逆),然而對新事物的接受能力又得不到鍛鍊,一旦遇到這種情況,在接觸新事物的時候會產生更多的問題(欠下的債總要還的)。
第三步,“將相關的元件實現並進行組合,完成建設”這就是實際的coding過程,而 coding是一個主觀的,完全由人主觀掌控的事情 。
人畢竟不是機器,不可能不犯錯,就如前面提到的寫文章的時候出現錯別字一樣。
可能你會說,有測試人員啊,測試的工作不就是透過逆向思維來給程式設計師查缺補漏嗎?
的確是的,但測試的介入只是降低錯誤率,只是讓不出現bug的機率小數點後多幾位
,指望發現100%的問題還是不太現實的。至少在當下的條件下是這樣,為什麼呢?因為程式碼的本質是各種邏輯的組合。
比如,一個完整的業務流程有10個環節,每個環節有3種可能性,這是一個什麼複雜度的系統?3 ^ 10 = 59049個分支(理論上存在的可能性數量),想要100%覆蓋這些場景,付出的成本幾乎是不可接受的。
然而我們實際的系統中遇到的個別場景甚至還要複雜的多。
其實每個正在執行的系統都有bug,包括我們每天在使用一些熱門系統(玩遊戲的小夥伴們肯定熟悉“卡bug”這個詞)。只是這些bug有沒有被執行到,有沒有被發現,被多少人發現而已。
那麼,我們只能舉手投降嗎?那倒不至於,辦法還是有的。
減少bug的慣性想法
首先最容易想到的一點是,增加測試人員。
這也是最容易看得到的“成本”一種方式,畢竟招一個人就得支出一份工資啊。所以,增加測試人員這個方案是最不容易被老闆們採納的方案。除非你可以說服這個人力成本的投入小於獲得的價值。
另外,這個方案其實還增加了溝通成本,溝通的「隱性成本」其實非常大,但是往往容易被忽略。(關於溝通成本,感興趣的可以看我之前寫的《 就簡單聊聊溝通效率問題 》)
其次會想到的就是程式設計師程式碼寫的嚴謹一點,仔細一點啊。這也是一種缺啥補啥的慣性思維。
先撇開到底能不能達到嚴謹一點,仔細一點的目的。那怕達到了,他會產生什麼結果呢?可能是下面3種。
-
更多的條件驗證
-
更多的單元測試
-
更多的抽象提煉
可以確定的是,這些工作會增加2樣硬性的東西,投入的時間和整體的複雜度。時間很好理解,我們就來聊聊複雜度。
一個常識是,越簡單的東西越不容易產生bug。比如1+1=2,出現bug的可能性無非就是加號寫成來減號,1寫成了4之類。但是,1+1=2,並且1*1=1,並且1/1=1,。。。等等這些驗證條件越多,那麼由於驗證條件自身的錯誤而產生問題的可能性反而更多。
所以, 程式碼的複雜度和產生bug的機率是成正比的,並且具有「邊際效用遞減」的效果 。這就意味著,做更多的驗證帶來的收益會越來越小。
因此,這個方案哪怕真能執行到位,也不是一個特別好的方案。
那有沒有相對靠譜一些的辦法呢?有,但需要我們換一個角度來看待這個問題。
換一個角度看待bug
既然無法100%避免bug,那我們可以換個角度考慮一下,如何讓解決bug的過程更快,甚至快到你都沒有察覺。
解決bug主要就是做2件事,找到bug的產生點,然後修復它。
每天都在解決bug的程式設計師們應該知道,這事 最費時間的是“找bug”的過程 。
因為“修復bug”是一個技術性問題,這個對不同人的差異其實是很小的,因為程式設計師們每天在寫的程式碼都是差不多的,非常同質化的,況且還有標準答案“文件”可以參考。比如,都知道string.concat()是拼接,string.split()是分割。該用分割的地方不小心用了拼接,那改掉就好。
但是“找bug”就不是這樣了。比如,你剛剛改完一行程式碼後釋出出現的問題,你不用找就知道問題出現在哪。但是讓你排查一個剛接手沒多久的系統肯定是一臉懵逼。
根本原因在於,這個過程不像技術性問題具有確定性,它是充滿不確定性的,處在一個“混沌”的環境中。
所以, 對待bug的重點就變成了:如何更快的發現和找到bug 。
關於這點Z哥的建議是:
-
打好日誌
-
學會利用工具
-
每次的迭代規模儘可能的小
首先,打好日誌。日誌其實就是我們在編碼的時候安插在程式中“記錄員”,它替我們記錄著我們認為容易出現問題的地方所產生的資訊。
但是系統無時無刻都在執行著,必然會產生大量的日誌資訊,如何從這些資訊中快速的找到關鍵資訊,就是需要考慮的問題。
另外,如果每個人都隨意的用自己喜歡的記錄日誌的方式,那麼從風格迥異的日誌中找你需要的資訊就變得很頭疼,時間不一致,格式不一致等等。
所以,要做好打日誌這個事情,就需要定義一個標準,比如必須要有時間,包含當前上下文的引數等等。
我們還可以給日誌做一下歸類,定義不同的日誌級別,在記錄的時候帶上字首。比如【info】、【warning】、【error】之類。如此一來,平時更著重關注的就是error級別的資訊,而且由於將其他級別的資訊剝離了出去,使得這裡的資料量大大減少,更便於檢視。
不過,日誌記錄畢竟是一個在做“預判”,如果日誌中沒有記錄到怎麼辦呢?這裡提醒大家 不要先想著怎麼除錯 。
如果你面對的系統是一個單體應用倒還好。如果你面對的是一個大型的分散式系統,除錯的效率低不說,這事你一個人可能還完不成。而且,如果你直接除錯生產環境的話,說不準還會產生什麼副作用,攤上新的問題 。
找bug本質上是一個排除法的過程,設斷點除錯也是如此。但是從起點開始一步一步的做排除法效率太低了。應該先透過自己的經驗、擁有的部分資訊先邏輯推理一下,縮小排查的範圍。哪怕你最終還是需要除錯的話,先做這個事情也會讓後續的工作更高效一些。
第二點,利用工具。 這裡的“工具”不要簡單的理解成利用“除錯工具” 。正如上面提到的,找bug的本質是一個排除法的過程,那麼任何能夠幫你更高效的做排除法的工具都是可以利用的。比如,
-
從系統的「事件檢視器」中獲取更多的環境資訊。
-
利用windows平臺的windbg、lunix平臺的MAT之類的工具直接分析抓到的dump檔案。
-
藉助視覺化工具更高效的發現問題,如FlameGraph等。
另外,如果能主動的告訴你哪裡出現bug了,就更棒了。所以,我們可以搭建一套檢視方便,資訊同步及時的日誌框架,以便讓有價值的資訊第一時間呈現在你的面前。如果有高效的篩選功能就更好了。
很多日誌框架Z哥沒用過,就不發表什麼言論了,但是elasticsearch + logstash + kibana這套用起來還是很爽的,體系也比較成熟,部署起來也很簡單,大家可以嘗試一下。再配上ElastAlert或者Sentinl,可以把實時預警機制也包含了。
最後,每次的迭代規模儘可能的小。這個說起來容易,做起來難,因為這是由整個團隊的文化來決定的。這個點的內容完全可以單獨開一篇講,這裡就簡要闡述下。
MVP(Minimum Viable Product)式的小步快跑,其實除了讓系統或者產品的功能演進更科學之外,還可以讓每次迭代所面臨的風險更小。正如前面提到的,你改一行程式碼釋出上去,如果出問題,你說問題在哪?
相對的,再想象一下,一次性釋出一個開發了半年的版本,前一晚能睡的安穩不?
總結
好了,我們總結一下。
這篇呢Z哥先闡述了我對“什麼是bug”的理解,然後分析了bug是如何產生的,以及我們可能會做的一些慣性選擇。
最後給你的建議是, 以如何更快的找到bug為出發點來考慮。透過「打好日誌」、「學會利用工具」、「每次的迭代規模儘可能的小」這3種方式來進行 。
不過話說回來,雖然我們無法避免出bug(一個專案開發完後沒測出bug?你問任何一個技術人員都說“做夢呢”),但是爭取讓bug更少是我們的本職工作。
因為對bug容忍度低的另一層含義是,大家對系統的依賴越來越重,越來越多的事情在透過程式完成,而不是人力。
但是再有人咄咄逼人,就把這篇文章丟給他!
相關文章:
作者:
Zachary
出處: https://www.cnblogs.com/Zachary-Fan/p/bugwhy.html
如果你喜歡這篇文章,可以點一下左下角的「 大拇指 」。
這樣可以給我一點反饋。: )
謝謝你的舉手之勞。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31544142/viewspace-2639212/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 為啥遊戲大作總會跳票?遊戲
- 關於 interface{} 會有啥注意事項?下
- 關於 interface{} 會有啥注意事項?上
- 為啥呼叫new Thread().start()方法會呼叫run()方法?thread
- 被產品經理懟了,線上出Bug為啥你不知道
- Java 開發者的程式設計噩夢,為什麼你的程式碼總有 bug??Java程式設計
- 專案管理心得——你為啥會覺得自己很忙?專案管理
- Linux為啥會那麼受歡迎?Linux學多久Linux
- 中外程式設計師到底有啥區別?程式設計師
- 當機對獨立伺服器會有啥影響?伺服器
- 為什麼會有這麼多的程式語言?
- SAP RETAIL MM41 建立的商品主資料裡為啥會有Vendor Char.按鈕?AI
- SEO 為啥 nofollow
- [BUG反饋]AuthGroupModel的CheckId有BUG
- Python為啥又火了?Python
- 過濾器和攔截器有啥區別,這次會了!過濾器
- 【Not BUG】微軟Winform窗體中設計上的Bug,會導致程式編譯失敗?不,這不是BUG!微軟ORM編譯
- 外賣小程式為什麼如此火爆,優勢是啥?
- java中WAITING狀態的執行緒為啥還會消耗CPUJavaAI執行緒
- 實戰模擬│揭祕為啥年會你抽不到特等獎
- 【乾貨分享】當機對獨立伺服器會有啥影響?伺服器
- 前沿·探索·想象力,今年的雲棲大會有啥不一樣?
- 明明只改了一行語句,為啥鎖有這麼多?
- [譯] X 為啥不是 hook?Hook
- 三大主流程式語言Python為啥這麼牛?Python
- require和import有啥區別?UIImport
- 高防CDN有啥優勢
- 這次的星戰遊戲,為啥連路人都會覺得真香?遊戲
- 為啥你用@JsonFormat註解時,LocalDateTime會反序列化失敗?JSONORMLDA
- 為什麼js會有閉包JS
- 我可是遊戲主角,為啥連說話的權利都沒有?!遊戲
- 面試一個6年 Java程式設計師,竟然問啥都不會!面試Java程式設計師
- Protobuf 為啥比 JSON、XML 牛?JSONXML
- 只要你懂為啥有人愛砍傳奇,就能明白《逃離塔科夫》為何會成功
- 我讓 ChatGPT 化身為全知全能的文件小助理,啥姿勢她都會......ChatGPT
- 程式設計師越來越多,為啥工資反而越來越高?程式設計師
- Redis的字串底層是啥?為了速度和安全做了啥?Redis字串
- 前端儲存除了 localStorage 還有啥前端