Sikuli帶來的意義與無限的潛力

Saturday, January 30th, 2010 | 瀏覽:5,551人次

這禮拜真是我人生中最瘋狂的一天了..。

自從Sikuli發表後,我本來還打算一封封回覆所有的問題,後來發現排山倒海而來的郵件和留言速度遠大過我能閱讀和回覆的量。前幾天我優先把Sikuli比較大的bug和一些平台問題修掉,昨天釋出了0.9.7讓各平台都提升到同樣的版本(只剩Linux還是沒有抓圖的快捷鍵了),整體運行的速度也提昇了不少,並且新增了一個.skl格式讓人能透過command line或double-click直接執行script。如果之前下載過舊版的朋友強烈建議升級到0.9.7。

修完緊急的bug後,我們會再陸續補上一些文件和教學,說明一些常見的問題要怎麼解決。例如說,畫面上有多個一樣的元件(像check box, radio button)要怎麼處理如果按特殊鍵或是在不同的鍵盤排列上使用(用dvorak的人還真不少,一堆人跟我說type()在dvorak上會有問題)..。

但這篇文章中我想談的不是被上萬人盯著的壓力,而是關於Sikuli能帶來的改變,以及未來的潛力。

有些人說Sikuli看起來只是另一個按鍵精靈或是AutoHotkey,但其實Sikuli還有許多在這個直觀意義之上的潛力我們沒直接說出來。

第一,Sikuli最重要的革命是程式碼的可讀性(readability)和易用性(usability)。把螢幕截圖直接放在程式碼裡面,讓人能直接「看到」他想控制的東西,這是從來沒人想過的事情。以往的方法,不管是透過應用程式自己的程式介面(API)或是透過XPath拿到網頁裡的某個元件,都是只有程式設計師才能寫、才能讀懂的神秘外星語言。機器喜歡精確的語言,人類花越多力氣把事情描述的越清楚,機器就越容易讀懂。

可是,有沒有人想過,人類發明這麼多程式語言來操控電腦,究竟是便利了人類還是便利了電腦?現在我們每天用的程式語言,不管是C++、Java、C#、Python、Javascript..都是只有程式設計師才能寫才能讀的語言。更諷刺的是,這些「現代」語言跟五十年前就有的LISP、Fortran本質上並沒有什麼不同,一樣都是純文字,一樣要求精確嚴謹的語法,一樣是架在百層高塔的系統架構上。即使是訓練有素的程式設計師,要寫程式做些有用的事情也都得先翻翻充滿黑話的說明文件,看看需要的功能對應到什麼函式,運氣不好可能還得學個COM+之類的鬼東西才能使用。

如同我在追求神乎其技的程式設計之道(十):程式設計師的生產力之謎中提過的一樣,即使同為程式設計師,運用電腦的效率依然會有數十倍甚至百倍的差距。如果每天都要按一百個按鈕,程式設計師可以找到適合的命令列工具使用,或是自己寫程式呼叫應用程式提供的函式,就可以用一個按鍵取代這一百個按鈕。那完全不懂程式的一般使用者呢?恐怕只能兩手一攤任由別人寫好的軟體擺佈。也就是說,即使一個人掌控了鍵盤和滑鼠,但實際上卻是被別人的軟體限制住,如此使用電腦其實完全沒有自由可言。

Sikuli的革命把寫程式的門檻降低了,人們和系統或應用程式溝通不再需要讀用黑話寫的文件,也不用搞懂底層的架構是怎麼做的,只要把平常使用鍵盤滑鼠的方式,再加上想控制目標的螢幕截圖,就可以輕易寫成能自動執行的程式。

Sikuli Script範例

除了好寫外,任何人看程式和圖都能很容易讀懂程式到底做了什麼事,於是Sikuli很自然就能成為一種寫教學文件的最佳媒介。以往的教學文件常常step by step列出使用者要做的事,加上使用者應該要看到的畫面,很巧的是這兩者Sikuli script都有。但比傳統的文字描述更好的是,只要把Sikuli的指令混用在文件中,或是透過簡單的對應把文字描述轉成script,這樣一份文件不只人能看懂,連電腦都能執行這些步驟並且一步步告訴你要按的按鈕在哪裡。

第二,除了直觀上的GUI自動化外,其實Sikuli更重要的意義是提供了一種把使用者操作UI的互動過程記錄下來的新方法。以程式設計師的黑話來說,這可以說是GUI操作過程的serialization,如果用一般人的方法說,這就是把人機互動過程「數位化」的一種方法。

電腦發展的過程中,一條必經之路就是把人類周遭的一切資訊全部數位化。一旦資訊被數位化,就可以輕易儲存在電腦裡,或是透過網路分享給別人,電腦科學家也才能發展更多方法來處理、分析、運用這些資料。在21世紀的今天,人們把聲音、影像、文字全都數位化了,所以我們可以輕易的複製、傳播、使用這些資訊。但在人們如此依賴電腦的今天,人和電腦的互動過程其實一直沒有一個好方法可以記錄,所以更別提要複製或是分享這種互動過程。

而Sikuli在這個人機互動領域開了一條全新的道路,這也是為什麼Sikuli的論文是出現在「User Interface Software and Technology」的會議上,而不是在討論程式語言的會議上。

人機互動的過程一旦能被一個標準的方法記錄下來,接著就能複製,就能分享,就能讓電腦自動執行或是演算這些過程。未來的應用方式有千百種,唯一的限制只是看我們的想像力而已。

第三,Sikuli把電腦視覺的研究領域,從真實世界延伸到電腦的桌面上。這點說起來真是很有趣,電腦視覺的研究人員數十年來嘗試想讓電腦能像人一樣「看」這個「真實世界」,可以像人一樣認得別人的臉,或是認得馬路長什麼樣才能讓電腦自動開車,但卻沒什麼人想到讓電腦「看」電腦自己輸出的畫面。在技術上來說,電腦螢幕上的資訊全都是電腦自己產生出來的,沒有光影問題,沒有角度問題,辨識上的難度遠低於真實世界所需的難度。以現在的電腦視覺技術來說,辨識螢幕上的東西簡直可以說是殺雞用牛刀。

Sikuli把電腦視覺和人機介面兩個研究領域打通了,有很多古老的問題(例如OCR,文字辨識)在真實世界很難解決,但在電腦桌面上卻可能可以發展出又快又準確的方法。Sikuli也可能激發更多人把電腦視覺應用到軟體介面上的創意,讓使用者介面不只是簡單使用,也能讓每個人能真正隨心所欲的操控電腦。

第四,建立在Java平台上並且open source的Sikuli,很有潛力能讓每個人都能打造給自己的專屬程式。

Sikuli不只是提供了一堆自動按滑鼠和按鍵的指令集而已,每一個Sikuli script都是一個和Python語法相容的程式。這意味著你可以使用任何的Python語法,不管是迴圈、if、定義function、或是定義class,每一個Sikuli script都是一個真正的Python程式(嚴格來說,應該是Jython,但這中間的差別並不太重要)。除此之外,Sikuli核心是跑在Java平台上,所以可以輕易的使用任何Java的函式庫。例如說,你可以用swing建立一個新的視窗包含了兩個按鈕,按下第一個就用Sikuli執行每天上班前的例行工作,而按下第二個紐則執行下班前的例行工作。會寫程式的人可以輕易混用Sikuli和現有的函式庫,把Sikuli當成和系統或其他應用程式溝通的媒介,並在上層建立自己的新介面。也就是說,這就是桌面環境的mashup,可能的應用是無限大。

雖然不懂程式設計的人,難以撰寫複雜的GUI程式或是資料處理。但Sikuli結合了現有的平台並且open source,這樣的好處是會有來自世界各地有閒有能力的人幫忙讓Sikuli變得更簡單更好用,並結合其他的程式語言或是函式庫讓寫程式的整體門檻大大降低。

雖說Sikuli現在還不是那麼完美,但我相信open source會加快Sikuli的發展,讓更多有興趣的人進來幫忙。很多技術上的問題其實都好解決,例如有人問到是不是桌面換個skin後script就廢了,或是能不能在背景執行script。這些問題其實都有好幾種可能的答案可以解決,只是有沒有必要現在就做而已。技術問題向來都不是能阻擋我的絆腳石,真正困難的只有突破自身創意和想像力的界線而已。

每個人使用電腦的方法都不同,軟體公司設計的軟體也只能按照大部分使用者的需求和習慣所設計。但不論有多少功能,總是不可能涵蓋到每個人的大大小小需求。讓每個人都能寫程式(不論他們是不是知道他們正在寫程式)是我一心嚮往的目標之一,或者說是我希望每個人都能100%按照自己的意願花最少力氣完成最多工作。但在今天的電腦環境上,不會寫程式就有太多事都無法做到,即使會寫程式的人,也不見得願意花那麼多力氣去研究讓自己未來更省力的方法。

這個問題的癥結不在於使用的人太懶惰或是不夠聰明,而是電腦太難用。一個人得經歷幾年的訓練才能熟悉這種用程式「掌控」電腦的感覺,實在太不合理。或許沒有人想研究讓寫程式變得更簡單是因為怕丟了自己的飯碗,但我偏偏就覺得每個人應該要有聰明使用自己工具的自由,而不是反過來被工具限制了自己。所以,我希望Sikuli能讓更多人把使用電腦的自由搶回自己手中,而不是被軟體工程師們掐住脖子動彈不得。

寫到最後,能參與Sikuli這個project其實最需要感謝的人是和我合作的Tom Yeh,在我進MIT前他就在跟我老闆Rob Miller討論用螢幕截圖來搜尋文件的可能性,所以其實在我還在當兵時我們就已經搭上線開始合作了。後來我到了MIT後,一連串的討論就激發出許許多多混合螢幕截圖和電腦視覺所產生的點子,其中第一個成果就是現在的Sikuli。

Sikuli Script只是這一串研究的開端和基石,在這之上其實我們還做了很多東西。例如說我們已經有一個能錄製螢幕和使用者動作的程式,可以把使用者的動作自動轉換成Sikuli Script,也就是說使用者一行程式都不用寫,只要把想做的步驟做一次,程式碼和螢幕截圖就會自動產生出來讓你修改或直接使用。用這個錄製程式,我們可以輕易的在現有的GUI系統上觀看全系統的操作歷史,甚至是自動redo某一部分操作。有這些系統做基礎,我們能做的事情實在太多了,我只怕自己時間和能力有限,沒辦法把所有的點子都做出來。所以,這也是我們把Sikuli公開的目的,希望開放這塊寶石後,能有更多人發揮想像力發明出更有趣更有用的東西來,並徹底打破現今使用電腦的方法,一起來改變世界吧!

Change The World!

Monday, January 25th, 2010 | 瀏覽:16,553人次

之前一直沒機會跟大家分享我在MIT到底在做什麼研究,但拜登上MIT首頁的一篇報導「Picture-driven computing」所賜,我這兩年的project Sikuli像原子彈爆炸一般透過slashdot和twitter以不可思議的速度擴散開來。而這幾天,剛好碰上學校每年都會舉辦的滑雪三天三夜旅行,我照著計劃坐上遊覽車到四小時車程外的緬因州滑雪。第一天晚上到旅館發現沒網路可用,只好早早上床睡覺養足隔天的精神。到了隔天中午,在雪場的餐廳吃午飯時,我想說該來試試有沒有網路用,於是拿出ipod touch連上網後,沒想到迎面而來的是近百封關心sikuli的郵件。在震驚之餘,我還沒意會過來到底發生什麼事了,直到我看到一封來自跟我同實驗室的學長Michael發給實驗室所有人的信,標題寫著:「Sikuli on Slashdot!」,接著我才意識到:啊!原來是遭到slashdot effect攻擊了!(slashdot是全世界關心科技、網路、電腦技術的人幾乎必看的網站,只要某個網站一被登上slashdot,馬上就會遭到來自世界各地數以千計的閱覽攻擊,其效果等同於分散式阻斷服務(DDoS)攻擊,而這現象就被稱為slashdot effect。我以前都以為只有網站會有突然出現的巨大流量,沒想到連我的信箱也會…)

在這件事情之前,我從沒體驗過媒體和網路的力量可以有多麼驚人。從MIT News發出的一篇報導,隔天被轉載到一小部分科技、技術網站,並且在twitter上開始有人開始口耳相傳這個新玩意。再過一天,有人把這消息推上了Slashdot: MIT Offers Picture-Centric Programming To the Masses With Sikuli,很快的sikuli這名字開始傳遍世界。我在twitter上搜尋了sikuli,想看看人們都說些什麼,結果看到由各種不同語言寫的tweet不斷湧出,就在我還沒看完一頁時又冒出 「xx more tweets since you started searching」 的訊息。搜尋出來的tweets除了絕對多數的英文外,也看到很多俄文、法文、日文,反倒是中文的消息最少,實在讓我有點哭笑不得。(關於訊息的傳播,我也透過這次的事件觀察到不同國家對同一事件反應的一些有趣現象,以後再另寫新文跟大家分享。)

人在偏僻的山中滑雪,突然看到這麼多人們在討論著我的project,還有信箱裡塞滿各種關於sikuli的問題,讓我興奮得不得了。當時我的心情其實完全顧不得滑雪了,但難得的旅行還抱著電腦一直坐在餐廳裡實在也有點可惜,只好趁著有網路時把每封信大略瀏覽一下,下午就趁著坐纜車上山的空檔想想怎麼回覆這些郵件。

太陽下山後,我終於按奈不住卸下裝備就拿著電腦回到餐廳裡繼續連上網,結果又是更多的郵件湧入、更多的tweets、更多的衝擊。而當初把sikuli open source的決定,也讓我接到來自世界各地開發人員的意見和回饋,有人在一天內幫我把Linux上還沒實作的幾個功能寫完並送了patch給我,也有人為了在它的64-bit Windows上執行而直接hack了沒有原始碼的二進位EXE wrapper。除了寫程式的人外,有專業的user experience designer願意加入,也有人志願幫忙移植到Linux的工作。看著這些不知道什麼時候才能回完的信,我突然發現,我似乎真的做了一件不得了的事….。

在MIT裡其實常常能看到許多很驚人的點子,但可惜的是即使在MIT,大部分的東西也都停留在為研究而做的雛形階段,研究人員雖然產出了論文,但如果沒有對的人讀到那些文章,很多好點子也不過是停留在紙上變成可回收的資源而已。

Sikuli的論文其實在去年九月就在ACM關於user interface中最頂尖的會議UIST上發表了,在當時還拿了Best Student Paper Award,但為什麼一直到今天才突然爆發開來變成人們口中「革命性的新發明」呢?

說起來這還是得感謝MIT有自己的News office,一個記者剛好問了我老闆最近有沒有什麼有趣的研究,於是sikuli這個字就從這篇報導散播開來。但除此之外,我也蠻慶幸之前自己決定要把sikuli release出去,而且老闆也很支持我這麼做,整學期都沒問我「研究」上的進度。(把程式release跟研究本身沒什麼關係,有些教授對這些研究結果的實作是否能實用也不太關心,甚至覺得做這些事是浪費時間。)

其實一般人可能很難想像,要把一個研究用的雛型打磨到能夠公開讓任何人用的程度,所花費的力氣可是遠超過寫出最重要的核心功能。我花了幾個星期研究怎麼把Java程式包成Mac上的.app,研究怎麼把.sikuli變成能夠點兩下就打開的document package,怎麼把sikuli會用到的一大包dynamic libs包進.app中讓使用者不用安裝其他的相依函式庫…。搞定Mac後,我又花了一陣子把Sikuli移植到Windows上,雖然上層是Java寫的很好解決,但有部分程式碼是透過JNI連結到C++呼叫OS提供的API才能完成的。因為我一直都用Mac開發,所以這些東西本來都只有寫Mac版的,但為了要真正讓多數人能用這個軟體,只好跟老闆要了一台PC裝上Windows來完成這些相依平台的程式碼。Windows並不是我熟悉的平台,除了國中時玩過VB外,之後就幾乎沒在Windows上寫過什麼程式了。所以為了搞定Windows的移植,除了得速成學會一些Windows API外,還得搞定DLL+EXE的包裝,最後再包成installer讓人能一路按Next就裝完整個軟體。雖然這些事情我都是第一次做,但還好沒遇到太多困難,即使每個禮拜都要花兩三天寫Distributed Algorithms的作業,剩下的時間也剛好夠我處理完這些瑣碎的工作。

完成Mac和Windows初步的包裝後,我也一邊開始做網站、API文件,也請跟我合作的Tom一起寫了一些教學文章,順便讓實驗室的同學們當一下測試的白老鼠。因為周圍沒什麼人用Linux desktop(真是有點出乎意料?),所以Linux版就暫時被我擱著沒動。
後來大家都去放聖誕假期時,我趁著空閒做了一個demo的影片放到youtube上,但因為我也還不急著釋出public beta,所以也沒跟其他人說我做了這個影片。

就在MIT News來採訪的前幾天,0xlab剛好有幾個人突然寫信問我有沒有Linux版的sikuli。雖然不知道他們怎麼發現的,但看到有人想用我也就有了勁想把Linux版趕快完成。花了一天在我新要來的PC上裝好ubuntu後(還包含一個小時在搞定這台電腦的無線網卡driver…。沒想到到了2010年我竟然還在做這種事情…),再修一修Makefile後就包了一個功能不全的Linux版放到網站上。

有句話說「機會是留給準備好的人」。當sikuli被公諸於世的時候,之前做好的事情就突然就派上了用場。MIT News促成了這個好機會讓sikuli這個很酷的想法脫離UI研究會議的小圈圈,進入世界上有網路的每個角落,這時我之前憑著一股熱血就自顧自的作了這麼多的雜事,突然都有了它的意義。於是,在機會到來時,demo的影片加上能下載試用的軟體讓人們親眼看到並且能把玩這個革命性的點子,結果就讓twitter上充滿了一大片的「holy crap this is awesome! http://sikuli.csail.mit.edu」。

我一直夢想著要做些不一樣的事情來改變世界,徹底發揮我的長處做出能夠對世界產生巨大影響力的東西。還記得三年前我在申請MIT時,在SOP上大膽的寫了我的目標「I believe that programming environments should be smarter and more intuitive, and it is my goal to reinvent one that allows beginners to learn easily and adepts to be more productive.」,而三年後的今天,我非常興奮我踏出了改變世界的第一步。

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

Thursday, August 13th, 2009 | 瀏覽:62,953人次

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

最近被很多人提醒這個神乎其技系列停在第八集很久了…(汗)。其實這集草稿已經存很久了,今天總算決定要把它告一段落後貼出來。

先來個題外話,台灣最近遭受莫拉克颱風帶來的巨大災難之苦,雖然我人不在台灣能幫上的忙很小,但還是希望災區的所有人都能平安度過這次災難。

高中到大學

春天的國際科展結束後,我的高中生活也即將劃下句點。回顧高中三年,從校內的資訊比賽一路走到奧林匹亞的國際舞台,在保送大學資格的保護下,到高三又誤打誤撞變成國際科展的代表。雖然從結果看來一切都是如此美好,但在我剛升上高中時,沒有人知道未來會發生什麼事。我爸媽只想要我好好唸書,考上好大學;而我對學校教的科目早已失去興趣,每天都只想泡在電腦前探索這個神秘盒子的內部。於是每次考試結束,家裡就會因為我的爛成績而引發一次大戰,我爸媽也會一再的限制我坐在電腦前的時間。

就像七龍珠裡的標準情節一樣,悟空總是可以和敵人奮戰到垂死邊緣才爆發出最後一擊取得勝利,我總覺得在逆境時才能看出一個人真正的意志力和求生能力。雖然我爸媽能不斷縮減我能用電腦的時間,但他們可沒辦法限制我在學校做什麼或是面對課本時心裡到底在想些什麼。我還記得高一時,我天天都帶著Introduction To Algorithms(當時還是第一版,很多人叫它白皮書)到學校,不管上課時老師講得多麼口沫橫飛或是下課同學們玩得多開心,我都是看我自己的書。有時碰上管得嚴的老師,我就不看書開始想ACM的題目,用筆在白紙上寫code。我還記得當時為了手邊要隨時有充裕的題目可以想,我把ACM online judge上所有的題目全都印了出來放在一個資料夾裡隨時帶在身邊。

現在想想我那時瘋狂的程度真是難以想像,我當時心思幾乎完全沒放在學校課業上,就連體育課我都躲在樹蔭下想題目的解法。於是到了要升高二選類組時,家裡又爆發了第N次的世界大戰。

還記得升高二前有個考資優班的機會,我爸媽非常想要我去考考看,但我死都不答應。我很堅持的原因是,中一中的數理資優班非常奇怪,進去後就自動變成第三類組,也就是要多念一科生物,但我已經很確定未來我只想念資訊相關的科系,所以我只想選二類,不想浪費時間多念一科生物。就為了這件事,爭執的戰火延伸到我花太多時間在電腦上未來會考不上好學校之類的陳腔濫調上。

台灣父母似乎都想要孩子選擇他們覺得的安全、穩定的路,但我大概天生叛逆了點,說什麼都只想堅持自己的路。不管成功的可能性有多小,或是風險有多大,我覺得我就是應該照著心中的聲音去走。跟他們吵了一陣子後,我決定跟他們立下一個約定:讓我完全自由到高二,如果我沒辦法在資訊比賽拿到夠好的成績足以保送大學,那我到聯考前就都不碰電腦,即使我考不上大學也是我自己的決定所造成的。

從此以後,我就更認真的拼命研究演算法,研究歷年來所有大大小小資訊比賽的題目,只要我醒著的時間,腦袋就全速運轉放在這些東西上。雖然理論上我應該是背水一戰,但那時心裡其實沒有太大壓力,反而覺得可以每天都在玩自己有興趣的東西很幸福很開心,如果比賽結果不好,那可能只是說明我沒有這個天份和這個命而已。

現在回想起來,我覺得當時的我真是不怕死到了極點。要靠資訊比賽保送,至少也要進入奧林匹亞的培訓營,並成為留到第二階段的最後十人之一才有機會(有機會的意思是大學有可能會拒收…)。簡單的說就是實力大概要在全國高中生的前十名就是了。

我想我當時一定沒有想這麼多,只傻傻的做自己想做的事,所以才會這麼有勇氣立下聯考前都不碰電腦的可怕約定。還好我運氣很好,上了高二後從第一場校內賽就把我累積一年的力量爆發出來,就這樣一路打進培訓營甚至還選上國手。

順利拿到保送資格後,父母鬆了一口氣,於是就完全放任我花更多時間泡在電腦裡了。到高三時,我誤打誤撞說要參加國際科展,於是就有了正當理由請公假,各科老師對我的缺席也見怪不怪。高三我幾乎每天都待在教官室裡玩Linux、架各種系統和server來玩,雖說要做科展,但其實也是對什麼有興趣就玩什麼。(可能很多人覺得奇怪,為什麼會待在教官室… 因為教官室是少數有電腦有網路,我又能自由進出的地方。再加上當時有教官找我幫忙做網站,所以….)

到了要畢業的時候,我才發現我高三幾乎都沒踏進教室過,班上的同學我也幾乎都不認識。雖然在自己的世界裡過得很開心,但要畢業時才發現我的高中生活和其他人都不一樣。班上老師們對我也頗有微詞,所以畢業前我還碰到了一個可怕的畢業危機:我高三的學科被當了九科……。(現在想起來還真難想像,到底有哪九科啊orz…)

這件事大概是我一帆風順的高中生活中最驚悚的一件事了。雖然台大已經張開手等我進去,但要是高中不能畢業,那我不就變成比櫻木花道還悲慘的笑話了嗎…。(註:櫻木花道在全國大賽前發現被當太多科無法參賽,所以只好閉關唸書準備補考,當然最後還是順利過關去參賽,不然灌籃高手就畫不下去了。)漫畫中的主角當然不會被要補考這種小事打倒,但現實生活中誰知道呢… orz

在畢業前遭受到如此巨大的危機,實在完全出乎我的意料之外。還好當時帶我們參加比賽的指導老師非常挺我,幫我跟各科老師要一個補考的機會。學校也很好心不打算找我麻煩,就讓我把考卷帶回家寫一天。隔天交出去後我就沒再得知過關於成績的事,我甚至不知道我畢業時每一科的成績,但總之我還是拿到畢業證書了(汗)。

回想起年輕時的瘋狂,真是覺得很不可思議。如果我當時沒有堅持自己的想法,而依照爸媽的意思「好好唸書」,我想現在的我一定過著完全不同的人生,至少不太可能憑聯考進入台大資訊系,而現在也不會在MIT了..。

(待續)

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

Wednesday, March 11th, 2009 | 瀏覽:90,696人次

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

第八集終於寫完了…。雖然我寒假過得很輕鬆悠閒,但不知道為什麼人就是會在很閒的時候不做平常一直說沒空做的事,然後硬是要在很多作業和工作時開始寫blog….。雖然開學後又開始變忙了,但我到目前還是每個禮拜都跑去滑雪,這樣看來這一系列最後突然會變成追求神乎其技的滑雪之道也說不一定XD

前言夠多了,本集將繼續我在高三時朦朧無知的學習故事…。

Intel ISEF國際科展

第五集裡提到我一直以來都夢想著讓電腦學會自己寫程式。就在我把這個想法的雛型用基因演算法實做出來後,沒想到竟然真的看到了一點結果,電腦真的能透過基因演算法來產生出一個能夠正確運作的程式!

在高三時,已經取得保送資格的我對學校的課業時在沒什麼興趣,於是我想閒著也是閒著,乾脆就把這個點子拿去參加科展看看,這樣一來我就又有理由可以請公假了(笑)。當時似乎是因為已經來不及報名全國科展了,所以我就跑去報名了國際科展,但那時我其實完全不知道這兩種科展有什麼差別。後來查了一下才知道,原來台灣的國際科展除了是一種比賽外,主要的目的其實是要選出代表去參加其他國家(如美國、法國、加拿大…)的科展活動;而一般的全國科展就是一個區域至全國性的展覽兼比賽,在全國選出前幾名後就結束了。

2001年時,那時科教館還在建中對面,那也是我第一次踏進科教館的大門。在展場內把自己的海報貼上看板後,我就到處逛逛欣賞別人的作品。因為資訊科在高中不是正式科目,參加的人比起其他科來說少了許多,但其中還是有些非常驚人的作品出現。當時有個建中的學弟Eric,他寫了一個用類神經網路辨識並動態追蹤影像中人眼位置的程式,於是他就用了個普通的攝影機加上這程式,就變成可以用眼睛控制滑鼠游標的神奇裝置。

除了Eric的作品外,其他的作品看起來大多只是某種現有產品或課本上習題的複製品,並沒有什麼令人特別印象深刻的東西出現。說起來這其實也不奇怪,因為在高中階段要自己學好一個程式語言其實並不容易,在基礎還未打穩前,即使有再多創意也無法發揮出來。而很可惜的是,很多人上了大學終於學會寫程式後,創意和熱情也被磨損的差不多了;而畢業後雖然已經有了基本功力,但卻只能照著老闆開的規格刻畫死板的功能與介面,與其說是程式設計師不如說是程式工匠。

我覺得台灣人的能力並不差,但社會中卻瀰漫著一股抄襲與仿冒的氣息,從最近的酪梨壽司事件(相關抄襲事件還可參考MMDays的整理),可以看出抄襲風氣在台灣並不只是小時候在學校抄抄作業而已;媒體工作者在報導中任意抄襲及轉載是種不尊重自己專業的表現,不但隱含著一種應付了事的心態,更代表著這些人對於自己的工作沒有熱情,更沒有著一點堅持。如果要說我在美國看到這邊和台灣有什麼最大的不同,我想關鍵的差異就在對自己的工作有沒有熱情和堅持而已了。

在評審的過程中,有兩個教授一起來聽我介紹我的作品。因為我沒有任何參加科展的經驗,也沒做什麼講稿或準備就去了,一切只能靠臨場發揮,還好教授們還蠻喜歡我的作品,一來一往的討論之下才讓我不至於太緊張而說不出話來。

自己的介紹結束後,終於鬆了一口氣,教授們對我的作品似乎感到非常新奇和有興趣,後來還問了我「如果再給你兩個月,你能做出更好的結果嗎?」這問題聽起來像是要給我個機會再繼續深入研究下去,難道是意味著要選我當代表嗎?當時我對於得獎其實是沒什麼興趣和期望的,只是想看看別人對這個東西的意見,但如果有人喜歡當然是很棒的事情。這問題無非是給我挑戰的機會,我腦中還有很多改進的想法,如果有更多時間,一定還能做出更棒的結果。所以,我就毫不猶豫的就回答了:「可以,當然可以!」

到了頒獎典禮時,司儀一一宣佈每個學科的獲獎人以及之後要代表台灣去哪個國家參展,同時也頒發一些企業贊助的特別獎。我原本一直以為Eric的作品應該是穩拿第一的,畢竟相較之下我的作品並不夠成熟和完整,甚至連個能稱上科學實驗後的結果都沒有。但這個新奇的點子威力還是很大,我完全沒預料到無心插柳參加科展竟然讓我拿到了Intel頒發的電腦科學最佳獎,並且還選上了美國代表,之後可以代表台灣去美國參加Intel主辦的國際科學暨工程展(ISEF, International Science and Engineering Fair)。

程式設計之內功心法

得獎當然很開心,這是對於我這個想法和努力的肯定,但隨之而來的也是一股很大的壓力。我得代表台灣站出去,到美國跟來自世界各地的教授、學者、參展代表用英文介紹我的作品,那不能像在台灣這樣輕輕鬆鬆跟教授聊聊天就好,我要用不熟悉的語言跟不熟悉的外國人介紹我這個只花一兩個月做出來的雛型作品… 光想到這個背都涼了。

選上科展代表跟選上奧林匹亞國手是完全不同的感覺。奧林匹亞對我來說是個已經努力很久的目標,我很清楚自己的實力有多少,我對自己花了將近一年所打下的基礎很有信心,而且我對比賽本身已經非常了解,出國比賽不過就是做我已經很擅長的事情而已,一點都不需要害怕和擔心;但選上科展代表真的完全是意料之外的事情,我自覺還沒有花足夠的功夫在這問題上研究,就像一個腳底有油漆還到處亂跑的小鬼,糊里糊塗的鬼畫符被長輩當成畢卡索的作品一樣。

驚恐之餘,我還是警覺到我得開始做很多事來讓我能充滿信心出國去參展。我得趕快把英文練好,至少要能流利的跟人介紹作品,還要能回答各種問題;我還得了解Intel ISEF到底在幹麼,參展代表要做些什麼事;最重要的是還得繼續在這個作品上做更多研究,看能不能在兩個月內做出更好的結果。

參加科展讓我意外領悟到一些事,我發現我高一開始花了一年多投入資訊比賽所得到的並不只是那塊獎牌與一堆獎狀,在練習的過程中,我把台中圖書館所能借到的演算法和資料結構的書全都看過了,就連冼鏡光當初在微電腦傳真雜誌上的專欄也被我從圖書館地下室的陳年庫藏中挖出來,一本一本的影印裝訂起來。我收集了我所能找到的所有大大小小資訊比賽歷年來的題目,加上當時ACM Online Judge上做過的四百多題,我當時參加比賽幾乎都是看完題目馬上就能想完所有可行的演算法和所搭配的資料結構,並用直覺挑出能最快寫出來且又最有效率的解法。除了解決問題的方法外,我也能輕易的把任何想法寫成程式碼,只要能把過程講出來,就能毫不猶豫寫出code來。

這個花了一年多練出來的功夫,讓我到今天都受用無窮。這種感覺就像唸完九陽真經後內力大幅提昇,之後不管再練什麼武功都是易如反掌。在高中時,我改以Linux作為我主要的工作環境,同時也幫中一中架起BBS,並自己架了web server、mail server來玩玩。這些系統底層的功夫乍看之下跟寫程式沒什麼關係,但我後來發現要做各種能在現實生活中應用的軟體系統,總是會碰到這些現有系統的細節問題。

我以前在大學時常觀察別人的project會碰到什麼阻礙,而開發不順利的原因幾乎都是被一些瑣碎的細節所絆住而導致嚴重的進度落後。這些細節都是些小事,甚至跟寫程式沒有直接相關,但總是會讓人陷於泥沼之中。舉一個簡單的例子,假設要在Linux上寫程式需要用到某個library,動手前得先安裝一下。這個看似簡單的安裝其實牽扯到許多瑣碎的細節,像是:distro有沒有提供package可以直接透過網路安裝? 沒有的話就要自己編譯,那就得知道如何用configure、make等工具;編譯中可能還會發生缺少其他相依的工具或package的情形,這時還要能從錯誤訊息中看出到底少了什麼東西,並且想辦法先安裝起來…。這些事情跟寫程式的理念其實一點關係都沒有,但很殘酷的是,有許多人都會被這種細節所絆倒而中途放棄。

紮實的內功和熟悉系統底層的基本武功帶給我非常有效率的實做能力,我可以在想出新的idea的同時馬上勾勒出實做上大大小小的細節;我可以很快設計出核心的高效率演算法,也知道系統各部份的功能有什麼現有的library或系統可以利用,這兩種能力讓我能快速完成prototype。我只怕沒有夠好的點子,完全不會擔心是不是真的能做得出來。

不久前有位數字先生開了一個程式速成班,號稱能在4堂課內教會web程式的開發,只要帶著點子過去就能在上完課後開始創業。我覺得學寫程式本身其實不用很久,我也曾教過一個12歲的小朋友寫程式,兩個禮拜總共約十小時就足夠讓他掌握基本的程式邏輯概念,包括變數、迴圈、if、陣列、抽象化..。但認真說起來這些東西只是基礎內功,有了內功後自己還是要花很多時間去學相關的底層武功,像是要做web程式還得摸熟web server的架設和管理、UINX的shell和系統管理、各種相關網路傳輸協定、資料庫的使用和管理、前端的HTML和CSS設計….。光web程式所牽扯到的實做細節就多如牛毛,如果要在完全沒有穩固基礎的情況下同時學這麼多東西,只要一旦出現問題,一個對系統從上到下每個環節都不熟悉的人是完全沒辦法鎖定問題發生點的。而debug的基本概念就是要先鎖定問題發生的地方,要做到這件事的先決條件就是要很有信心的先排除一些不可能的地方,再做些假設並驗證假設是否成立來判斷可能問題。如果對每個環節都沒有充分的經驗,我不覺得這樣的人有能力清楚的定位出問題所在,更別提是否能獨力完成一個像樣的完整系統。

每個人都聽過成功是一分的天才加上九十九分的努力,如果說天才是能想出絕妙idea的能力,那我覺得還有個關鍵是,要在有點子前先做過夠多的努力打好基礎,等到靈光一現時才能把握住機會馬上實現它。如果等到一分的天才出現時,才準備開始做九十九分的努力,那很容易就會被許多基礎能力不足所帶來的挫折感和障礙所壓垮。

(待續)

我活下來了

Monday, December 15th, 2008 | 瀏覽:66,538人次
book pile

第一學期的「收穫」

在MIT的第一學期終於結束了!!從9月3號開學到這星期期末考和project都結束,也不過是三個月又一星期,中間還放了兩次長假加上兩次莫名其妙的星期一假期(據說是防止學生壓力過大自殺的假日,幾乎每個月都會有一天),但我有種已經過了一整年的感覺。學期結束後,我終於能從地獄爬出來了,說實在的,我現在只想對著天空大叫一整天!

很多人都說MIT是個會徹底毀滅一個人的地方,毀滅你的生活,毀滅你的自信,毀滅你的愛情。經過一學期的摧殘,我很高興我終於撐過去了。而且事後想想其實我也沒有過得多糟,至少我每天都還能睡滿七、八個小時,即使在期末週被兩科考試加project交叉攻擊下,我還是奇蹟般的把他們都一一擊破了。這真是讓我親身體驗到人類在危急時總是會爆發出無限潛能是怎麼回事XD 雖然學期順利結束,但也不知道能不能順利都拿到A。我們的資格考之一是要在指定的四門課都拿到A才行,所以要是沒拿到A我等於是白修了這門課,之後又得再痛苦一次(真是讓人想到就胃痛orz)。

其實來MIT後我才開始學著當個認真上課的好學生。以前台大的課我幾乎都不會想去,仔細想想我六年下來有全勤的課其實…只有兩門課吧。或許會這樣的原因其實是台大的教授教材都做得很好,所以只要寫作業或考試前把投影片看一看,再和同學討論一下,幾乎沒什麼難到自己看會看不懂的東西。但是,在這裡卻完全不是這麼一回事。我這學期修了兩門課,除了中間一個禮拜去加州參加conference外,每堂課都乖乖去上課還乖乖抄筆記(教授們都不太愛用投影片…||),但每次作業出來時看到題目都覺得沒有一題會寫的,搞得我們雖然每天都在寫作業,卻還是要連續寫上一個禮拜才寫得完。

除了修課之外,我們group每天都有個「下午茶時間」,其實也就是研究生都知道的meeting時間。只是我們的下午茶時間比較非正式一點,除了跟研究直接相關的進度報告外,其他就都是在閒聊,整個氣氛都很歡樂,跟傳統式輪流報告paper的meeting完全是兩種極端。我們會聊什麼呢,我們有個大家都可以編輯的google docs,上面寫了每天預計要討論的事項,還列了一大串有趣的話題,只要當天預計的事項都討論完就會拿出來聊。這些有趣的話題包羅萬象,但主要圍繞在人機介面、軟體工程、程式語言、WEB技術上,像是最近從網路上看到的新奇資訊或影片,或是剛發表的Python 3.0多了什麼新鮮的功能,我們也討論設計user interface的心理學,或是人與人之間互動的社交心理學;我們會一起做brainstorming討論各種可能的新點子,也會很nerdy的花半小時研究VGA接頭上的第9支針腳到底有什麼功能(呃,因為當天投影機怪怪的,於是我們就開始研究起它的VGA接頭規格,看能不能把它修好…..)。我們最近甚至還設立了一個blog,會把部份討論的主題分享出來,有興趣的人可以過去看看。

我的老闆也是一個很神奇的人,他是個會在meeting中討論討論就馬上開始coding來驗證的教授。他不但是我第一個看過還會自己寫程式的教授(後來我才知道其實很多MIT的教授都會自己動手,而台灣大部分的教授都進化(?)到只出一張嘴的等級了XD),而且他還是個會堅持漂亮的coding style的人。再加上他研究的興趣和我幾乎是100%相同,讓我不禁覺得能在這裡碰到這麼契合的老闆,應該是我到目前最幸運的一件事了吧 :D

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

Friday, October 10th, 2008 | 瀏覽:103,531人次

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

這次拖稿了很久,雖然下禮拜就要期中考了,但我決定還是要趁這個作業都剛交出去的忙碌低峰期來補上一篇,不然真不知道下一篇要等到什麼時候了…(泣)

思考的高度

上一篇談到了優秀程式設計師的第一要件:「熱情」,這一篇我想要談我覺得熱情之外最重要的能力:「思考」,特別是抽象化的思考能力。

寫程式可以說是一件進入門檻很低的工作,拜現代的GUI開發工具以及大量的open source library所賜,很多低階、跟硬體和作業系統直接相關的細節都被隱藏起來了,所以說其實只要學會某種程式語言並且會把自己的想法鉅細靡遺的轉換為程式碼,就可以說自己會寫程式了。到達這個階段並不困難,只要有心學習的話即使是國中生自己看看書或到巨X電腦上上課都能學會。那麼究竟要如何跨過這個階段,讓自己能和巨X電腦的畢業生有所區隔呢?我認為關鍵就在思考的高度。

寫程式需要的思考能力第一是邏輯思考,主要其實就是用正確、清晰的邏輯表達想法而已,說來簡單但要做好也是需要一定時間的訓練。第二是抽象化思考,這是許多人忽略掉的一點,也是我覺得區隔一個平凡與偉大程式設計師的重要特質。

我覺得所有的程式都可以看成一個巨大的金字塔,頂端是這個程式的最終目標,一個模糊的概念;底部是細節的程式碼。而中間是一個經由不斷切割與抽象化所構成的高塔,每一個程式都是切割為許多的元件、模組,再切為更細的class和function,再來是最底下的變數與邏輯判斷式。

很有趣的是,不同的人看這個塔就會有不同的樣子。初學者看到的塔只有兩層,他們和人溝通的方法是鉅細靡遺的描述程式碼:「我在這裡寫個for,第一次把i設成0,在迴圈內每次檢查這個陣列的第i個元素…」,在他們眼中只有程式的目標和程式碼本身,所以還可能會寫出下面這種讓人哭笑不得的註解:

  1.  
  2.  a = 1;  // 把a設為1
  3.  

有些經驗後,會再多看到一層,利用function把一段程式碼包裝起來,賦予一個名字和獨特的意義。學會這個後,就可以利用抽象化後的function名稱來溝通,例如:「我在這個迴圈裡每次都用isCaptial來檢查這個字串是不是都是大寫…」再接下去呢,可以再利用class,利用design patterns,利用更大的模組、子系統來溝通,認真說起來,這其實是一個無止境的切割。

在資訊科學這個領域,抽象化是個無窮無盡的必要行為。因為世間萬物實在太多太複雜,我們只好不斷把東西歸類,並賦予一個名稱、一個意義,經由這樣的過程我們才能用抽象的語言和符號來溝通,避免每次都要從最底層的瑣碎細節開始說起。而平凡和偉大的程式設計師,我覺得他們之間的差別就在於能看到多少這個高塔中間的分層。厲害的高手都很善於切換自己思考的高度,一下能跟你討論高階的系統架構設計,一下又能深入到最底下的組合語言和二進位除錯。他們腦中除了有這高塔每一層的詳盡平面圖,甚至也非常了解不同樓層之間的交互關係。而平凡的程式設計師大多只能專注於自己所開發的範圍,對於其上的架構或其下的細節都不一定能理清頭緒,萬一出現bug也會搞不清楚到底是哪一層出了錯,而被完全無關的細節絆住手腳。

程式語言決定了思考的高度

大部分資訊系學生接觸的第一個語言是C語言,其實我覺得到了21世紀還從C語言開始教是非常值得商議的一件事。我在台大時曾當過兩次計算機概論的助教,雖然大一學生同時還在修計算機程式設計(也就是教C語言的課),但我在課上也同時教他們學Python。

有人問我:「只學C語言不夠嗎?」。如果是為了畢業後能找工作,其實學C就夠了,因為幾乎所有公司都只考基本的C語言能力,也就是說他們認定只要會寫C就能勝任日後的工作。事實上大部分大學都不太教程式語言的,會教C也只是因為大一總得選一個語言教,而C還是老得辣,加上大部分教授也只會這個,所以自然就決定是它了。近年來因為物件導向風行,所以大部分學校還會教個Java或C++,但這也是因為要教物件導向的概念,而不是以教這個語言為目的。除了這兩種外,大概就剩下組合語言了,而這也是因為要教電腦最核心的CPU運作方式,所以才會順便教到的。

程式語言的地位在資訊系其實一直很卑微,大部分教授覺得這只是一個基本工具,就像螺絲起子和鐵鎚一樣。但我一直覺得程式語言是很重要的工具,它不只是讓人用不同語法和電腦溝通,而是讓人能用完全不同的思考方式來解決問題。簡單的說,我覺得程式語言就是決定思考高度的一個關鍵因素,而這也間接決定了寫程式的能力。

舉一個簡單的例子,高階的script語言幾乎都內建map這個資料結構。(也就是一對一的對應表,給它一個key,就能很快的找到其對應的value。有的語言稱為dictionary、hash、或associative array。)如果寫習慣Python或Ruby的人,一定會很直覺的用map來儲存任何對應關係,甚至用來表示會動態變更欄位的struct。但是,在C語言裡沒有這種東西,這讓很多只會寫C的人直覺的用陣列加上linear search來存放這種對應關係。如果資料結構學得好的人,會知道這樣寫效率很差,但很多時候因為沒有方便的library,也懶得自己寫一個高效率的map(不過是存一個電話簿,我難道要先寫一個紅黑樹嗎?),就妥協於沒效率的儲存方法。

這就是一個被程式語言限制住的典型例子。在高階語言用map存東西實在太容易了,所以這會變成思考時的一個小單位,跟人溝通或是規劃架構時都能隨時拿來用。但相反地,在低階語言裡,要有效率又簡單的儲存這種對應關係實在很麻煩,所以人們在思考時會傾向選擇容易的方法來做,而自然忽略掉了以map為基礎的解決方法。

除了script language外,functional language也是另一個進化到神乎其技路上必備的技能。functional language是以function為基礎來思考的程式語言,典型的代表是LISP、Scheme、Haskell。(這邊所說的function是higher order function,可以以其他function為參數的function,和C語言裡的function是不同的概念。)在functional的世界最棒的特性是程式可以只靠function間的相互組合而生成,不用迴圈不用if一樣可以達成同樣的目的。

舉例來說,如果我要要從一個電話簿中挑出所有姓張的人,並傳回他們的電話,用低階語言(其實我指的是imperative language,但這裡就不要這麼講究了)寫起來大概是這樣:

  1.  
  2. PhoneData contacts[N] = {…..};
  3. String number[MAX_NUMBERS];
  4. int count = 0;  
  5. for(int i = 0; i < N; i++){
  6.   if( !strncmp( contacts[i].name, "張", 1 ) ) // well, 讓我們假設這個strncmp支援unicode
  7.     ret[count++] = contacts[i].number;
  8. }
  9. return ret;
  10.  

用低階語言寫程式必須不斷處理瑣碎的細節,像是要開多大的陣列、要弄一個額外的counting變數、要用迴圈一個個檢查陣列….。當腦袋裡充滿這些細節時,是很難切換到更高的角度思考的。而functional language提供完全不同的思考方式來解決同樣的問題,以下我用Ruby的語法寫同樣的程式(Ruby具備許多functional language的特性,但不全然是個functional language):

  1.  
  2. contacts = [ { 'name' => '...', 'number' => '...' }, ... ]
  3. return contacts.find_all{ |c| c['name'][0,1] == '張' }.map{ |c| c['number']}
  4.  

是的,你沒看錯,就只有兩行,而且真正做事的只有一行而已。這裡用到的是functional language的基本工具:filter(Ruby裡叫find_all)和map。這兩個function特別的地方在於他們能用來取代一般需要迴圈才能做的事,並賦予除了「迴圈」以外更高階的抽象意義。filter的意思是過濾,可以從一個陣列中用一個給定的function為條件來去除不合條件的元素;而map的意義是對應和轉換,可以用一個給定的function作為規則把一個陣列中的每個元素全轉換成另一個樣子。

多了這一層抽象化後,寫程式的思考方式會變得完全不同。迴圈不再只是迴圈,而是可以根據它的目的將之區分為map或filter(其實還有更多,這邊只是先舉兩個做例子),思考時便能以組合這些小元件的方式來構思程式的寫法。這裡提供的不只是語法上的簡便而已,而是整個思維的大躍進,以及思考高度的提昇。

這就是為什麼我要教大一新生Python。Python融合imperative language、object-oriented language、以及functional language,語法簡單清楚威力又強大。雖然他們學過後不見得會繼續用Python,但有了不同語言的概念後,思考的高度會完全不同,寫出來的程式品質自然也不同。

(待續)

地獄生活初體驗

Tuesday, September 16th, 2008 | 瀏覽:72,379人次

才剛進入開學第三個禮拜,我已經非常深刻體會到哈佛大橋上所指的「地獄」是怎麼回事了….。

我記得以前在台大時,直到期中考前幾天,才會在同學間看出比較緊張的氣氛,大家開始相約去唸書,在師大夜市裡的咖啡店邊聊天邊準備期中考。在台灣考場打滾十幾年,每個人都身經百戰,區區一個期中考期末考也不過是拼個兩三天就能唸完的小考試,根本沒人在怕的。至於其他的作業和project呢,反正大多也只是一兩個晚上的份量,即使習慣拖到最後一天的人,熬個夜也都還是能來得及做完。

在出國前,早就耳聞美國大學課程驚人的份量和紮實的程度,但百聞還是不如一見,親身體驗後才知道這種生活有多可怕…。我這學期只修了兩門課,Machine Learning在星期一、三中午,另一門Database在星期二、四中午。Machine Learning自從上一堂課開始,我就已經開始沒辦法在上課時聽懂教授到底在講什麼,只好趁下一次上課前再自己複習趕快追上進度。本來還以為自己太笨,後來發現其實很多人也都開始沒辦法搞懂上課的內容(你以為MIT每個人都是數學天才嗎,別開玩笑了XD),教授就像開了加速器一樣批哩啪拉的一直狂寫數學式,下課後總覺得自己已經瀕臨精神衰弱邊緣,更慘的是我還是得趕快搞懂上課內容,不然不但作業寫不出來下堂課還會繼續聽不懂,實在沒有比這更悲慘的事了..。

其實也不是沒有更悲慘的事,就在我自認為前幾次上課都還聽得懂的時候,第一次作業就出現了。這作業乍看之下只有三題,可是每一題裡面又分了個四、五個小題,剛拿到時稍微瞄過覺得似乎不會太難,誰知道實際做下去才發現這根本不是一兩個晚上可以寫完的,每一題其實都是以前台大一份作業的份量。就這樣在三倍量的作業轟炸下,昨天的中秋節我就把整天都奉獻給這個作業了,只是讓人覺得更想哭的是,我其實還寫不到一半………。

相較於Machine Learning的地獄,Database只能說是輕鬆愜意。教授上課還蠻有趣的,不但一邊說SQL真是爛到爆,還會一直嘲諷微軟和Oracle等大象公司。(後來才知道這個教授其實就是PostgreSQL的原作者……)。雖然Database上課時挺享受的,但上課前就不太有趣了。因為Database每次都指定了一大堆的論文或課文要在上課前看完,不看又不行,誰也不想在大家都很熱烈討論的課堂上突然被問了問題卻只能回個囧給老師看吧…。

兩門課交錯著上,每天上完課、meeting完(對,我每天都要meeting!!!),不是得趕快複習,不然就得趕快準備下一門課,更糟的是現在還得加上趕作業,因為每個禮拜都會有作業……………Q_Q

除了上課外,我還是領系上薪水的博士生,不用付學費又有錢拿的代價就是我得乖乖跟指導教授作研究寫論文,所以除了應付這兩門課外還得一邊作research project、每天參加meeting、每個禮拜還得報告些東西讓我看起來像有在認真做事的樣子。可是我光兩門課的作業都快搞不定了,哪裡有時間去作研究啊,偏偏指導教授才不管學生修課的死活,反正即使被當掉研究還是得繼續做….。

唉,為什麼,為什麼現在明明才剛進入第三個禮拜,我卻已經有種生不如死的毀滅感呢..Q_Q

這就是所謂的地獄嗎?

Boston新生活開始!

Thursday, August 28th, 2008 | 瀏覽:54,523人次

到美國來也快一個禮拜了,每天從早到晚都排滿行程,到昨天好不容易把重要的to-do list都解決掉,跟國際學生辦公室辦到完畢、拿到學生證、在銀行開好戶頭、學會開支票繳了學費以外的雜費、還辦好了暫時的手機…,現在終於有空閒能靜下來寫寫blog,明明只過了五天,感覺卻像一個月那麼長。

我在Boston旁邊的小城市Cambridge,即將開始漫長的博士班生活。雖然還沒開學,滿滿的orientation(就是新生座談,最近因為陳家公子讓這個詞突然變得廣為人知XD)和welcome party把每天的時間都壓榨得一乾二淨,每天晚上回到宿舍都累得想直接躺上床睡覺就算了,可是這時候看看錶往往才不過六、七點,太陽都還沒下山呢….。

這就是MIT的瘋狂生活序曲。

還沒開學就搞得我人仰馬翻實在是讓人很抓狂,我有天跟我們實驗室的學長講起這件事,說希望開學後可以正常一點,沒想到他竟然說:「這有點困難。MIT是個瘋狂的學校,你很快就會知道了…..」

雖然學校很瘋狂,但Boston還是個很美的城市,夏秋交接之際大概也是這裡天氣最舒服的時候了,現在還有一種置身仙境的感覺。昨天下午有點空閒就沿著哈佛大橋從Cambridge走向Boston,散落在查爾斯河上的帆船配上Boston的天際線,美得好像我走進了畫中的世界一樣。

下面這棟是Stata Center,我未來的系館。我的辦公室在其中的蓋茲大樓(就是微軟那個比爾大叔捐的..)7樓。

哈佛大橋上有以前MIT學生用某人的身高為單位(Smoot)量出來的刻度,橋的中間還寫上了「到地獄的半路上」。從MIT逆向而行看到這個標記,心中想的是:「啊 我從地獄中走出來了,是不是該慶祝一下XD」

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

Tuesday, August 19th, 2008 | 瀏覽:76,088人次

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

最近新玩具太多,差點讓我的blog被N82系列文章淹沒了。幸虧即時看到qing兄兩篇不錯的文章 程式設計的兩個觀點 (1/2)程式設計的兩個觀點 (2/2),讓我決定還是來早點把這個系列寫完,不然就快變富奸了。

qing兄的兩篇文章指出程式員的兩種型態,一是重視演算法、資料結構、執行效率的「效率魔人」,二是重視程式架構、擴充性、彈性、可理解性的「架構狂」。這兩種人其實都很好,要完成一個偉大的軟體,團隊中兩種人一定都要有。比較糟糕的是,有很多「第三型態人」,他們的信念只有一條:「程式只要會動就好」。第三型態人不在乎效率,也不管架構漂不漂亮,上面要求他做什麼,他就想辦法東湊西湊,從Google找程式剪貼,從MSDN抓範例來用,反正只要能隨便測過一個case就能交差了。

其實第三型態人也不一定是不懂演算法、不懂design patterns,他們常常只是因為火燒屁股了,就不管三七二十一先弄出可以動的程式再說,效率或架構等到下一階段再來改就好…。問題是,下一階段又有新的功能要做,這些人再度面臨抉擇時還是會決定先讓程式「會動再說」。我看過很多各式各樣的程式員,只要碰到這種人,同樣的過程是履試不爽不斷出現。

所以要成為一個優秀的程式設計師的關鍵是什麼?關鍵不在於coding速度有多快、懂多少演算法,或是背了多少patterns,最重要的是「熱情」!

偉大的程式設計師都非常喜歡寫程式,寫程式的過程是一種絕妙的享受,他們執著的地方或許不同,可能是程式的效率,也可能是開發的效率,甚至是架構的彈性或是程式碼的精簡美觀程度,但他們都非常想要並堅持自己應該寫出「好程式」。熱情能驅動他們把軟體的某一個面向雕琢到極致,這需要超乎常人的毅力和堅持,以及絕不向壓力妥協的精神。只要具備這種熱情,不管你在乎的是什麼,都可以成為一名偉大的程式設計大師。

P.S. 雖然這篇文章講的東西很八股,但我發現這真的非常重要,看一個人的熱情就能知道他做出來的成品是什麼樣子。如果是我來面試,我一定會在面試時觀察這人有沒有喜歡寫程式的熱情,沒有熱情的人容易向現實壓力低頭,也不會要有不斷精益求精的信念,在如此競爭的時代是很難生存的。

P.S.2 要追求神乎其技前,當然要先知道自己的目標是什麼樣子,所以我本來想在這篇寫一個優秀的程式設計師應該要有的特質和能力,但才寫了第一項就落落長。所以還是等待下一篇再繼續這個主題好了。(路人:「這不就是擺明要當富奸嗎!」)

(待續)

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

Friday, July 25th, 2008 | 瀏覽:43,155人次

讓電腦自己寫程式的夢

在高三突然對於讓電腦自己寫程式產生興趣後,我每天就都想著這件事,夢想著未來某一天的電腦能跟我一起寫程式,當我把程式目的說給它聽時,它就一邊把細部的程式碼產生出來:我不用想如何命名變數,或是要用什麼演算法,還是我到底要不要把這個功能變成獨立的class…;我只要動動嘴巴:「我想寫一個橫向捲軸的射擊遊戲。玩家操縱著會變形的飛機,還有四種武器。第一關要長這樣這樣……」,然後電腦就幫我把遊戲寫出來了!如果真的可以這樣,那該有多好啊!(如果真的成真,恐怕我也要失業了?)[註一]

這個想法實在太讓人興奮了,雖然說這是一個遙遠的夢想(其實那時候我並沒有覺得這麼遙遠,只能說自己太不自量力XD),但也開啟我對於人工智慧、程式語言結構、軟體工程等領域的高度興趣。

寫程式很難?

在高中時代頗不知天高地厚的我,一邊嘗試著利用基因演算法(Genetic Algorithms)讓電腦自己產生程式碼,一邊研究各種程式語言的結構和特性。靠直覺摸索出利用tree作為中介來描述一個程式後(那時沒唸過compiler,不知道這個其實就是Abstract Syntax Tree),我突然就對這個想法的可行性信心大增,所以一時衝動就去報名了國際科展,打算把這個想法實做出來。

真的做了以後才發現,最難的部份不是產生出程式碼。如果你把程式語言的基本元素,像是if、for、變數、運算符號等東西做成一塊塊磁體,然後拿給一隻猴子玩,那麼牠其實也能拼出一堆程式給你,問題是:「你要怎麼知道這些程式碼真的達到了你想要的目的?」

悟出這個道理後,我突然了解寫程式最難的部份是在驗證程式碼真的跟你所想表達的事情完全相同。(所以說我對於各家軟體公司的QA地位都低於RD其實感到很不平)

基本上,我們只能設計大量的可能輸入值丟進程式裡,並比對程式跑出來的結果和我們想要的輸出相不相同。即使在這種情況下,我們也只能說這個程式在測試過的這些輸入值上所產生的結果是正確的。也就是說,除非我們測試過所有可能的輸入(這意味著無限多種可能),不然永遠沒辦法知道某個程式是對還是錯。除此之外,即使只測試一個輸入值,也還有個很嚴重的問題:「我們怎麼知道這個程式要跑多久?」換句話說,當你程式跑下去,你怎麼知道他是掉入一個無窮迴圈,還是其實正在拼命計算當中?

我在參加國際科展時,認識了歐陽明教授,他告訴我這個問題叫做Halting problem,Alan Turing在70年前就證明了這是一個無解的問題。知道這件事後,才發現自己所知實在太少,對於資訊科學的基本知識實在非常不足,但這次經驗其實也給了我一個明確的方向,讓我把書中的理論和實際的目標連結在一起。

見樹又見林的學習之道

提到書本中的理論,有很多人問過我要怎麼學習寫程式或資訊相關的知識,我順便在這邊分享些心得給大家參考。

常看到許多人抱怨大學裡學的東西都是理論,畢業後找工作時才發現什麼都不會都得重學;當然企業也會抱怨,大學應該多教一些實務課程,不然出社會後還得重新訓練。說來說去,一致的口徑指向理論和實務是打死也扯不上關係的樣子,尤其念資工的人更常這麼說:「學校為什麼不教C#?為什麼不教我做網頁?好歹也要教個HTML嘛!」


我覺得學習任何事物,一定要有充分的興趣才會有效率,在不知道所學為何的情況下被逼著學習是非常痛苦且沒有效率的。最近看了一本書:沒有資優班,珍視每個孩子的芬蘭教育,書中提到芬蘭教育成功的秘密在於「見樹又見林」,這句話也是我對於如何學習最想分享的秘訣。

台灣的教育方法是「先見樹,再見林」,也就是先教你細部的方法和技術,等你都學會之後(或是硬背起來之後),出社會後就會知道為什麼要學這些東西。(很多人小時候都聽過「等你長大就知道唸書有多重要」吧。可是現在比較多人畢業後反而說「我不知道之前念那麼多書有什麼用」)在這種體制之下,許多人在還沒見到整片森林的美景前就被一棵棵大樹搞得暈頭轉向,痛苦萬分,在不知道「學了這個可以做什麼」的情況下,不管學什麼都會覺得沒有意義沒有動力。

而「見樹又見林」的學習方式,是先找到能引起自己興趣的目標,讓自己有個理由去認真學習,之後再往細部的技術和理論去學習。我從小就很想自己寫遊戲,為了達成這個目標,我就四處尋找相關的資料,慢慢的我就知道自己應該要學好一個快速的低階語言(像是C++),如果要寫繪圖引擎可能還得學一點圖學的理論和技術,如果要做網路連線還得學網路相關的技術…。

這裡有個重點是,不要看過森林後就忘記它,而又迷失在幾棵樹幹上,要讓自己一直重複見樹又見林的過程。

這跟如何有效開發軟體的秘訣是一樣的。一個有效率的軟體開發方式是用iterative process,把包含設計、實做、測試的iteration時間縮短,但要一直不斷重複這個iteration無數次來改進現有的成果。同理,在已經有目標的狀況下學習時,每當學會一些新東西,就要馬上試著把它實現出來,即使是只有幾行程式碼的prototype也沒關係。只要一直不斷的學,這個prototype就會一直被改進,一直加進最新學到的知識和技術而更接近最終的目標。

同時動腦也動手(註二),用這種角度來學習就能充分了解自己學會的東西可以用在什麼地方,馬上得到回饋的成就感還會刺激自己繼續向前進,形成一個非常有效率的學習循環。用這種角度看學校教的東西,就能知道書本上的理論可以用在哪,並且又欠缺哪些實務知識讓自己無法做出想要的東西。

這方法理論上可以擴展到任何事物的學習,重點在找到有興趣的目標和書本裡知識的連結,我覺得這是老師應該要出力的地方,無奈的是台灣的教育體制把中小學老師們變成出考題和改考卷的機器人….。

註一:
其實,現在真的有這樣的研究,而且驚人的是目前已經有了非常接近我想像中未來的雛型。最讓我興奮的是MIT Media Lab的Hugo LiuHenry Lieberman做的Metafor:只要對電腦用英文描述你要的程式,電腦就自動把Python code生出來給你….。

註二:
話說,MIT的校徽上就是一個拿著鎚子的工匠和一個拿著書的學者,所代表的意義就是 “Mind and Hand”,也就是期望每個學生都能手腦並用,除了做夢外也要實做出來才算數啊。

(待續)