無意間看到一篇文章在分享自己學網頁的歷程與心得,而這類型的文章其實我也曾經想要寫過。

在我寫十年程式自學之路的時候,其實我原本想寫的是像剛才提到的那樣,有許多篇幅在講述自己學程式的經歷以及做過的事。可是我寫一寫發現那時候徵文的主題其實是自學的一些心得,所以才改成後來大家看到的那樣,著重在十年裡面學習到的經驗。

這一篇其實算是個人傳記,在動筆之前想到了以前看過的經典文章:追求神乎其技的程式設計之道,風格大概會比較像那樣吧!就是詳細地紀錄了自己一路上究竟學了些什麼,是怎麼走過來的。

這篇最難的部分大概就是標題了,原本想取叫:「十年程式之路」,發現跟上一篇太過於類似,可能會有人以為是同一篇。幸好靈機一動想出來現在的這個標題,但其實「講學」這個詞用得有點過了,在這邊先跟大家說聲抱歉。講學純粹是為了跟前面兩個「學」相互呼應,我不認為我有到講學的程度,頂多就是分享一些經驗跟教學而已。

好了,前言差不多就到這邊。因為這系列會很長,所以拆成上中下三篇來寫。

接觸電腦的開端

要接觸到程式,必定要先接觸電腦。我第一次接觸到電腦應該是我小二的時候,那時候大概是 2002 年(如果我沒算錯的話),平時也沒做什麼,應該就是玩玩遊戲或者是用 Yahoo 即時通跟其他同學聊天。

因為電腦接觸的早,再加上用電腦的時間又多,自然就會接觸到很多不一樣的東西。例如說論壇,我小學四年級的時候就在巴哈姆特哈拉區裡面打滾了,甚至還做過超級短暫的楓之谷版副版主以及瘋狂阿給版版主,現在想起來覺得很荒謬,怎麼會讓一個小學生來管版。但也因為接觸的早,讓我不像其他同齡小孩一樣會打注音文或是火星文(我可是很遵守版規的)。

不過那段不是重點,那比較適合寫成「我的網路史」之類的系列文。

總之呢,因為接觸電腦接觸的很早,所以總會在網路世界上面看到各式各樣的文章,以及五花八門的資源。

而我接觸程式的契機,也跟許多人一樣,是遊戲。

與程式的第一次接觸

老實說,其實我忘記是遊戲還是駭客引起我對程式的興趣,畢竟都這麼久以前的事情了。最有可能的情況應該是覺得遊戲外掛很帥很猛,就去查資料查到駭客這個詞,再去找一些駭客相關的文章,都提到說:駭客一定要會寫程式。就因為這句話,決定開始自學程式。

我記得很清楚,我第一次接觸程式是我小六的時候,那是 2006 年的事情。不過,儘管小二到小六的這四年都與程式沒什麼關係,但對我來說也很重要。那幾年都在網路上面的社群打滾(巴哈姆特、XBOX 論壇),以及與朋友用 Yahoo 即時通聊天訓練打字速度。這兩個對我的影響至今仍然存在,尤其是後者,不斷訓練打字速度的結果就是我的中打速度滿快的,現在大約一分鐘 150~180 個字(新注音),視狀況好壞跟要打的文章內容而定。

決定接觸程式以後,第一件事情就是先上網搜尋要學什麼程式語言。沒錯,我也當過懵懂的初學者,我也做過幾乎全天下想學程式的人都會做的事情。

搜尋到一些網路資源之後,發現有人推薦 Visual Basic,因為比較容易學習,也有人推薦 C,說是學程式一定要從這個開始才能打好基礎。我最後選了 VB。原因很簡單,因為 C 的程式碼我完全看不懂在幹嘛,我討厭那些惹人厭的分號跟大括號,讓程式碼看起來像天書一樣。而 VB 相對之下就和善許多。

找到學習目標之後,一樣先用關鍵字去搜尋大家推薦的書籍(沒錯,就跟所有初學者都會做的事情一樣),最後得到了一些清單,再去書店裡面找實體書來翻翻看,看一下前幾章的內容自己是否能夠理解。

確認自己能夠理解之後,就買下了我人生中的第一本程式設計書籍:Visual Basic 2005 完美的演繹

那時候我就知道,我選 VB 真的是選對程式語言了。為什麼?因為在眾多程式語言之中,VB 是最簡單開發 GUI 程式的一個。你只要在畫面左方選擇你要的控制項並且丟到右邊去,你的介面就這樣做完了。整個流程根本超級簡單,馬上就可以做出一個看得到的程式。

(圖片來源:http://darkranger.no-ip.org/archives/v5/files/project/club-web/vb6/ide.htm

我人生中的第一個程式是畫面上有一些按鈕,按了按鈕之後有一個文字會改變。就是這麼簡單的一個小程式,但卻讓那時候的我感動不已:「原來操控電腦是這種感覺!原來寫程式是這種感覺」,看到自己寫出來的程式能動並且活生生地展現在你面前,是一件非常有成就感的事情。

現在我之所以會極力推薦 Scratch 作為新手入門的第一個程式語言,其中一個原因就是因為 Scratch 能夠很輕易地做出互動式的介面,會讓你剛開始學程式時的成就感更大,也能夠馬上看到回饋。比起 C 入門萬年不變的黑底白字 Terminal 畫面,我相信 Scratch 或是 VB 寫出來的程式會讓你覺得更有趣一點。

學 VB 還有一個重點,那就是當時的電腦內建都可以跑 VB6,只要丟一個 exe 檔給你的朋友,他們就能夠執行。原本我學的是 VB2005,後來跑去寫 VB6,因為 VB2005 寫出來的程式需要安裝  .NET framework,那時候 XP 還沒有內建這個東西,所以要安裝很麻煩,但 VB6 寫出來的程式,什麼都不用裝就可以執行了。

而那時候我也跟所有剛入門程式的人一樣,會問一些「程式設計師之後會沒落或興起嗎?」之類的問題,現在看起來有點好笑,但那是我國一時候問的問題,應該還算是合情合理吧,畢竟才國一嘛!問題連結:只學 VB 的話,可以走上程式設計師這條路嘛?

我學程式的時候是小六升國一的暑假,利用暑假的時間把那本書的前半段都看過了,後半段什麼 DAO 跟資料庫的因為太懶惰就直接忽略不看。我印象最深刻的一件事情是迴圈,我怎麼看都看不懂迴圈到底在做什麼。但過了一兩個禮拜之後,不知道為什麼我就突然看懂了。這讓我學習到一件事,時間是最好的武器,有些解不開的問題時間一久,就不知道為什麼自動解開了。

國中階段是我的程式萌芽期,現在回想起來應該也是我最認真的一段期間,也是最主動的一段。我把它分為三個不同的支線來講:

  1. 幹壞事是進步最大的原動力
  2. 利用程式解決自己的問題
  3. 科展與程式競賽

幹壞事是進步最大的原動力

(標題來自:Gea-Suan Lin’s BLOG

這一條支線來自於國中階段無意間發現有一個網站叫做恰吉網(現在去搜尋,只能搜到這篇新聞:架「恰吉網」炫耀 大學駭客攻擊網站 po 教學),裡面有一些影片教學,全部都是在講駭客有關的東西。

駭客對一個國中生來講絕對是很有趣的東西。為什麼?因為很帥、很酷,可以入侵網站耶!超酷的吧!

而就是在這個階段,我開始有了資訊安全的概念,我知道什麼是木馬,什麼是肉雞,知道加殼、脫殼,也知道 SQL Injection 與 XSS,還實際用過' OR '1'='1'入侵過網站,偷偷改了首頁跟放了 PHP 木馬。也知道 WPE Pro 可以抓封包並且更改、重新發送,發現某個線上遊戲可以利用這樣來改變角色的位子什麼的。

但其實上面這些東西我都沒有深入研究,我的理解僅止於:「知道這個東西大概是什麼」而已,所以我不會手工脫殼也不會加殼,要叫我用 IDA Pro 去反組譯一個程式並且追蹤我也做不到。SQL Injection 我也不會自己打,我甚至看不懂 SQL 那一堆有的沒有的指令,我只會用' OR '1'='1'而已。因此那時候的我應該算是個腳本小子吧,只會撿現成的工具來用。

總之在這一條支線裡面,讓我瞭解到許多資訊安全的基本概念,儘管很多東西沒有真的實作過,但至少我知道名詞也大概知道原理。而根據往後的經驗,在國中就能有這樣的資訊安全基礎,對以後的程式生涯非常、非常有幫助。

利用程式解決自己的問題

許多人在程式自學的路上常會碰到一個問題,那就是基礎都學完之後,不知道該怎麼繼續精進,這時候我就會推薦他們寫一些小作品。有些人會回我說:可是我不知道要寫什麼啊!我就會跟他們說從模仿開始,留言板啦,部落格啦,都是很好的模仿。或是我認為每個人的生活周遭一定都有一些小問題,這時候就可以嘗試自己用程式來解決。

而那時候的我就是這樣,喜歡自己寫程式來解決自己的問題。

例如說我碰到的一個問題就是我要貼文章到 PTT 上面的時候,因為網址太長所以要用 Tinyurl 去縮網址,可是如果我有十個網址,我就要複製貼上並且產生短網址十次。那時候我就想說,有沒有辦法能夠優化呢?

因此我寫了一個小程式可以偵測剪貼簿裡面的內容,當偵測到剪貼簿裡面有網址時,就用 API 去呼叫 Tinyurl 縮網址,並且把回傳的結果取代回剪貼簿。意思就是說你今天複製某個網址,等個兩三秒再貼上,長網址就變成短網址了。

還有一個有趣的小程式是在聊天的時候,偶爾會不小心忘記切換中英文,打出 uv;4g45k4u;4 這種東西,我就寫了一個小程式能夠複製剛剛那段文字,並且幫你轉換成中文。而原理就是先幫你把輸入法切換成中文,再呼叫鍵盤的 API 直接用程式幫你把上面的字再打一次。

或是那時候我有一台電腦好像哪邊壞掉或是沒電,每次重開機時間都會還原成出廠時間,都要手動自己再調整很不方便。我就乾脆寫了一個開機自動執行的小程式,連上網路抓取最新的時間並且自動設置。有了這個程式之後替我省了很多麻煩,從那時候我就體驗到自動化的好處。

所以囉,我才說生活中一定有一些你常碰到的問題,這時候就可以自己寫程式去解決它。如果不會寫怎麼辦?就查啊!例如說我上面那些我原本也不會寫,都是去查怎麼用之後才學會的,例如說:vb 開機 執行vb 模擬 鍵盤等等的。

而我寫過的眾多小程式裡面,有一個一定要特別提出來講,那就是 Yahoo 即時通狀態輪播程式。大家應該都還記得以前的通訊軟體都有一個功能叫做:狀態,會顯示在自己暱稱的右邊,原本的設計初衷應該是放一些:工作中、勿擾等等的狀態,但後來就演變成什麼都可以放,有人放歌詞也有人放一些心情小語。

最酷的一種就是有一種程式叫做狀態輪播程式,設定好之後就可以讓你的狀態像跑馬燈一樣,每一秒改變一次,顯得十分酷炫。那時候我就稍微研究了一下,發現 Yahoo 有提供相對應的 API 出來,只要用 VB6 引入一個 Yahoo 即時通的 Library 即可,實作十分容易。於是最後就自己做出來這個小程式了:

之所以會特別提這件事情,是因為我在國二的時候(2007 年)自己寫信去投稿電腦王,那時候應該是有朋友跟我說可以試試看我才去投的。而且我看了一下我的信箱,原來在投稿電腦王之前,我有先寄信給松崗出版社,說我想出一本 VB6 程式新手教學的書,他們有沒有興趣。後來他們回覆說入門書已經太過氾濫,要有特定主題才能有比較好的切入點。

我差點就在國二的時候成為電腦書作者了(開玩笑的)

寄了一封不知所云的信給電腦王之後,他們很有耐心的詳細回覆,後來我就參考了他們網站上提供的外稿提案範例,自己寫出來一份提案,後來這提案也順利通過。

最後刊載出來的時候他們有寄給我一本實體雜誌,看到的時候真的超級興奮,是雜誌耶!我寫的東西居然實體出版了!

這件事之所以一定要特別提出來講,因為它是我人生中重要的一個里程碑,對我來說,它達成了以下幾件事:

  1. 第一次自己賺錢(那時候稿費是 1 字 1 元,好像連程式碼都算,所以我拿了 3000 多的稿費)
  2. 證明自己是有能力寫東西的(仔細想想,應該也顯現了我那時候就喜歡教學吧)
  3. 提升自信(一個國中生投稿電腦雜誌,成功出刊並且賺取稿費,我那時候怎麼想都覺得自己滿厲害)
  4. 辦身份證

最後一點滿好笑的,出刊之後那邊的編輯跟我要我的身分證字號跟匯款帳號,要匯稿費給我順便在他們 ERP 建檔(那也是我第一次知道 ERP 這名詞),我跟他說:「可是我沒有身分證,我還沒滿 14 歲,過一個月滿了之後我再去辦」

除了即時通輪播以外,我後來又以原本就想要寫的檔案監視程式再投了一次,也順利通過出刊並且拿到三千多塊的稿費。之後編輯問我對 ASP, PHP 有沒有研究,他們希望能有相關的主題,而我那時候婉拒了,說我對網頁設計很不熟,恐怕無法勝任。

跟電腦王的故事就到這邊結束,感謝電腦王雜誌,為我的國中生涯,甚至是在我整個人生中都立下一個重要的里程碑。

即時通那篇最後的完稿,如果有人有興趣的話)

這一條支線:「利用程式解決自己的問題」對我的另一個影響就是,我發現解決自己的問題是一個非常好的出發點。現在創業都講究要「解決問題」,但常常碰到的難關是:「這真的是一個問題嗎?真的需要被解決嗎?有多少人碰到這個問題?」,而我認為從解決自己的問題著手是一個不錯的開始。

儘管你的問題不一定是別人的問題,但如果不是的話又如何?至少你解決了自己的問題,幫助了自己。

科展與程式競賽

國二的時候仗著自己會寫程式,而且自認功力不差,想說跟幾個同學報名參加科展好了。雖然那時候我根本不知道科展要幹嘛,但我想說:「我滿會寫程式的,就寫個程式去參加吧!」,因為科展沒有資訊組,就報了個「生活與應用科學組」,標題是:揭開網路遊戲的神秘面紗,但其實就是寫一個「多人連線五子棋遊戲」。


這已經是我那時絞盡腦汁畫出來的介面了(用 PhotoImpact 自己畫的),儘管介面長得超級像 Flash,但其實是用 VB6 寫的。

我剛剛在信箱裡面找到當時的科展說明書,我終於想起來那時候是做什麼了,原本不只是一個遊戲。

當時的主題因為是:「揭開網路遊戲的神秘面紗」,所以一開始先介紹網路遊戲的連線方式,再講到 C/S 架構,每一個 Client 都通過 Server 轉傳訊息,轉到另外一個 Client。然後以文字的方式傳送要的指令,例如說:Talk 你好,就是在聊天室講話的意思。

接著講到外掛的實作原理,簡單分成第一種是攔截封包並且修改,例如把上面的「你好」換成「去死吧」,還截了一張 WPE Pro 抓封包的圖。第二種是修改記憶體位址,截了一張 OllyDbg 的圖說可以反組譯之後從程式碼裡面找到一些資訊。

之後就是實作時間,實作出一個多人連線遊戲,有 Client 端(就上面看到的那兩張圖),有 Server 端,Server 端可以看到目前玩家人數跟房間狀態,還可以踢人。最後自己寫一個外掛出來,證明上面講的外掛實作原理是有效的。

這應該是我第一次接觸到網路相關程式。感謝 VB6 的 Winsock,讓我可以很方便的就實作出連線的部分。

後來這個作品在校內初選的時候被評審說跟科展的方向其實不太符合,科展必須要有一個研究的主題,但這個不太算是在研究。但之後校內有個電腦老師看中我程式能力這點,說我們可以改一個符合科展方向的題目。

經過老師的建議,改成了:「亂中有序-電腦五子棋研究」(當時參賽的海報檔案

給一個五子棋的盤面,利用電腦亂數下棋(蒙地卡羅法),看看電腦落子的位置是否跟其他五子棋軟體(如五子棋大師)一致。有興趣的可以看看上面我附的那個檔案,裡面說明的很詳細。

最後拿了台北縣科展優等,之後高中申請上師大附中的時候好像有小加分了一下。而老師也有問我明年的科展要不要繼續參加,主題是基因演算法與圍棋的研究。我原本說好,但後來發現國三了時間好像不太夠,於是就作罷了。

現在想想其實有點後悔,如果當初有做那個主題的話應該還滿好玩的,至少國中就可以知道基因演算法在幹嘛。

在這一年的科展生涯裡讓我學到做研究的一些方法跟方向,也覺得利用電腦來亂數下棋滿好玩的。但其實在國中階段,影響我最深遠的是另外一條線:程式競賽。

國中生能比的程式競賽只有一個,由台大主辦的 NPSC,網際網路程式設計全國大賽

程式競賽在幹嘛呢?其實就是用程式去解決問題,如果要我說的話,會比較像解數學題的感覺,但其實也沒那麼數學。我們直接找一題 NPSC 2016 國中組初賽的題目讓大家看看:

頗旺是地虎國⼀個很認真的學⽣,每個禮拜星期⼀到星期五都會到學校上課,⽽星期六及星期天便可以在家裏休息,做其他有趣的課餘活動(如參加 NPSC)。

⽽地虎國是⼀個潮溼的熱帶⼩島,因此,時不時便會有颱⾵來肆虐。只要颱⾵來襲,爲了保護所有⼈⺠的安危,全國便會放假⼀天。

⽽對頗旺⽽⾔,如果在星期⼀到星期五的時候,恰好有颱⾵來襲,便會賺到⼀天在家裏休息的機會,頗旺便會覺得很開⼼;反之,若沒有颱⾵,便⼀樣要到學校上課,頗旺便會覺得不開⼼。但如果是在星期六及星期⽇時,有颱⾵來襲,原本可以好好放假的⼼情,便會被外⾯的⼤⾵⼤⾬給影響,頗旺便會覺得不開⼼:反之,若沒有颱⾵,頗旺便會覺得很開⼼。

現在,你剛好發現⼀⾴頗旺的⽇記,上⾯記著當天的年份、⽉份、⽇期、星期幾、以及有沒有颱⾵,你很好奇頗旺當天是開⼼還是不開⼼。

測試資料只有⼀⾏包含五個整數 Y, M, D, X, T,分別代表年份、⽉份、⽇期、星期幾、有沒有颱⾵。當 X = 7,代表當天是星期天。當 T = 0 代表當天沒有颱⾵、T = 1 代表當天有颱⾵。

如果頗旺當天開⼼,請輸出 “happy” 於⼀⾏,否則請輸出 “unhappy” 於⼀⾏,皆不包
  含引號。輸出後請記得換⾏。

Sample Input: 2016 9 28 3 1 , Sample Output: happy
Sample Input: 2016 10 21 5 0 , Sample Output: unhappy

就是有一個題目說明,跟 Input, Output 的形式跟測試資料。你要做的任務就是去寫一個程式,能夠針對不同的輸入產生出正確的輸出。

由於我們國中本來就有在做相關的培訓,因此午休時間可以到電腦教室去練習題目,有問題可以問老師或學長,但大多數時間還是自己練習。其實在練習的就是演算法與資料結構,只是我記得國中的時候沒有學到那麼多,好像會 DFS, BFS 跟最短路徑、最小生成樹之類基本的就可以破台了(不太確定,而且國中組難度日漸增加)。

國二跟國三我都有參加 NPSC,對這比賽的印象是結束後發的餐盒很好吃,那也是我第一次進去台大校園。第一次去台大校園是去比賽的,聽起來就滿厲害。

名次的話大概都 10 幾名左右,不算太好也不算太壞,就是一個滿普通的成績。但我那時候很享受程式解題的感覺,喜歡思考問題跟解決問題,想通之後再用程式碼寫出來。上課太無聊的時候也可以來想問題,可以想個好幾節課都不會睡著,因為腦袋一直在思考。

但國中其實只是程式競賽的一個開端而已,真正的戰場,在高中。

續集傳送門:

自學、哲學、講學:我的程式之路(中)
自學、哲學、講學:我的程式之路(下)