有哪些迅速提升編程技術的方法或途徑?


守-破-離

"創造發展劍招的過程,有守、破、離三階段。

最初學劍時固須順從老師所教,把它熟練體會,變成自己的東西,

以後突破老師的教導原則,招式心法,

而如有新的心得,則離開師傅,創成新招。 」

----宮本武藏 《五輪書》

最早在《敏捷軟體開發》里,(不是Martin大叔那本《敏捷:原則模式實踐》),Alistair Cockburn引用了源自日本守-破-離的概念,來描述學習編程技藝以及敏捷實踐所必須經過的三個步驟,而該項理念在日本是用來指導研究茶道與武道等學問時的順序,愚以為他也是可以指導任何一本技藝的學習的。

具體到學習軟體開發中

守:

就是新手入門最簡單就是照著書上敲代碼看結果,熟悉整個編程環境,各種概念

我推薦初學者籍由任何一本類似《VC++編程百例》開始,而不是去閱讀《C++primer》這樣的神書來入門,因為我相信學習應該是樂趣驅動的,敲打鍵盤並且立刻看到有東西出現是有創造樂趣的事情,因為大多數推薦《C++primer》或者《代碼大全》給初學者去看的人,大概都太興奮於該書是如何之好而忘記了當初他是怎麼互拼亂湊,狂喜的搞出他的第一個可運行程序的。

破:

破就是讀源碼,改代碼,嘗試修改,結合自己的回饋理解第一個階段所學。

把那些上面學到的例子上面的代碼改一下,看一下結果,或者兩個程序結合在一起看一下是什麼樣….,體會那種神奇感覺,那些說寫程序很苦逼的人多半都沒有寫過程序。

離:

這個時候可以嘗試開始全新構建自己的代碼了

推薦的實踐是在自己的工作生活當中發現痛點,用自己所有學習的例子和網上找來的例子拼湊幫助自己實現解決痛點的程序,不管實現得漂亮不漂亮:),漂亮不漂亮都是後面才具有的能力看到的。

個人是當年在運營商機房工作,曾有每天很多固定的且機械的設備維護命令要敲,最後我代碼實現完畢就可以把原來每天2個小時的工作變成10分鐘,這個快感讓我徹底愛上的編寫程序

循環往複:

當然,必然出現的是,在開發程序的過程中,會發現自已經運行起來的代碼中存在諸多不爽之處,比如要到處機械複製代碼,或者老是改動的時候只改了一個地方其他地方就忘了其他地方,或者Bug出現了,發現牽扯代碼太多,調試起來很痛苦,改了這個bug,另外一個新的bug又冒出來了,這個就是新的痛點,需要學習新的技巧,這個時候開始閱讀別人的源代碼,看看別人是怎麼解決這些個問題的,閱讀好的源代碼,看解構類,語言理念類的書籍,比如《C++Primer》,《Effective C++》《設計模式》,《代碼大全》《重構》,並把這些規則技巧應用到自己的代碼裡面去解決哪些問題同,時這又是一輪守破離的開始......抱歉,沒有回答關於「迅速」的問題,我個人猜想,速度是一個結果不是目標,興趣即天分,有興趣自然會快。

總結:

解決問題獲得成就,是激勵自己學習的不二法門,,程序是一件處理程序員,客戶,機器之間關係的技藝,不可避免的你會發現有新的痛點,你要學習新的技巧去解決,

  • 發現「客戶」需求變化之痛並為之振奮的人,發展成了需求分析師,產品經理,或者乾脆成為了創業者
  • 發現「機器」難以駕馭但任然有興趣為之努力的人,成為了資深程序員或者技術架構師
  • 發現「程序員」合作或者部門合作中存在某種神秘技巧的人,學習技巧,成為了項目經理或者敏捷磚家

受邀X次。這個問題我的第一感覺回答就是 reelai 的回答,第二感覺還是,所以點擊了贊同之後無需再回答。這個圖的經典之處在於:即便你把從第五個框圖,開始學習物理化學的內容略過,剩下的內容依然靠譜。

編程技術這問題就視乎你需要什麼,快速提升是不可能的,但「比平均水平提升得更快」也許有可能。而且編程技術的內涵其實可以擴展到整個社會各行各業,這個意思是,編程並不是「一種」技術,而是「一類」技術。這類技術在具體不同的應用不同的領域方面會大有不同。

馮東的話在某些領域很有道理,換個人卻覺得他胡扯。為什麼會出現截然不同的觀點?因為編程是個很寬廣的領域,每個人都不可能通曉編程的全部,因此每個人基於自己所知給出的答案,都會存在一定的局限性。

鑒於「編程技術」本身的內涵十分寬泛,因此這個問題屬於「寫出答案來要一本書」的那種問題,按照「三表」的意見,此類問題其實是無需回答的。

如果真的要回答,我想我的回答仍然是:reelai 的漫畫圖,其中第三幅與第四幅是重點。


1,基本訓練。基礎課程很枯燥,但不是白搭的。

2,多看。讀代碼的能力遠遠比寫代碼的能力重要。見多之後,才是識廣。

3,想像和預測。寫代碼不是目的,達成結果才是目的。代碼和實現之間偏差最小的,就是高手。

4,保持視野,多扯淡。github,stackoverflow,ycombinator。。。編程技術一日千里,視野和對新技術的敏感很重要。用一把鎚子解決所有問題的,看上去是高手,但是結果往往很擰巴。


如果你是初學者:

少看別人的代碼,多寫,哪怕代碼質量很差。

如果你是老手,想上一個台階:

先多想,然後多看,再然後一定要動手寫代碼。


@馮東的那個回答在很大程度上是胡說八道,完全不切實際。

現實中有那麼多程序員連計算機本身都不是太了解,你讓他們去讀linux這種級別的源碼是不是太荒謬了,就算是lua也非常不靠譜,讀完這些源碼對那些問出這種問題的人有什麼實際幫助?根本沒有抓住編程的關鍵。

編程的關鍵在於寫程序時依賴的隱喻、約定、假設、潛規則(關於這些東西的解釋可以看看《代碼大全2》,我這裡只能簡單說你寫下的代碼對別人讀懂和改動的要求),你依賴的這些東西是不是少而且穩定一致,太多容易讓人接觸你的代碼時要記住太多東西,恨不得把你拖出去暴打一頓,而且越多依賴改動維護就越困難;不一致就是自己打自己嘴巴,這種蠢事我想沒有人願意干。

要在這方面有所提高,讀代碼是一個很有效的方法,但選擇源碼是一定要注意項目本身跟你平時接觸的、習慣的隱喻比較接近,你一個普通web程序員讀linux源碼幹什麼,在你不熟悉其背景的情況下只能是事倍功半,大大增加你的挫敗感,還不如去讀你平時常用的web伺服器的源碼來得有幫助。

當你在這方面有了較高水平,只要補上背景知識,什麼源碼對你來說都不在話下,包括linux。你自己的編程水平就更不用說了。

提高編程的另一個方法是記住重用你的代碼,寫過的東西盡量不要再寫,用你以前寫過的,如果以前寫得不好導致相似的問題無法用寫過的代碼來解決,說明你寫得不好,改造你的代碼去同時適應新舊兩種情況。但這樣也要注意不要走入相反的誤區,就是試圖用一把鑰匙開所有的鎖。

另外,對數據結構的理解和運用對你的編程水平有很大影響。

在合理借鑒優秀思想和代碼的同時,不斷的錘鍊自己的代碼,編程能力一定會得到提高。你不一定要成為那5%,但你依然可以是一個優秀的程序員。


昨天作答之後(分割線之後部分),一直關注這個問題的討論。很有意思。所以補充一下我這麼作答的原因。

首先這是我自己的體會。走到今天這個狀態,自我感覺沒走什麼彎路。當然,路只能走一次,很難說別人一定可以或者適合重複。所以有反對很正常。

關於 parser。自我感覺的經歷是,這絕對是 passable programmer 和 great programmer 之間的一道坎。不過不用太著急,從大學開始我有過不下三次半途而廢的嘗試,在工作兩年多之後有了一些時間才爬過的。但是如果你工作四五年還爬不過,就不要在編程這條路上太費力了。

關於讀和寫。首先我懷疑編程技術是否就是「編」的技術。我舉兩個例子:第一,你三年後成為了所謂 senior developer,這時有人讓你 review 一段不正常的 code。有兩種方式,一是說這段東西爛透了,我半天重新寫好。二是花半天仔細看出 code 的問題在哪裡,告訴對方(或者給對方 patch)。我覺得後一種對整個軟體的生命貢獻更大。第二,有人指出過,如果用圖形的大小來表示工作量,我們通常畫框圖的形式都是和現實顛倒的,應該是模塊小,連接部分大。想想 OS X:xnu,gcc,BSD,WebKit,TrustedBSD 這些都是現成的技術,把它們集成到一起才是 Apple 不僅在品味上也在技術上超過 Microsoft 的關鍵。

========================

  • 讀 code。盡量讀質量高的。比如 Linux, Lua。

  • 學習理論知識。如果時間緊,盡量學這三種(按重要順序):編譯(不是全部的編譯,而是 language recognition 部分,俗稱 parsing),操作系統內核(預備知識包括 Linker and Loader,可執行文件格式),計算複雜度和自動機。
  • 學習歷史人文知識。Code 是人寫的,複雜的 code base 要存在十幾年。所以,不了解寫 code 的人,不以了解人的方式了解 code 是不行的。

天賦我也一定程度承認。不過只要你能啃過 parsing,基本上就屬於 Knuth 說的那 5% 適合編程的人。


樓上的有幾位說少看別人的代碼?這點我倒不是太贊同,除了自己寫代碼以外,最好的提升自己的代碼能力就是看別人的代碼。認為別人的代碼阻礙了自己「純凈」的代碼?認為別人的思路阻礙了自己的思路?至少我認為不存在這麼回事。哪怕別人最爛的代碼,你也可以警示自己說相同的問題至少我不能犯。更遑論很多人的代碼很優秀,細細體會收穫很多。博觀而約取,否則必定會孤陋而寡聞!


代碼大全,UML,GOF設計模式,架構模式。

懶得長篇大論,如果相信的話就看這些資料吧。


經過這幾年的編程學習,我認為學習編程沒有快速的捷徑,基本上就是三個步驟循環往複:看經典書和技術文檔,看代碼,寫代碼。循環往複,代碼寫了10W行,自然就有心得了。


好的程序員最後都會想盡辦法研究實現一門語言,或者一個系統。

按這個思路去錘鍊自己就行啦。


引述一下王垠同學的觀點,就是對於尚不明白的東西,試著自己去實踐,動手做一個,而不是立刻去google解決方案,以前帶我的學長講過一個故事,兩個模塊因為位元組序的問題死活對接不上,他室友折騰一天沒弄出來(其實就是在網上各種找庫),他後來忍無可忍,插進來幾行代碼搞定,他和他室友所差的,就是解決問題的意識和能力。

另外王垠很強調解決問題的過程中所獲得的直感,這個我同樣深以為然,他舉得例子是做作業的時候獨立實現了自動CPS變換,通過實現這個系統他接下來很容易的就搞定了ANF等等,我曾經在某寒假被Lambda-Calculus的習題弄得頭昏腦漲,於是自己寫了一個LC的解釋器,寫的過程反覆了幾次,很大程度的加深了我對LC和類型系統的理解,之後在著手其他語言的解析的時候就十分得心應手了。

上面兩段所要表達的,就是看起來懂和真正的理解之間是有一道鴻溝的,構成這道溝的是大大小小的理解錯誤與疏忽,這些被疏忽的東西幾乎是不可能避免的,想要跨過,最簡單直接的方法就是去實現一次,計算機是不會說謊的,它會把你所有的理解不夠的地方表達出來,修正這些疏漏的過程就是你理解整個系統的過程,直到實現完成且通過了測試,你才能真正掌握一塊知識。

這只是一個籠統的建議,具體的請參照其他人的答案。

以上


其實如果你問這個問題,基本上你本身對程序沒那麼感興趣了吧。

我都是因為喜歡,才學的。所以我就是努力學習咯。


1. 多寫

2. 多看,多學習

不過要承認,還是要有天賦的


嚴肅認真的做一個東西出來,即使被人說是重複造輪子也要克服各種艱難險阻做一個能用的、有用的、好用的、不一樣的輪子出來。


說得冠冕堂皇一點就是要以興趣為導向,理論聯繫實際。呵呵

編程的最終目的,就是要實現功能。以什麼樣的形勢來表達這個功能?如何實現這個功能?自己是如何思考的?有沒有在其它項目中見到類似的實現?有沒有在開源項目中遇到過類似功能? 這些應該都是自己平時的積累吧,與具體某項技術無關。但如果平時不留心的話,估計做起事來也是事半功倍,不是重複發明了輪子,就是做了一個相當拙劣的小板凳。

稍微有點基礎的程序員,如果拿刀架在脖子上,讓他用一個從沒用過的的語言實現一個小功能。參考著說明文檔,不出三五日也能完成基本任務。但是如果再講求效率,風格,語言特性。就有點強人所難了。

之前曾反覆看了設計模式,一直都是停留在概念階段。直到後來參加到一個大型項目,用設計模式完美解決了幾個棘手的問題之後,才體會到其精秒所在。跟完一個項目之後,感覺收穫良多。

所以我覺得:興趣是很重要的,它決定你在編程這條路上走的輕鬆還是辛苦。入門很容易,很是想要進階,只看書或都只寫代碼都是沒有多大用的,要兩者相結合,這是一個反覆迭代的過程。

寫到這裡,才發現我想要說的樓主各位都已經講過了。其實道理大家都懂,所謂捷徑,只是懶人給自己的一個借口罷了。


總是看到很多渴望速成的問題,但是我們應該明白,編程它本身就不是一件可以速成的事情。編程它有成功的路徑和方法,上面的答案很多都是。你只要按照這些方法路徑踏踏實實地去做,你最終能夠達到成功的終點。如果你一開始就夢想找個捷徑,一步登天,那恐怕你只是在白日做夢。

大家渴望成功,渴望快速成功的心情可以理解,但是凡事都應該按照規律而行,否則,你只會受到規律的懲罰。

想起愛因斯坦說過一句:時間的意義就在於,它讓任何事情都無法一蹴而就。

問問自己,葵花寶典可以速成,自己願意不?


我就一個方法:多想。

看的代碼比較少,寫的也不多,這是我的一個缺點,不過也因此保持了最純凈的想法,可以想出一些比較創新的方法和脫穎而出的方法。。。自吹自擂了。。。

初學的時候看別人的代碼其實挺重要,只要是你覺得看著很神奇的代碼都可以研究下,模仿下。

等你到了看著別人的代碼都沒啥感覺的時候,就要多想了。。


如果完全不懂一門語言/一個操作系統下的編程,最快的學習方法就是找本相關領域的公認的經典書(比如學windows編程就是《windows程序設計》),把書上的代碼一行一行「喂」給電腦,出錯自己找,實在找不到錯在哪就上論壇問,完了再在人家的基礎上添添改改。


想走捷徑總是走了彎路之後才發現捷徑的。不要著急,十年學會編程。

http://daiyuwen.freeshell.org/gb/misc/21-days-cn.html


從你問的問題,可以看出,你真的是這方面的新手。這不是你的錯。這裡面有個潛在的問題。新手由於不了解某個領域,所以他根本無法提出有建設性的問題,或者正確的問題。這種問題,無論回答者怎麼回答,都不會幫到你,因為問題本身就是錯誤的。要想真正解決你問題,需要把你提出的那個問題拆解成更具體的問題,比如但不限於以下問題:

1 如何讓我開發出一個XXX網站

2 如何讓我通過XXX認證考試

3 如何讓我了解XXX技術

4 如何讓我通過XXX面試

5 如何能看懂XXX源碼

……

你認為要完成以上任務,就要提高你目前的編程技術,所以你問了問題;實際上是,你應該試圖去完成以上任務,之後,你的編程技術就提高了。

注意,我把你問題中的「迅速」去掉了,因為這個對於解決你的問題,沒有幫助反而有可能有副作用,但凡給你推薦方法的人,都是覺得這是最好的方法,至於快慢,那就仁者見仁智者見智了。


推薦閱讀:

印度的軟體產業為什麼發達?
遊戲公司的程序員會不會在做項目的時候預留後門,然後自己編寫外掛之類的惡意程序賺錢?
為什麼會有編程行業的轉行做IT培訓?
為什麼主流播放器都無法變速播放WMV格式呢?
udp協議怎麼穿透Symmetric NAT?

TAG:程序員 | 軟體開發 | 編程語言 | 編程 | 計算機科學 |