程序員偷偷愛著的9個不良編程習慣快來看看你有沒有缝裤?

我們曾經(jīng)都做過這樣的事情:當媽媽不注意的時候,偷偷地吃糖果零食颊郎,然后導致有了蛀牙憋飞。

同樣的,我們都違背過一些編程的基本規(guī)則姆吭,并且都會堅定地表示這種行為是不可取的榛做。但我們就是偷偷愛著這些不良的編程習慣。

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

這是因為糟糕的編程不像安裝電路或者摸老虎屁股那樣有直接的危害性获茬。大多數(shù)時間里它也是可以工作的港庄。規(guī)則通常是作為一種指導或格式上的建議,并沒有硬性規(guī)定一定要遵守恕曲,也不會導致代碼馬上死掉鹏氧。當然,你的代碼可能會被人恥笑佩谣,甚至可能大家公開嘲笑你把还,不過,這種挑戰(zhàn)慣例的行為可以讓人增加一點顛覆傳統(tǒng)的快感茸俭,哪怕是在不經(jīng)意間吊履。

為了讓問題變得更加復雜,有時候違反規(guī)則反而更好调鬓。(一般人我不告訴他Mа住)出來的代碼會更干凈,甚至可能會更快和更簡單腾窝。規(guī)則通常顯得太過于寬泛缀踪,有技巧的程序員可以通過打破這些規(guī)則來提高代碼。不要告訴你的老板虹脯,這對你的編碼生涯會很有意義驴娃。

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

編程習慣No. 1:使用goto

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

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

但絕對的分支是沒有問題的宋列。這就讓人糾結(jié)了。通常评也,巧妙的 break 語句和return 語句可提供一個非常干凈的關(guān)于代碼在那個時候執(zhí)行什么的聲明炼杖。有時候灭返,添加 goto 到case語句會比更恰當?shù)亩嗉壡短椎膇f-then-else語句塊更易于理解。

也有反例坤邪。在蘋果的SSL堆棧中的“goto fail”安全漏洞就是最好的例子之一熙含。但是,如果我們能夠仔細避免case語句和循環(huán)的一些尷尬問題艇纺,那么我們就可以嵌入良好的絕對轉(zhuǎn)移怎静,使閱讀代碼的人更容易明白這是怎么回事。

最后我要推薦一下我的前端教程學習群:657137906黔衡,里面都是學習前端的蚓聘,如果你正在學習前端,小編歡迎你加入员帮。小編會在群中不定期分享干貨或粮,包括我精心整理的一份前端零基礎(chǔ)教程导饲。歡迎各位初學和進階中的小伙伴捞高。

我們可以插入break和return 語句,讓每一個人感覺更清潔和更愉快——可能得除了goto的敵視者渣锦。

編程習慣No. 2:成功避開文檔

我的一個朋友有一個非常精明的老板硝岗,這位老板雖然從來沒有寫過任何代碼,但卻秉持著每一個功能都必須包含在文檔中的理念袋毙。哪個程序員不提供注釋型檀,那么他就會受到懲罰。

所以听盖,我的朋友在他的編輯器中聯(lián)入了一個有點像人工智能的玩意兒胀溺,于是乎,他的每一個功能就都有幾行“文檔”了皆看。因為這位精明的老板還不夠聰明到能理解這些注釋其實啥意思也沒有仓坞,所以我的朋友逃過一劫。他的代碼常常被作為正式文檔腰吟。我想无埃,他應該快要升職了!

許多函數(shù)方法毛雇,甚至一些類或多或少都能自文檔化嫉称。冠以insertReservation或cancelReservation或 deleteAll 等名稱的函數(shù)并不需要多此一舉來解釋它們的作用。為函數(shù)取一個正確的名字往往就足夠了灵疮。事實上织阅,這比寫一段長長的注釋要好,因為函數(shù)名可以出現(xiàn)在代碼中的其他地方震捣。而文檔只能默默地呆在某個角落蒲稳。自文檔化的函數(shù)名可以改進它們出現(xiàn)的每個文件氮趋。

在有些情況下,寫文檔甚至會導致情況變糟江耀。例如剩胁,當代碼瞬息萬變,團隊像瘋了似的重構(gòu)的時候祥国,文檔會產(chǎn)生分歧昵观。代碼是這樣寫的,但文檔解釋的還是四五個版本以前的情況舌稀。這類“過時”的文檔通常位于代碼頂部啊犬,有的人會在這里對代碼應該發(fā)生什么作一個美好總結(jié)。因此壁查,盡管重構(gòu)團隊已經(jīng)仔細修改了相關(guān)的注釋觉至,但還是會遺漏文件頂部的這段“美好總結(jié)”。

當代碼和文本出現(xiàn)分歧的時候睡腿,注釋就變得毫無價值语御,甚至會產(chǎn)生誤導。在這樣的情況下席怪,良好的自文檔化的代碼顯然勝出了应闯。

編程習慣No. 3:一行寫太多代碼

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

他認為他的這個法令將能使調(diào)試變得更加容易抵卫。就像你單步調(diào)試代碼一樣,調(diào)試器會一個動作一個動作地前進胎撇。這樣就不會卡在某一行介粘。而且更容易執(zhí)行。

但是這樣一來晚树,鍵盤上的回車鍵煩不勝煩姻采,因為我需要不斷地插入行。而且我敢肯定爵憎,老板因此還可以到處吹噓他的團隊能寫多少行代碼慨亲。

有時在同一行中聲明一堆變量反而更容易婚瓜;有時把所有的布爾子句放在一起反而更簡單——一切都能變得更加緊湊。那也意味著刑棵,我們可以在屏幕上看到更多的邏輯而無需滾動鼠標巴刻。更易于閱讀就意味著理解起來更快。這才是簡單的精粹蛉签。

編程習慣No. 4:不聲明類型

那些熱愛類型化語言的人認為胡陪,如果為每個變量添加明確的數(shù)據(jù)類型聲明,就可以寫出更好的碍舍、沒有錯誤的代碼柠座。花一點時間來拼寫類型片橡,能幫助編譯器在代碼開始運行之前標志愚蠢的錯誤妈经。可能會讓人覺得痛苦捧书,但很有幫助吹泡。這是編程中停止bug的一種有備無患的方法。

但是時代變了鳄厌。許多較新的編譯器完全可以智能地通過查看代碼來推斷類型荞胡。它們會向后和向前瀏覽代碼妈踊,直到可以肯定這個變量是string 還是int了嚎,抑或其他。如果這些被查看的類型不成隊列廊营,那么錯誤標志就會點亮歪泳。因此再也不需要我們輸入變量的類型了。

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

編程習慣No. 5:搖擺不定的代碼

有的程序員在代碼上特別優(yōu)柔寡斷慎式,猶豫不決伶氢。先是一開始將值存儲為字符串,然后又解析成整數(shù)瘪吏。接著又轉(zhuǎn)換回字符串癣防。這是非常低效的,你甚至可以感覺到CPU在咆哮這種浪費負載的行為掌眠。聰明的程序員之所以能快速地編碼蕾盯,是因為他們事先會設(shè)計架構(gòu),以盡量減少轉(zhuǎn)換蓝丙。他們的代碼能更快地運行是因為他們有一個良好的規(guī)劃级遭。

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

當然迅诬,你可以重寫所有的代碼,以盡量減少轉(zhuǎn)換婿牍,但是這需要時間侈贷。而且,有時候讓代碼稍微多花點額外時間來運行也未嘗不可等脂,因為重寫代碼需要耗費我們更多的時間俏蛮。有時,背負這樣的技術(shù)債務比一開始就正確構(gòu)建的成本要更低上遥。

有的時候搏屑,庫不是專有的代碼,但那些你以前全部自己寫的代碼是你獨有的粉楚。有的時候辣恋,再次轉(zhuǎn)換數(shù)據(jù)比重寫庫中的所有代碼要快得多。所以模软,就讓它這樣吧伟骨,就讓代碼搖擺吧。

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

有一個標準規(guī)則是燃异,程序員在完成數(shù)據(jù)結(jié)構(gòu)課程的第二年携狭,不應該寫用于存儲數(shù)據(jù)的代碼。基本上我們需要的所有的數(shù)據(jù)結(jié)構(gòu)回俐,已經(jīng)有人寫好了逛腿,而且其代碼已歷經(jīng)多年的測試和再測試。它和語言捆綁在一起仅颇,而且常常是免費的单默。你的代碼只能造就bug。

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

如果遇到這種情況汽摹,那么就應該著手寫我們自己的數(shù)據(jù)結(jié)構(gòu)李丰。這或許能讓你做得更快,做得更多逼泣。而且代碼會變得更清潔趴泌,因為我們不會包括那些多余的用于格式化數(shù)據(jù)來完成一些功能的代碼。

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

有一個規(guī)則制定小組宣稱拉庶,每個循環(huán)都應該有一個“常量”嗜憔,也就是說當這個邏輯語句為true的時候,循環(huán)一直執(zhí)行氏仗。當常量一定不會是true的時候吉捶,循環(huán)才會結(jié)束。這是考慮復雜循環(huán)的好方法皆尔,但它會導致愚蠢的禁令——例如禁止我們在循環(huán)中間使用return 和break 語句呐舔。這一條也包含在禁止goto語句的規(guī)則中。

這個理論是好的慷蠕,但它通常會導致更復雜的代碼珊拼。請看下面這個簡單的案例,遍歷數(shù)組流炕,將找到的元素傳遞給test函數(shù)澎现,并將該元素返回:

while (i

...

if (test(a[i]) then return a[i];

...

}

“循環(huán)常量”愛好者會要求我們增加一個布爾變量,命名為notFound浪感,然后這樣使用:

一昔头、數(shù)while ((notFound) && (i

...

if (test(a[i])) then notFound=false;

...

}據(jù)圖表化

如果這個布爾值能夠合理地命名饼问,那么這就是一段很棒的自文檔化的代碼影兽,更易于大家理解。但這也增加了復雜性莱革。這意味著你需要分配另一個局部變量峻堰,并堵塞寄存器,因為編譯器也許還不能足夠智能到解決這個問題盅视。

有時候捐名,一個goto 語句或一個跳轉(zhuǎn)會更干凈利索。

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

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

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

正如這篇文章前面鼓勵的是自文檔化的代碼,而非長長的注釋饺谬。在上述情況下洲赵,單個字母的變量名也是自文檔化的。字母 i 是通用的迭代器商蕴。只要是程序員立刻就會懂叠萍。

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

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

當然這是延伸了决采,不過有一個觀點是自沧,在一個大的代碼塊內(nèi),當重新定義一個或多個所謂的常量時树瞭,速度會更快拇厢。有時老板會要求代碼做一些截然不同的事情。當然晒喷,你可以修改代碼的每個事件孝偎,或者,你可以重新定義凉敲。這讓你看上去像一個天才衣盾。不必重寫一個龐大的庫寺旺,只需翻轉(zhuǎn)一下,就可以做相反的事情了势决。

這9個習慣就都在這兒了迅涮。千萬不要輕易嘗試,不管它看上去有多牛掰徽龟。太危險了——真的叮姑,這是實話。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末据悔,一起剝皮案震驚了整個濱河市传透,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌极颓,老刑警劉巖朱盐,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異菠隆,居然都是意外死亡兵琳,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門骇径,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躯肌,“玉大人,你說我怎么就攤上這事破衔∏迮” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵晰筛,是天一觀的道長嫡丙。 經(jīng)常有香客問我,道長读第,這世上最難降的妖魔是什么曙博? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮怜瞒,結(jié)果婚禮上父泳,老公的妹妹穿的比我還像新娘。我一直安慰自己盼砍,他們只是感情好尘吗,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浇坐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黔宛。 梳的紋絲不亂的頭發(fā)上近刘,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天,我揣著相機與錄音,去河邊找鬼觉渴。 笑死介劫,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的案淋。 我是一名探鬼主播座韵,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼踢京!你這毒婦竟也來了誉碴?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤瓣距,失蹤者是張志新(化名)和其女友劉穎黔帕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蹈丸,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡成黄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了逻杖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奋岁。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖荸百,靈堂內(nèi)的尸體忽然破棺而出厦取,到底是詐尸還是另有隱情,我是刑警寧澤管搪,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布虾攻,位于F島的核電站,受9級特大地震影響更鲁,放射性物質(zhì)發(fā)生泄漏霎箍。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一澡为、第九天 我趴在偏房一處隱蔽的房頂上張望漂坏。 院中可真熱鬧,春花似錦媒至、人聲如沸顶别。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驯绎。三九已至,卻和暖如春谋旦,著一層夾襖步出監(jiān)牢的瞬間剩失,已是汗流浹背屈尼。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拴孤,地道東北人脾歧。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像演熟,于是被迫代替她去往敵國和親鞭执。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 姓名:王明騫 學號:16050510061 轉(zhuǎn)載自:http://mp.weixin.qq.com/s/...
    王明騫閱讀 238評論 0 0
  • 第2章 基本語法 2.1 概述 基本句法和變量 語句 JavaScript程序的執(zhí)行單位為行(line)芒粹,也就是一...
    悟名先生閱讀 4,151評論 0 13
  • .bat腳本基本命令語法 目錄 批處理的常見命令(未列舉的命令還比較多兄纺,請查閱幫助信息) 1、REM 和 :: 2...
    慶慶慶慶慶閱讀 8,109評論 1 19
  • 古人限于交通不發(fā)達的緣故是辕,只能依靠步行囤热、騎馬或者行船,效率很低获三,怕是一別旁蔼,就是半生了,因此在唐宋的詩篇中疙教,送別詩占...
    十年北山閱讀 1,110評論 5 4
  • 青絲伴燈苦求佛棺聊。衣帶漸寬,思君緒成河贞谓。倚窗輕喚曾經(jīng)名限佩,夢中浮現(xiàn)松依蘿。 一念成執(zhí)心生魔裸弦。癡怨不應祟同,暗夜雨滂沱。別后...
    快樂的憨豆閱讀 209評論 0 3