Go 語言系列(十一):面試必問問題

這是 Go 語言從零到 Web 應用系列的第十一篇。前十篇我們完成了從基礎到實戰的完整學習路徑,這篇整理 Go 面試中最常被問到的核心問題,幫助你在面試中展現對 Go 的深入理解。 Goroutine 與 Channel Q1:Go 的 Goroutine 排程模型是什麼? Go 使用 GMP 模型來排程 goroutine: G(Goroutine):要執行的工作單元,每個 go func() 建立一個 G M(Machine):作業系統執行緒,實際執行程式碼的載體 P(Processor):邏輯處理器,持有本地的 G 佇列,數量預設等於 CPU 核心數 排程流程: G1, G2, G3 ... → P(本地佇列)→ M(OS Thread)→ CPU P 從自己的本地佇列取出 G 放到 M 上執行。當本地佇列空了,會從其他 P「偷」G 來執行(work stealing)。 package main import ( "fmt" "runtime" ) func main() { // 查看 P 的數量 fmt.Println("GOMAXPROCS:", runtime.GOMAXPROCS(0)) // 查看目前的 goroutine 數量 fmt.Println("NumGoroutine:", runtime.NumGoroutine()) for i := 0; i < 5; i++ { go func(n int) { fmt.Printf("goroutine %d running on thread\n", n) }(i) } fmt.Println("NumGoroutine after launch:", runtime.NumGoroutine()) runtime.Gosched() // 讓出 CPU 給其他 goroutine } 面試加分點: ...

2026年2月24日 · 6 min · 1269 words · Jack

Go 語言系列(四):資料結構

這是 Go 語言從零到 Web 應用系列的第四篇。上一篇學了基礎語法,這篇要來認識 Go 的核心資料結構。 Array(陣列) Array 是固定長度的同型別元素集合。 // 宣告陣列(長度是型別的一部分) var scores [5]int // [0, 0, 0, 0, 0] // 初始化 scores = [5]int{90, 85, 78, 92, 88} // 簡短宣告 names := [3]string{"Alice", "Bob", "Charlie"} // 讓編譯器計算長度 primes := [...]int{2, 3, 5, 7, 11} // 存取元素 fmt.Println(scores[0]) // 90 scores[1] = 95 // 取得長度 fmt.Println(len(scores)) // 5 Array 在 Go 中較少直接使用,因為長度固定且是值語意(傳遞時會複製整個陣列)。大多數情況我們用 Slice。 Slice(切片) Slice 是 Go 中最常用的集合型別,可以視為動態長度的陣列。 建立 Slice // 從 array 建立 arr := [5]int{1, 2, 3, 4, 5} s := arr[1:4] // [2, 3, 4](左包含,右不包含) // 直接宣告 nums := []int{10, 20, 30} // 使用 make(指定長度和容量) s1 := make([]int, 5) // 長度 5,容量 5 s2 := make([]int, 3, 10) // 長度 3,容量 10 長度 vs 容量 s := make([]int, 3, 5) fmt.Println(len(s)) // 3(目前元素數量) fmt.Println(cap(s)) // 5(底層陣列的大小) append:新增元素 nums := []int{1, 2, 3} nums = append(nums, 4) // [1, 2, 3, 4] nums = append(nums, 5, 6, 7) // [1, 2, 3, 4, 5, 6, 7] // 合併兩個 slice more := []int{8, 9} nums = append(nums, more...) // [1, 2, 3, 4, 5, 6, 7, 8, 9] 當 append 超過容量時,Go 會自動分配更大的底層陣列。 ...

2026年2月24日 · 6 min · 1163 words · Jack