程序員(yuán)在普通人的印象裏是一(yī)份嚴(ku)謹(bi)的職業,也是一(yī)個被搞怪吐槽樂此不疲的職業,程序員(yuán)們面對複雜(zá)的代碼敲打電腦時連眉頭都不會皺一(yī)下(xià),但是有一(yī)個詞卻是他們痛苦的根源,它就是Bug。
千萬不要和程序員(yuán)直接說有Bug
程序員(yuán)遇到Bug時的30個反應
開(kāi)發應用程序是一(yī)個非常有壓力的工(gōng)作。沒有人是完美的,因此在這個行業中(zhōng),代碼中(zhōng)出現Bug是相當普遍的現象。
面對Bug,一(yī)些程序員(yuán)會生(shēng)氣,會沮喪,會心煩意亂,甚至會灰心喪氣,而另一(yī)些程序員(yuán)會依然保持冷靜沉着。因此,如何處理修複Bug的過程也值得我(wǒ)(wǒ)們細細琢磨。
我(wǒ)(wǒ)想分(fēn)享一(yī)些程序員(yuán)修複他們的源代碼時所經曆的想法。我(wǒ)(wǒ)相信很多開(kāi)發人員(yuán)和軟件工(gōng)程師經曆過這些艱辛,然後在事後一(yī)笑而過。以下(xià)你經曆過哪些?
1.“我(wǒ)(wǒ)不知(zhī)道是要删除還是要重寫它”
回顧從前老的源代碼,會有一(yī)種想要返工(gōng)寫成較大(dà)塊集群的沖動和誘惑。醜陋的邏輯語句,還有冗長的語法,導緻代碼非常難以閱讀!
但話(huà)又(yòu)說回來,如果代碼沒有壞掉的話(huà),那就不要去(qù)修複它。這種洶湧澎拜的鬥争是我(wǒ)(wǒ)經常要面對的,而且顯然會困擾許多軟件開(kāi)發人員(yuán)。
2.“對于起始框架我(wǒ)(wǒ)應該查看Github”
我(wǒ)(wǒ)想大(dà)多數開(kāi)發人員(yuán)都知(zhī)道Github,上面每天都有數量驚人的開(kāi)源項目發布。
任何語言的程序員(yuán)都可以通過互聯網借鑒現有項目,加入維基讨論,或者創建自己的代碼倉庫。它是各種項目所需插件和模闆的超棒資(zī)源。
3.“爲什麽這個腳本需要這麽多庫?”
尤其是一(yī)些比較大(dà)衆化的語言,如Java和Objective-C,庫的數量可能變得異常兇猛。當構建一(yī)個需要大(dà)量基礎的框架時,所需的庫的數量就變得顯而易見得多。
即使是一(yī)些适用于JavaScript的插件,也會額外(wài)需要無數的文件。有時,這會讓人覺得煩雜(zá)惱人——但至少是有用的!
4.“在互聯網的某個地方一(yī)定已經有了解決方案。”
我(wǒ)(wǒ)面對棘手問題的**反應是上網查。程序員(yuán)會将他們遇到的問題通過帖子發布到論壇上,然後這個問題最終得到解決并歸檔。
谷歌搜索問題關鍵字的好幫手,可以指點你往正确的讨論方向走。不幸的是,有的時候卻是因爲手頭沒有特定問題的太多信息而找不着北(běi)。
5.“有沒有這個功能的插件?”
爲什麽要重新發明輪子?插件是擴大(dà)任何程序或網站用戶界面的偉大(dà)資(zī)源。此外(wài),它們還爲開(kāi)發人員(yuán)提供了一(yī)些自定義和**的選項。萬一(yī)真的沒有可用插件的話(huà),爲什麽不自己構建一(yī)個呢?
6.“雖然網站可以工(gōng)作,但我(wǒ)(wǒ)害怕IE浏覽器。”
在Internet Explorer中(zhōng)渲染網頁的曆史充滿了艱辛考驗,是我(wǒ)(wǒ)們有目共睹或親身體(tǐ)驗過的。
從5.5版本升級到IE9、IE10,總是需要争取到更高級浏覽器的支持。Web開(kāi)發人員(yuán)可能會害怕調試網頁,因爲在IE6中(zhōng)打開(kāi)頁面是一(yī)個渲染噩夢。值得慶幸的是,這樣的日子正在慢(màn)慢(màn)成爲過去(qù)。
7.“對于邏輯表達式而言,這似乎并不怎麽合乎邏輯。”
對于if/else循環,for循環,while循環,do循環等等,都有邏輯表達式。當浏覽示例代碼時,我(wǒ)(wǒ)試圖指出我(wǒ)(wǒ)的邏輯是如何工(gōng)作的。
NOT運算符和比較标記的數量又(yòu)是如此之多。我(wǒ)(wǒ)經常回過頭去(qù)更新我(wǒ)(wǒ)自己的邏輯以便于更好地适合未來的做法。
8.“我(wǒ)(wǒ)用30分(fēn)鍾寫函數,花2小(xiǎo)時讓它工(gōng)作。”
這難道不像我(wǒ)(wǒ)們自己的編程故事嗎(ma)?你正興緻勃勃地在構建着什麽,但是突然之間,函數輸出了一(yī)個緻命的錯誤。
所以,現在你必須回過頭去(qù)删除一(yī)些代碼塊,以找出錯誤發生(shēng)的行号。當你終于找到罪魁禍首,并解決它時,雖然有種精疲力竭的感覺,但也滿心安慰。
9.“在閱讀多篇博客文章之後,我(wǒ)(wǒ)意識到,我(wǒ)(wǒ)之前全都是錯的。”
我(wǒ)(wǒ)常常會一(yī)開(kāi)始就根據自己的編程思想,一(yī)頭紮進去(qù)研究,但是這可能會導緻麻煩,如果事情不像原先設想地那樣順利的話(huà)。
已經有很多次在我(wǒ)(wǒ)啓動一(yī)個項目之後,陷入了困境,然後隻好尋求博客和其他論文的支持。
最後我(wǒ)(wǒ)發現我(wǒ)(wǒ)的整個方法實際上是錯誤的,而且從頭來過更容易!如果我(wǒ)(wǒ)開(kāi)始的時候能先做一(yī)番研究的話(huà),從長遠來說,反而節省時間。
10.“Stack Overflow上和善的人或許願意幫助我(wǒ)(wǒ)。”
我(wǒ)(wǒ)已經數不清有多少次我(wǒ)(wǒ)通過Stack Overflow解決了難題。社區裏都是和善和聰明的人,他們非常願意提供幫助,如果你邁出**步的話(huà)。
在所有的在線論壇中(zhōng),Stack Overflow絕對是對軟件編程以及前端/後端web開(kāi)發支持最廣泛的網絡。
11.“花費(fèi)大(dà)力氣才找出問題的原因是缺少了右括号。”
調試是你必須要采取的步驟,進兩步,退一(yī)步。盯着代碼數個小(xiǎo)時,以爲函數名或變量作用域中(zhōng)有哪裏搞錯了,最後才發現是遺漏了一(yī)個括号,這滋味,酸爽得不要不要的。所有這些時間都因爲一(yī)個小(xiǎo)小(xiǎo)的語法錯誤而浪費(fèi)。
12.“喝(hē)杯咖啡,休息一(yī)下(xià)!”
有時候,你隻是需要站起來,遠離(lí)顯示器。将鼠标懸停在鍵盤數個小(xiǎo)時,反而有助于打破常規。大(dà)多數健康指導都會建議我(wǒ)(wǒ)們每隔30-60分(fēn)鍾休息一(yī)會。
但是這一(yī)切都取決于你的需要,如果你覺得在程序中(zhōng)間休息更令人懊惱的話(huà),那就不要中(zhōng)斷。
13.“我(wǒ)(wǒ)應該把這個項目束之高閣,以後再來處理它。”
休息的另一(yī)個選擇是離(lí)開(kāi)你的項目,而不僅僅是遠離(lí)你的電腦。如果還有其他工(gōng)作需要做,那麽不妨去(qù)做其他工(gōng)作。
相對于已經花費(fèi)了5個小(xiǎo)時來解決問題依然不得入門而言的話(huà),這将能更好地分(fēn)配時間和資(zī)源。
14.“我(wǒ)(wǒ)很懷疑古典音樂能否激發我(wǒ)(wǒ)的編程能力。”
有一(yī)種說法是,古典音樂可以在生(shēng)命的早期階段促進植物(wù)生(shēng)長。我(wǒ)(wǒ)個人非常喜歡在寫複雜(zá)筆記時聆聽(tīng)古典音樂。爵士樂、鋼琴、大(dà)樂團,優雅的音樂在全世界的人類文化中(zhōng)都有一(yī)席之地。
那麽,在編程的同時傾聽(tīng)智慧的音樂真的能夠讓你更智慧地調試嗎(ma)?可能不會,不過希望它不會讓你變得更笨拙。
15.“喝(hē)點酒吧,也許現在是檢驗鮑爾默峰值理論的好時機。
很多讀者都聽(tīng)說過鮑爾默的峰值理論,根據一(yī)個特殊XKCD漫畫而得出。簡單地說,這個理論認爲程序員(yuán)的編碼能力在喝(hē)了一(yī)定量的酒之後,會達到一(yī)個峰值。
作者名叫史蒂夫·鮑爾默,他的行爲古怪,就像是一(yī)個醉漢,這有一(yī)定的諷刺意味,因爲鮑爾默在微軟從來就不是一(yī)名真正的程序員(yuán)。也許我(wǒ)(wǒ)們需要等待别人來實踐證明這個理論吧。
16.“是不是有人動過了我(wǒ)(wǒ)的源代碼?”
這聽(tīng)起來有點妄想和偏執,但有時你會不由自主地懷疑,是不是有人在你補覺的時候,寫過這個東西了。
回顧過去(qù)幾周或幾個月做的項目會讓你的心不斷地往下(xià)沉。有時候你會發現一(yī)些你已經不記得添加的東西——甚至這個項目你最近一(yī)周才剛剛浏覽過!我(wǒ)(wǒ)爲代碼而瘋狂,但你永遠不會知(zhī)道…
17.“我(wǒ)(wǒ)不知(zhī)道這意味着什麽。”
你能遇到的最壞情況是,你對你正在浏覽的源代碼**不知(zhī)道該怎麽做。可能是你自己的項目,也可能是别人的項目,但問題的根源是相同的。
現在,你必須決定是否值得花更多的時間去(qù)搜索替代方案,或仔細檢查腳本以了解它是如何工(gōng)作的。
18.“我(wǒ)(wǒ)需要Google錯誤信息。”
在PHP中(zhōng)工(gōng)作了多年之後,我(wǒ)(wǒ)不得不說,Google是我(wǒ)(wǒ)調試問題時最好的朋友。使用Objective-C、C++、Java、Python和其他主要語言,也是如此。
錯誤信息非常有幫助,但是除非你記得不同的代碼意味着什麽,否則它讀起來更像是翻譯過的計算機語言。值得慶幸的是,有很多在線支持可以幫助我(wǒ)(wǒ)們确定這些錯誤信息的真正含義。
19.“我(wǒ)(wǒ)應該停下(xià)來,收工(gōng)……但我(wǒ)(wǒ)真的很想解決它!”
我(wǒ)(wǒ)們都有過*度灰心喪氣,想要放(fàng)棄的感受,但總感覺半途而廢不是正确的選擇。于是,你繼續埋首鑽研,并嘗試新的解決方案來調試。
但是,如果這還是意味着另一(yī)個小(xiǎo)時的浪費(fèi)呢?對于這樣的情況我(wǒ)(wǒ)并不陌生(shēng),令人非常令人沮喪。
20.“哦,天哪,我(wǒ)(wǒ)以前爲什麽不寫點注釋呢?”
當涉及到比較基礎的前端HTML/CSS/JS時,我(wǒ)(wǒ)們沒有必要寫注釋。但更複雜(zá)的腳本和程序卻需要一(yī)定形式的條理組織,當你在幾個月後,甚至若幹年之後需要再回過頭來看的話(huà)。
有時你會忘記注釋函數及其參數、輸出格式,和其他的必要數據。這在一(yī)段時間之後無疑會導緻混亂。而且,當Bug開(kāi)始出現時,你必須調試整個腳本來尋找解決方案。因此,要是有一(yī)些有幫助的注釋就會讓你獲益良多。
21.“20分(fēn)鍾前它還可以工(gōng)作的……”
在構建程序時,可能最令人沮喪的部分(fēn)就是,它從能工(gōng)作到不能工(gōng)作——而你沒有更新代碼的任何部分(fēn)!我(wǒ)(wǒ)發誓這是真的,而且這是沒有任何意義的事情——也許是其他程序正在運行緩存版本?
有很多次你更新了一(yī)丁點代碼,卻導緻了整個程序崩潰出錯,**停止了工(gōng)作。恢複到最近可工(gōng)作的複制文件,然後從那裏開(kāi)始一(yī)步步前進。
22.“隻是忘記了一(yī)個分(fēn)号,然而整個程序卻因此而轟然倒下(xià)。”
幾乎所有我(wǒ)(wǒ)使用的編程語言都需要結束符。雖然不是所有的語言都有,但在C/C++中(zhōng)是很常見的。
忘記添加結束符,不過是一(yī)個很顯然的錯誤!但是解析器不知(zhī)道這一(yī)點,它會抛出一(yī)個緻命錯誤。
于是,你不得不額外(wài)花20分(fēn)鍾去(qù)搜索技術故障,而原本隻需要用1秒鍾補上那個缺少的分(fēn)号即可。嗯,這就是調試軟件的樂趣。
23.“我(wǒ)(wǒ)不知(zhī)道讓别人來修複我(wǒ)(wǒ)的代碼,得花多少錢?”
聘請另一(yī)個開(kāi)發人員(yuán)的點子是挺誘人的,但從财政上看顯然沒有那麽可行。而且如果你不親身體(tǐ)驗的話(huà),又(yòu)怎麽能從這些錯誤中(zhōng)學到東西呢?
當你在經曆多次失敗之後,終于理解了某個編程概念的時候,那感覺真是棒*了。盡管如此,我(wǒ)(wǒ)的腦海裏依然時不時地有一(yī)種“讓别人來修複代碼”的沖動。
24.“快速浏覽Hackers News可以提高我(wǒ)(wǒ)的工(gōng)作效率。”
很多程序員(yuán)最喜歡閱讀的,有關于軟件和創業公司等社會新聞的選擇是Hackers News頭版。它有很多關于自由職業、時間管理、軟件開(kāi)發、以及創業發布和融資(zī)的大(dà)量信息。
雖然HN可以通過自我(wǒ)(wǒ)教育讓你感覺自己變得更有效率了,但同時它也會浪費(fèi)你的時間。每隔幾小(xiǎo)時去(qù)快速浏覽下(xià)Hackers News也不是那麽糟糕。
25.“這個API怎麽沒有文檔?!”
在使用帶有壞文檔的插件或框架時,最令人沮喪的是,你必須靠自己去(qù)深入鑽研源代碼。我(wǒ)(wǒ)喜歡開(kāi)發人員(yuán)花時間去(qù)專門設計可用文檔頁面的項目。
所有的參數和選項都解釋得清清楚楚,甚至可能會被用在一(yī)些示例代碼片段中(zhōng)。但可悲的是,事實并非總是如此。所以最簡單的方法是遠離(lí)不良文檔,不自找麻煩。
26.“我(wǒ)(wǒ)真希望我(wǒ)(wǒ)保存了那個數據庫的備份副本……”
在編寫和調試代碼時,我(wǒ)(wǒ)不會想到要備份。然而,數據備份提供了允許我(wǒ)(wǒ)們回過頭去(qù)修改的踏腳石。這在實時的服務器環境中(zhōng)尤爲有用,因爲有什麽變化會立即執行。
以防萬一(yī),我(wǒ)(wǒ)們應該記得保存網站文件和數據庫的本地副本!雖然這會是一(yī)個惱人的任務,但其惱人程度遠遠比不上重建損壞的SQL數據庫。
27.“讓它正常工(gōng)作的最快解決辦法是什麽?”
在花費(fèi)數個小(xiǎo)時苦苦思考自定義的解決方案之後,很明顯你需要一(yī)種新的方法。在設計漂亮的界面之前,程序員(yuán)率先想到的是讓功能正常工(gōng)作。
确定最快、最準确的解決方案,并實施這個解決方案讓其工(gōng)作才是100%利用了時間,然後再轉移到漂亮美觀方面。
28.“我(wǒ)(wǒ)敢打賭更新我(wǒ)(wǒ)的軟件将解決這個問題。”
管理編程語言依賴和插件的團隊并不需要經常發布版本。有時,在你從計算機傳輸文件到實時服務器的時候,更新PHP/Ruby/Python/SQL版本可以解決調試問題。
本地更新很少能夠幫助修複源代碼中(zhōng)的Bug,除非你的版本已經過時得無可救藥。所以,值得一(yī)試!
29.“我(wǒ)(wǒ)應該更有條理并且去(qù)學習Git……下(xià)周就去(qù)研究它。”
開(kāi)源版本控制包Git在程序員(yuán)中(zhōng)非常受歡迎。相對于其他的競争對手,它提供了更容易的學習曲線,并且被許多在線代碼倉庫,如Github上和Bitbucket使用。
開(kāi)發人員(yuán)很容易拖延去(qù)學習Git的行動,因爲它對于初學者而言顯然是有難度的。但是一(yī)旦你知(zhī)道了基本命令,那麽Git就是小(xiǎo)菜一(yī)碟。而且它還能使調試版本控制更加清晰。
30.“算了,我(wǒ)(wǒ)還是從頭再開(kāi)始吧。”
有時候,在你絞盡腦汁花費(fèi)數個小(xiǎo)時之後,可能要做的隻是将你的工(gōng)作文件移動到歸檔目錄(或删除它們),再從頭開(kāi)始就可以了。但是,考慮到先前已經耗費(fèi)的時間,你很難下(xià)定這個決心。
當我(wǒ)(wǒ)一(yī)籌莫展時,我(wǒ)(wǒ)往往會選擇從頭開(kāi)始,因爲這樣才有可能找到完成項目的正确道路。
爲什麽程序員(yuán)發現不了自己的Bug?
最近在朋友圈流行了這樣的一(yī)個小(xiǎo)學數學題,當然結果是“出乎意料”,看似簡單的結果,幾乎很少有人做對,而分(fēn)析下(xià)來的原因無非是慣性思維下(xià)的粗心導緻的**錯誤,今天小(xiǎo)編就帶大(dà)家一(yī)起分(fēn)析下(xià)思考過程。
看圖可知(zhī),貓=X貓頭=Y貓爪=Z,既:
3X=30
X+Y+Y=20
Y+Z+Z=9
所以得出X=10 Y=5 Z=2,故結果:Y+Z+X=5+2+10=17。
一(yī)般大(dà)多數的**結果可能都是這樣!等等,注意最後一(yī)個應該是Y+Z×X=?
心中(zhōng)一(yī)百隻草泥馬奔過,再算一(yī)遍,Y+Z*X=5+2*10=25。
對不起還是錯的,因爲貓爪從2隻。
變成了1隻。
所以應該是Y+Z/2*X=?心中(zhōng)一(yī)千隻草泥馬奔過,再算一(yī)次:Y+Z/2*X=5+2/2*10=15。
對不起還是錯的,因爲最後一(yī)隻貓少一(yī)個爪子,所以應該是:Y+Z/2*(X-Z/2)=?
心中(zhōng)一(yī)萬隻草泥馬奔過,再算一(yī)次:Y+Z/2*(X-Z/2)=5+2/2*(10-2/2)=14。
其實大(dà)家會發現這個題目非常的“坑爹”,不就是故意折騰人麽,但是在很多系統中(zhōng),開(kāi)發看到測試提出的Bug也是這樣的感覺。
作爲開(kāi)發就和我(wǒ)(wǒ)們成人一(yī)樣看到問題總是以自己的世界觀來理解,導緻理所當然的就這樣就對了,而真正的真相就被隐藏了。
而兒童一(yī)般能夠做對的原因是,老師有引導性的提示細心的重要性并且長期踩雷。這也是測試人員(yuán)和開(kāi)發人員(yuán)的區别之一(yī),現在知(zhī)道爲啥測試不是誰都能做的工(gōng)作了吧,開(kāi)發也爲啥找不到Bug了吧。
當程序員(yuán)面對Bug的時候,如何機智甩鍋?
當你面對Bug時,切勿慌張,以下(xià)措施教你輕松應對Bug帶來的困擾。
1.打死不承認,這代碼不是我(wǒ)(wǒ)寫的,将鍋甩出去(qù)。
2.睜眼說瞎話(huà),在我(wǒ)(wǒ)電腦上是正常的呀,超級無辜。
賺取同情分(fēn)
3.對方使用了錯誤的打開(kāi)方式。
一(yī)定是對方的打開(kāi)方式不對,重新打開(kāi)試試,我(wǒ)(wǒ)神馬都不知(zhī)道
4.痛斥産品經理一(yī)頓,自己偷偷改好,氣勢不能弱,立場要堅定,迅速進入角色,**沒有Bug這回事,我(wǒ)(wǒ)就是王道。
以上模式可任意切換使用,但最終都逃不了,自己背地裏偷偷,改Bug的宿命。