1. 前言
一直聽說真正的工業界,真正的代碼量占用了很少的精力,更多的精力都在其他的環節,
50%的精力在討論、展示自己的想法和思路
20%的精力在造輪子、單元測驗
20%的精力在寫說明檔案
10%的精力在真正寫代碼
還有100%的精力在改自己發現的BUG,自己沒發現的BUG,別人發現的BUG,哎,不對啊,怎么總精力不是100%而是200%?沒錯,這就是程式員為什么需要經常加班的原因,
那么,當我們在面對程式出現了我們不能理解的BUG的時候,應該怎么辦?
下面是幾個準則,供大家參考,
2. 充分相信代碼和機器
程式員第一要義,要充分相信代碼和機器,就像戰士相信自己手上拿的東西一樣,
遇到最多的情況莫過于:“哎,明明我這樣這樣做了,為什么電腦不按照我的想法來呢?它總有自己的想法運行,”毫不夸張的說,如果真有電腦可以擁有自己的思想運行代碼的,請聯系我!
正經點,我們來看看這個問題所在,我們把整個程序分為4個環節,
第一,我們有一個想法
第二,我們把想法實作成了代碼
第三,機器運行了實作的代碼
第四,出現了預期之外的結果
現在就我而言,出問題的環節按照概率大小排序的話:把想法實作成代碼>我們有一個想法>出現了預期之外的結果>機器運行了實作的代碼,我優先考慮是我們的實作部分出現了問題,然后是我們的想法不正確,人的錯誤率是相當高的,而機器出錯的概率微乎其微,
以人為本的考慮結果是:“這一定是機器出了問題,我肯定不會出問題的,什么,機器給我報錯了,不,一定是機器錯了,我不聽解釋,不聽!”
機器可不是人,不會說,先點幾下給你提示錯誤,然后看你不高興了,再點的時候錯誤沒了,機器能自己修復BUG嗎?顯然不能啊,
當然,你說,會不會存在機器和代碼確實存在物理性的問題,這個不排除有,但是我們一般人遇到的可能性幾乎為0,所以當我們遇到BUG時,應該優先考慮我們自己的問題,然后才能夠解決這個問題,不然,你會寄希望于機器自己解決這個問題嗎?
3. 避免燈下黑
一定要仔細檢查那些你一致忽略的地方,80%的BUG都是我們自己的小失誤造成的,而不是真的邏輯上有問題,這些小失誤可能是命名不規范,重復賦值,參考不正確,多寫了個符號,引數忘記傳等等,基本上都是在容易想當然的認為這個地方一定會正確的時候,恰恰是我們最難以發現的地方,
4. 問題為導向
當代碼出現與預期不符的時候,一定要先去思考,從邏輯上講,這個應該是什么問題,而不是直接就跳躍到代碼上查找,如果不清楚是什么型別的問題,當你面對代碼的時候,就很容易無從下手,這就像去醫院看病,醫生先會問你出現什么癥狀,然后給你一個大致判斷你這是什么病,病因可能來源于哪個部分,然后再根據需要,進行特定部位的檢查和分析,沒有見過醫生等你來到就先給你說,做個全身檢查吧,檢查完咱再看哪里有問題,
5. 縮小觀察視野
當預期不符合的時候,要學會倒推,看一下具體是哪個部分出了問題,不要有跳躍思維,一定要聚焦問題,才能夠縮小觀察視野,才能夠發現問題所在,要把整個程序劃分為具體的若干個單元,如果在第n個單元出現了問題,先去看它的前置單元第n-1個單元里哪些部分會影響這個出現問題的部分,然后再看一下是第n-1單元里哪個部分出現了問題,如果定位后,發現是第n-2個單元出了問題,依次往前遞推即可,萬萬不要第n個單元出了問題,就考慮是前面所有單元出了問題,甚至斷言是第一個單元出了問題,因為每個單元間的聯系可能不止一條兩條,所有出現問題的可能性可能早就已經超過了人工檢查的能力,
6. 多看官方手冊和源代碼
問別人雖然能短平快的解決問題,但是多看官方手冊和源代碼才是最終提升自己能力的正途,因為官方手冊是最正式和最正確的指南,從里面可以學習到很多精細化系統化的知識,從而對于整個系統有更清晰的認識,而觀看源代碼會讓你對于思維到實踐的映射有一個直觀的認識,看完源代碼你會恍然大悟:“哦,原來這里是這樣實作的,真巧妙,”
你也能夠學習到規范的代碼風格以及編程思想,從而完成從觀察者到參與者的轉變,最后你就可以舉一反三,真正的將別人的代碼變為自己的代碼了,這就是為什么面試的時候,別人總喜歡問,你看過源代碼嗎?因為別人并不是真的想問你源代碼的細節,而是看你有沒有這個習慣,因為工業開發中,你經常需要看別人的代碼,
那么什么時候是問別人更合適呢?
- 如果問題是比較精細的或者少見的小問題,詢問有經驗的人會更好一些,
- 如果這個問題不在你的主流技術堆疊中,以后大概率也用不到,只是你現在臨時碰到,但是需要快速解決的時候,
- 如果這個問題是比較抽象的,并不能從現有的展示中直接獲得答案的,需要高度凝練和總結的時候,可以詢問有經驗的人,
7. 理解編程思想而不是代碼實作
寫代碼本身并不是非常困難的事情,因為它的本質就是思維的表達,就像是在寫英語作文一樣,我們寫英語作文難在哪?為什么寫漢語作文就容易很多?我們不知道要說什么,通常英語作文沒有抒情文,也很少有記敘文,都是議論文為主,只要想好論點、論據,構思一下說明思路,只要單詞過關,英語作文要比漢語作文容易,
寫代碼也是一樣,只要記住某種語言的語法,本質還是要實作某些功能的思路和想法是什么,在計算機里,這個就是演算法的一種體現,演算法不僅僅是實作某種特定功能的一串代碼集合,而且也是解決某一類問題的特定方法,顯然學會后一種的思維方式比形而上的死記硬背一行行代碼更加重要,
8. 舉個栗子:深度學習模型構建程序中遇到的問題
以深度學習模型學習不到想要的效果,從整體程序上應該作如下考慮:
-
本身這個問題是否可以被形式化為你執行的代碼
有些問題的解憑借樣本是可以被學習解決的,但是有些是不能的,你待觀察的特征與學習目標的相關性較小,或者基本上沒關系,比如根據拍西瓜的聲音、顏色等是可以判斷西瓜的成熟度的,這個無論是人還是模型都是可以學習到的,但是你說觀察一下西瓜的顏色,判斷一下西瓜里包含多少籽,甚至預測一下給這個西瓜的人是男是女,那我覺得這種是無法被人學習到的,也無法被模型學習到, -
訓練代碼/測驗代碼是否正確
訓練代碼是否正確應該檢查兩個部分,邏輯是否正確和資料處理是否正確,正確與否的判斷取決于是否達到了你想要的目的,- 邏輯是否正確
- 是否按照了你想要的程序進行訓練?
- 訓練程序中的引數傳遞是否沒有出現誤傳、引數是否都已經填寫齊全且正確?
- 是否按照規范的訓練流程進行的?如果沒有,你的改動有哪些,那些部分會出現問題嗎?
- 資料處理是否正確
- 資料被處理成的物件是否合理?
- 資料的內容和形狀是否符合預期?
- 邏輯是否正確
-
模型選取是否正確
- 是使用別人的模型嗎?別人的模型里的引數是否設定正確了?模型的輸入是否符合它約定的輸入形式?
- 如果是自己設計的模型,那么就要看一下自己設計的模型哪部分是移植過來的,哪部分是自己寫的,自己寫的部分能夠保證一定正確嗎?有無模型圖的展示?
-
及時反饋,深入思考
出現問題先搜索一番,說不定有遇到同樣問題的,有些時候模型的報錯不是特別容易理解,很多時候都是一些編程錯誤,并不給你指出真正的問題所在,這時候你就需要推斷一下,比如說有的說兩個向量相加失敗,一看定位,是在基礎庫里的,那顯然加法不能出現問題啊,出現問題的只能是兩個向量,兩個向量為什么會相加失敗呢?有一個原因是兩個向量的形狀不同導致的,那是哪個向量的形狀不符合預期呢?這個向量從哪里來的?經過了什么樣的處理?通過這樣一個逐漸深入的程序,你就能定位到是哪里出現了問題,
9.小結
以上都是在日常調整BUG時遇到的一些小技巧,希望能夠幫助我們更好的科研與開發,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/293652.html
標籤:其他
