期末考結束了!這學期我負責開了大二必修課:資料結構(Data Structure),雖然作業、小考都是由TA(課程助理)幫我批改,不過期中期末考都是我自己把所有的考卷改完的。總共大約是將近150份的考卷,有兩個班。而期末考的內容,其實基本上我把大部分的規則、程式碼都寫在題目裡面或者放在附錄讓同學可以一邊考試一邊參考。這個時代,講究的是「素養教育」,既然很多東西問AI就可以知道了,那麼學生要如何培養能力?要學的東西是什麼呢?
在改了超過一百份的考卷之後,也從學生的作答當中觀察到了一些現象,而最後很可惜被扣了很多分數的學生,甚至是不及格的學生,在「以演算法的思維來想程式的執行」這種思考方式方面,稍微比較弱一些。
演算法的邏輯&程式的執行步驟
在我們系上,課名叫做資料結構,不過基本上「資料結構和演算法(data strucutre and algorithms)」是難分難捨的概念,畢竟討論到資料的排列、資料的群組、資料的關係 (這裡的資料指的是單一data) ,勢必還是連帶會討論到演算法。只是既然課名叫做資料結構,課程的側重點不同而已。而演算法,這三個字,或algorithm這個詞,聽起來可能太沉重、太高深,平易近人一點說,它是「程式的操作步驟」。
不過,對這門課很苦手的同學,有很大一部分的同學很難掌握住「操作步驟」的概念,也就是說,沒有辦法很好的在思考過程中豎立良好的操作步驟原則,讓程式可以順利的在腦海中run下去。
在介紹每一種資料結構的時候,也會連帶介紹該資料結構的插入(insertion)、刪除(deletion)、搜尋(search)、遍歷/走訪(traverse)會發生什麼事情,而在進行這些資料的運算(operation)的時候,就會有一連串的步驟來進行他們的記憶體安排、重組、規劃資料與資料之間的關係(reference and pointer的概念),但如果沒能把握住步驟,很容易就會在這些過程當中迷失,然後導不出下一步的結果。
我在課堂上會說,「同學們,要把你的頭腦變成一台電腦!」
其實意思就是這是一種思考的鍛鍊,人腦在想事情的時候很容易變成經驗的判斷,或者利用捷思法略過各種細節。然而,在想這些資料結構的運算時,要能像電腦一樣堅持住那些操作步驟。
例如,我在題目中會給定多個資料元素,讓同學們試著透過程式碼或者根據題目的敘述,推演出最後會輸出的結果。
完全能吸收且表現得好的同學,當然是能順利的輸出結果,寫出/畫出答案。但是有的同學沒有辦法推出結果,有的同學結果是寫出來了,可是一樣的邏輯一樣的步驟,卻會在結果上只出現半套,有一半成功了但有另一半卻偏離步驟了。
而若是在幾乎是開書考般的考卷上也沒有辦法順利推出最後的結果的話,那麼我想這在寫程式方面也是相當吃虧的。我們寫程式總不可能寫一行就試run一次,還是必須得有個規劃程式碼的過程。而即使是使用AI幫助寫程式碼,更重要的能力也是去閱讀那些程式碼,然後要能跟所需要撰寫的功能相互進行檢查,在腦中推演看看是否能達成所需的目的。若是簡單的資料處理步驟都無法在腦海中跑出來,遑論更大型的程式結構。
課本上寫說,學習資料結構的目的在於學習如何製作一個有效率的程式。這門課了解資料的關係、在記憶體裡的排列、了解結構的運算步驟,了解程式的操作步驟等等,我想不只是資料結構本身,同時也是在鍛鍊一個寫程式的人訓練自己可以把寫好的東西適用到各種情境之上,也就是把固定的操作步驟(演算法)適用到該段資料的操作上。
鍛鍊演算法思維的進步方法
以大二必修課來說,如果在這個階段還未能進入狀況的同學,還時常覺得腦袋糊糊的同學,我想還是有一些進步方法的。
- 先從複習程式設計的基礎開始
通常以資管系來說,大一會有程式設計的基礎課程,可以回頭去看看當時的練習題,從基本的if/else和那些for迴圈開始看,想想自己能不能在不讓電腦run的情況下,自己丟input再自己導出output。
更進階的,可想想自己能不能想出「如何測試」的這個問題。也就是說,如果要測試自己的解法是不是對的,要丟哪些測試子進去,可以最好的檢查出程式有沒有錯誤。可以是極端小的值、極端大的值,除此之外,還有哪些值也是應該值得要被放進去的,如果能夠連測試面都想得到,想必對於該段程式碼的運作已經相當能熟練地在腦中推演了。
2.挑戰解題
如果想要更加鍛鍊這方面的思維,甚至可以去找解題書,例如《提升程式設計師的面試力:189道面試題目與解答》之類的,或者上leetcode刷題。
不過,如果這方面太困難的話,也可以搭配資料結構來對應解題,現在leetcode上面也可以用資料結構的單元來選擇練習題,可以感受一下不同的資料結構變成程式題目的時候會是什麼樣子。對於寫程式碼和建立思維來講,都是不錯的練習。 而即使是中文書,也有不少資深老師出書把解題的題目結合資料結構的單元編成教科書,對於操作方面很不擅長的同學,也都可以從這類的參考書籍得到不少啟發。
- 抽象思考、文意理解與英文能力
最後,還有一些同學是基本的讀書方法也可以再更多的進行修正,有的時候透過同學下課時後來問問題,也讓我注意到有些同學在閱讀教科書/講義的內容,容易會有不理解的地方,尤其遇到符號變多的時候,會很難以轉換。
以國高中數學來說,我想應該不少數學老師會利用在題目上劃線,教同學們把應用問題的敘述轉換成數學式子,這樣的教學法來進行教學。所以同樣的道理,在資料結構這門課程也可以應用類似的想法來學習,只是大學課堂時間有限,不一定所有的概念都能夠手把手的像國高中數學老師一題一題解釋畫線寫式子,但是,既然都是大學生了,經過國高中的訓練後,應該已經能用這樣的方式來幫助自己理解內容。
而除了文字轉換成數學式或程式碼的能力之外,純粹的文意理解也是可以加強的地方,而還有一點很重要的事,有的時候用中文很難理解的部分,其實用英文去想,或者用程式碼、圖形去想會比較簡單而直觀,那麼也可以放膽地讓自己不要再受到中文的限制。我感覺有些同學會很需要中文來建立自己的安全感,不過中文可以想成課堂上溝通的一種媒介而已,真的要去理解課程內容,我還是覺得直接用英文K書也許會更容易一點。而最後,若能用自己的話重新說一遍或是作圖重新想一遍,那麼就表示概念上已經能理解了。
後記
這學期,從授課者的角度認識了一門課,這樣run過一輪之後我覺得其實還蠻有意思的。儘管這是一門經典的必修課,內容的本身部分可能不會有什麼太多新的變化,但是教學的思維和學這門課所要培養的思維與能力,應該算是有與時俱進吧,也希望同學們能在經典的課程中學到東西,去迎接新世界。