此篇為系列文章第二篇,若是你錯過了第一篇誤打誤撞進來這裡,傳送門在這:

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

眼界的開闊與自信的泉源:高中的競賽人生

高中的主線就只有一條,那就是程式競賽。

我先大概說明一下高中的程式競賽,或其實我之前在 ptt 其實就有講過,我這邊稍微再整理一次。

高中的時候資訊競賽這一塊就有官方辦的了,比較重要的比賽是區域性的程式競賽,我的學校(師大附中)在台北市,因此叫做北市賽,全名是:台北市資訊能力競賽。每個學校能夠派出的選手名額有限,因此如果太多人,學校會先辦一個校內賽。

北市賽的獎項分成四種:一等獎 5 個、二等獎 5 個、三等獎 10 個跟入選獎,前十名(也就是一二等)可以參加全國賽。

全國賽就是各個區域賽的前十名聚集在一起比賽,獎項跟區域賽一樣,而全國賽前十名可以保送 TOI 選訓營。

TOI 就是臺灣資訊奧林匹亞研習營 Taiwan Olympiad in Informatics,想進去 TOI 的話有兩種管道,第一種就是全國賽前十名,第二種是 TOI 會自己辦一個入營考,入營考的前二十名也能進去。

所以一屆 TOI 會有 30 個人,這 30 個人進去之後就叫做選訓營的第一階段,會集體住到師大去培訓兩個禮拜。在這期間都是跟學校請公假,整整兩個禮拜不用去上學。而這兩個禮拜就是政府包吃包住,在師大的學生餐廳出示證件就能夠免錢吃飯。

培訓期間白天就是找資工系的教授來上課,教一些演算法與資料結構相關的東西,但大部分時間其實都還是靠自己練習跟研究。因為全部三十個人都有共同的興趣,所以要找人討論問題也很容易。晚上就是自由活動時間了,我只有在高一的時候進去過一次選訓營,那也是我第一次玩 Dota 這個遊戲。因為我們晚上都在打 Dota。

第一階段的兩週期間內會有兩次考試,考試成績會決定你能不能進去第二階段。我在這一個階段就被刷掉了(成績好像還是最後一名),能進到第二階段的大約有 12 個人左右,一樣繼續在師大培訓兩個禮拜,一樣也會有兩次考試。第二階段的兩次考試結束之後會取出前四名,這前四名就是國手了,代表國家去參加 IOI,資訊奧林匹亞。

除此之外呢,走這條競賽路線有一個額外的好處,那就是靠著這條管道升學。基本上只要你在第二階段有前幾名,都能夠保送台大資工,別人還在準備考試的時候你就已經是大學生了。比較後面的名次好像也能夠試著申請看看清大或是交大等等的資工系。

我最認真的時候應該是高一,那時為了準備入營考、北市賽等等可以跟學校請公假來練習,但也因此缺了很多課,例如說 log 的部分我好像幾乎整章都沒有上到。但請公假的時光滿開心的,可以盡情做自己喜歡做的事。

而這種程式題目平時的練習都會透過一種自動的系統來批改,叫做 Online Judge,線上測驗系統。最有名的就是UVa Online Judge,那時候我們大家習慣用的是建中資訊社自己架的系統,叫做 TIOJ。

我在練程式解題的時候,就是不斷去找新的題目來練習,同時也在看一些資料結構與演算法的書籍,每解完一題還會在自己的 BBS 個版上面記錄心得:

那時幫助我最大的網站是演算法筆記,可以看著上面的文章來練習,再利用解題的方式去驗證自己到底有沒有搞懂。

國中跟高中那幾年裡面,我大概學了一些基本的東西,像是:DFS, BFS, 最短路徑, 最小生成 🌲, 背包問題等等。

但其實對我來說幫助最大的不是學了哪些演算法,知道哪些資料結構,而是在解題過程中培養的能力。可以從題目快速的就猜到大概是哪一種題型,大概要怎麼解。這些思考的過程跟方法都是很重要的收穫。

除此之外,其實最大的幫助有兩個,就是我標題講到的那兩個。

開闊眼界

在資訊競賽中認識的朋友們都是一時之選,是全台灣資訊競賽最厲害的一群人。我認識的大部分的人後來都跑去唸台清交的資工系了,都往本科系這條路上繼續走,到大學都一直有繼續比程式競賽。也有滿多的人都跑去 Google 實習什麼的。

會說開闊眼界,是因為這些人其實就是全台灣資訊能力最頂尖的一群人(其中的一群人啦,我相信還有更多不是走這一塊但資訊能力一樣超強的人),認識到這些人會讓我知道前段的人的能力到哪裡,都過著什麼樣的生活。

知道人外有人天外有天也是一件很重要的事,會讓你知道自己有多渺小。認識了這麼多強者,就會覺得自己連邊都沾不上。

自信的泉源

怎麼維持自信的平衡是一件很重要的事,前面才講說覺得自己很渺小,怎麼現在又說程式競賽反而是我自信的來源?這個平衡是指說知道比你優秀的人在哪裡,同時也知道自己在哪個位置。雖然跟他們比起來很渺小,但其實跟同年齡的其他人來說,我的資訊能力已經是很不錯的了。

之所以程式競賽這一段經歷會成為我自信的其中一部分,是因為演算法與資料結構這些其實是大學資工系會修到的課(但課程難度比高中學的那些還要難上好幾倍)。在這之前,其實我的程式都是自己學的,無論是一開始的 VB 或是之後拿來程式解題的 C/C++,都是自己練習而成。儘管之後有老師帶,但也只是給一些方向給資源,其實大部份時間還是靠自己。

因此,演算法與資料結構這一塊就變成我跟資工系的連結之一,儘管我從來都沒有唸過資工系,但至少我知道他們會學些什麼,而且我也確實學過其中一部分的東西。這讓我覺得我好像也不是那麼非本科系,至少我可能有半隻腳是在資工系裡面的(?)。

而且比起其他同樣是自學的人,他們可能會先學寫網頁,像大部份的程式補習班都是直接教你那些工作以後會用到的技能,而不是著重在這些資訊工程本科系的基礎(演算法與資料結構、作業系統、網路概論、計算機組織等等),跟他們相比,我就多了演算法與資料結構這一塊的基礎,這通常是半路轉職出家的工程師最缺乏的一塊。

而我很幸運地,在高中就把這一塊補齊了。(但我其實只會很基本的,而且一段時間沒練習就會忘光)

上面這一段競賽經歷是我資訊生涯中很重要的一塊,給了我十足的自信心,覺得自己不會比本科系的人還要差。除此之外,高中也是我遠離 VB,開始學習其他程式語言的時候。

山不轉路轉

高二的時候我們班上很喜歡打橋牌,每一節下課都在打,全盛時期可以開到四桌,同時有 16 個人在玩牌。但因為要面臨大考,班導覺得打橋牌會影響到其他人(因為我們打牌真的滿吵的),所以禁止帶橋牌到班上,全部撲克牌都沒收。

那時大約是 2011 年,智慧型手機還沒興起,大家用的都是現在俗稱的「智障型手機」,最受歡迎的牌子是 Sony Ericsson。那時候手機裡面也有遊戲,大家喜歡玩的是小朋友下樓梯、Doodle jump 跟 Lumines,都是單機遊戲。一直到之後有小精靈或是三國殺大家才會用藍芽連線。那時候的手機可以上網,但是是用 GPRS 或是 2G,要瀏覽什麼網頁都很慢。

既然班導下令不能帶橋牌,那有沒有可能我自己寫一個在手機上跑的橋牌連線程式呢?這樣大家就可以用手機打橋牌了!

就因為這個突然其來的 idea,我開始研究 J2ME。在這之前,我完全沒寫過 Java。

那時候的我似乎對程式已經滿有 Sense 的了,知道要完成橋牌連線程式最重要的一部分就是藍芽連線,只要可以搞定這一塊,其他的其實都不是什麼問題,於是我就上網找相關的資源來看。

我印象最深刻的是中文資源極少,幾乎沒什麼文章是在講 J2ME 的藍芽連線,我只好到後來找到一些國外的文章或甚至是 PDF 電子書裡面的其中一個章節,才總算搞懂要怎麼在 Java 裡面呼叫藍芽的各種功能,像是搜尋跟連線。還記得我國一時寫的那個五子棋連線程式嗎?因為那時候已經有相關經驗,所以這一次寫起來其實沒什麼困難。其實就只要把藍芽的部分搞定,剩下就差不多了。

大概兩個禮拜的時間,我就完成了我第一個手機應用程式:多人藍芽連線橋牌遊戲。

這是遊戲畫面,還有主畫面跟邀請對戰的畫面,流程就是其中一個人當 Server,另外三個人用藍芽連線到他的手機,所有資料都是透過這台手機再轉傳給其他人。

完成這個遊戲的時候很有成就感,因為我找了好多資料去研究藍芽怎麼連線,而且這是我第一個手機應用程式,可以隨時拿給別人看說:這我寫的。

但這遊戲在我們班上的存活時間大約是五天,五天過後就被小精靈給取代了,就再也沒有人用手機玩橋牌了。

不像補習班的補習班

高中的最後一條支線是我那時候的補習班:得勝者文教。

我是個不愛補習的人。

但每次總是會被補習班的招生人員吸引,覺得應該去補習班拼拼看,我要考台大!我要考榜首!何況這間補習班跟其他的不一樣,當初負責招生的老師跟我聊的不是學校成績,而是魔獸信長該怎麼出裝比較好,聊說打信長打了多久、最愛用哪一個角色。就是因為這樣,我選擇加入這個補習班,因為我覺得他特別。

以後見之明來看,我選對地方了。

我是個不愛補習的人。這我前面講過一次了,為什麼要再講一次呢?代表我真的很不愛補習。

我那時候是從高一開始補吧,一直補到高二學測結束為止,可是我補了三個月還是半年我就不想補了,我實在是懶得去補習班,要被關在同一個地方實在是太難受了,我想要自由,想要百分百的自由。於是我就跟我媽說我不想補了,後來就到補習班去辦退費。

在退費的時候有跟補習班主任聊了一下,他有問我說我為什麼不想補之類的,我就說因為我覺得靠自己念也可以,再加上我有「其他的升學管道」。沒錯,我指的就是上面說的資訊競賽,曾經我是想要靠著這條路升學的,但身為一個只會空想而不會付諸實際努力的人,最後也僅能是空想。

而主任聽到這個之後很感興趣,我就跟他多說了一點,跟他說什麼是程式解題,什麼是資訊奧林匹亞,要怎樣才能保送台大資工,才能出國比賽。他看起來滿感興趣的,我那時候就覺得,這個人不一樣。

儘管如此,我還是離開補習班了。因為我就是不喜歡那個地方。

一直到學測失利之後我發現:「不行,快要指考了,不真正拼一次不行了」,才又重回補習班去乖乖待著,很努力地唸了一百天左右的書。但那時我看上的是補習班的環境,一個你可以整天待在那邊寫考卷,看參考書的環境。這點是其他地方都沒辦法給我的,我是一個在家裡就絕對、絕對念不下書的人。

高三學測結束的時候,主任問我有沒有認識會寫網頁的人,他想來做個學測落點分析之類的網頁,我那時候介紹他我一個大安高工的朋友,我知道他會寫 PHP。後來我那朋友跟我說:「PHP 很簡單啦,你一定學一下就會」,我就跑去看了一下 PHP 的教學,看一看發現:「哇,真的好簡單!」

從那時候開始,我就習得了網頁後端這個技能。

話說我其實在高中的時候就想學 Ruby on Rails,那時候是 Rails 最潮的一段時間,那時候的我完全沒有任何後端基礎,衝著 Rails 說它可以快速開發這點就去找一些資源學了一下。碰了一點之後發現:好難,真的好難。我明明就有程式基礎,為什麼會這麼難?

從那時候開始,我就認為 Rails 不適合初學者,因為它簡化太多東西了,我不知道為什麼這邊只要設定一個東西,另外一邊的程式就能夠接收到。我不知道我要改的時候要改哪邊,它全部都幫我設定好了。這大概就像是直接叫一個新手去學 React 一樣,你可以教他,他一樣會寫,但是他不知道為什麼要這樣用,他不知道原來在 React 之前我們還有 vanilla js,還有 jQuery。

但總之呢,我很慶幸接觸了 PHP,它打開了我網頁設計的這一條路。

而剛剛提到的補習班主任跟我那個朋友,在我高三的時候共同打造出網頁版的學測落點分析系統,那時候好像算是個創舉,因為很少人這樣做,都只是提供實體的落點分析服務(這段其實我不太確定,也有可能網頁版落點分析已經有很久了)。但至少,我們幫助補習班多了一個新產品。

Android 的興起

高中生涯結束於跟社團的朋友們一起去南部玩,那時候大家都差不多換成智慧型手機了,而我靈機一動,想說順便來練功試試看寫一個 Android App 好了,最後寫出了一個超級陽春的行事曆 App,說穿了其實就只是一個 ListView 而已。

但寫出這個的時候我也證明了一件事:對那時的我來說,學一項新的東西已經沒什麼困難的了(這邊專指寫應用程式)。寫網頁、寫 App 對我來說都差不多,只是程式語言換了一個而已,背後的原理都是一樣的。

而會寫 Android App 這個技能,也在日後起了作用。

邁向下一個階段

國中是累積程式實力,不斷藉由解決自己的問題打造出各式各樣的小程式。高中是沈浸於程式解題,打下演算法與資料結構以及解題的基礎,也是與資工本科系的連結之一,除此之外也認識到資訊能力頂尖的一群朋友。同時也培養了自己寫應用程式的能力,會寫網頁又會寫 App。

那大學呢?大學就是真正走向戰場,驗證自己在市場上的價值的時刻。

在把時間軸推進到大學之前,其實還有一個重要的問題必須回答:「為什麼我是念哲學系?」(如果你現在才知道我念哲學系,沒關係,畢竟前面這些文章看一看,你也絕對不會想到我是念哲學系)

其實我在高二以前,都還是把資工系定為我的第一志願的。那之後是什麼讓我轉變了呢?第一點是因為我開始發現自己其實滿討厭物理跟化學,對這些東西都提不起什麼興趣,尤其是化學,我最不喜歡的就是化學。

再來是因為我程式一路走來都自學,我那時候就想說:就算大學不念資工系,也還是可繼續自己自學程式啊,念不念資工系跟要不要寫程式是沒有衝突的兩件事情。就算不念資工也可以繼續精進程式。

學測我考了 60 級分,班排倒數第二,校排大概是最後 5 %,但我還是申請了幾所學校的資訊相關科系,像是北教大、國北教、中山、中央等等,這幾間都是我覺得這個級分可能有機會進去的科系。結果呢?結果放榜那天收到這封簡訊:

我那時已經決定,如果學測考不上,指考就要改考一類組了。比起物理化學,我更喜歡歷史跟公民(不喜歡地理),考一類組的分數一定會比考二類組高很多很多,而且念自己喜歡的科目也比較能夠念得下去。因此,就做了考一類組這個決定。

分數出來以後發現自己大概能上台大最後面幾個系跟政大的非商科,原本想念政大廣告,覺得廣告系聽起來很有趣,不然的話去念個語言相關的也可以,至少能學會一種新的語言。但後來跟補習班主任以及家人討論過後,發現文組的任何一個科系我好像都不排斥,但也沒有到很喜歡,那不如就選校吧,去台大看看台大長什麼樣子。

我仔細想一想也合理,這輩子還沒進過台大,現在不進,以後也不會進了,那不如就去台大看看吧!於是我按照分數填了志願,最後上就上了台大哲學系。這就是我之所以為什麼不念資工系而是念哲學系的故事。

但我對哲學當然也不排斥,甚至在看了史上最強哲學入門之後對哲學產生了興趣,覺得哲學其實也沒有這麼艱澀難懂。

進了哲學系之後,開啟了我人生中一個新的篇章。

續集傳送門:

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