追求神乎其技的程式設計之道(十)

追求神乎其技的程式設計之道系列:

程式設計師的生產力之謎

很多人都聽說過,同樣是寫程式,一個頂尖程式設計師和一個普通程式設計師之間的生產力可以有十倍甚至百倍的差距。這是其他行業很少見到的現象,於是不禁令人納悶,為什麼會這樣呢?

其實單就解決同一個問題的coding能力來說,差別還不至於這麼巨大。我在高中參加奧林匹亞和大學參加ACM比賽時,已經遇過全世界數一數二的coding高手,這些人每天都在練習解題和實做各種複雜的演算法和資料結構,隨便說一個演算法都能直接把code透過肌肉記憶反射出來給你。他們能在數十分鐘內想出高效率的演算法並寫成程式解決一個複雜的難題,即使我高中時已經花了一整年在訓練,依然不是他們的對手。這些人除了絕頂聰明外,每個人在高中時少說也寫過至少十萬行的code。但我發現,即使他們能解一般人解不出來的問題,打字快到鍵盤會冒煙,在做一個大系統時,這方面的差距還不一定會如此明顯。

所以我想,除了先天的智商和後天對於寫程式的熟悉度與經驗外,一定還有什麼因素造成巨大的生產力差異。

我後來發現,程式設計師和其他行業有個很大的不同點:一般行業只能在現有的工具上磨練自身的技術,但程式設計師除了磨練技術外,還可以獨自創造、修改自己使用的工具;換句話說,程式設計師的能力就是在電腦上創作出更好的軟體,不但能便利他人,也同時能增進自身使用電腦的工作效率。舉例來說,理髮師能磨練使用剪刀和設計髮型的技術,但理髮師並不知道怎麼發明及製造新的剪刀讓自己更有效率的剪頭髮;電機、化工、土木工程師要設計IC、化學製程、建築結構,但他們得依賴電腦軟體才能設計,並且靠許多大型機器和工具才能生產,即使想提昇自身的工作效率,也不是自己一個人想做就能辦到的。但軟體工程師就不同了,我們只靠一台電腦就能工作,我們的工具是軟體,我們的產出也是軟體,我們的所依賴的一切都是軟體,只要自己願意投入心力,隨時可以修改每天使用的工具和系統讓自己更有效率的工作。

這一點可以說是程式設計師的先天優勢,也是頂尖的程式設計師和普通程式設計師的生產力差距的關鍵。

Eat Our Own Dog Food

我發現厲害的程式設計師常有種共同特質:寫工具給自己用,解決自己日常工作碰到的問題或改善自己的工作效率。英文有句話叫eat one’s own dog food,字面上意思是說一家公司應該要吃自己做出來的狗食,實際上是引申為一家公司應該要在內部用自己的產品解決自身的問題,才能發現真正的問題,並且說服人這東西真的很實用。Google是奉行「吃狗食」原則的典型公司,Google內部有一個獨立的搜尋引擎搜尋公司內部網路的資料,新技術也都能在上面先行測試;Google內有獨立的gmail、google docs,都在對外公開前先讓內部的人實際用上好一陣子;Google甚至做了自己的Linux distribution給工程師用、自己的compiler、自己的瀏覽器…。

會這樣做的動機其實很簡單:如果我每天都要花10分鐘手動做同樣的事情無數次,為什麼不花一個小時寫個程式把這件事情自動化,以後可以省下更多時間做點真正有意義的事;如果我每天都要用這個彆腳的軟體,忍受他設計上的不便,為什麼不想法辦改善它或自己做一個呢?

程式設計師每天都用電腦在工作,尤其做一個系統時常常需要花時間做一些瑣碎的工作,像是編輯設定檔、把一些檔案搬來搬去、重開伺服器、清除暫存檔…等等。這些工作通常不難,但可能步驟繁雜,或是每個步驟都要等待它慢慢完成,累積起來每天就很容易浪費許多時間手動做這些無趣的事情上。

出於「懶惰」的美德,頂尖的程式設計師工作時想的不只有產出最終產品就好,而是如何花最少力氣最少時間把產品做到最好。但這件事說來容易做來難,能不能實行往往跟程式設計師工作的系統環境有很大關係。

UNIX是Programmer的天堂

如果要說我高中時期最大的收穫是什麼,我想有兩件事的重要程度不相上下:一是我確認了自己對寫程式的熱情,並且花了足夠多時間打好基礎;二是我在這段時間內摸熟了Linux,並且愛上了UNIX世界工作的哲學。

UNIX可以說是一個非常適合程式設計師工作的天堂,UNIX的工作哲學(泛指所有UNIX like的系統,像是Linux、BSD、Mac OS X..等等)是提供許多小工具,每樣小工具只做一件事,使用者可以合併使用多種工具完成複雜的工作。此外,UNIX的工具都是以command line為介面,非常適合寫script做自動化的操作。而在Windows的世界中則完全不同,Windows上的軟體傾向於提供整合式的GUI環境,把所有相關或可能會用到的功能全都一手包下,雖然方便使用者,可以點幾個按鈕就自動做完所有事情,但對於程式設計師來說其實不是一件好事。

以寫程式的工具來說,在UNIX下可以選自己喜歡的文字編輯器,不管是Vim或Emacs,也可以選自己喜歡的compiler,可以用makefile加上command line工具自動化整個程式編譯、測試、執行的流程,並且隨時都可以加入shell script或是perl script把開發流程中瑣碎的工作一併自動處理,不管需求有多麼特別,這種完全自訂的流程彈性可以說是無限大。

但在Windows環境,主流開發軟體以整合開發環境(IDE)為主,像Visual studio這種無所不包的巨獸,對於新手來說按一個鍵就能搞定一切,不用去想底下的細節,實在方便得很。可是依賴於IDE卻有個致命缺點:只要是IDE的設計者一開始沒考慮到的事,你就沒辦法做。

舉例來說,早期visual studio不支援版本控制系統(version control system)時,程式設計師就很難把版本控制整合到開發過程中(例如說在編譯成功時自動commit、或是自動加入新的原始碼…);即使到現在visual studio已經支援了一些常見的版本控制系統,用它的人依然要看這個支援的清單包含哪些系統,如果是想用新的系統,或是用非標準的方法使用這些系統,恐怕只能遺憾的兩手一攤什麼事也不能做。有些IDE雖然有提供plugin功能(像是Eclipse),但其實也沒好到哪,因為IDE龐大無比,寫plugin的難度和所需時間遠高於使用者手動完成這些日常瑣事所花的力氣,自然不會有多少人願意去做。

簡單來說,用IDE的話,程式設計師沒辦法掌控自己用的工具,也沒辦法改善開發流程中的問題,開發效率的極限很自然會被IDE限制住。但UNIX上的環境就不一樣了,採用多種工具的組合讓自己能掌控開發流程中每個步驟。因為每個步驟和所用的工具都是透明的,只要有需求或是發現哪裡可以改善,很容易可以從滿手的工具中抓出一個來解決,或是寫個迷你的script來自動處理較複雜的工作。即使哪天有新的小工具出現(例如說一個新的版本控制系統),因為每個小工具都是獨立運作,靠程式設計師自行整合的,所以也比較容易把舊的「零件」替換掉。除此之外,open source興起後,帶有原始碼的系統更帶給程式設計師一個「完全控制」的機會,除了能替換零件外,有能力的人還能直接對零件本身做修改以符合自己的需求。種種因素加起來,讓程式設計師不再被單一個工具能力所限制,而是手中握有無數可以自由運用的籌碼,唯一的限制只有自身的創意和熱情而已。

狗食是生產力的關鍵

我一直覺得念資訊系的人不應該依賴於用IDE寫程式,當然這並不只是因為「用command line才是真男人」這種geeky的理念,而是念資訊系的應該要能擅長於「把電腦能做的事交給電腦做」。今日的軟體介面大多是以多數的日常使用者為目標,雖然方便操作,但設計者不可能把所有使用者可能會想做的工作列表做出各種排列組合放在選單裡。如果是設計者沒考慮到的功能,使用者往往也只能手動慢慢處理。但程式設計師和一般使用者是不同的,程式設計師的能力就是和電腦溝通,讓電腦用我們想要的方式幫我們完成工作。如果我每天要重複按照順序按100個不同的按鈕,為什麼不寫個程式自動按這100個按鈕?

我跟一些人聊過這個想法,但典型的反應是「正事都做不完了,哪裡有時間先做一個工具?」

但我覺得很諷刺的是,正是因為抱持這種觀念才會讓生產力低落,所以讓正事做不完,時間越緊迫就越不敢花時間做這種沒有立即產出的事情。相反地,如果在意識到自己已經三番兩次手動重複執行同樣的冗長工作時,就應該靜下來好好想想是不是有什麼辦法可以讓電腦來做這些事,只要常有這種想法,寫這些script和小工具所節省下來的時間和自己得到的經驗是一輩子都用得上的。

現在有許多open source軟體一開始都只是程式設計師為了方便自己所寫的小工具,在做正事的時候撥出時間先做好工具,然後不知不覺可能就成了偉大的軟體。最有名的例子是Knuth為了寫他的The Art Of Computer Programming,他竟然先重頭自己打造一個針對數學環境設計的排版系統,最後就成了著名的TeX。他不但完成了電腦科學界的聖經,還「順便」完成了一個經典的排版系統並分享給全世界使用。

如果持續抱持著這種態度寫程式,說不定你我也能成為下一個Knuth呢? (笑)

(待續)

44 thoughts on “追求神乎其技的程式設計之道(十)

  1. Pingback: Tweets that mention 追求神乎其技的程式設計之道(十) | vgod’s blog -- Topsy.com

  2. Pingback: Tweets that mention 追求神乎其技的程式設計之道(十) | vgod’s blog -- Topsy.com

  3. 不得不驚歎這篇文章的洞察力!

    作為一個大陸電腦系的學生和微軟的實習生,我一直是Windows/Visual Studio的堅定擁護者,相信只要Linux或者編譯調試工具鏈能做到的事,Windows或Visual Studio同樣能做到。這篇文章終於說服了我,讓我理解了為什麼專業的開發者應當在Unix/Linux環境下開發。感謝這篇文,流暢的論證,自然的語言,不愧為MIT的高材生!

  4. 心有悽悽焉
    或許或說:「正事都做不完了,哪裡有時間先做一個工具?」
    只是習慣了吧!

    不管多做一個工具,或少做一個工具,
    領的薪水還是一樣多,
    加快效率,也不能提早下班,
    到是看起來比較閒了些,
    畢竟在不懂的人眼中看起來像偷懶,
    一間公司不是只有程式設計師,(如果老闆也是不懂程式的人,那可能還會被扣薪)
    可能是上述種種事實,
    造就了後期決定裝忙會找事瞎忙的程式勞工吧!

    如果我每天要重複按照順序按100個不同的按鈕,為什麼不寫個程式自動按這100個按鈕?
    ========
    程式勞工會問說:「如果我寫了個程式按了這100個按組,那我接下來的一百分鐘要靠什麼裝忙?」

    • 換個角度看,提昇工作效率後,省下的時間還是自己的。你可以超前老闆預期的進度,再依據老闆的個性決定要回報給他多少進度,多出來的時間可以悠閒地研究自己有興趣的東西,或是把以前的程式重構得更好。無論拿來做什麼事,都比瞎忙好,您說是吧? :p

    • 我最近在想,畢業其實是不應該找一份與本科有關的工作。
      其一,無論走到那裡,是大公司或是 start-up 公司,你自己都沒法子決定所有事情。每件工作派下來的作法很多時已經給上頭定好了。實在有太多限制。並不是你想幹什麼,就能幹什麼…。(除非你自家開一間公司…)
      其二,工作上已經每天八至十小時面對著電腦的工作,再如何高漲的熱情也會冷卻掉吧?我想說的是,放工後,那就沒有動力在家作自己有興趣的小 projects 了。

  5. 其實有人提出另一種講法: Drink Your Own Champagne (喝自己的香檳)

    另外,整篇都 s/程式設計/系統管理/g 其實也講得通 :p

  6. 個人淺見:專就寫程式來說,演算法的能力和模組化的能力是兩碼子事,就像是裝潢技工與室內設計師的差異。開發大型系統的情況下,生產力傾向取決於模組化的能力。

    一百支一百行的演算法程式,直接拼湊起來終究不會是一個一萬行的系統。很多程式設計師數學底子很好,可以設計很棒的演算法,可以用很短的程式碼實做出演算法,卻不見得擁有把一支程式寫到一萬行的才華。資訊科學有一個神祕的領域,叫做「軟體工程」,就是在研究把一支程式碼寫到一萬行之後會發生的現象,以及研究如何集眾人之力把程式寫到一萬行。你可以參考看看。:)

  7. 我想問一個關於運用或撰寫工具的選擇問題,因為在linux環境底下常會動手寫一些工具來幫助自己或是自娛,舉例而言,我自己嘗試寫過一個http proxy來上網和wget,可是google之後發現已經有類似的軟體如squid等,只要設定、編譯、blah blah、最後背景執行,功能往往更加豐富或是觀看其原始碼、演算法常寫得比自己簡單俐落,令人驚嘆。因而常常會想說到底該了解原理後就踏在前人肩膀上使用現成工具,還是說該自己動手寫,經歷一下那段辛酸但有成就感的過程呢?(前者當然可以說是懶,但不得不承認有時候後者也蠻耗費時間的。)

    • 我只能說閱讀別人的 source code 是一個很好的體驗。
      如果那個工具已經做到你想做的東西,就用吧;否則,自己動手吧!
      千萬不要用一些很拙劣,很 awful 的 workarounds to “patch” the existing tools such that you get your work done..

  8. Pingback: Sikuli帶來的意義與無限的潛力 | vgod’s blog

  9. 這篇文章的某些理念,跟汽車界的手排、自排之爭,有著相同的煙硝味。真男人堅持手排,且可以舉出自排的種種缺點,例如動力傳輸損耗、換檔速度過慢等。但曾幾何時,這些聲音越來越小,而且在雙離合器自手排的系統推出後,以實力證明了後者的優越性。
    沒錯,你要利用高超的跟趾技術,才能在彎道展現絕佳的動態,所以你需要手排變速箱。問題是,如果自排也可以模擬跟趾動作、在降檔的同時幫你補油,而且每次的動作都毫無誤差,這不也一樣達成目標嗎?現今的自排變速箱甚至可以模擬不同情境,讓你在一般道路、濕滑路面、或競速的條件下運作,說穿了,就是黑箱作業,讓使用者方便就好,專注於你手握的方向盤,雖然使用者不知道細節,但總比你開著手排、在結冰的路上失控要好,不是嗎?
    不使用IDE?別鬧了!這篇文章提到多數工具、或理念,我都明白、也表示贊同,但我仍然堅持使用IDE才是正確的,原因是什麼?生產力罷了!早期的VC不支援VSS,但現在呢?按個右鍵就能處理許多版本控制的事情,多人一起工作時更顯出完整整合的便利,而且新版本Team Suite甚至做的…該怎麼說呢?太超過!就是這個意思。
    IDE不是只有微軟一家的專利,就像文中提到的Eclipse就很棒,而且免費。我不需要為任何廠商或產品背書,我提出的只是:使用IDE開發是正確的方向,雖然他會有副作用(不再撰述),但我只能說:瑕不掩瑜囉。

    • 以我所知,他們也是在用「IDE」,不過是用他們自己「組裝」出來的「IDE」,就像組裝電腦那樣。
      (我正在學習中)

      你所說的「手排」跟「自排」之爭,其實這篇網誌文所倡導的是「自排」,程式師本身就有能力製作、改進和創造「自排」。

  10. Pingback: 我的外星人老大 | 咪咪米米愛編劇

  11. Pingback: 《追求神乎其技的程序设计之道》读后感 | 封朋成|Pengcheng Feng's Homepage

  12. 看到不使用IDE 感觸頗多….之前寫C…可以用手key 現在微軟極力推行的C# 光屬性,方法就超級多,命名方式又臭又長,不用IDE 基本上跟本沒辦法作業,雖然一樣也可以靠手KEY,但光翻書查詢或是因為不小心KEY 錯,DEBUG 兩三天才發現原來是某各屬性或方法名稱KEY錯是常有的事

    該說…微軟應該要改進嗎!?

    另外復合上頭某位同行說的工作上司非資訊概念問題,這在台灣很常見….沒錯我可以把進度超前…時間上可以做其他的事…但是事情永遠做不完的…因為老闆上司未必能跟你有同樣的知識….職場沒辦法拋開其他事務只專職在自己職務上的事情…還是算多數的

    • 此乃人類共通的劣根性:又賤又懶惰
      程式設計師的懶惰是有目的的,是經過大腦思考過的,是為了更有效執行某事物深思熟慮下所得的結論,與Larry Wall提倡的懶惰道理是一樣
      為了有效率執行某事物需要考量優化許多細節,作大量的人腦運算 (思考本身就是一種人腦運算),重複許多表面看似無趣但,其實程式設計師的懶惰,本質上是傾向心力交瘁

      相反地,人性本惰的惰是指:好逸惡勞,崇尚安逸享樂,排斥大腦思考
      這個勞不是身體的勞動,而是大腦心理方面深層的人腦運算思考
      這是所有人類必需坦然承認接受且努力抑制與對抗的天生劣根性,無法移除與改善,只能加以抑制與對抗
      熱情就是一個抑制與對抗人性本惰的有效手段,這方面Stephen Hawking是佼佼者,一個值得所有人學習效法,大半輩子都在抑制與對抗人性本惰的典範

      所以,谷歌,蘋果與微軟坐大的根本原因不是文化,不是人為操縱,也不是經濟;而是更深層的原因:人性本惰 (好逸惡勞)
      一個好的管理者需要考量許多方面,作許多決策,本質上就是大量的人腦運算思考
      看清這層道理就能理解上司與管理者的懶惰無能
      即使是白領管理者階級,卻比每天流汗的藍領階級更加懶惰;不是因為藍顉階級要出力流汗看似比較勤勞,而是因為藍顉階級也常常要動腦思考,但是管理者卻不動腦思考,把動腦思考都推卸給屬下了
      同樣地,也是因為人性本惰才會出現這種:不用學數學,或不用有紮實的數學根基也能當程式設計師的荒謬言論

      回歸正題,早在2005時,連大師級人物Charles Petzold都已公開發表厭惡微軟了,台灣還在抱Wintel的大腿真奇怪
      下面是部分的公開發表(最後幾段),大師的文章連結: http://www.charlespetzold.com/etc/DoesVisualStudioRotTheMind.html

      I decided to use plain old ANSI C, and to edit the source code in Notepad — which has no IntelliSense and no sense of any other kind — and to compile on the command line using both the Microsoft C compiler and the Gnu C compiler.

      Even after this preliminary process, there’s still coding to do, but there’s no APIs, there’s no classes, there’s no properties, there’s no forms, there’s no controls, there’s no event handlers, and there’s definitely no Visual Studio.

      It’s just me and the code, and for awhile, I feel like a real programmer again.

  13. UNIX是Programmer的天堂

    那能解释一下为什么 Windows 平台的软件比 UNIX like 平台的还要多么?
    做过 Linux 的,很快陷入 Linux 的配置中。
    而 windows 却不需要配置就可以拿来用。

    • Unix Like 不等於 Linux,Linux 也分很多 distro,有合適初學者也有合適老手,MacOS X 也算是 Unix Like.

      為何 windows 平台軟件多 ?
      windows 程式以 GUI 為主,A 程式做不到某些功能時,你就需要去找 B 程式… 在 Unix 下面不同,很多需求是由 “現有的” 程式去組成一個新的應用 (軟件)。這樣說來,”假若” windows 的軟件真的很多,也不足為奇。

    • 此乃人類共通的劣根性:又賤又懶惰
      程式設計師的懶惰是有目的的,是經過大腦思考過的,是為了更有效執行某事物深思熟慮下所得的結論,與Larry Wall提倡的懶惰道理是一樣
      為了有效率執行某事物需要考量優化許多細節,作大量的人腦運算 (思考本身就是一種人腦運算),重複許多表面看似無趣但,其實程式設計師的懶惰,本質上是傾向心力交瘁

      相反地,人性本惰的惰是指:好逸惡勞,崇尚安逸享樂,排斥大腦思考
      這個勞不是身體的勞動,而是大腦心理方面深層的人腦運算思考
      這是所有人類必需坦然承認接受且努力抑制與對抗的天生劣根性,無法移除與改善,只能加以抑制與對抗
      熱情就是一個抑制與對抗人性本惰的有效手段,這方面Stephen Hawking是佼佼者,一個值得所有人學習效法,大半輩子都在抑制與對抗人性本惰的典範

      所以,谷歌,蘋果與微軟坐大的根本原因不是文化,不是人為操縱,也不是經濟;而是更深層的原因:人性本惰 (好逸惡勞)
      一個好的管理者需要考量許多方面,作許多決策,本質上就是大量的人腦運算思考
      看清這層道理就能理解上司與管理者的懶惰無能
      即使是白領管理者階級,卻比每天流汗的藍領階級更加懶惰;不是因為藍顉階級要出力流汗看似比較勤勞,而是因為藍顉階級也常常要動腦思考,但是管理者卻不動腦思考,把動腦思考都推卸給屬下了
      同樣地,也是因為人性本惰才會出現這種:不用學數學,或不用有紮實的數學根基也能當程式設計師的荒謬言論

  14. 狗食是生产力的关键颇有同感,这就是时间管理的第二象限,重要但不紧迫,但是如果不处理这类事件,就可能转化为第一象限了.

  15. Pingback: 微風夕語 — [Scala][狗食] 在工作列上顯示 CPU 的溫度。

  16. 你好!我是一個高二生…剛看完你的文章,覺得自己好渺小….QQ
    看到你在高中階段就已經有如此成就,讓我敬佩不已!!

    我也是從遊戲慢慢對電腦有興趣,進而想自己寫遊戲出來
    但我是從高中才開始接觸程式設計,現在只會C++和VB的初階語法,也參加過比賽
    我很喜歡寫程式,但是學校的課業就讓我應付不來,又沒有像你那種保送大學的決心..

    我從你的第一篇文章開始看,覺得很有動力,但看到最後,就感覺自己離程式設計還有很大一段距離= =
    不知現在專注拚課業,到大學在專心研究程式設計會不會來不及??
    還有目前要先專研一套語言,還是每種都要會一點??

    看了你的文章很感動^^

    • 考量到你已經高二了,但仍然不確定自己的方向,那專注在現在的課業上可能是比較好的選擇。到大學再來研究程式設計絕對不會太晚,很多高手都是半路出家,在大學時念的專業跟電腦甚至沒什麼關係。不太需要擔心什麼時候開始才是正確的,重點是要專注和喜愛你現在做的事,不管做什麼都要用盡全力,這樣自然就能做好每一件事。
      同樣的道理,如果要學程式語言,先專注精通一個語言,之後要學其他的都是易如反掌。

  17. 看完vgod的故事,
    我覺得超精采,
    真的可以找人拍成電影,
    相信會比社群網戰更夯!
    加油~~~~

  18. Pingback: 程式設計 | 深海大章魚

  19. Pingback: Lagos State Safety Commission joins the rest of the World in Celebrating the ILO themed, World Day for Health and Safety at Work

Leave a Reply

Your email address will not be published. Required fields are marked *

*