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