Friday, December 23, 2011

該如何學好 "寫程式" ??

會寫這篇是因為上禮拜,有個資深的同事問我個問題,如何把底下的 programmer 素質拉上來? 跟他講這問題害我那天拖到晚上十點才回家吃晚飯 @_@,不過我想這也是現在台灣軟體業普遍碰到的人才問題,就順手寫了這篇。這篇是打算要貼在公司的 BLOG 裡給同事看的,這裡先貼一下,到時整理好再搬過去...。


-----------------------------------------------------------------------------------------
其實在這之前,一直有人問我這類問題,我的回答總是一樣: "要從基本功做起。"   只不過大部份人都會皺皺眉頭,想說 "為什麼沒有速成一點的方法? "
先撇開軟體開發一定要有其它領域的 domain know-how 之類的東西,我就針對到底有沒有辦法把 CODE 寫好這件事來討論。如果真的存在速成的方法,那滿街就都是高手強者了。技術及工具的進步,是簡化你操作工具及開發過程的細節,但是其中累積的知識及理論,只會越來越多
現在要寫程式所必須俱備的技術門檻越來越低,但是要能專精所必要的知識及經驗則是越來越高。我常在想,我是一路學習摸索上來的,大學四年唸了電機學到了硬體的底子,大三大四本來想修資工當輔系,後來直接去考資工所... 這三四年下來也有點資訊的底子,這些知識讓我到現在都還不用辛苦的去 "追" 技術,我只要看看 overview,大概就能掌握這些技術能解決什麼問題,不能解決什麼問題等等。真正需要用的時後,文件翻一翻就能找到我要的段落,就能夠上手了。
不過現在的年輕人就沒那麼好運了,要從 CPU 是怎麼設計,怎麼執行指令,到瀏覽器為什麼點下網址就能看到網頁,這一連串的細節,大概現在的大學畢業生都回答不出來吧? 現在隨便買本書翻一翻,就能寫出一個漂亮的網站,誰還願意去唸那些基本功? 也因為這樣現在的人都少了那份 "內功",只剩漂亮的招式,出招很勵害,不過打沒兩下就後繼無力,或是對手出了沒看過的招,就不知怎麼接下去了。
如果你真的有心把底子練好,我是有幾個建議的方向,雖然看起來沒什麼用,但是看熟了你一定會發現,你寫什麼程式都逃不了這幾個基礎知識。
  1. 最基本的: 計算機概論 & 資料結構這些有助於你用正確的邏輯寫程式。要成為一個合格的 programmer 一定要有這樣的能力。
  2. 進階一點的系統層面,作業系統 & 系統程式
    這些有助於你瞭解系統層面如何運作,如果你開發的系統需要些基礎建設,像是元件等等,這些知識很有用。成為 software engineer 就應該要有這些基礎。
  3. 再來就專精一點了,我推薦 OOP 理論 / Design Patterns、或是軟體工程的方法論 ( XP, TDD ... 等 )
    這個層次的知識能幫助你設計正確的架構,或是用正確的方式開發軟體,是成為 ARCHITECT 的必要技能。
每一項都代表一個階段。上禮拜跟同事討論的,其實只有討論到 (1) 的部份。如果工程師都 "" 寫程式,但是用的邏輯看起來都 "怪怪的",那就是要加強 (1) 的部份了。我簡單的舉個例子,資料結構在學什麼? 跟實際寫程式能有什麼關聯?
想到資料結構,不外忽一堆排序 (SORT) 的演算法,或是各種 TREE / LIST 等怎麼 "放" 資料,及怎麼 "找" 資料的問題,如 LINKED LIST,HASH TABLE,BINARY TREE,HEAP,STACK 等等。再來就是什麼問題可以用什麼資料結構來處理? 像是走迷宮要靠 STACK,各種資料結構的特性為何? 它們的時間複雜度 (Time Complexity) 為何? 什麼時後該用那一種?
這些是很基礎的問題,不過你如果不是科班的,只是翻翻書就會寫程式的,那這些問題應該都回答不出來吧? 針對這部份,我強烈建議要學的人一定要先搞懂這些 "邏輯"。我不稱為理論,是因為他們還太淺,只是個作法而以。搞懂這些邏輯,你至少要有能力把程式寫出來。
因此第一課很簡單,挑幾種 SORT 的方式,比如 Bubble Sort, Quick Sort 等等,不用多,兩三個就好,步驟搞清楚了,還能用你熟悉的程式寫出來 ( 如: C# / JavaScript,當然你不能作弊用現成的 SORT 函式庫 ),你就過關了。
再來就是搞懂各種資料結構,我舉幾個 .NET 內建的,卻又常讓人搞混的幾個 Collection。List / LinkedList 用的方式都一樣,那麼兩者到底有什麼不一樣? 只塞一百筆,找出一筆要 10 ms 的話,塞一萬筆找出一筆要花多少時間? 是 100 倍嗎? 還是 10 倍? 還是都一樣?? 是 Microsoft 工程師太無聊,故意寫來讓你傷惱筋的嗎?
如果這部份你也搞懂了,接下來就是應用了。就拿導航系統來說就好,地圖要用什麼方式存才好? 使用者選定起點及終點,你該怎麼幫它找出最佳的路逕? 不管畫面等等問題,你有辦法寫出程式找到答案嗎? 這就是典型的資料結構的應用。你沒學好資料結構的話,看再多 C# / ASP.NET 的書,一點用都沒有啦,碰到這類問題,管你用 VB / C++ / C# 還是  Java, 只能坐在螢幕前發呆而以。

總結一下,你符合我講的 (1) 基本要求嗎? 很簡單,這些問題或程式你都寫的出來就符合了:
  • 丟一付洗過的撲客排給你 (不要多,黑桃1 ~ 13就好),你知道怎麼用 Bubble Sort / Quick Sort 的步驟把它排好嗎? 丟一個陣列,裡面隨便打幾個數字,你能寫程式把它由小到大排好印出來嗎?
  • 假設記憶體夠大的話,你有辦法把一百萬筆通訊錄資料讀到記憶體內 (用什麼物件都隨你),然後還能用很快的速度找到你要的資料嗎? 不同的搜尋方式,你知道該用什麼樣的方式找才有效率嗎?
  • 以台灣高速公路為題 (中山高、北二高、國道二號),你有辦法寫程式,讓使用者指定起點跟終點的交流道,然後替它找出建議的路線嗎? (把延路經過的交流到跟收費站列出來就好)
看起來就像是作業,沒錯。不過它是很實際的基本功夫,如果寫不出來,那就真的該好好唸個書了。其實這些問題,都跟熱門的技術 (如 DB / WEB / RIA 等等) 無關,就很單純的看你的邏輯能力而以。這個主題我會繼續寫下去,大概一兩個禮拜一篇吧。我的目的是希望大家底子打好再來學這些熱門技術,這樣你才有辦法更進一階,否則就只能隨著技術規格推陳出新,不斷的在追新技術而以。上面那三個問題,有興趣的話歡迎找我聊聊。在這留話或是 mail 給我都可以。

Reference:
http://columns.chicken-house.net/post/2008/09/27/GoodProgrammer1.aspx

No comments: