close
老師您好, 我是 b94 的畢業生, 看到這麼多 CSIE 大家族的成員分享心得.
心裡也有一些想法想分享, 希望能給學弟妹們當作一些參考.
首先照規矩給一下自己的背景, 我應該算是滿少出沒的族群.
勉強能跟強者這個稱號沾上邊, 有偶而能幫到同學的人.
但是跟貨真價實的強者們比起來還是差得很多, IOI 在中部地區初賽就被刷掉了.
雖然名次足夠保送上研究所, 但是總是離角逐書卷的範圍有段不小的距離.
我想這樣的背景應該不會讓人覺得太遙不可及吧.
我覺得學弟妹們有 DSA 這麼扎實的課程可以修, 是件很幸運的事情.
如果最後 DSA 以調降難度收場, 將會非常的可惜.
雖然說對於只有接觸過 ACM online judge 基本題跟計程作業的資工系大學新生,
可能會覺得需要寫加上 debug 300~500 行 code 的程式作業量實在是很大.
不過到了真的要把自己所學應用出來的時候, 就會發現這樣長度的 code 能做的事情很少.
隨意想到的 idea , 像是要寫一隻程式把自己個人板上的文章複製下來,
就會逼近這個數字了.
如果要實做再複雜一點功能, 把介面弄好一點, 處理好例外狀況,
程式碼的數量就會輕易的突破上千行.
如同前面學弟所提的, 基於行政上面的問題, 如果老師要這樣紮實的要求學生,
會帶給老師自己還有 TA 們很大壓力, 所以許多老師最後以降低課程與作業難度解決.
雖然表面上學生輕鬆拿到了不錯的成績, TA 也不會太勞碌, 像是個雙贏局面.
但是從長遠的角度來看, 這只是把必須要學的東西往後拖延.
不管是做研究或是在資訊領域就業, 這種程度的熟練是必要的.
與其在往後捉見見肘, 或是跟難得的機會. 理想的工作失之交臂.
不如趁現在有熱心的老師. TA . 同學協助, 好好的把程式練好.
雖然說這樣的學習過程往往會讓初學的學弟妹們感到挫折,
但是這就是要成為獨當一面的資工人所必經的道路.
培養起好的寫程式能力非得靠一次次練習與失敗經驗中學習.
我也想找到一本秘笈, 告訴我怎樣照步驟 123 就會寫出好程式.
不過這世界上不存在這種東西, 其實光是定義怎樣是好程式. 壞程式都有困難,
涉及到開發程式的速度, 執行效率, 可讀性( 這會影響到 bug 好不好 De ),
等等多方面的取捨, 結論還是沒有明確的最佳解.
所以 Martin Fowler 在教人改善程式的 Refactoring 一書之中也只能用
"Bad Smell" 這樣的字眼來形容不好的程式.
這情況就像是學寫作文, 除了八股文跟 GRE AWA 這種特例,
一般只能一邊多去閱讀, 一邊多寫幾篇長文, 這樣來增進自己的寫作程度.
前面有人提到對語言. 工具的熟悉程度會影響到寫作業的速度.
我覺得這些地方的確會有影響, 但是造成五倍十倍的時間差距還是在於建構程式的思路.
引用 Frederick Brooks 在 "人月神話" 提到的理論 :
程式的複雜度跟其 code 長度不是呈單純正比的 O( n ) 關係, 而是呈指數關係.
一支大約有 300 行 code 的程式要要寫完並且 debug 完,
複雜度會比寫好三支 100 行的程式高上不少.
如果沒有好的思路去釐清這些 code , 結果就是這樣的差距.
在寫大一計程最簡單的作業的作業時, 用到的變數可能就只有 5. 6 個,
就算把他們命名成 ABCDEF 也不會有太大的問題, 這種程度難不倒打敗大考的人的記憶力.
忘記傳遞參數就把變數從 local 改宣告到 global ,
寫到某個地方發現要再執行相同的步驟一次, 就直接從前面 copy / paste .
這些壞習慣的影響在要寫的程式不夠大的時候看不太出來,
反而是好好的整理架構的人會顯得有點小題大作.
當要寫的程式變長, 你沒有辦法記住程式裡的每一行的時候,
這些做法就會讓你補洞補到 0rz , 然後 bug 永遠找不出來.
其實實際上你如果逼強者們看這樣寫出來的 code 要他們把程式修好,
他們 0rz 的時間會跟你差不多是幾十個小時, 結果他們一定會翻桌重寫.
差別就在於建構程式的思路,
現在在這邊不是要求學弟妹要去碰什麼 Design Pattern 之類的東西,
只是非常簡單的 Divide and Conquer 後整理好想法再寫程式.
像是前面舉例的複製個板文章的程式, 粗略分析起來應該會有個 telnet 連線的部分.
字串處理的部分. 下指令控制 BBS 的部分, 和檔案讀寫的部分.
這些部分各自要負什麼責任, 完成什麼工作, 然後它們之間要怎麼溝通,
參數是什麼, 回傳值是什麼, 這在寫程式的過程中都要在心裡有個底.
當程式有問題的時候可以有系統地排除掉不可能發生問題的部分,
鎖定該盯的地方, 而不用把整個程式重看一遍, 要花的時間也就會大幅減少.
像是如果單純圖方便把變數丟到 global , 讓所有人都可以任意改它,
當這個變數爛了, 你會答不出來是哪裡有問題.
這就像在部隊裡管槍械彈藥, 如果都是隨便來, 要用自己拿, 用完記得還,
沒有記錄. 沒有負責人. 哪天 406 跑出營區你會永遠想不出來到底是怎麼發生的.
但是如果是把函式. 介面寫好. 出了問題可以一層一層往回推,
看到某個參數錯了, 或是回傳值爛了, 兇手馬上就現形了.
像前面所說的, 這種分析. 設計架構沒有絕對好的做法, 也沒有一蹴可幾的學習方法.
靠的就是 trial and error .
當架構想錯要重改 code 的時候請不要灰心, 這代表你又學到東西了.
成功靠的是經驗, 而經驗只能從失敗中汲取.
除了最重要的寫程式的思維, 還有一些工具像是 Debugger 或是 Version control
也建議趁這個機會熟悉.
這些工具之所以被創造出來就是因為大家依照實務經驗認為它們有其必要性,
只是因為前述的原因, 學校作業給的難度不夠, 沒有辦法顯示出他們的好處.
當作業只有 50 ~ 100 行, 不要說 Version control , 可能連備份大家都懶得做.
弄丟了大不了重 code 一份, 這點時間大部分的人都負擔得起.
diff 這種長度的程式也沒有甚麼意義, 如果是不小心改爛掉,
跑得動變成跑不動, 一樣砍掉重練辦理.
但是 DSA 作業改爛又改不回來一次, 蒸發掉一次,
我想大家就體會到為什麼 Version control 會存在於這世界上了.
Debugger 也是一樣的情況, 當程式不夠複雜, 就是 printf 大法到底,
反正跟監看記憶體差不多.
當程式一大起來, 你會很高興 debugger 不只有監看記憶體,
還有像是 stack trace 這種東西好用.
我想再重申一次我對 DSA 這麼扎實的看法,
我覺得這樣的份量才是反應資工人在現實世界面對的問題的基本難度.
這標準不會因為台大資工以前沒有這樣要求, 或是其他學校沒有這樣要求而變得不合理.
雖然放眼望去, 要寫演算法作業. 要寫大程式.
然後又有嘮叨的學長說要學什麼什麼工具, 會讓人感到不知所措.
但是在學校這個溫馨的環境, 加上有願意奉獻的老師跟 TA , 有可以凹的同學.
這是克服必須跨過的難關的最佳機會, 跨過去後,
你寫程式實做能力才能開始跟上你的想法,
才能開始像資訊界裡眾多成員一樣, 有實現任何 idea 的自由.
我相信未來的你一定會覺得很值得的.
題外話:
我覺得資工系裡面一直有著一種微妙的 "強者" 文化,
會把一些人 tag "強者" 之後, 把他們當成不可拍打餵食珍奇異獸看待.
實際上扣除極少數極具天賦的人之外, 其他人只是曾經花在資工上面的時間比較多而已.
差距是有, 但是只要肯花時間追趕, 不是永遠拉不近距離的.
再加上新手遇到的問題通常問周遭的人就會問得到,
"強者" 走在前面常常會遇到求助無門的情況.
認真學習, 善用身邊的資源. 其實要縮短大學入學時的差距, 沒有想像中的難.
提到問問題, 其實有些問題我還是非常不喜歡.
像是 "我程式掛掉了, 我完全不知道原因, 你可以看一下嗎?" 或是
"可以直接告訴我該用哪個 function 嗎?"
如果問完這樣的問題, 作業交出去就不管了, 你是不會進步的.
要別人回答這樣的問題完全只是把你該花的努力轉嫁到別人身上而已.
我知道新手往往會有時間上的壓力, 被迫要問這樣的問題,
但是在問之前還是可以用一小段時間自己摸索一下, 整理出一點自己的想法.
再跟回答的人比對一下想法的差別, 這樣問問題才會進步, 回答也才有意義.
最後請大家記得不只是作業有困難要找強者, 有活動. 出去玩也請不要忘記強者們.
謝謝大家耐心閱讀.
延伸閱讀:
寫這樣的文章總是非常難提筆, 因為終究我得程度只是普普, 沒有辦法從很高的高度去寫
所幸真強者 vgod 學長也寫過他學習經驗的分享, 他的寫的深度跟廣度都遠超過我,
推薦學弟妹們有時間可以慢慢研究:
vgod - "追求神乎其技的程式設計之道"
http://blog.vgod.tw/category/divine-code/
心裡也有一些想法想分享, 希望能給學弟妹們當作一些參考.
首先照規矩給一下自己的背景, 我應該算是滿少出沒的族群.
勉強能跟強者這個稱號沾上邊, 有偶而能幫到同學的人.
但是跟貨真價實的強者們比起來還是差得很多, IOI 在中部地區初賽就被刷掉了.
雖然名次足夠保送上研究所, 但是總是離角逐書卷的範圍有段不小的距離.
我想這樣的背景應該不會讓人覺得太遙不可及吧.
我覺得學弟妹們有 DSA 這麼扎實的課程可以修, 是件很幸運的事情.
如果最後 DSA 以調降難度收場, 將會非常的可惜.
雖然說對於只有接觸過 ACM online judge 基本題跟計程作業的資工系大學新生,
可能會覺得需要寫加上 debug 300~500 行 code 的程式作業量實在是很大.
不過到了真的要把自己所學應用出來的時候, 就會發現這樣長度的 code 能做的事情很少.
隨意想到的 idea , 像是要寫一隻程式把自己個人板上的文章複製下來,
就會逼近這個數字了.
如果要實做再複雜一點功能, 把介面弄好一點, 處理好例外狀況,
程式碼的數量就會輕易的突破上千行.
如同前面學弟所提的, 基於行政上面的問題, 如果老師要這樣紮實的要求學生,
會帶給老師自己還有 TA 們很大壓力, 所以許多老師最後以降低課程與作業難度解決.
雖然表面上學生輕鬆拿到了不錯的成績, TA 也不會太勞碌, 像是個雙贏局面.
但是從長遠的角度來看, 這只是把必須要學的東西往後拖延.
不管是做研究或是在資訊領域就業, 這種程度的熟練是必要的.
與其在往後捉見見肘, 或是跟難得的機會. 理想的工作失之交臂.
不如趁現在有熱心的老師. TA . 同學協助, 好好的把程式練好.
雖然說這樣的學習過程往往會讓初學的學弟妹們感到挫折,
但是這就是要成為獨當一面的資工人所必經的道路.
培養起好的寫程式能力非得靠一次次練習與失敗經驗中學習.
我也想找到一本秘笈, 告訴我怎樣照步驟 123 就會寫出好程式.
不過這世界上不存在這種東西, 其實光是定義怎樣是好程式. 壞程式都有困難,
涉及到開發程式的速度, 執行效率, 可讀性( 這會影響到 bug 好不好 De ),
等等多方面的取捨, 結論還是沒有明確的最佳解.
所以 Martin Fowler 在教人改善程式的 Refactoring 一書之中也只能用
"Bad Smell" 這樣的字眼來形容不好的程式.
這情況就像是學寫作文, 除了八股文跟 GRE AWA 這種特例,
一般只能一邊多去閱讀, 一邊多寫幾篇長文, 這樣來增進自己的寫作程度.
前面有人提到對語言. 工具的熟悉程度會影響到寫作業的速度.
我覺得這些地方的確會有影響, 但是造成五倍十倍的時間差距還是在於建構程式的思路.
引用 Frederick Brooks 在 "人月神話" 提到的理論 :
程式的複雜度跟其 code 長度不是呈單純正比的 O( n ) 關係, 而是呈指數關係.
一支大約有 300 行 code 的程式要要寫完並且 debug 完,
複雜度會比寫好三支 100 行的程式高上不少.
如果沒有好的思路去釐清這些 code , 結果就是這樣的差距.
在寫大一計程最簡單的作業的作業時, 用到的變數可能就只有 5. 6 個,
就算把他們命名成 ABCDEF 也不會有太大的問題, 這種程度難不倒打敗大考的人的記憶力.
忘記傳遞參數就把變數從 local 改宣告到 global ,
寫到某個地方發現要再執行相同的步驟一次, 就直接從前面 copy / paste .
這些壞習慣的影響在要寫的程式不夠大的時候看不太出來,
反而是好好的整理架構的人會顯得有點小題大作.
當要寫的程式變長, 你沒有辦法記住程式裡的每一行的時候,
這些做法就會讓你補洞補到 0rz , 然後 bug 永遠找不出來.
其實實際上你如果逼強者們看這樣寫出來的 code 要他們把程式修好,
他們 0rz 的時間會跟你差不多是幾十個小時, 結果他們一定會翻桌重寫.
差別就在於建構程式的思路,
現在在這邊不是要求學弟妹要去碰什麼 Design Pattern 之類的東西,
只是非常簡單的 Divide and Conquer 後整理好想法再寫程式.
像是前面舉例的複製個板文章的程式, 粗略分析起來應該會有個 telnet 連線的部分.
字串處理的部分. 下指令控制 BBS 的部分, 和檔案讀寫的部分.
這些部分各自要負什麼責任, 完成什麼工作, 然後它們之間要怎麼溝通,
參數是什麼, 回傳值是什麼, 這在寫程式的過程中都要在心裡有個底.
當程式有問題的時候可以有系統地排除掉不可能發生問題的部分,
鎖定該盯的地方, 而不用把整個程式重看一遍, 要花的時間也就會大幅減少.
像是如果單純圖方便把變數丟到 global , 讓所有人都可以任意改它,
當這個變數爛了, 你會答不出來是哪裡有問題.
這就像在部隊裡管槍械彈藥, 如果都是隨便來, 要用自己拿, 用完記得還,
沒有記錄. 沒有負責人. 哪天 406 跑出營區你會永遠想不出來到底是怎麼發生的.
但是如果是把函式. 介面寫好. 出了問題可以一層一層往回推,
看到某個參數錯了, 或是回傳值爛了, 兇手馬上就現形了.
像前面所說的, 這種分析. 設計架構沒有絕對好的做法, 也沒有一蹴可幾的學習方法.
靠的就是 trial and error .
當架構想錯要重改 code 的時候請不要灰心, 這代表你又學到東西了.
成功靠的是經驗, 而經驗只能從失敗中汲取.
除了最重要的寫程式的思維, 還有一些工具像是 Debugger 或是 Version control
也建議趁這個機會熟悉.
這些工具之所以被創造出來就是因為大家依照實務經驗認為它們有其必要性,
只是因為前述的原因, 學校作業給的難度不夠, 沒有辦法顯示出他們的好處.
當作業只有 50 ~ 100 行, 不要說 Version control , 可能連備份大家都懶得做.
弄丟了大不了重 code 一份, 這點時間大部分的人都負擔得起.
diff 這種長度的程式也沒有甚麼意義, 如果是不小心改爛掉,
跑得動變成跑不動, 一樣砍掉重練辦理.
但是 DSA 作業改爛又改不回來一次, 蒸發掉一次,
我想大家就體會到為什麼 Version control 會存在於這世界上了.
Debugger 也是一樣的情況, 當程式不夠複雜, 就是 printf 大法到底,
反正跟監看記憶體差不多.
當程式一大起來, 你會很高興 debugger 不只有監看記憶體,
還有像是 stack trace 這種東西好用.
我想再重申一次我對 DSA 這麼扎實的看法,
我覺得這樣的份量才是反應資工人在現實世界面對的問題的基本難度.
這標準不會因為台大資工以前沒有這樣要求, 或是其他學校沒有這樣要求而變得不合理.
雖然放眼望去, 要寫演算法作業. 要寫大程式.
然後又有嘮叨的學長說要學什麼什麼工具, 會讓人感到不知所措.
但是在學校這個溫馨的環境, 加上有願意奉獻的老師跟 TA , 有可以凹的同學.
這是克服必須跨過的難關的最佳機會, 跨過去後,
你寫程式實做能力才能開始跟上你的想法,
才能開始像資訊界裡眾多成員一樣, 有實現任何 idea 的自由.
我相信未來的你一定會覺得很值得的.
題外話:
我覺得資工系裡面一直有著一種微妙的 "強者" 文化,
會把一些人 tag "強者" 之後, 把他們當成不可拍打餵食珍奇異獸看待.
實際上扣除極少數極具天賦的人之外, 其他人只是曾經花在資工上面的時間比較多而已.
差距是有, 但是只要肯花時間追趕, 不是永遠拉不近距離的.
再加上新手遇到的問題通常問周遭的人就會問得到,
"強者" 走在前面常常會遇到求助無門的情況.
認真學習, 善用身邊的資源. 其實要縮短大學入學時的差距, 沒有想像中的難.
提到問問題, 其實有些問題我還是非常不喜歡.
像是 "我程式掛掉了, 我完全不知道原因, 你可以看一下嗎?" 或是
"可以直接告訴我該用哪個 function 嗎?"
如果問完這樣的問題, 作業交出去就不管了, 你是不會進步的.
要別人回答這樣的問題完全只是把你該花的努力轉嫁到別人身上而已.
我知道新手往往會有時間上的壓力, 被迫要問這樣的問題,
但是在問之前還是可以用一小段時間自己摸索一下, 整理出一點自己的想法.
再跟回答的人比對一下想法的差別, 這樣問問題才會進步, 回答也才有意義.
最後請大家記得不只是作業有困難要找強者, 有活動. 出去玩也請不要忘記強者們.
謝謝大家耐心閱讀.
延伸閱讀:
寫這樣的文章總是非常難提筆, 因為終究我得程度只是普普, 沒有辦法從很高的高度去寫
所幸真強者 vgod 學長也寫過他學習經驗的分享, 他的寫的深度跟廣度都遠超過我,
推薦學弟妹們有時間可以慢慢研究:
vgod - "追求神乎其技的程式設計之道"
http://blog.vgod.tw/category/divine-code/
全站熱搜
留言列表