一個BUG引發的...

        昨日,在使用Hadoop平臺進行開發的時候,出現了一個令我百思不得其解的問題:
        解析字符串的時候,在context.write(key,value)之後,字符串居然會神奇的消失,寫入文件的只有key的前一部分,而後面的包括value的值都神奇的消失了。理應說,就算是我key的字符串問題,那麼value值也應該會寫入的,但居然消失了!於是,開始如下假設:
        1、我第一反應是,會不會因爲字符串太長,導致key把後面的內容都遺棄了,就像是溢出一樣。但沒有理由value的值也消失的。測了許久,排除了這個可能性。
        2、Hadoop平臺處理中文不給力?那麼,便是編碼的問題了,但是,直接寫入中文進行處理,是沒有問題的,但應用在在整個流程中,卻出現了問題。那麼,應該會源頭進行查找問題所在。
        3、是因爲從mysql中提取數據後,寫入hdfs中時,由於編碼問題,而導致字符的混亂?於是,將寫入hdfs文件的內容存入了另一個文件中,進行處理,沒有問題!那麼,問題一定出在將數據寫入文件中這個階段。
        4、是由於mysql來源的數據格式的問題,而導致字符編碼的錯誤?於是,直接在程序中模擬相應的數據寫入,執行後,依舊錯誤!
        5、那麼,看來錯誤是在讀完數據到寫入數據的過程了。爲了避免寫入亂碼,使用的是Text類來處理字符串,換了String.getBytes(“utf-8”)的方法,搞定!
        原來,當初爲了偷懶,在網上看到了往hdfs中寫入中文的方式:使用Text類來進行封裝,然後調用getBytes()方法,便能夠成功顯示中文而不會出現亂碼。興高采烈的就繼續下一步了,但Text是用於處理Mapreduce中的值的,爲了能夠處理數據,他會進行一些自己的字符串處理,如添加一些標示性的字符,而就是添加進的分隔符,導致了進行鍵值處理的時候,產生了錯誤。
        由這個問題,看出,偷懶、不求甚解,很容易導致後面的一系列的問題。程序員的許多工作,就是爲了“懶”,爲了達到“懶”的目的,而開發出了大量的用機器替代人力的程序,節省了勞動力。但“偷懶”則不同,“偷”這個詞,本身含有貶義的一味,偷懶,則意味着在本不該懶的時候,卻懶了,實則不該。一個是因懶而行動,另一個是行動時卻懶。二者是有很大的差別的。
        爲了調試一個程序,有時候會搞的我們焦頭爛額,卻徒勞無功,感覺這種行爲純粹是浪費時間,卻又無法推脫,畢竟,程序是自己寫的!我們要爲自己的行爲買單!但是,在我們在爲瘋狂的調BUG的時候,看看周圍那些大牛,卻噼裏啪啦的敲着代碼,似乎他們的程序不會出現BUG,或者至少不會出現這種莫名其妙的BUG。效率的差別,就在此處了。探其所以,一是技術原因。由於經常敲代碼,使用某種語言,那麼熟悉程度一定很高,效率自然提升。但這種方式對效率的影響僅限於前期,之後,就是另一個重要因素了:二是編程習慣。知識有限、能力無窮,一個好的編程習慣能夠提高我們的效率。
        第一點就不多說了,原則是多練!
        關於第二點,有以下幾點:
        1、先思考,再編碼。程序員與代碼似乎有一種怨恨又愛着的情節,一旦有一個新的任務,就迫切的想第一時間入手將它搞定。我現在漸漸形成了這種方式,每次在自己很興奮地想要開始敲代碼的時候,總是強迫自己淡定,先去構思整個流程,乃至細節算法,之後,再按部就班的用代碼的方式將其實現。當我們在還未構思清楚就實現的時候,往往對於整體缺乏考慮,而僅僅考慮到某一局部的實現方式,甚至局部也是還沒構思就開始動手。這就像是沒有做好設計的建築師,在匆忙的完成一堵牆之後,發現歪歪曲曲;甚至在完成了一間房屋之後,才發現與整體不協調,於是——拆!雖然對於程序來說,代價會小很多,但就在這種一拆一建的行爲中,這種沉沒成本便彰顯了。效率之差,也就體現出來了。
        2、善於重構。這裏所說的重構,並非將項目進行大規模重構,這是需要徵求上頭的意見的,而上頭往往不會給你時間做這種事。我所說的重構,是對自己的項目進行重構,而重構的目的就是讓程序的邏輯清晰。即便一開始我們有大局觀,構思好如何實現,但越往後走,這個構思會隨着實際實現中的偏差而有較大的改動,加之在實現中進行的妥協,那麼,一開始清晰的設計會變得模糊,如果在這個時候,不懸崖勒馬,暫緩自己前進的不法,項目會變得越來越亂,最後,你都無法清晰地看清楚整體的邏輯。而一旦邏輯開始混亂,隨之而來的便是BUG的出現,各種莫名其妙的BUG,“每一個BUG都暗示你要重新審視自己的程序邏輯”,一個清晰的程序應該是很容易看出其中問題的程序。因此,每次出現BUG,我都會先回顧代碼邏輯,看看有哪些地方設計的不好或者不對,多數情況下,問題都能夠迎刃而解。
        3、寫上必要的測試用例。在沒有外界壓迫的情況下,很難自覺地爲每個類寫上測試用例,因爲這會耗費很多時間來換取未來可能節省的時間,人都的目光不會總那麼長遠。因此,對那些用的較多的,較爲複雜的核心類儘可能寫上測試用例,以便在今後修改的時候,無需再重新模擬數據,重新測試,或者因爲測試不足而導致BUG。儘可能進行單元快的測試而非整體的測試,以減少測試時候等待的時間。甚至可以寫上一些腳手架程序,來進行自動化測試。關於測試與重構,在這篇文章有提及:測試與重構,讓我們活的更輕鬆
        4、善於使用工具調試。IDE中,可以進行斷點調試、通過輸出語句等方式進行調試,在此之前,我一直以爲hadoop這種分佈式框架是無法調試的,直到他們跟我說…

這些點,算是這個BUG風波引發的思考,也算是給自己提個醒,不僅僅是爲了減少BUG,而是爲了養成好的編程習慣、讓程序邏輯清晰,而減少BUG,只是他帶來的一個贈品罷了。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章