1. 程式人生 > >如何才能寫出沒有BUG的程式碼?

如何才能寫出沒有BUG的程式碼?

1947年9月9日,美國海軍准將 Grace Hopper 在哈佛學院計算機實驗室裡使用 Mark II 和 Mark III 計算機進行研究工作。她的團隊跟蹤到 Mark II 上的一個錯誤,操作人員發現是由於一隻飛蛾鑽到了 Mark II 的繼電器裡導致的。團隊清除了這隻飛蛾,一切恢復正常。當時的工作人員記錄了這樣一句日誌:” First actual case of bug being found. ”  這次著名的事件,猶如潘多拉打開了魔盒,從此,程式設計師的世界裡,bug 滿天飛。

788453-20180704141521851-1267604373.jpg

世界上第一個 bug

在我所擔任過的角色中,有一個崗位叫做 Development Manager,通常簡稱 DM. 記得在一次基於一款平臺的二次開發專案中,因為 bug 實在太多,我們幾乎拿出了一整個里程碑的週期來 debug,於是我這個DM有了新的解釋:Debug Man.

沒有人喜歡 bug,bug 意味著錯誤、不確定性、加班、交付風險,等等…… 負面的詞語怎麼堆砌都不冗餘。隨便找個有過一、兩個專案經驗的開發者,問問他 debug 的回憶,那氣氛就跟上墳一樣。

對於 bug,開發者的神經往往也很敏感。有個段子很有趣 —— 說的是“應該如何向程式設計師反饋一個 bug ” ——

你不能直接跟他說:“這裡不對啊,是不是你程式有 bug 啊?”,要這麼說的話,會直接被懟回來:“你丫的自己不會用吧!”。

你可以換個說法:“咦,這裡好像不對,是我操作錯了嗎?”,這時程式設計師心裡就一咯噔:“Shit.. 不會是我程式碼有 bug 吧?”

從業多年,發現有個現象還蠻有趣的:有時候,當某個 bug 被發現時,犯下這個錯誤的始作俑者會開玩笑地為自己解脫:“誰沒寫過 bug 啊,Windows 還有 bug 呢。” 這句託詞我也用過,感覺挺好用的,就好比:梅西都能罰丟點球,我空門沒進,也是可以理解的嘛。

但其實吧…… 這邏輯經不起推敲的。

Windows 作業系統,一款長達30多年,裝機量估計都超過了地球人口數量的巨型工程,複雜度基本只能靠猜。以微軟公佈的資料來看:

Windows 95 程式碼量約 1500 萬行 Windows XP 程式碼量約 4500 萬行 Windows Vista 程式碼量約 5000 萬行 Windows 7 程式碼量 5000+ 萬行

以 Windows 7 為例,超5000萬的程式碼量,23個小組,共1000多人的開發團隊。如此規模下產生的bug,和一個在辦公室裡上了1天班,寫了200行程式碼,就鬧出一堆bug,搞得專案亂七八糟的,能同日而語嗎?最後再輕描淡寫地來句 “微軟也有 bug ”,不害臊?

所以我後來不用這句了,如此開脫,水平太low。其替代方案容我稍後再講。

788453-20180704141912620-976779412.jpg

為了對抗 bug,人們發明了各種各樣的工具和手段,上至方法論,下至生產工具。越來越先進的 IDE, 複雜的程式碼審查制度,從單元測試到整合聯調,再配上 beta 版,試用,公測,等等。凡此種種,其目標無一不是消滅 bug 。可這些琳琅滿目的解決方案的存在,反倒證明了一個悲劇:人類,實在是太容易犯錯了。

如果說凡事都有正反兩面的意義,那麼 bug 的正能量就是硬生生造就了大量就業機會,進而維護了社會穩定。

那麼,為什麼我們總是無法避免 bug 的產生?我們能不能杜絕 bug ?

答案當然是不可能了。因為那樣一來,程式設計師的日子豈不是太舒服了?不符合苦逼的定位。而且,我們所處的這個世界,但凡越是高呼要消滅的東西,越是會普遍地存在。就像蒼蠅、蚊蟲、汙染、犯罪、戰爭,不一而足。

按照常識,經驗越豐富的老手寫出來的程式碼,一次通過的機率更高,比如他們思考得會更周全,對異常的判斷和處理更老練,邊界條件把握得更精確,等等。所以我們可能會幻想:是不是隻要我們足夠仔細,並努力磨練技藝,通過讓一部分碼農先老練起來,然後實現共同老練,最終就可以達到全世界開發者聯合起來消滅bug的大解放了?

很遺憾,這只是一個治標不治本的思路,因為bug是有階級的。老手們的bug相對少,只是低階錯誤少,他們也會遇到bug,而他們的bug,往往都是一眼蒙逼的難度係數N.x的難題,不發生在程式碼層面,大多在業務層面,甚至需求設計層面,或者直接是一些不可抗拒因素(做過政府專案嗎?)。總之,萌新有萌新們的秀逗,大叔有大叔們的短路,老杆也會有自己的滑鐵盧。

bug 這個概念的起源,就預示著它的不可避免性。世界上第一個 bug 是一隻飛蛾,這劇本,誰能料到?某種意義上說,bug 就是不可預見的錯誤,能被預估並且提前做好準備的,那叫 exception, try catch 是他們的朋友。

對於為什麼會產生 bug 的原因,著名的荷蘭電腦科學家 Edsger W. Dijkstra 有過一句經典名言:

If debugging is the process of removing software bugs, 

      then programming must be the process of putting them in.

這就是上文提到的那句託詞 “ Windows 也有 bug. ” 的替代方案。