0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

程序員不經(jīng)意的 9 個(gè)不良編程習(xí)慣介紹

電子工程師 ? 來源:網(wǎng)絡(luò)整理 ? 2018-01-16 14:45 ? 次閱讀

我們?cè)?jīng)都做過這樣的事情:當(dāng)媽媽不注意的時(shí)候,偷偷地吃糖果零食,然后導(dǎo)致有了蛀牙。同樣的,我們都違背過一些編程的基本規(guī)則,并且都會(huì)堅(jiān)定地表示這種行為是不可取的。但我們就是偷偷愛著這些不良的編程習(xí)慣。

我們對(duì)所謂的編程規(guī)則嗤之以鼻,輸出的代碼也很糟糕——但我們依然活著。編程上帝沒有下閃電劈死我們,我們的電腦也沒有爆炸。事實(shí)上,只要我們能編譯和發(fā)布代碼,客戶似乎就很滿意了。

這是因?yàn)樵愀獾木幊滩幌癜惭b電路或者摸老虎屁股那樣有直接的危害性。大多數(shù)時(shí)間里它也是可以工作的。規(guī)則通常是作為一種指導(dǎo)或格式上的建議,并沒有硬性規(guī)定一定要遵守,也不會(huì)導(dǎo)致代碼馬上死掉。當(dāng)然,你的代碼可能會(huì)被人恥笑,甚至可能大家公開嘲笑你,不過,這種挑戰(zhàn)慣例的行為可以讓人增加一點(diǎn)顛覆傳統(tǒng)的快感,哪怕是在不經(jīng)意間。

為了讓問題變得更加復(fù)雜,有時(shí)候違反規(guī)則反而更好。(一般人我不告訴他?。┏鰜淼拇a會(huì)更干凈,甚至可能會(huì)更快和更簡(jiǎn)單。規(guī)則通常顯得太過于寬泛,有技巧的程序員可以通過打破這些規(guī)則來提高代碼。不要告訴你的老板,這對(duì)你的編碼生涯會(huì)很有意義。

下面這9個(gè)編碼習(xí)慣,雖然在編程規(guī)則中是被駁斥的,但我們很多人就是會(huì)不由自主地使用它們。

編程習(xí)慣No. 1:使用goto

關(guān)于禁止使用goto可以追溯到許多結(jié)構(gòu)化編程工具還未面世的時(shí)代。如果程序員想要?jiǎng)?chuàng)建一個(gè)循環(huán)或跳到另一段程序中,那么他們需要輸入goto后再跟一個(gè)行號(hào)。過了幾年之后,編譯器團(tuán)隊(duì)讓程序員使用字符串標(biāo)簽取代行號(hào)。這在當(dāng)時(shí)被認(rèn)為是一個(gè)熱門的新功能。

有的人認(rèn)為這會(huì)導(dǎo)致“意大利面條式代碼”。代碼會(huì)變得不可讀,并且很難理解代碼的執(zhí)行路徑。線程混亂,纏纏綿綿到天涯。Edsger Dijkstra就三令五申地表示應(yīng)該禁止這個(gè)命令,他有一份詼諧的手稿,題目為《Goto語(yǔ)句害人不淺》。

但絕對(duì)的分支是沒有問題的。這就讓人糾結(jié)了。通常,巧妙的break語(yǔ)句和return語(yǔ)句可提供一個(gè)非常干凈的關(guān)于代碼在那個(gè)時(shí)候執(zhí)行什么的聲明。有時(shí)候,添加goto到case語(yǔ)句會(huì)比更恰當(dāng)?shù)亩嗉?jí)嵌套的if-then-else語(yǔ)句塊更易于理解。

也有反例。在蘋果的SSL堆棧中的“goto fail”安全漏洞就是最好的例子之一。但是,如果我們能夠仔細(xì)避免case語(yǔ)句和循環(huán)的一些尷尬問題,那么我們就可以嵌入良好的絕對(duì)轉(zhuǎn)移,使閱讀代碼的人更容易明白這是怎么回事。我們可以插入break和return語(yǔ)句,讓每一個(gè)人感覺更清潔和更愉快——可能得除了goto的敵視者。

編程習(xí)慣No. 2:成功避開文檔

我的一個(gè)朋友有一個(gè)非常精明的老板,這位老板雖然從來沒有寫過任何代碼,但卻秉持著每一個(gè)功能都必須包含在文檔中的理念。哪個(gè)程序員不提供注釋,那么他就會(huì)受到懲罰。所以,我的朋友在他的編輯器中聯(lián)入了一個(gè)有點(diǎn)像人工智能的玩意兒,于是乎,他的每一個(gè)功能就都有幾行“文檔”了。因?yàn)檫@位精明的老板還不夠聰明到能理解這些注釋其實(shí)啥意思也沒有,所以我的朋友逃過一劫。他的代碼常常被作為正式文檔。我想,他應(yīng)該快要升職了!

許多函數(shù)方法,甚至一些類或多或少都能自文檔化。冠以insertReservation或cancelReservation或deleteAll等名稱的函數(shù)并不需要多此一舉來解釋它們的作用。為函數(shù)取一個(gè)正確的名字往往就足夠了。事實(shí)上,這比寫一段長(zhǎng)長(zhǎng)的注釋要好,因?yàn)楹瘮?shù)名可以出現(xiàn)在代碼中的其他地方。而文檔只能默默地呆在某個(gè)角落。自文檔化的函數(shù)名可以改進(jìn)它們出現(xiàn)的每個(gè)文件。

在有些情況下,寫文檔甚至?xí)?dǎo)致情況變?cè)恪@?,?dāng)代碼瞬息萬變,團(tuán)隊(duì)像瘋了似的重構(gòu)的時(shí)候,文檔會(huì)產(chǎn)生分歧。代碼是這樣寫的,但文檔解釋的還是四五個(gè)版本以前的情況。這類“過時(shí)”的文檔通常位于代碼頂部,有的人會(huì)在這里對(duì)代碼應(yīng)該發(fā)生什么作一個(gè)美好總結(jié)。因此,盡管重構(gòu)團(tuán)隊(duì)已經(jīng)仔細(xì)修改了相關(guān)的注釋,但還是會(huì)遺漏文件頂部的這段“美好總結(jié)”。

當(dāng)代碼和文本出現(xiàn)分歧的時(shí)候,注釋就變得毫無價(jià)值,甚至?xí)a(chǎn)生誤導(dǎo)。在這樣的情況下,良好的自文檔化的代碼顯然勝出了。

編程習(xí)慣No. 3:一行寫太多代碼

老板突然發(fā)神經(jīng)地給團(tuán)隊(duì)發(fā)了一封討厭的郵件:為了執(zhí)行非常嚴(yán)格的風(fēng)格規(guī)定,我們大家都必須重寫我們的代碼。最神奇的要求是:每個(gè)行為或步驟或子句必須各自成行。你不能使用點(diǎn)語(yǔ)法連續(xù)調(diào)用函數(shù)。在一個(gè)分支語(yǔ)句中,你不能有兩個(gè)及以上返回布爾值的子句。如果要定義變量,那么另起一行。如果你正在做一個(gè)復(fù)雜的計(jì)算,那么不要使用括號(hào)。每個(gè)片段也自成一行。

他認(rèn)為他的這個(gè)法令將能使調(diào)試變得更加容易。就像你單步調(diào)試代碼一樣,調(diào)試器會(huì)一個(gè)動(dòng)作一個(gè)動(dòng)作地前進(jìn)。這樣就不會(huì)卡在某一行。而且更容易執(zhí)行。

但是這樣一來,鍵盤上的回車鍵煩不勝煩,因?yàn)槲倚枰粩嗟夭迦胄?。而且我敢肯定,老板因此還可以到處吹噓他的團(tuán)隊(duì)能寫多少行代碼。

唉,有時(shí)在同一行中聲明一堆變量反而更容易;有時(shí)把所有的布爾子句放在一起反而更簡(jiǎn)單——一切都能變得更加緊湊。那也意味著,我們可以在屏幕上看到更多的邏輯而無需滾動(dòng)鼠標(biāo)。更易于閱讀就意味著理解起來更快。這才是簡(jiǎn)單的精粹。

編程習(xí)慣No. 4:不聲明類型

那些熱愛類型化語(yǔ)言的人認(rèn)為,如果為每個(gè)變量添加明確的數(shù)據(jù)類型聲明,就可以寫出更好的、沒有錯(cuò)誤的代碼。花一點(diǎn)時(shí)間來拼寫類型,能幫助編譯器在代碼開始運(yùn)行之前標(biāo)志愚蠢的錯(cuò)誤??赡軙?huì)讓人覺得痛苦,但很有幫助。這是編程中停止bug的一種有備無患的方法。

但是時(shí)代變了。許多較新的編譯器完全可以智能地通過查看代碼來推斷類型。它們會(huì)向后和向前瀏覽代碼,直到可以肯定這個(gè)變量是string還是int,抑或其他。如果這些被查看的類型不成隊(duì)列,那么錯(cuò)誤標(biāo)志就會(huì)點(diǎn)亮。因此再也不需要我們輸入變量的類型了。

這意味著我們現(xiàn)在可以在代碼中省略掉一些最簡(jiǎn)單的聲明。代碼更清潔,而且閱讀代碼的人也猜得出for循環(huán)中命名為i的變量表示一個(gè)整數(shù)型。

編程習(xí)慣No.5:搖擺不定的代碼

有的程序員在代碼上特別優(yōu)柔寡斷,猶豫不決。先是一開始將值存儲(chǔ)為字符串,然后又解析成整數(shù)。接著又轉(zhuǎn)換回字符串。這是非常低效的,你甚至可以感覺到CPU在咆哮這種浪費(fèi)負(fù)載的行為。聰明的程序員之所以能快速地編碼,是因?yàn)樗麄兪孪葧?huì)設(shè)計(jì)架構(gòu),以盡量減少轉(zhuǎn)換。他們的代碼能更快地運(yùn)行是因?yàn)樗麄冇幸粋€(gè)良好的規(guī)劃。

但是,不管你信不信,這種搖擺不定的代碼有時(shí)候也是有意義的。比如說,你有一個(gè)非常棒的庫(kù),在它專有的黑盒子里能做無數(shù)智能的事情。如果庫(kù)需要字符串的數(shù)據(jù),那么你就給它字符串,即使你剛將這個(gè)數(shù)據(jù)轉(zhuǎn)換成為整數(shù)型。

當(dāng)然,你可以重寫所有的代碼,以盡量減少轉(zhuǎn)換,但是這需要時(shí)間。而且,有時(shí)候讓代碼稍微多花點(diǎn)額外時(shí)間來運(yùn)行也未嘗不可,因?yàn)橹貙懘a需要耗費(fèi)我們更多的時(shí)間。有時(shí),背負(fù)這樣的技術(shù)債務(wù)比一開始就正確構(gòu)建的成本要更低。

有的時(shí)候,庫(kù)不是專有的代碼,但那些你以前全部自己寫的代碼是你獨(dú)有的。有的時(shí)候,再次轉(zhuǎn)換數(shù)據(jù)比重寫庫(kù)中的所有代碼要快得多。所以,就讓它這樣吧,就讓代碼搖擺吧。

編程習(xí)慣No. 6:編寫你自己的數(shù)據(jù)結(jié)構(gòu)

有一個(gè)標(biāo)準(zhǔn)規(guī)則是,程序員在完成數(shù)據(jù)結(jié)構(gòu)課程的第二年,不應(yīng)該寫用于存儲(chǔ)數(shù)據(jù)的代碼?;旧衔覀冃枰乃械臄?shù)據(jù)結(jié)構(gòu),已經(jīng)有人寫好了,而且其代碼已歷經(jīng)多年的測(cè)試和再測(cè)試。它和語(yǔ)言捆綁在一起,而且常常是免費(fèi)的。你的代碼只能造就bug。

但有時(shí)你會(huì)發(fā)現(xiàn)數(shù)據(jù)結(jié)構(gòu)庫(kù)有點(diǎn)慢。有時(shí)它們會(huì)迫使我們使用標(biāo)準(zhǔn)的,但于我們的代碼卻是錯(cuò)誤的結(jié)構(gòu)。有時(shí)庫(kù)會(huì)把我們推向在使用結(jié)構(gòu)之前重新配置數(shù)據(jù)的地步。有時(shí)庫(kù)會(huì)包含一些所謂有備無患的保護(hù)功能,如線程鎖,但其實(shí)我們的代碼并不需要。

如果遇到這種情況,那么就應(yīng)該著手寫我們自己的數(shù)據(jù)結(jié)構(gòu)。這或許能讓你做得更快,做得更多。而且代碼會(huì)變得更清潔,因?yàn)槲覀儾粫?huì)包括那些多余的用于格式化數(shù)據(jù)來完成一些功能的代碼。

編程習(xí)慣No.7:在中間打破循環(huán)

有一個(gè)規(guī)則制定小組宣稱,每個(gè)循環(huán)都應(yīng)該有一個(gè)“常量”,也就是說當(dāng)這個(gè)邏輯語(yǔ)句為true的時(shí)候,循環(huán)一直執(zhí)行。當(dāng)常量一定不會(huì)是true的時(shí)候,循環(huán)才會(huì)結(jié)束。這是考慮復(fù)雜循環(huán)的好方法,但它會(huì)導(dǎo)致愚蠢的禁令——例如禁止我們?cè)谘h(huán)中間使用return和break語(yǔ)句。這一條也包含在禁止goto語(yǔ)句的規(guī)則中。

這個(gè)理論是好的,但它通常會(huì)導(dǎo)致更復(fù)雜的代碼。請(qǐng)看下面這個(gè)簡(jiǎn)單的案例,遍歷數(shù)組,將找到的元素傳遞給test函數(shù),并將該元素返回:

while (i

“循環(huán)常量”愛好者會(huì)要求我們?cè)黾右粋€(gè)布爾變量,命名為notFound,然后這樣使用:

while ((notFound) && (i

如果這個(gè)布爾值能夠合理地命名,那么這就是一段很棒的自文檔化的代碼,更易于大家理解。但這也增加了復(fù)雜性。這意味著你需要分配另一個(gè)局部變量,并堵塞寄存器,因?yàn)榫幾g器也許還不能足夠智能到解決這個(gè)問題。

有時(shí)候,一個(gè)goto語(yǔ)句或一個(gè)跳轉(zhuǎn)會(huì)更干凈利索。

編程習(xí)慣No. 8:使用短變量名(i和x和and也是有意義的)

Edgar Allan Poe這位詩(shī)人和小說家曾經(jīng)說過,在一個(gè)故事中的每一個(gè)詞都應(yīng)該是有內(nèi)涵的。編碼規(guī)則也強(qiáng)調(diào)如此。變量名應(yīng)該說明這個(gè)變量的所作所為。那些使用駝峰式大小寫的方法來寫變量名,以表達(dá)關(guān)于變量細(xì)節(jié)的Java程序員深以為然,于是一個(gè)又一個(gè)瘋狂長(zhǎng)度的變量名出爐了。有些程序員寫的變量名,會(huì)組合五六個(gè)甚至更多的詞語(yǔ)。

但有的時(shí)候,使用單個(gè)字母作為變量名反而會(huì)更方便。有時(shí)在循環(huán)迭代中只使用i或j會(huì)更簡(jiǎn)單。有時(shí)使用字母a代表array,l代表list會(huì)更便捷,即使是字母l和數(shù)字1看上去很難辨別。

正如這篇文章前面鼓勵(lì)的是自文檔化的代碼,而非長(zhǎng)長(zhǎng)的注釋。在上述情況下,單個(gè)字母的變量名也是自文檔化的。字母i是通用的迭代器。只要是程序員立刻就會(huì)懂。

編程習(xí)慣No. 9:重新定義運(yùn)算符和函數(shù)

一些最有趣的編程語(yǔ)言允許你去做一些特別詭異的事情,例如重新定義元素的值,就如同常量一般。例如Python,你可以輸入TRUE=FALSE(在Version2.7及之前的版本)。這并不會(huì)產(chǎn)生某種邏輯崩潰,或?qū)е掠钪娼K結(jié)——僅僅只是互換了TRUE和FALSE的含義。你也可以在C預(yù)處理器和一些其他語(yǔ)言中玩玩類似于這樣的危險(xiǎn)游戲。還有一些語(yǔ)言允許你重新定義運(yùn)算符,如加號(hào)。

當(dāng)然這是延伸了,不過有一個(gè)觀點(diǎn)是,在一個(gè)大的代碼塊內(nèi),當(dāng)重新定義一個(gè)或多個(gè)所謂的常量時(shí),速度會(huì)更快。有時(shí)老板會(huì)要求代碼做一些截然不同的事情。當(dāng)然,你可以修改代碼的每個(gè)事件,或者,你可以重新定義。這讓你看上去像一個(gè)天才。不必重寫一個(gè)龐大的庫(kù),只需翻轉(zhuǎn)一下,就可以做相反的事情了。

這9個(gè)習(xí)慣就都在這兒了。千萬不要輕易嘗試,不管它看上去有多牛掰。太危險(xiǎn)了——真的,這是實(shí)話。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3635

    瀏覽量

    93892
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    程序員的好習(xí)慣

    程序員的好習(xí)慣
    發(fā)表于 08-06 16:34

    優(yōu)秀程序員的十個(gè)習(xí)慣(轉(zhuǎn)載)

    )。經(jīng)過一段時(shí)間后,這些人也許能夠成為一個(gè)優(yōu)秀的編碼人員,他們會(huì)非常熟悉如何用計(jì)算機(jī)語(yǔ)言來完成自己的工作。但是,如果你要成為一個(gè)優(yōu)秀的程序員,你還可以需要有幾件事你需要注意,如果你能讓下面十個(gè)
    發(fā)表于 05-27 15:31

    轉(zhuǎn):優(yōu)秀程序員的十個(gè)習(xí)慣

    和精力反而更多。欲速而不達(dá)。優(yōu)秀程序員習(xí)慣是前面多花一些時(shí)間多作一些 調(diào)查,試驗(yàn)一下不同的解決方案,如果時(shí)間允許,一個(gè)好的習(xí)慣是,每 4 個(gè)
    發(fā)表于 08-08 17:02

    優(yōu)秀程序員是怎樣煉成的?

    轉(zhuǎn)一個(gè)好的總結(jié)要想成長(zhǎng)為一名優(yōu)秀的程序員,其過程是艱巨的,其道路是漫長(zhǎng)的。不經(jīng)過悉心栽培,花兒開不出鮮艷的花朵;不經(jīng)過時(shí)間的歷練,幼苗長(zhǎng)不成參天大樹。在軟件行業(yè)更是如此。
    發(fā)表于 02-14 20:45

    UC安全的高效不經(jīng)意傳輸協(xié)議

    非承諾加密機(jī)制是語(yǔ)義安全的,不能抵抗選擇密文攻擊. 在non2erase 模型的安全假設(shè)下,基于非承諾加密機(jī)制的不經(jīng)意傳輸協(xié)議不能實(shí)現(xiàn)自適應(yīng)攻擊者UC(Universally Composable) 安全的定義. 利用可
    發(fā)表于 06-20 16:48 ?16次下載

    程序員2011第9

    程序員2011第9期_《程序員》雜志2011年第9期 有關(guān)敏捷開發(fā)、kinect有關(guān)介紹等,值得一看
    發(fā)表于 12-30 15:02 ?0次下載
    <b class='flag-5'>程序員</b>2011第<b class='flag-5'>9</b>期

    一種Cut-and-Choose雙向不經(jīng)意傳輸

    不經(jīng)意傳輸作為現(xiàn)代密碼學(xué)的一個(gè)基本工具,在安全協(xié)議的研究中起著重要作用.近年來,許多功能性更強(qiáng)的不經(jīng)意傳輸變種被提出來,以適應(yīng)不同的需求和環(huán)境,提出一個(gè)
    發(fā)表于 01-03 13:59 ?0次下載

    10倍效率程序員是否真的存在

    編程神話中,一個(gè) 10 倍效率的程序員可以完成一個(gè)普通程序員 10 倍的工作量。「普通程序員
    的頭像 發(fā)表于 10-30 11:50 ?2058次閱讀

    程序員的十大編程禁忌

    程序員編程的時(shí)候難免會(huì)犯錯(cuò)誤,但如果不從錯(cuò)誤中吸取教訓(xùn),那么習(xí)慣成自然,你會(huì)經(jīng)常犯錯(cuò)的。從錯(cuò)誤中不斷的學(xué)習(xí),鍛煉好的行為習(xí)慣有助于事業(yè)上的穩(wěn)定。
    的頭像 發(fā)表于 11-09 16:27 ?2098次閱讀

    程序員如何定義

    當(dāng)了幾年的程序員了,一直都在想一個(gè)問題,什么是程序員,程序員應(yīng)該做好那些事情,什么樣的程序員是有素質(zhì)的
    的頭像 發(fā)表于 12-18 14:15 ?2681次閱讀

    程序員基本素質(zhì)要求有哪些

    計(jì)算機(jī)中最講邏輯的,程序員邏輯不嚴(yán)密,計(jì)算機(jī)是不會(huì)自動(dòng)幫你處理的,最后的結(jié)果就是不經(jīng)意間跳出幾個(gè)臭蟲。不講邏輯的程序員是最可怕的。比如,當(dāng)系統(tǒng)需要處理證件號(hào)碼信息,如果程序員在代碼中直
    的頭像 發(fā)表于 01-08 14:42 ?3311次閱讀
    <b class='flag-5'>程序員</b>基本素質(zhì)要求有哪些

    程序員的十個(gè)日常習(xí)慣

    程序員日常工作都是寫需求、改Bug、看別人的代碼、改別人的代碼。別看說得簡(jiǎn)單,但是每一件事都是需要非常長(zhǎng)時(shí)間來實(shí)現(xiàn)的。不然程序員拿著高薪豈不是說不過去?而長(zhǎng)年的編程生涯中,有很多程序員
    的頭像 發(fā)表于 05-21 16:37 ?3455次閱讀

    什么是程序員

    當(dāng)了幾年的程序員了,一直都在想一個(gè)問題,什么是程序員,程序員應(yīng)該做好那些事情,什么樣的程序員是有素質(zhì)的
    的頭像 發(fā)表于 06-04 16:21 ?9064次閱讀

    這10個(gè)習(xí)慣程序員受益匪淺

    當(dāng)談到編程時(shí),很多人應(yīng)該都有聽過10x程序員的說法。 據(jù)說一個(gè)10x程序員的效率大約是其他程序員的10倍。
    的頭像 發(fā)表于 01-04 11:33 ?2125次閱讀

    AI編程工具會(huì)不會(huì)搶程序員飯碗

    AI編程工具可輔助編程,減少手動(dòng)編碼,提升效率,對(duì)程序員有積極影響也有挑戰(zhàn)。程序員需深化技能、拓寬知識(shí)應(yīng)對(duì)。長(zhǎng)遠(yuǎn)看,AI與人類程序員將共生共
    的頭像 發(fā)表于 11-08 10:17 ?206次閱讀