距離上一篇文章也超過三個月了,直到最近才靜下心決定把這個系列補完...
初學者的慣性思維:學?背就對了
身為從小接受標準華式教育的我來說,說到「學習」,最直接的聯想便是「背」。
國文背唐詩、背課文、背生字註釋,
數學背質數表、背面積公式、背二元一次方程式,
英文背單字、被片語、背文法,
歷史背朝代、背人名、背年份、背俄德法美日奧義英......
基本上,只要你勤背、肯背、死命背,把課本上的內容複製到腦裡,面對考試基本上都不會混得太差,甚至到大學考試這套基本上都管用。
因此,在出學程式語言時,我也理所當然的拿出「背字訣」,把看到的所有東西不加思索地整理起來,想說只要把所有東西都背起來,一定就能漸漸掌握 programming 了吧?
程式語言的整數型別有 byte、small int、int、big int,每一種型別又都有自己的上界下界?背!
String 相關的 function 有split( )、slice( )、concat( )、replace( )、find( ),每種 function 又有各種不同組合的 arguments 配合不同的情境?背!
ASCII 的每個英文字母、數字、符號都有相對應的數字?背!
html 的 tag 有好多種,每一種又可以配合不同的 CSS property 操作?背!
......
當我的 word 程式筆記來到第五十幾頁時,我開始有點吃不消了。
首先是寫下了這麼多的學習內容,這些龐雜的而瑣碎的筆記卻難以整理成有主軸的概念系統,讓我完全沒有任何在「學習」的感覺,反而有點像是在編寫字典,照著比劃、順序依序抄寫而已;
而且尷尬的是,這本「字典」筆記也不怎麼實用,如果哪天我想查一下 str.split( ) 這個函式的參數順序怎麼放時,與其去翻我是寫在筆記哪一頁的哪一行,還不如直接 Google “Python string split“,馬上就能找到比筆記更詳盡的官方文件了。
第二個問題則是在心理層面。當要背的東西隨著你學習的進度海量增加時,勢必會開始背了後面、忘了前面的狀況。
雖然這個現象挺正常的 ( 尤其是浩瀚的程式領域 ),但對於一個保持著「定型心態」的學習者來說,無法完美的背下這些學習到的所有知識細節,就好像這段學習付出的努力、時間沒有等價的回饋:如果連這點基礎的東西都無法背下來,那我真的有能力駕馭這門技術嗎?
在學習上缺乏成就感、付出時間卻無法掌握知識的不安全感,是我在初學程式時最讓我痛苦的負面情緒來源。我有將近一年以上的時間,都在這些程式的細節中掙扎,學習成效與進步幅度可以說幾乎沒有。
如果我後來沒有改變學習心態與方法的話,我想我應該已經卸載我的 VS code,從此放棄我的程式生涯了吧。
用熟悉建立印象,用精準表達搜尋解答
在進入 ccClub 讀書會 ( 詳情請看
EP0. )、以及接觸了第二個程式語言的經驗後,我才漸漸掌握程式學習的技巧與心法,擺脫初學程式時的學習困境。
首先,不論你是學哪種領域的語言、框架、工具、應用,請都有意識的「拒絕」在學習過程中任何強記背誦的行為。
在以前無法快速獲取資訊的時代,過目不忘所有細節確實是很有價值的技能。然而在網路時代,當取得資訊的成本如此低廉的情況下,大膽的把「記憶 (memorize) 」的角色外包給網路吧!身為學習者的我們,不應該把自己變成字典,而是成為那個查閱字典的人。
對於靠著「背多分」在過去無往不利的人來說,背誦學習法雖然「體感上」很又進步的感覺,但我強烈建議大家戒除這種學習成就感。一方面這是一種「低層次的努力」,另一方面則是程式領域裡能背的東西太多了,你肯定是背不完的🙃。
如果不用記憶的話,那所謂的學習,到底是要學什麼東西?
這裡就要展開我對「印象學習法」的解釋了😃。
(ps. 這是我自己發展的學習哲學,不要把這個詞拿去估狗搜尋XD)
關於程式的印象學習法分為兩個部分:
一:對於 “能夠辦到什麼事” 有印象。
二:知道如何用文字表達 “能夠辦得的這件事”。
這麼說有點抽象,以下我簡單舉一個例子。
C++ 、Java、Python、JavaScript、PHP,各種不同的程式語言,雖然在語法上可能存在不少差異,但有一些的程式邏輯是共通的。
他們都有基礎的判斷式、迴圈、基礎資料結構與其基本操作。
比如說,以 String 字串這個型別而言,每種語言都可以
1) 將兩個字串接接一起,變成一個新字串
2) 將整個字串中以某個特定字元 (如空白鍵) 切開
3) 將字串的某個字元組合以另一組字元組和取代
4) 將字串從某個位置切開
不論你是從哪個語言入門程式的,我相信你都對上面的操作描述非常熟悉,甚至能背出你熟悉的那個語言是用哪個 function 來達成操作的。
當你對 String 能達到的操作有基本的印象時,即使今天要你轉換語言,比如從 Java 轉成 Python,你也不需要把過去的經驗打掉重練、從 0 開始學習,只要知道如何將某個功能行為轉換成相對應的文字,上網搜尋即可。
比如說上述的功能 1,以程式的語言來說就是 concat,上網搜尋 "Python concat two strings" 就可以找到相對應的 python 函數;
功能 2,叫做 split ,Google "Python split string";
功能 3,叫做 replace,Google "Python replace string";
功能 4,叫做 slice,G......恩你應該知道怎麼做了。
只要你知道 string "可以辦到的事",再加上知道 "如何正確表達這件事的關鍵字",對於 string 的操作就沒有難的倒你的問題了,你唯一需要擔心的可能只有網路不穩的狀況了XD。
這是對於微觀尺度下的印象,隨著你的學習時間越來越多,你的 "印象庫" 裡的相關資訊也會越來越豐富,小至某個簡單的函數操作、大至某個功能面的行為,只要你有印象、知道如何去搜尋,你就做得到。
比如說,今天你想要給自己的網站後台加上快取系統來加速整個服務的速度,上網搜尋 “backend cache system choice” 等關鍵字,發現常見的簡單解法有 redis、memcached 等小型應用程式,再進一步搜尋 “redis basic tutorial”,瞭解基本的用法以後,試著把相對應的程式碼嵌入後台主程式後,就完成簡易的快取系統 -- 即使你在幾小時前,連 redis 是什麼都不知道。
當我領悟了這種印像學習的模式後,我對於那些所謂的“資深”的程式大神,也有了一層不同的見解:
以前覺得這些程式大師都是過目不忘的天才,才能記得住那麼多有如天書的程式碼,而自己這種連早上吃什麼都會忘記的人大概一輩子也難以望其項背;
而現在有了正確的認知後,才知道所謂資深,其實就是「經驗的堆疊」,他們遇過很多種不同的情境與問題,腦海中的「印象工具箱」有很多相關聯的概念、關鍵字、模式、解方,才能對於問題有最全面的分析,找出最適恰的解法。
對於程式小白來說,看到網頁顯示錯誤,腦中的印象只有 “程式壞掉了 QAQ”;
對於資深工程師來說,首先先檢查 status code,找出是 400, 404, 還是 500;如果是網路請求完全沒有反應,則會進一步檢查架構面,是 DNS異常、 ip 錯誤、防火牆沒開、對應的 port 不對、proxy 執行異常,還是主機整個 shutdown 了?
經驗越多,對每個步驟環節的概念越有印象,也就越能透過逐步分析,找出真正的病灶,一舉解決問題。
( 當然偶爾還是有連資深工程師都無法排查的狀況,這時你也只能祈禱機台上的乖乖能發揮作用惹XD )
重要的事情說三遍,關鍵的重點會重複出現
看到這裡,你可能會質疑說,ㄟ 你說要有印象,這不就還是要背嗎😂,比如說要記下 concat,split 等之類的專有名詞啊?!
之所以會稱此為「印象」,是因為我之所以能記得這些東西,源自於我一直“看/聽” 到這些關鍵字,一次次加強了我對這些字詞的印象,才變成了記憶。
不說別的,一個初學者學過程式語言一個月以後,即使半年不碰程式,我保證他一定還記得 string、integer、if、else、while、for、array 等字詞,就算當初沒有特別死背這些東西。
原因無他,這幾個字是在學程式的時候,出現頻率最高的單詞。每出現一次,就會加強你的印象,久而久之,印象就凝結成記憶。
因此,比起強記,我更鼓勵大家「長期的」、「持續的」接觸,讓這些印象知識在過程中無痛的轉換成長期記憶。
我自己在成為工程師後、學習全新的技術時,也不曾再用死背的方式去掌握技術。畢竟如果這個技術很重要,我勢必會一直接觸它,它自動會變成我的知識印象;相對的,如果他只是一個瑣碎的技術環節,那其實也沒有記憶的必要,等到遇到問題時在搜尋解答也不遲。
講完建立印象的建議後,再針對二點:知道如何用文字表達行為,做個小建議。
雖然目前也有很多中文的程式社群或是學習課程,大大的降低了學習 coding 的門檻,讓原本對全英文學習資源感到望而生畏的同學來說,也有管道學習程式語言。
即使如此,我還是建議所有想在程式領域更精進的同學,都一定要習慣“英文教學資源”,不論是影片或是文章。
就算你已經透過中文資源學完了初階 python,我依然強烈建議你隨便上網找一步英文解說的 Python tutorial,從頭到尾看一遍。
看影片時的重點不是那些你已經知道的語法規則,而是注意講師“用什麼關鍵字”去描述、說明他接下來的行為”。
如在迴圈的單元裡,你可能會聽到 "We goona use a for-each loop to iterate through the array to find the target",iterate 這個動詞就是表示增加 index 來逐一走過每個 array element 的行為。
原因無他,程式領域從使至終都是個英語霸權的世界,相關的資源也大多是用英語為主,不論是教學影片、文件、問題討論串等。
多接觸這些英文資源,你自然會對那些真正重要的關鍵字有印象,等到實際要查的時候,便能信手捻來的透過印象中的關鍵字來精準搜尋你想表達的問題 。
coding 中最痛苦的事,莫過於是“你完全知道你想要達到的事情是什麼,但你不知道怎麼用英文關鍵字描述這件事情,以至於你找不到相對應的解答”。
堅持只自己的母語來學習城市不是不行,但我只能說你會錯失很多很棒的學習資源,比如說 Stackoverflow,這個堪稱工程師界的聖地麥加的論壇,不論是初階的或是進階的問題,幾乎都能在這裡找到答案。
如果因為對英文的排斥就拒絕這些資源,我只能說你的程式之旅將會是一場地獄苦旅🥲。
結語:從固定式學習法解放自己,用更好的姿勢擁抱新知
從過去偏向固定心態的背誦學習法:把所有知識細節背下來才是真正的學習,轉換到印象學習法後,除了卸除在學習過程的壓力、心理負擔,讓自己用更彈性、更敏捷的狀態學習新知技術,也更能享受學習本身的樂趣之外,另一個我覺得很直得一提的改變,便是我對「筆記」這件事的態度。
對過去身為一個完美注意者的我來說,「筆記」就應該是一個完整匯集所有你學習到的知識細節的地方,用(在你認知中) 更好的表達方式,解釋那些你學習到的概念,甚至要補充那些課堂中沒講到、但你覺得很重要的補充內容,也要一滴不漏的包含在筆記裡,不然這份筆記就沒有意義了。
以這種心態來面對筆記,首要的問題是你會一直覺得你的筆記「不完美」,會一直想要重寫一份新的筆記,把你之前沒有補充的、或是寫不好的地方,重新再復刻一份更好的筆記;
再來,隨著你的學習內容越來越龐雜,你也會嘗試著給自己的筆記建立章節、列表、清單,然後花很多時間思考該如何規劃整個筆記架構。這個章節放在這裡是對的嗎?這兩個章節好像提及有點類似的概念,要不要合併?現在的這個概念架構,可以讓我用最直覺的方式找到我想查找的問題嗎?
最後,就是重複上述兩個行為,並深深在這樣的過程裡感到心累,甚至最後因為整理筆記這件事情太痛苦,乾脆心態一橫,把之前所有的筆記都丟掉,抱著從零開始的心態又開啟了新一輪的學習跟筆記 (即使是學一模一樣的東西,其實完全沒有必要重頭再來)。
在領悟了印象學習法後,並非就從此不需要筆記,而是能用更「擁抱當下 」的心態來使用筆記:
這份筆記不是要成為百科全書,沒有要恆久永流傳,他就是一份幫助「現在的我」認識新知識的過程,在簡單整理筆記的過程中,釐清在這個章節裡接觸到的知識脈絡,加深我現在的印象 ,僅此而已。
在印象學習法裡,筆記的重點就是單純作為強化印象的工具,你不需要一份「超級筆記」來證明自己的學習成果,而且就算日後對這個部分的細節有問題,直接網路搜尋也絕對比回頭翻自己的筆記來的快;
相對的,從做筆記的過程中,你收穫了哪些重要的資訊,而且成功的把它提煉成「印象」,我覺得這才是在整個學習的旅程中,最重要的事。
感謝你有耐心的看到這裡,這麼長的文章我自己閱讀也覺得吃力XD,希望從我簡單的分享中可以幫助到你未來的學習,讓你用更有效率的方式掌握知識與技術。
下一篇 (如果我還有毅力寫下去的話...) 會分享我另一個關於學習過程中的心態思維,敬請期待~