(圖/shutterstock)
圖片來源:Shutterstock
作者:Arthur Liao
職業道德
甚麼?寫程式也有職業道德?
有的,而且還很重要。
我說寫程式是一門良心事業,
因為通常你寫的程式只要符合規格、
能正確執行,就可以交差了,
而你的主管或同事
很難一眼看出程式碼品質有問題,
例如:在特定條件下會爆掉、
濫用複製貼上、採用一些骯髒寫法、
程式可讀性很差、
模組之間糾結在一起,等等。
焊接過電路板嗎?
要是電路板繞線一團亂、
零件歪七扭八、接腳沒焊好,
你能交差嗎?但是寫程式可以。
因為程式碼是一種抽象產品,
沒有「外觀」可以觀察。
如果你的團隊要求code review,
這個問題可以得到某種程度的改善,
但仍不能徹底解決。
程式員的紀律和職業道德很重要。
(關於軟體的抽象本質及軟體開發的特殊性,
我去年寫過一篇英文blog探討這一主題,
有興趣的人可以參考看看:
“Making Abstract Products Makes Things Hard”)
程式語言
程式語言的學習,
是程式員最最基本的能力,
而且應該至少精通一兩種語言。
隨著程式經驗的累積,
學習不同程式語言的速度會越來越快,
例如從幾個月縮短到幾週。
當然精通一門程式語言,
不是幾星期、甚至幾個月就能達成的,
但迅速接手並維護既有程式碼,
是對合格程式員的基本要求。
通常第一種程式語言學最久,
因為很多觀念也是第一次學,
例如變數、迴圈、陣列、遞迴、I/O、
網路、多執行緒、物件導向、
regular expression、functional programming……。
等到學第二種、第三種程式語言,
新的觀念越來越少,
主要在學語言本身,速度就會變快很多。
資料結構及演算法
如果你是本科系畢業,
資料結構及演算法應該是必修課。
如果沒學過,建議花點時間學一下。
倒不需要買一本厚厚的書折磨自己,
但基本的概念一定要有,例如:
1.資料結構
●陣列(array)、串列(list)、
堆疊(stack)、佇列(queue)
●樹(tree)、二元樹(binary tree)、
雜湊表(hash table)
●指標(pointer):
這也許不算資料結構,
許多高階語言也不讓你用pointer,
但是對記憶體、指標要有概念,這
是程式員與非程式員的區別之一
2.演算法
●對以上資料結構的各項操作
●排序(sort):
至少搞懂3、4種基本的排序演算法,
例如bubble sort、quick sort、merge sort等
●搜尋(search):
depth-first-search、breadth-first-search、
binary search等
●其它:
迭代(iteration)、遞迴(recursive)、
分治法(divide and conquer)、
時間/空間複雜度的基本概念(big O)等
網路上資源很多,
Google一下、多寫一些程式練習,
弄懂以上基本概念,應該就夠用了。
網路協定
TCP/IP、HTTP、DNS等這些
都是基本的網路協定。
不需要到專家程度,但身為一個程式員,
除非你的工作與網路完全無關
(這種工作應該越來越少了),
否則對這些網路協定的運作
應該要有起碼的了解。
例如你能講清楚,
從你在瀏覽器輸入一行網址到看到網頁內容,
在網路上發生了哪些事?
以前我在 Yahoo面試前端工程師的時候,
喜歡問一個問題:
請解釋 cookie是怎麼運作的,
結果不少人答不出來。
當然現在的程式開發環境很方便了,
各種 library一大堆,
我們通常不需要自己實做這些底層的東西。
但不懂這些東西運作的基本原理,
會讓你在 debug時被卡住,
因為整個網路系統的運行,
都是建立在這些基礎架構之上。
這些網路協定,
再過很多年還是會繼續存在,
花一點時間搞懂這些,我認為很值得。
除錯能力
講除錯能力不太準確,
因為除錯不是單一能力,
而是結合了經驗、對程式的了解、
對系統架構的了解、抽絲剝繭的能力、
直覺,以及各種 hands-on能力的綜合,
就像當偵探一樣。
台語有句話叫「醫生怕治咳,師傅怕抓漏」,
差不多就是這個意思。
我在 Yahoo工作期間,
最刺激的事莫過於排全球 on-call了。
所謂 on-call,就是全球 Yahoo網站出包時,
你要在最短時間內找出問題並修復,
那真是超級 debug。
拜託,Yahoo網站那麼複雜、程式碼又那麼多,
出問題的模組又不是我寫的,
美國同事都下班了,誰知道怎麼解決?
對不起,那是你家的事,
排了on-call你就得想辦法解決。
功能上的問題還有跡可尋,
最棘手的是像系統過載這類問題,
爬 log、寫 script、trial-and-error,
總之想方設法揪出元兇。
程式員應該具備良好的除錯能力,
不管程式誰寫的。
另外,修 bug也是一門學問,
是採用鋸箭法、貼狗皮膏藥,
還是找到病灶、解決問題背後的問題,
就看程式員功力了。
寫出可讀、易維護的代碼
這個要求聽起來很合理,不是嗎?
其實這是最難的。
寫程式這麼多年,看過多少代碼,
我跟你說,
這個世界上的爛 code佔絕大多數,
好 code只佔一小小部份。
我自己也不斷在這條路上努力著,
到現在也不敢說自己寫的code多好。
為甚麼這件事這麼難?
我想了一下,大概有以下幾個原因:
1.可讀性高的代碼,
通常是用很好的解法,
解決了真正的問題
●你需要徹底了解問題(problem domain)
●你需要考慮過至少幾種合理的解法(solution domain)
●你需要對程式語言、程式庫、
既有程式架構和可運用工具很嫻熟
●你要能以簡馭繁,
而這代表你掌握了更高的東西
例如牛頓的F=ma、愛因斯坦的E=mc2,
這是神人等級的功力
(只是舉例說明,寫程式不需要到這樣)
2.你寫程式必須很有紀律,例如:
●不急著馬上寫 code,
先想清楚問題、解法、架構
●恰到好處的註解,少了不行、過猶不及
●用心想過的命名
(程式界有句名言:
There are only two hard things in Computer Science:
cache invalidation and naming things.)
●壓抑 copy & paste及產出一堆爛code的衝動:
Bingo! 找到一段 code了,
看我的 copy & paste
可以 work就很好啦、
這麼漂亮的解法……
好累,我不行了,先 commit code再說
●在 commit code之前,
自己再好好 review一次
(我個人經驗,
通常這個步驟可以改進程式好幾個地方)
3.越容易維護、擴展的代碼,
代表它的複雜度越低
●降低軟體複雜度是軟體工程的最大挑戰,
軟體複雜度就像軟體的熵
(我的第一篇英文 blog
“Software complexity is software entropy”,
就是講這件事)
●必須做到 low coupling、high cohesion,
而這兩件事都很難
●低複雜度的軟體系統,
代表裡面各個模組的複雜度都必須更低
當你輕易多用了一個外部組件、
增加了一個 external dependency,
你就把它的複雜度整個帶進來了,
所以要很小心
4.現實環境的因素,
導致好的程式碼不易產生
●專案時程的壓力
●程式員經驗的限制
●團隊未採用一些最佳實務
●有決策權的人對軟體開發不夠了解
代碼品質的重要性,每個人都知道,
連路人甲都知道。
現實的難處在於:
第一版的代碼,只要能 work,
品質好壞是很難看出來的;
它們的差別,
要到系統後續的運行、
維護及擴展才能看出來,
然而此時木已成舟,
程式只能修修補補繼續用下去,
最多小幅重構(refactor),
直到軟體生命週期的結束。
寫出好的代碼,
時間會花比較久、會導致專案時程延後嗎?
其實並不會,
這是能力限定,不是時間限定。
寫出第一個版本,花的時間都差不多。
但後續版本就差很多了,
寫得越好的代碼越好改。
你如果改過那種 high coupling的系統,
你就知道我說的意思了,
那真是人仰馬翻,超 high的。
這種代碼要是裝在箱子裡,
箱子上會標示「易碎/ FRAGILE」。
寫出好的代碼並不容易。
假如我們從 1分到 10分給程式碼打分數,
10分真的很難很難,我自己也做不到。
但一般人經過努力,
達到 6、7分應該是沒問題的。
如果你想看書,我在這裡推薦一本:
Code Complete 2nd Edition。
教人寫程式的書中,
這是我看過最好的一本了,
只是內容比較多,需要時間消化。
如果還有興趣多看,
我個人覺得 Martin Fowler也寫了不少好書。
相關文章》
程式員求生指南》關於寫程式的二三事:程式員 須具備哪些 進階能力?
程式員求生指南》關於寫程式的二三事:程式員 除了技術,還需要什麼?
未經授權,請勿轉載侵權!
(責任編輯:CMoney編輯 / Alodia)
菁英軟體工程師戰鬥營
第六屆 熱烈招生中!
想學程式、成為工程師
卻怕自己沒基礎、學不好嗎?
這裡有史上最專業的魔鬼訓練課程,
讓你有機會 朝夢想前進
全程免費、不用基礎從頭開始、培養就業競爭力!
填寫報名表,將有專人與您聯絡
名額有限>>馬上報名
詳細活動介紹>>點我查看!
有問題歡迎私訊粉專:從0開始學程式!
或是寄信到:engineertraining@cmoney.com.tw