# 掌握學習程式的本質與方法(二):整理思考脈絡 ## 內容大綱 一、這篇想傳達的 二、開場問題 三、軟體開發的學習難題 四、該怎麼解決?理解並梳理思考脈絡 五、理解思考脈絡的本質,注意學習的陷阱 六、結論 ## 一、這篇想傳達的 第一篇針對了「被動學習」和「主動學習」,傳達了看不到終點的學習焦慮和煩惱,主要來自於自己的學習認知和狀態。 接下來希望透過這篇,傳達學習程式技術的方向問題,為何主要源自於思考脈絡的雜亂,導致學了東,忘了西,學了一堆,等到需要拼在一起綜合運用的時候,腦袋一片空白。 除此之外,第二篇內容會延伸第一篇提到的內容:如何混用專案式學習和實驗式學習。 ## 二、開場問題 以下幾位正面臨學習煩惱的人,描述了他們的學習方式和煩惱,先將他們的描述放進腦海當中,看完本文之後,思考看看,除了建議對方直接躺平,你會怎麼點出對方的問題? **A君:工作需要接觸 Angular 框架** 我是某公司的 Junior 前端工程師,接下來需要接手幾個 Angular 的專案,在前兩個月,我很努力的把官方文件的內容都一個一個看完並且跟著做,第三個月開始,我準備接手一個 Angular 專案,裡面的程式碼都看過,但是每次需要調整某個頁面的功能、新增某個頁面的時候,卻不知道從何下手,我是不是要回去複習 Angular 的官方文件? **B君:從 .NET 6 框架轉換到 Spring Boot 2.7 框架** 我是公司的後端工程師,在公司已經待了一年,由於公司的專案,主要使用的後端框架除了 C#.NET 6,還有 Java Spring Boot 2.7,因此主管希望我去接觸和學習,但我沒有 Java 的基礎,而且 Spring 又有 Spring Boot、Spring WebFlux、Spring Data、Spring Security 這麼多要學,我到底該從何學習? **C君:準備踏入零經驗前端工程師** 我每天花了很多時間觀看網路上的 HTML & CSS 教學,把所有的 HTML 標籤和 CSS 語法記下來,但我總是容易搞混不同的標籤和語法,\<head> 跟 \<body> 差在哪、\<link> 跟 \<script> 差別在哪?CSS 的 vertical-align 和 justify-content 差別在哪? **D君:工作需要接觸 Linux** 我是某個初階後端工程師,因為許多的專案都是架設在 Linux 環境,因為聽大家說鳥哥的書超級讚,結果買來之後看了一個月,發現要記的指令和常用資料夾路徑超多,越是學到後面,前面學過的指令和觀念越是沒有印象,我需要從頭回去複習前面的內容嗎? ## 三、軟體開發的學習難題 從上述四位的描述當中,你能否想像他們所學的東西,在腦中是什麼樣子?**思考路徑不僅混亂,而且觀念抽象沒有連結**。 為什麼?多數有方向和混亂的問題,因為在學習時,**聚焦在學習的內容**,**忽略**或甚至**輕忽**學習的**思考脈絡**。 假設一個學了變數、條件判斷、輸入和輸出語法,但沒有方向完成 Console 版猜數字遊戲(1~100 猜一個整數)的人做類比,他們腦中的思考脈絡大概長這個樣子: ![image](https://hackmd.io/_uploads/r1yIn6oDT.png) 這樣的思考脈絡究竟有哪些問題? ### (一) 每個脈絡之間的路徑沒有主次和順序之分 (迷路) **大腦的思考路徑,不知道主要先想哪些,其次想哪些**。 最直接的結果:不知道從何下手,腦袋一片空白。 對應到第一張思考脈絡圖: 每條思考路徑的**粗細、顏色、深淺都一樣**,隨著學的東西越來越多,思考路徑也容易越來越跳躍。 ### (二) 每個脈絡之間的路徑是分散且無法連結的 (混亂易忘) 程式開發這個領域,**許多的觀念、語法,對大腦來說都是相當的「抽象」而且「沒感覺」**。如果反覆死記硬背,記到後來不只難以回想,又容易遺忘。 對應到第一張思考脈絡圖: 每條思考路徑之間**分散且沒有連貫**,隨著學的東西越來越多,思考路徑也容易變得越來越難發現。 ## 四、該怎麼解決?理解並梳理思考脈絡 ### (一) 以剛才的猜數字遊戲為例,學習時該怎麼整理思考脈絡? :::info 如果要使用 C# 完成一個 Console 的猜數字遊戲,第一層要想的事情有哪些? - **首先,怎麼從 1~ 100 的整數,產生並記錄正確答案** - **接著,玩家怎麼輸入答案,並記錄在程式** - **再來,如何比對玩家的答案與正確答案一樣** - **最後,怎麼輸出比對的結果,告知玩家答對還是答錯** ::: 當我把第一層的思考脈絡整理之後,最後會是下圖的樣子。第一層思考路徑,就像這顆樹一樣,一開始從中間的樹幹,**從下到上,依序往兩側的樹枝思考**。 一旦主次和順序整理出來之後,每次回想猜數字遊戲的時候,都能很快的從這四個問題切入。 ![image](https://hackmd.io/_uploads/r1jR7GjDa.png) :::info 回到剛剛猜數字遊戲的例子,第一層脈絡整理出了,猜數字遊戲要依序解決的問題情境。接著依序思考,每個問題情境需要用到哪些程式觀念和語法? - **首先,怎麼從 1~ 100 產生並記錄正確答案** - 亂數:使用 Random 產生亂數 - int 型態:產生完的整數亂數,使用整數(int)型態的變數存放 - **接著,玩家怎麼輸入答案,並記錄在程式** - 輸入的函數 Console.ReadLine() - 輸入的資料使用字串型態的變數存放 (string) - **再來,如何比對玩家的答案與正確答案一樣** - 條件判斷: if {} else {}、三元運算子 - 比較運算: if (userAnswer == inputAnswer) - 型態轉換:字串跟整數比較前需要將字串轉成整數型態 int.Parse() 或 Convert.ToInt32() - **最後,怎麼輸出比對的結果,告知玩家答對還是答錯** - 輸出函數:使用 Console.WriteLine() ::: 當我把第二層的思考脈絡整理之後,最後會是下圖的樣子。 ![image](https://hackmd.io/_uploads/rJlBMAzoD6.png) 學完整理出完整的脈絡後,**原本抽象而且沒感覺的語法,和第一層的問題情境有了連結**,有助於語法觀念的記憶和聯想。 接著就可以依照自己的需要,深入學習和實驗每個語法觀念。例如:我想要瞭解更多亂樹的用法,可以新增一隻實驗用的程式專案,去瞭解和實驗每個亂數的函數。**因為有了脈絡之後再看語法觀念,跟你一開始直接看語法觀念的感覺會完全不一樣。** :::success 備註:因為這篇要把思考脈絡的「路徑」強調出來,所以使用樹來做比喻,你也可以使用心智圖或樹狀圖來整理。 ![image](https://hackmd.io/_uploads/rk6F4J3P6.png) ![猜數字遊戲2](https://hackmd.io/_uploads/H1NAZIJOT.png) ::: ### (二) 從 C# 轉換為 JavaScript 繼續延伸猜數字遊戲的例子: :::info 如果今天改從 C# 換到在瀏覽器的 Console,使用弱型別的 JavaScript 實現,你會發現哪些差別?第二層的程式語法和觀念細節。 1. **亂數產生的函數**:Math.random()。 【語法差異】 2. **int 型態**:使用 let 宣告,而且不需要型態。 【語法差異+語言特性】 3. **輸入函數**:如果是瀏覽器的 prompt() 當作輸入函數。 【語法差異】 4. **型態轉換**:parseInt()。 【語法差異】 5. **比較運算**:除了嚴格相等 (===),即使型態不同,弱型別的語言也會自動轉換。 【語言特性】 6. **輸出函數**:console.log() ::: ### (三) 從瀏覽器 Console 轉換為網頁表單 在轉換相似的思考脈絡當中,你也整理了當中的語法差異和語言特性差異。同樣的還可以練習看看: :::info 如果要從 Console 改成網頁表單的形式,原本的脈絡會怎麼變化?這邊以**第一層脈絡**的「輸入答案」和「比對答案」,使用原生 JavaScript 為例: - ~~輸入函數~~ **表單**:欄位的說明 (label) 、輸入的欄位 (input)送出按鈕(Button)) - **事件(event)**:表單送出事件(submit) 或按鈕事件 (click) - **取得 input 的內容**:submit 事件的 event.target\['xxx'].value 或使用 document.querySelector('yyy').value 從 DOM 下手 ::: 當你學習時,從整理的脈絡發現,對於表單、DOM、事件的觀念不太熟悉時,你就可以抽一些時間,深入學習這幾個部分的整體觀念。 ### (四) 從 Console 版猜數字遊戲加入功能變化 除了用來轉換到不同的語言或工具,還可以加入變化,如果覺得抽象,可以自己嘗試照著上面的原則,「**主要先想那些,哪些是次要接著想的,觀念和問題該怎麼連結。**」將思考脈絡條列並畫出來: :::info 在 Console 的猜數字遊戲,加上「可以重複猜測直到答對」、「最多猜測十次」、「最大最小的範圍提示」、「再玩一輪」等功能。 - **可以重複猜測直到答對**: 在第一層脈絡上,多了一條分支「可以重複猜測直到答對」,往下延伸一條第二層分支: while 迴圈,重複的條件為「使用者答案 不等於 正確答案」 (userAnswer != correctAnswer)。 - **最多猜測十次**: - 第一層「計算並判斷作答次數」,底下延伸一條「算術運算」。 - 接著回到第一層,想到剛才的「可以重複猜測直到答對」,重複的條件改為「『使用者答案 不等於 正確答案』,而且『猜測的次數 小於等於 5 (初始值從1開始)』」(userAnswer != correctAnswer && guessTime <= 5)。 - **最大最小的範圍提示**: 第一層先想到「比對答案」,接著想到「條件判斷」,原本的程式邏輯只有「答對(\==)」、「答錯(!=)」,加上提示範圍的程式邏輯變成「答對(\==)」、「比答案小(<=)」、「比答案大(>=)」。 - **再玩一輪**: 第一層脈絡,多了一條分支「再玩一輪」,底下延伸兩條第二層分支,包含 「do...while 迴圈」和「輸入函數」。 ::: ![image](https://hackmd.io/_uploads/SkygEJhvT.png) ![image](https://hackmd.io/_uploads/rJTOlj0Pp.png) ### (五) 總結整理脈絡的重點 對應第一篇提到的專案式學習和實驗式學習,在專案式練習,關注三個部分: 1. **釐清與拆解涵蓋的問題情境**:思考路徑的切入點 2. **整理問題情境的主次層級**:思考的層級順序 3. **將相對具體的問題情境,連結到陌生且抽象的觀念**:思考的連貫性。 當你透過實驗式學習,深入瞭解某一個路徑的觀念時,用相同的原則,將某個路徑從原先的脈絡拉出來思考,整理成**另一個抽象語法或觀念的思考脈絡**。 ### (六) 總結思考脈絡的好處 往後在回想的時候,不管你從問題情境的角度切入往下延伸,或者從抽象語法觀念的角度切入往前回想,思考脈絡對你來說**整體又容易掌握**。 1. **容易找到思考的切入點** 描述問題的時候,其他人比較容易理解並找到問題的癥結點。 2. **有助於記憶和回想抽象的語法觀念** 快速的從第一層問題脈絡的連結當中,找到和理解每個抽象的觀念和細節。 3. **轉換學習時,幫助掌握共通點與差異點** 換到不同的語言、工具或技術時,可以當作轉換的方向,專注在脈絡當中的差異點、較弱的觀念。 ### (七) 常見問題 1. 語法或觀念細節要怎麼辦? 整理思考脈絡的重點在,整理思考的路徑,**所以流程或語法觀念的細節,比較建議整理成文章、程式檔的形式**。不在第二篇的討論範圍。 2. 最多延伸到幾層?每一層要固定放什麼? 沒有標準答案,只要思考時,路徑能自然的連貫起來。 ### (八) 沒經驗或缺乏基礎的人,整理思考脈絡會遇到的狀況 1. **想不到一開始的切入點** 從**問題情境**或**實現的功能**切入並拆解。 如果認為發現實在有難度,我會直接建議找專案導向的書或課程 + Google 學習。 2. **鑽牛角尖,或者過於發散。** 通常是想的「太細」,或者「不夠具體直接」,可以試著**拉高層級**,整理歸納較為細節的脈絡。 3. **某個思考路徑,超出自身的認知,卡住無法往下延伸。** 思考跟目前的學習重點有關,如果連結性較小,選擇性的**暫時擱置**。 :::info 以上三點拿開場問題的B君學習 Spring Boot 為例,沒整理過的思考脈絡可能長這個樣子: 1. Java 的 JDK 與 JRE 2. IDE 或編輯器 3. Maven 或 Gradle 的使用 4. 怎麼啟動 Spring Boot 的 API 測試 5. 怎麼定義 GET, POST, PUT, PATCH, DELETE 的 API 6. API 的請求參數和回應參數怎麼定義和存取。 7. 連線資料庫的設定。 8. 資料表與欄位的 Class 定義。 9. SQL 操作在 Hibernate 的架構下該怎麼實作。 10. 實作基本的會員相關功能 ... 經過整理後的思考脈絡: 1. 開發前的準備:開發環境、開發工具 - Java 的 JDK 與 JRE - 開發用的 IDE 或編輯器 2. 怎麼建立和啟動一個專案 - 怎麼使用 Maven 或 Gradle 安裝套件 - 使用什麼指令啟動 API 測試。 3. 以前寫過的會員系統,在 Spring Boot 是怎麼實作的 - 如何定義 WebAPI - 怎麼定義 GET, POST, PUT, PATCH, DELETE 的 API - API 的請求參數和回應參數怎麼定義和存取。 - 相依服務的設定和使用 - 定義為可被注入的相依服務類別 (建立 Bean) - 注入其他的相依服務類別 (注入 Bean) - 搭配關連式資料庫 - 連線資料庫的前置設定。 - 資料表與欄位的 Class 定義。 (Model) - SQL 基本 CRUD 操作在 Hibernate 的架構下該怎麼實作。 (Repository) - 怎麼實作關聯查詢 (Join) - 怎麼使用資料庫的交易 (Transaction) - 註冊的商業邏輯 - 判斷帳號是否重複註冊 - 判斷密碼的強度 - 判斷密碼與確認密碼是否一樣 - 密碼的加鹽 - 登入的商業邏輯 ... - 登出的商業邏輯 ... - 忘記密碼的商業邏輯 ... ::: 如果你不像 B 君有足夠的經驗,延伸幾點學習上的建議: - **記錄下來當前常常卡住的部分,抽時間一起學習** 如果在學習 Spring Boot 的時候,發現 SQL、@Autowird 和 @Component 等等觀念和用法,常常讓你覺得卡東卡西,我會記錄下來,花點時間把卡住的觀念和語法整個學過一遍,另外開個實驗專案嘗試並觀察。 - **準備一至兩個自己能從頭到尾完成,而且相對完整的作品,找個練功的第一份工作** 練習的過程中,或許你的作法並不是 Best Practice,Code 寫的不是很好,或者有些脈絡是自學不容易接觸到的,但至少你有了屬於自己的學習脈絡和紀錄。 **先挑一個要求沒這麼高的低階工作練功,進入職場之後,跟隨較資深的前輩做中學,將有毒的作法、設計調整過來,並且補足自學不容易掌握的思考脈絡**。很多對程式碼好壞很敏銳的人,也是接手過別人的爛 Code,或者自己的爛 Code。如果是一位天份不錯的人,自認作品的 Level 比其他人高,那第一份工作就可以挑比較好的去挑戰,因人而異。 ## 五、理解思考脈絡的本質,注意學習的陷阱 ### (一) 思考脈絡是給「自己」的大腦用的 看完了思考脈絡的說明和舉例,要特別強調,思考脈絡是**給自己用的**。換句話說: 1. 主要必須靠自己思考和整理,別人的不一定適用自己。 2. 可隨時不斷的調整。 3. 每個人不會完全相同。 只有靠自己思考和整理的思考脈絡,**印象才會最深刻,思考起來才會靈活**。 ### (二) 「速成筆記」或「技巧」的使用時機避免過早 因此我會建議在剛開始學習程式的時候,最好避免: 1. 密技思維:剛開始學習,就直接使用網路或別人整理好的心智圖、學習路徑 (Road Map)、Cheat Sheet、XXX 個技巧學習。 2. 思考重心流於整理筆記,偏離思考事情本身。 **抄捷徑的密技和方法,適合在有一定思考脈絡的時候,補足不足的部分**,但如果當作一開始主要學習的內容,反而是大腦整理思考脈絡的殺手。為什麼? 工作面臨的開發與除錯問題,很多都是綜合性的問題,沒有脈絡的密技和技巧,很容易會以東拼西湊的角度切入,遇到問題越補越大洞、方向越來越偏。 ### (三) 當作一種習慣養成,而非唯一的萬用工具 1. 要練習多久?有什麼方法技巧快速練成?有哪些練習的題材? 當作一種習慣養成,用在整理平常學習的專業、工作的每一件事情,時間因人而異。 2. 是不是只要會整理思考脈絡,就能快速具備工程師的能力? 當然不是,整理完思考脈絡,只是幫你整理掌握整體的結構和方向,你還是要下功夫去理解、練習學習的內容。 ## 六、結論 專案式學習面對的問題情境、完成的功能,在學習的時候幫助蒐集、釐清、整理思考脈絡,混用實驗式學習,可以在有整體脈絡的支撐下,專心強化所學的理論。 看文本篇內容之後,我們來整理一下文章的思考脈絡: ![整理思考脈絡](https://hackmd.io/_uploads/HJiklPed6.png) 除了學習,工作要接手陌生的專案、文章或會議紀錄的大綱、找程式問題,有沒有習慣整理思考脈絡,做事的效率也會有明顯的差別。 如果本文整理思考脈絡的方式不完全適合你,你可以自行調整並轉換為自己的方式。 最後以開場問題的 A 君來進行總結: :::info A 君可以從網站的角度切入第一層脈絡,Angular 前端框架主要處理的問題有哪一些(以下是簡單舉例): - 開發的前置作業:開發環境的設定 - 管理網站底下的所有頁面位置:網站的路由 - 元件開發 - 頁面 UI 元件 - 共用 UI 元件 - API 串接的服務層 - 整個網站的資料共用: - 服務 (Service) - 狀態管理 (NgRx) - 多語系 - 環境變數 - 建置與部署 ::: 隨著時間,不斷累積開發處理的問題和情境,加上框架本身的更新變化,A君對於 Angular 的思考脈絡也會跟著改變。不同的人,對於 Angular 的思考脈絡也不會一樣。 C、D君,兩位的思考脈絡,就留給讀者自己整理看看。 :::info 題外話: 曾經下班為了練習 Angular 13,透過完成 UI Libary 的過程,熟悉 Angular 13 大部分的 UI 元件的語法,有興趣可以參考看看,怎麼轉成新版的 Standalone & Control Flow 寫法: https://ngx-youi.github.io/NGX-YOUI/ ::: 第二篇內容到這邊結束,謝謝大家耐心的閱讀。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up