這一點(diǎn)錯(cuò),那一點(diǎn)錯(cuò),錯(cuò)到一起就是大錯(cuò)。 ——《我是特種兵之利刃出鞘》 |
編程是一項(xiàng)聰明人玩的游戲,它既是對(duì)智力的考驗(yàn),也是對(duì)習(xí)慣的考驗(yàn),智力的好壞取決于父母的基因,人們無(wú)從左右,但習(xí)慣的好壞卻是可以不斷培養(yǎng)。一項(xiàng)由美國(guó)芝加哥大學(xué)國(guó)家研究組織進(jìn)行的綜合社會(huì)調(diào)查,公布了“十大最痛苦工作”排行榜,其中IT主管成了最讓人痛苦的職業(yè)。程序員如何才能讓自己的“痛苦”的職業(yè)不那么痛苦呢?
世間少有天才,所謂天才,只不過(guò)是把別人喝咖啡的功夫都用在工作上了。所以,對(duì)于絕大多數(shù)還稱(chēng)不上天才的程序員而言,以下這些編程的好習(xí)慣都是無(wú)數(shù)前人智慧的結(jié)晶,具有相當(dāng)意義的參考價(jià)值。
(1) 估算解決問(wèn)題所需要的時(shí)間。為自己定一個(gè)時(shí)間限制,如果在這期間未能解決問(wèn)題,那就去尋求幫助,或到網(wǎng)上找答案,而不是嘗試去做“超級(jí)堆碼員”,因?yàn)楹芏鄦?wèn)題,你很少會(huì)是這個(gè)世界上唯一一個(gè)遇到的人。站在別人的肩膀上,會(huì)讓你的形象變得高大、偉岸。
(2) 理解編程語(yǔ)言的原理。三流的人才懂應(yīng)用,二流的人才懂開(kāi)發(fā),一流的人才懂原理,要想學(xué)好一門(mén)編程語(yǔ)言,掌握語(yǔ)言的原理是必不可少的。各種語(yǔ)言之間存在相似之處,你所選擇的語(yǔ)言,你應(yīng)該覺(jué)得“舒服”,并且能夠?qū)懗鲇行Вǘ液?jiǎn)潔)的代碼。最重要的,讓語(yǔ)言去適應(yīng)項(xiàng)目,反之亦然。
(3) 重視,但不過(guò)于注重程序的設(shè)計(jì)模式。在大中型系統(tǒng)中,引入設(shè)計(jì)模式,往往能極大地提高系統(tǒng)研發(fā)的效率。但設(shè)計(jì)模式并非萬(wàn)金油,有時(shí)候,寫(xiě)一個(gè)簡(jiǎn)單的算法,要比引入某種模式更容易。如果一個(gè)100行就能寫(xiě)完的腳本,最終卻使用了8個(gè)類(lèi),10個(gè)接口,外加一大堆范式和標(biāo)記符,結(jié)果導(dǎo)致97%的代碼不做任何事情,這種優(yōu)化又有什么意義?在多數(shù)情況下,程序代碼應(yīng)是簡(jiǎn)單易懂,而不應(yīng)該是老太婆的裹腳布—又臭又長(zhǎng)。
(4) 做好版本控制,并及時(shí)備份代碼。編碼時(shí),最痛苦的事情不是有多少bug沒(méi)解決,而是突然停電了,一天的工作卻沒(méi)有保存。版本控制時(shí),最好使用版本控制軟件。無(wú)論什么時(shí)候改變自己的程序,它們都會(huì)將其保存為.bak文件。
(5) 對(duì)項(xiàng)目文件歸類(lèi)保存??梢园秧?xiàng)目文件放到SOURCE、HEADERS、MAKE、EXES等不同的文件夾中。如果工程包含多個(gè)源文件,則可以建立一個(gè)README文件,注明每個(gè)源文件、數(shù)據(jù)文件、臨時(shí)文件以及日志文件(如果有的話(huà))的作用。還可以注明編譯和運(yùn)行步驟。
(6) 動(dòng)手編碼之前,先做好分析和設(shè)計(jì)。項(xiàng)目開(kāi)始之初,不要急于編碼,而應(yīng)該做好詳細(xì)的需求與設(shè)計(jì)。做需求確實(shí)很難,不然也不會(huì)有程序員發(fā)出這樣的牢騷:需求無(wú)非兩種,一種是“你妹的,這還用做?”,另一種是“你妹的,這也能做?”不僅如此,實(shí)踐和分析設(shè)計(jì)過(guò)程也可存在很大的矛盾,但是好的分析會(huì)避免過(guò)早走向一個(gè)錯(cuò)誤的方向,好的設(shè)計(jì)可以避免混亂,否則,很有可能忙活了很久,最后發(fā)現(xiàn)方向錯(cuò)了或是架構(gòu)錯(cuò)了,需要不斷的監(jiān)測(cè)、修改與調(diào)試,甚至是完全推翻以前的工作,重新設(shè)計(jì),工作的成果看起來(lái)更像一個(gè)三歲小孩的涂鴉,而不是意見(jiàn)藝術(shù)作品,“撿了芝麻卻丟了西瓜”。永遠(yuǎn)不要在沒(méi)有任何設(shè)計(jì)的前提下就開(kāi)始編碼,除非所編代碼不重要。
(7) 多向其他優(yōu)秀程序員學(xué)習(xí)。你有一個(gè)蘋(píng)果,我也有一個(gè)蘋(píng)果,我們交換蘋(píng)果,你我還是有一個(gè)蘋(píng)果;你有一種思想,我也有一種思想,我們交換思想,你我就有了兩種思想。其實(shí),一個(gè)人能走多遠(yuǎn),要看他與誰(shuí)同行;一個(gè)人有多優(yōu)秀,要看他有誰(shuí)指點(diǎn);一個(gè)人有多成功,要看他有誰(shuí)相伴,更何況“一山總比一山高”。休息放松固然重要,但需要適可而止,生命不息,奮斗不止,尤其是年輕的時(shí)候,更是如此。時(shí)間的強(qiáng)大是不可逆轉(zhuǎn),再繁華的都會(huì)歸于塵土,與其把大把大把的時(shí)間浪費(fèi)在打dota、玩三國(guó)殺或是無(wú)聊發(fā)呆上,還不如與其他優(yōu)秀程序員坐在一起邊喝咖啡邊交流或是研究他們編寫(xiě)的代碼,吸收他們的經(jīng)驗(yàn)轉(zhuǎn)化為自己所用。在與這些人的溝通中,學(xué)習(xí)他們解決和自己相同的任務(wù)時(shí)所使用的方法,在此過(guò)程中所學(xué)知識(shí)可能會(huì)幫你省下幾個(gè)星期的時(shí)間。我們不贊成與臭棋佬下棋,棋會(huì)越下越臭的觀(guān)點(diǎn),但不可否認(rèn)這樣一個(gè)事實(shí):和什么樣的人在一起,就會(huì)有什么樣的人生,和勤奮的人在一起,你不會(huì)懶惰;和積極的人在一起,你不會(huì)消沉;與智者同行,你會(huì)不同凡響;與高人為伍,你能登上巔峰。
(8) 優(yōu)化代碼。優(yōu)雅的代碼非常的易讀,所以如果時(shí)間允許,應(yīng)該盡可能地優(yōu)化代碼,對(duì)時(shí)間和空間進(jìn)行合理分配與使用。之前聲明的一些變量,現(xiàn)在可能沒(méi)用了。同樣,并不依賴(lài)循環(huán)的一些聲明可以移到循環(huán)模塊之外去。否則后續(xù)開(kāi)發(fā)或是技術(shù)提供會(huì)比較困難。但也需要注意,優(yōu)化后的代碼并不是越簡(jiǎn)短越好,用的語(yǔ)法越偏僻越好,因?yàn)榛逎拇a,維護(hù)成本會(huì)非常高,而且好的代碼不但要實(shí)現(xiàn)功能,更要好維護(hù),最好是A寫(xiě)的代碼讓B能很輕易的理解和修改。
(9) 加強(qiáng)測(cè)試。測(cè)試的重要性并不亞于開(kāi)發(fā),所以要非常注重程序自測(cè)試。測(cè)試時(shí),一般使用工具為主,人工為輔的策略,工具包括用單元測(cè)試,assert語(yǔ)句,代碼測(cè)試容器,人工指用 print 和debugger 一行一行跟蹤。
(10) 使用輸出日志。打印輸出函數(shù)可以跟蹤變量的執(zhí)行,但頻繁地插入打印會(huì)使得屏幕的輸出很亂,而寫(xiě)一個(gè)日志函數(shù),可以保證 Debug 的時(shí)候的輸出以一種統(tǒng)一的,可管理的方式出現(xiàn),這樣在最后發(fā)布穩(wěn)定版本的時(shí)候,只需要簡(jiǎn)單的幾行命令就可以從代碼中剔除所有的日志打印行。
(11) 檢查代碼。代碼要經(jīng)常檢查(包括自查和其他同事檢查)。在提交代碼前,找個(gè)同事一起坐下來(lái),向他解釋代碼做了哪些修改。這樣做的過(guò)程中通常能夠發(fā)現(xiàn)代碼中的錯(cuò)誤,而不需要同事說(shuō)一句話(huà)。這比自己審查自己的代碼要有效的多。將代碼的bug發(fā)現(xiàn)的越早,成本越低。
(12) 回顧代碼。在看到自己以前的代碼時(shí),通常會(huì)有兩種矛盾不同的想法:第一種:我怎么寫(xiě)了這么爛的代碼;第二種,我寫(xiě)的代碼還是挺有成就感的。其實(shí),經(jīng)常回顧以前的代碼,往往會(huì)觸發(fā)新的想法,以及對(duì)以前編碼更深層次的思考。
(13) 編碼不能想當(dāng)然,任何時(shí)候都要嚴(yán)謹(jǐn)。一個(gè)簡(jiǎn)單的項(xiàng)目,表面上看可能可以輕松完成,其實(shí)不然,一個(gè)使用Microsoft Access的、只有3個(gè)頁(yè)面的網(wǎng)站,最后很有可能會(huì)變成一個(gè)有30個(gè)頁(yè)面并使用SQL Server作為數(shù)據(jù)庫(kù)的網(wǎng)站。所以除非有一個(gè)類(lèi)、組件或者一段已經(jīng)寫(xiě)好的代碼,并且在現(xiàn)有的項(xiàng)目已經(jīng)測(cè)試通過(guò),否則,切不可掉以輕心。
(14) 任何軟件都會(huì)有BUG。BUG像幽靈一樣,它是永遠(yuǎn)也改不完的,所以關(guān)鍵是要修復(fù)嚴(yán)重的、影響業(yè)務(wù)的、顯眼的Bug。一個(gè)軟件項(xiàng)目,參與的人數(shù)越多,并不代表軟件可靠性越好,相反,“人多手雜”,而且需求越變更,潛在的Bug會(huì)越來(lái)越多,很多時(shí)候,也許只是修改了一行代碼,其很有可能影響到很多關(guān)鍵流程的執(zhí)行。
(15) 養(yǎng)成耐心、冷靜的好習(xí)慣。作為一名程序員,不能像普通人一樣被計(jì)算機(jī)掌控,而應(yīng)該作為計(jì)算機(jī)的主人,去掌控計(jì)算機(jī)。所以,一定要有足夠的耐心,當(dāng)程序運(yùn)行不正確時(shí),要冷靜下來(lái),站在計(jì)算機(jī)的角度去看問(wèn)題、分析問(wèn)題。
(16) 遵循編程規(guī)范。例如“==”與“=”的區(qū)別;合理使用縮進(jìn);使用循環(huán)和條件語(yǔ)句時(shí),先把左右括號(hào)對(duì)應(yīng)起來(lái),然后再在里面寫(xiě)其他語(yǔ)句;避免使用幻數(shù)(magic numbers);使用有意義的變量和函數(shù)名稱(chēng),例如,使用‘radius’來(lái)代替圓的半徑,而不是用‘r’來(lái)表示。
(17) 了解底層知識(shí)。優(yōu)秀的程序員不會(huì)只關(guān)注程序如何實(shí)現(xiàn),而會(huì)深層次地剖析其實(shí)現(xiàn)機(jī)理,所以,程序員要對(duì)自己的操作系統(tǒng)和硬件要有足夠的了解,從CPU的執(zhí)行方法,到操作系統(tǒng)的運(yùn)轉(zhuǎn),到程序的編譯鏈接,到代碼的加載與運(yùn)行,到程序的調(diào)試,最后到實(shí)現(xiàn)的功能這一整套的內(nèi)容,只有做到這樣,才能真正提高。
(18) 要聰明但不要“小聰明”。不反對(duì)走捷徑,但是一定要論證充分,否則,可能會(huì)產(chǎn)生很多潛在的bug。編碼中走捷徑也許能夠提高程序的可讀性以及效率,但是如果論證不充分,不能把所有的潛在問(wèn)題考慮周全,很有可能犯了丟了西瓜揀了芝麻的錯(cuò)誤。最好的論證方法是多和他人商量,請(qǐng)別人檢查自己的工作,將問(wèn)題提早暴露。所以,不要為了做成某件事卻忽略過(guò)程的連帶效應(yīng),也許有一天你會(huì)為你當(dāng)初的“小聰明”買(mǎi)單。
(19) 要有創(chuàng)新的想法。對(duì)于大型企業(yè)而言,離開(kāi)了創(chuàng)新,就等于失去了生命力,對(duì)于程序員個(gè)人而言,離開(kāi)了創(chuàng)新,就等于停止了進(jìn)步的腳步。雖然說(shuō)天下學(xué)術(shù)全是抄,儼然一副“君不見(jiàn)創(chuàng)新項(xiàng)目一大堆,都被抄死化成灰”架勢(shì),但是不能因此而放棄創(chuàng)新,因?yàn)榇蟮夭豢梢砸驗(yàn)橛行笊圆荻粡?fù)生機(jī),山泉也不會(huì)因?yàn)橛型醢送邓幻盎钏K?,無(wú)論工作有多忙,生活有多艱辛,都要盡可能地保持有一顆生機(jī)靈動(dòng)的心。因?yàn)檫@個(gè)東西是別人偷不走的,也是最大的財(cái)富。即使暫時(shí)不具備這個(gè)東西,也要在生活中用心經(jīng)營(yíng)、好好培養(yǎng)。創(chuàng)新不一定要是改變?nèi)澜绲拇笈e,也不一定非得是世界上第一個(gè)做這件事的人,任何一種能改善生活的行為都可以認(rèn)為是一種創(chuàng)新。例如寫(xiě)一個(gè)腳本去改變重復(fù)勞動(dòng)或是采用什么方式解放自己。
(20) 對(duì)待知識(shí)要刨根問(wèn)底,要有“打破沙鍋問(wèn)到底”的決心?!爸R(shí)就像內(nèi)褲,看不見(jiàn)卻很重要”,在工作中,不能只知其然,不知其所以然,要不懈追求對(duì)細(xì)節(jié)一絲不茍的實(shí)干作風(fēng)與敬業(yè)精神,而不是浮于表面,滿(mǎn)足于填鴨,滿(mǎn)足于考試交差或隨便應(yīng)付,請(qǐng)記住,這個(gè)世界牛逼的人少,裝逼的人多,要從深層次去想其背后的思想和原理是什么。任何行業(yè)都有核心技術(shù),掌握某一項(xiàng)核心技術(shù),就可以讓你進(jìn)入這個(gè)行業(yè)并在其中生存,反之僅僅淺嘗輒止,就會(huì)讓你遭遇失敗,抱怨不公。例如學(xué)會(huì)了C++面向?qū)ο蟪绦蛟O(shè)計(jì),就應(yīng)該弄清楚一個(gè)對(duì)象在編譯后,在匯編代碼中是如何被初始化的;就應(yīng)該弄清楚這個(gè)對(duì)象的各個(gè)成員在內(nèi)存中是如何存放的;就應(yīng)該弄清楚當(dāng)一個(gè)成員函數(shù)被調(diào)用時(shí),編譯器在匯編代碼中加入了哪些額外的動(dòng)作;就應(yīng)該弄清楚虛函數(shù)的調(diào)用是如何實(shí)現(xiàn)的,而這些東西沒(méi)有人強(qiáng)迫你去弄懂,只有你自己。想得多了,自己的層次才有可能提高,如果只是停留在被動(dòng)的接受,那很難有所提高。
(21) 盡可能復(fù)用成熟代碼。如果有現(xiàn)成的允許使用的經(jīng)過(guò)測(cè)試的代碼或程序庫(kù),并且有人維護(hù)或維護(hù)成本可以接受,程序員應(yīng)該盡量使用現(xiàn)有代碼和庫(kù)來(lái)節(jié)省時(shí)間和開(kāi)發(fā)測(cè)試成本。
(22) 多一份追求完美的執(zhí)著。人是不完美的,但人們都在追求完美,程序也一樣,所以程序員要去追求完美。追求完美的人更容易出色、更具責(zé)任心,做事往往也顯得更專(zhuān)業(yè)。
(23) 不要心存僥幸,可能出錯(cuò)的地方一定會(huì)出錯(cuò),偶爾發(fā)生偶爾不發(fā)生的問(wèn)題就是大問(wèn)題。所以,對(duì)于一些常見(jiàn)的問(wèn)題,一定做到防微杜漸:每個(gè)變量都做初始化;每個(gè)函數(shù)都做聲明;引用每個(gè)參數(shù)都會(huì)做有效性檢查;在可能出錯(cuò)的每個(gè)地方都會(huì)做邊界條件檢查等等。這樣開(kāi)發(fā)出來(lái)的程序一定會(huì)穩(wěn)固很多,就是出錯(cuò)也會(huì)很容易修改。而一些沒(méi)經(jīng)過(guò)正規(guī)培訓(xùn)或是半路出家的所謂的高手,一般開(kāi)發(fā)速度很快,三下兩除二的就開(kāi)發(fā)完成了,結(jié)果很可能出現(xiàn)“功能大體實(shí)現(xiàn),bug總是在變”的情況,最后花費(fèi)很長(zhǎng)的時(shí)間來(lái)修改代碼中的bug,總時(shí)間甚至?xí)蟠笱悠?。而真正的高手,追求的境界是零缺陷代碼。
每個(gè)人的路都在自己的腳下,自己過(guò)得怎么樣,也只有自己心里明白。要想讓自己的編程變得快樂(lè)有趣,還是應(yīng)該努力培養(yǎng)一些好的習(xí)慣。也許上面的這些好習(xí)慣,要想都能在實(shí)際生活中落實(shí)并不是一件容易的事情,恐怕只有“大?!眰儾拍芡耆龅搅?,但只要你不斷地朝著那個(gè)方向努力,相信你也會(huì)在這個(gè)努力的過(guò)程中得到長(zhǎng)足的進(jìn)步。
聯(lián)系客服