原文:What I Didn't Understand as a Junior Programmer
譯者:杰微刊兼職翻譯張萬程
作者:Alex Naraghi
我還記得第一次接觸百萬行代碼庫的時(shí)候是在我實(shí)習(xí)期間帅刊,那是一個(gè)有十多年歷史的老系統(tǒng)檀咙,使用多種語言編寫,上千個(gè)單元測試优妙,被分成多個(gè)工程和dll文件,編譯一次需要一整晚。有些工程的構(gòu)造過程十分復(fù)雜,需要額外的腳本茶敏,甚至代碼控制系統(tǒng)還有自定義的鉤子,用來阻止代碼風(fēng)格不規(guī)范的提交缚俏。那時(shí)我感覺閱讀相關(guān)文檔需要花費(fèi)一周的時(shí)間惊搏。我的領(lǐng)導(dǎo)告訴我通常深入了解這些工程。需要一年的時(shí)間忧换,但的是的實(shí)習(xí)只有3個(gè)月的時(shí)間恬惯。
天哪,我想,難道這就是程序員的畢經(jīng)之路嗎?,
那時(shí)候,我知道自己掌握了哪些知識亚茬。不客氣地講宿崭,我知道所有常用排序算法的算法復(fù)雜度。學(xué)校里的課程對我來說很簡單才写,我已經(jīng)和朋友發(fā)布了兩款游戲葡兑。我掌握了面向?qū)ο蟮乃兄R奖蔓。
我不想寫出拙劣的代碼,尤其是掙錢的商業(yè)項(xiàng)目讹堤,不像簡單的課堂作業(yè)吆鹤。更糟糕地是你擔(dān)心那些老鳥們會(huì)看穿你的愚蠢。知道你在漫無目標(biāo)的亂寫代碼洲守,你修改了無數(shù)次的代碼被他們刪掉90%疑务。這樣一直到你放棄,聳聳肩梗醇,做些瘋狂的舉動(dòng)知允。如果你們有代碼審查,他們會(huì)審閱叙谨,皺著眉頭發(fā)表一些觀點(diǎn)温鸽,但你的代碼是如此之混亂像是在糊弄你的領(lǐng)導(dǎo),他們不能在你荒謬的接口和混亂的方法中看到任何的設(shè)計(jì)模式手负。他們眉頭緊皺涤垫,盯著屏幕,"這不是一個(gè)好的代碼方式,我們需要做質(zhì)量測試,如果有必要,我們需要回過頭來重構(gòu)這些代碼"竟终。真是糟糕至極蝠猬。
這是惡夢般的體驗(yàn),當(dāng)然我可能有點(diǎn)夸張统捶。但編程確實(shí)不容易.你呆在公司里榆芦,花費(fèi)整天時(shí)間非常痛苦地與代碼風(fēng)格,編程范式喘鸟,運(yùn)行時(shí)歧杏,調(diào)試工具,接口迷守,搜索,工作計(jì)劃做斗爭旺入,他們不停地打斷你的思路兑凿,令人發(fā)指的是你還要保證按時(shí)完成任務(wù)。
但是茵瘾,最終你還是一一戰(zhàn)勝了它們礼华。
我經(jīng)常問自己同一個(gè)問題: 哪些知識必須從經(jīng)驗(yàn)中得來,必須從錯(cuò)誤中學(xué)習(xí)拗秘。我無法回答這個(gè)問題圣絮,但我想和你講一個(gè)我所經(jīng)歷的特殊戰(zhàn)爭。
在過去雕旨,阻礙我成為高級程序員的最重要原因是我不能在不了解運(yùn)行狀態(tài)的情況下解決問題,我所謂的運(yùn)行狀態(tài)是指所有運(yùn)行時(shí)相關(guān)數(shù)據(jù)扮匠,通常和問題密切相關(guān)捧请。
那段時(shí)間我記憶猶新,我做出了很多努力棒搜,花費(fèi)了很多時(shí)間疹蛉,漫無目的地調(diào)整各種變量,希望能夠解決那些我還不了解的問題力麸,更糟糕的是我還為此感到自豪可款。我知道,如果我做的調(diào)整足夠多克蚂,問題會(huì)發(fā)生變化闺鲸,可能不太明顯,也可能一下子就把問題解決掉了埃叭。那時(shí)我最大的錯(cuò)誤是數(shù)學(xué)相關(guān)問題摸恍,主要是界面和渲染工作。如果偏高游盲,我會(huì)把"y - box.height / 2"調(diào)整為 "y - box.height / 4"误墓。這可以解決數(shù)學(xué)問題嗎?有時(shí)候也有可能益缎,如果我打一個(gè)斷點(diǎn)谜慌,我可能看到很多變量,但中間數(shù)據(jù)往往看起來都是枯燥乏味莺奔,沒有什么用處的感覺欣范,所以這些代碼很快就成了黑盒子。
這種解決問題的方式明顯太原始令哟,是反人類的恼琼,是愚蠢的。但卻被普遍使用屏富,對于課堂作業(yè)晴竞,小項(xiàng)目,它非常湊效狠半,因?yàn)樗鼈儚?fù)雜度低噩死,是不需要后期維護(hù),也沒有用戶使用的小型代碼庫神年。只要通過老師的單元測試已维,你就可以拿到A+。
開發(fā)人員在他們所不明白的哪些問題上不停地轉(zhuǎn)圈子已日,所浪費(fèi)的時(shí)間是驚人的.
現(xiàn)在我相信垛耳,通過這種瞎貓撞死耗子的方式,雖然貌似你把問題解決了,但實(shí)際上你并沒有真正解決堂鲜。經(jīng)常被修改的代碼最容易出問題栈雳,你只是碰巧解決了它。你不僅可以維護(hù)你自己寫的代碼泡嘴,為了解決問題你可能還會(huì)去修改以前的老代碼甫恩,因?yàn)槟悴涣私膺\(yùn)行狀態(tài)。更糟糕的是酌予,版本控制器中的日志可能會(huì)誤導(dǎo)將來查看這段代碼的程序員磺箕,因?yàn)樗麜?huì)基于你的實(shí)現(xiàn)方式來解決問題。這種影響還是雙向的抛虫,我已經(jīng)從親身經(jīng)驗(yàn)中對這類潛在問題有了深刻認(rèn)識松靡。
幸運(yùn)的是在這條路上我學(xué)到了很多東西,關(guān)于如何改進(jìn)建椰,從這種調(diào)試中解脫出來雕欺,我有一些心得可以分享給你。 如果代碼非常復(fù)雜棉姐,你可能需要開始重構(gòu)屠列,提高代碼可讀性(重構(gòu)后要檢查問題是否依然存在)。創(chuàng)建一些測試用例伞矩,要涵蓋數(shù)據(jù)的轉(zhuǎn)換笛洛,驗(yàn)證你的假設(shè)是否成立。如果數(shù)據(jù)可以可視化乃坤,并且數(shù)據(jù)呈幾何級增長苛让,或者使用了復(fù)雜的數(shù)據(jù)存儲(chǔ)結(jié)構(gòu),要考慮用可視化的方式來展示湿诊,如果有大量的過程數(shù)據(jù)狱杰,請準(zhǔn)備好紙和筆,自已動(dòng)手追蹤運(yùn)行狀態(tài)厅须。向代碼的作者獲取幫助仿畸。如果你失去了耐心,出去散散步朗和,呼吸一下新鮮空氣错沽。
我相信這種方式適用于任何代碼,不管有多復(fù)雜例隆。你可以追蹤運(yùn)行狀態(tài)的數(shù)據(jù)。代碼可能不是你的同事寫的抢蚀,可能像意大利面一樣混亂镀层,變量命名可能天馬行空般隨意。但是使用簡化,可視化唱逢,逐步深入吴侦,校驗(yàn)等方法,再加上時(shí)間坞古,你會(huì)獲取到你需要的一切备韧。
當(dāng)然,好的編程理念和設(shè)計(jì)模式可以更容易理解運(yùn)行狀態(tài)痪枫。如果你采用我的建議织堂,并開始運(yùn)用,你很快就會(huì)寫出健壯奶陈,易于維護(hù)的代碼易阳。后面我還會(huì)寫更多同類主題的文章!
如果你不了解你寫的代碼吃粒,或者你正在調(diào)試的代碼潦俺,不要找任何借口。編程沒有捷徑徐勃,只有脫離實(shí)際的幻想∈率荆現(xiàn)在,即便已經(jīng)解決了問題僻肖,我仍然要深入代碼的細(xì)節(jié)肖爵,以確保自己真正地理解代碼。如果有必要檐涝,我還會(huì)對它進(jìn)行重構(gòu)遏匆,或者在注釋里加上我通過分析學(xué)到的知識。只有這樣谁榜,我才認(rèn)為我解決了這個(gè)問題幅聘。
可能你想繞過對代碼的理解,但是在真實(shí)的項(xiàng)目中窃植,這個(gè)捷徑會(huì)讓你和公司付出更多的時(shí)間帝蒿,丟失更多的用戶,還有永無休止的維護(hù)工作巷怜。避免我曾經(jīng)有過的還習(xí)慣葛超,花時(shí)間學(xué)習(xí)復(fù)雜問題的分解,掌握調(diào)試工具的使用延塑,寫一些工具幫助你更舒服地工作绣张。這樣會(huì)還清你的技術(shù)債,不再做惡夢关带。
“所有bug的產(chǎn)生侥涵,都是因?yàn)榇a沒有按你的設(shè)想運(yùn)行。”
我不得不佩服John Carmack芜飘,他的一篇文章讓我的想法更加具體务豺。
精彩內(nèi)容推薦: