---
# System prepended metadata

title: "\U0001F680 轉職工程師零基礎學習指南：Golang 與開發基礎"

---

# 🚀 轉職工程師零基礎學習指南：Go (Golang) 與開發基礎

[TOC]

---

## 🎯 第一章：Go 程式設計基礎

本章節將為你打下最基本的程式邏輯和語法基礎。Go 是一門靜態強型別、編譯型的語言。

### 1.1 變數 (Variables) 🧱

* **觀念：** 變數就像是你貼上標籤的「**儲存箱**」，用來在程式執行過程中暫時存放資料。

#### 變數命名慣例 (Naming Conventions)

在 Go 中，命名首字母的大小寫決定了該變數是否能被其他套件存取（Public/Private）。

| 慣例名稱 | 說明 | Go 使用情境 | 範例 |
| :--- | :--- | :--- | :--- |
| **Camel Case (小駝峰)** | 第一個單字首字母小寫。 | **Go 推薦**用於內部私有的變數與函式。 | `userAge`, `calculateTotal` |
| **Pascal Case (大駝峰)** | 每個單字的首字母都大寫。 | **Go 規定**用於公開導出的變數與類別。 | `UserAccount`, `HttpRequest` |
| **Snake Case (蛇型命名)** | 以底線連接。 | **Go 社群不建議**使用底線命名變數。 | `user_age` |

#### 變數宣告

| 特性 | `var` 關鍵字 | `:=` 短變數宣告 |
| :--- | :--- | :--- |
| **適用範圍** | 可用於 **函式內** 與 **函式外** (Package 層級) | **僅限函式內部** |
| **初始值** | 非必填（不填則給予該型別的「零值」） | **必填**（須靠初始值推導型別） |
| **型別指定** | 可明確指定型別，也可由系統推導 | 只能由系統自動推導 |
| **語法範例** | `var x int = 10` 或 `var y = "Hi"` | `z := 20.5` |

---

#### 💡 快速判斷準則：
1. **全域變數**：一律使用 `var`。
2. **區域變數**：優先使用 `:=` 以保持代碼簡潔。
3. **只宣告不賦值**：使用 `var`（例如：`var user User`）。

#### 字串處理
1. strings.Contains(dessert, "豪華") //判斷一個字串裡「有沒有包含」另一個字串，回傳值是 bool
1. strings.HasPrefix("豪華蛋糕", "豪華") // 是否以某字開頭
1. strings.HasSuffix("蛋糕.jpg", ".jpg") // 是否以某字結尾
1. strings.ToUpper("cake")               // 轉大寫
1. strings.Split("a,b,c", ",")           // 切割
1. strings.Join([]string{"a","b"}, "-")  // 組合
1. strings.TrimSpace("  cake  ")         // 去空白


* **Go 範例：**
```go
package main
import "fmt"

func main() {
    // 方式 A：明確宣告型別
    var age int = 25
    
    // 方式 B：簡短宣告 (自動推導型別)
    name := "新手工程師"
    
    // 改變變數的值
    age = age + 1 
    
    fmt.Printf("%s 的年齡是: %d\n", name, age)
    // 輸出：新手工程師 的年齡是: 26
}

//input
package main

import "fmt"

func main() {
	var name string
	fmt.Println("請輸入你的名字：")
	fmt.Scanln(&name)
	fmt.Printf("你好,%s!準備好開始練習了嗎？\n", name)
}
```
第一個出現的 %s 會對應到後面的第一個變數 name。
第二個出現的 %d 會對應到後面的第二個變數 age。
最後的 \n 確保印完這行後，游標會跳到下一行，不會跟後面的輸出擠在一起。

| 佔位符  | 用途     | 範例       |
| ---- | ------ | -------- |
| `%d` | 整數     | `10`     |
| `%s` | 字串     | `"Go"`   |
| `%f` | 浮點數    | `3.14`   |
| `%t` | 布林     | `true`   |
| `%v` | 自動判斷型別 | **新手救星** |

x := 3.14159
fmt.Printf("%.1f\n", x) // 3.1
fmt.Printf("%.2f\n", x) // 3.14
fmt.Printf("%.3f\n", x) // 3.142

| 符號   | 意思       |
| ---- | -------- |
| `\n` | 換行       |
| `\t` | Tab（空格）  |
| `\"` | 字串內的 `"` |
| `\\` | 顯示 `\`   |

Printf 要換行 → 自己加 \n



---

### 1.2 資料型別 (Data Types) 🔢

* **觀念：** Go 是強型別語言，宣告後型別不可變更。
* **Go 範例：**
```go
count := 10 // int
pi := 3.14 // float64
greeting := "Hello Go" // string
isLearning := true // bool

fmt.Printf("%T\n", count) 
fmt.Printf("%T\n", isLearning)
```

---

### 1.3 流程控制 (Flow Control) 🚦

* **觀念：** 讓程式根據條件決定執行哪一段程式碼。Go 的 if 不需要圓括號。
* **Go 範例 (if/else if/else)：**
```go
score := 75
if score >= 90 {
    fmt.Println("A 等級")
} else if score >= 60 {
    fmt.Println("B 等級") 
} else {
    fmt.Println("C 等級")
}
```

---

### 1.4 迴圈 (Loops) 🔄

* **觀念：** Go 只有 for 一種迴圈，但功能非常強大。
* **Go 範例：**

```
for 初始值; 條件; 每次做什麼 {
}
```

```go
// 標準計數
for i := 0; i < 5; i++ {
    fmt.Println("目前數字:", i)
}

// 走訪切片 (Slice)
fruits := []string{"蘋果", "香蕉", "橘子"}
for index, fruit := range fruits {
    fmt.Printf("索引 %d: %s\n", index, fruit)
}

// 計算總合
sum := 0
    for i :=1; i <=100; i++{
        sum=sum+i
    }
    fmt.Println("總和是:",sum)
 }
```

---

### 1.5 函式 (Functions) ⚙️

* **觀念：** Go 函式支援多個回傳值，通常最後一個回傳值用於傳回錯誤。
* **Go 範例：**
```go
func add(a int, b int) int {
    return a + b
}
func main() { 
    result := add(3,5)
    fmt.Println("結果:",result)
 }

------

func getUserInfo() (string, int) {
    return "小明", 30
}

------

func main() {
    total := add(10, 5)
    name, age := getUserInfo()
    fmt.Printf("%s 今年 %d 歲\n", name, age)
}
```

---

### 1.6 序列與集合 (Slices, Maps) 🧺

#### ➡️ 切片 (Slices)：有序、可變動 (Mutable)
* **觀念：** 類似 Python 的 List，是 Go 最常用的集合型別。
```go
tasks := []string{"學習 Go", "撰寫履歷"}
tasks = append(tasks, "面試") 
fmt.Println(tasks[0])

-----

宣告一個 slice：[]int{10, 20, 30, 40}
用 for 把每個數字印出來
再印出所有數字的總和

func main() {
    numbers := []int{10, 20, 30, 40}

    sum := 0
    for _, v := range numbers {
        fmt.Println("數字:", v)
        sum += v
    }

    fmt.Println("總和:", sum)
}
```

#### ➡️ 映射 (Maps)：鍵值對 (Key-Value)
* **觀念：** 類似 Python 的 Dictionary。
```go
1.建立與讀取 Map
目標：學會宣告、初始化、讀取

person := map[string]int{
    "小明": 30,
    "小華": 25,
}
fmt.Println("年齡:", person["小明"])
```
map[keyType]valueType 來宣告。
用 map[key] 讀取值。

value, ok := map[key]
ok 是布林值，表示該key對應的值是否存在。

map[key] = value 更新值。
delete(map, key) 刪除元素。

```go
2.判斷 Key 是否存在
目標：學會 value, ok := map[key]

age, ok := person["小華"]
if ok {
    fmt.Println("小華存在，年齡:", age)
} else {
    fmt.Println("小華不存在")
}

```

```go
3.修改與刪除資料
目標：更新值、刪除 key

// 修改值
person["小明"] = 31
fmt.Println("小明的新年齡:", person["小明"])

// 刪除 key
delete(person, "小華")
fmt.Println("刪除小華後的 Map:", person)

```

```go
4.使用 for range 走訪 Map
目標：遍歷所有資料

for name, age := range person {
    fmt.Println(name, "的年齡是", age)
}


```
for key, value := range map 遍歷所有資料。
注意 Map 遍歷順序是 不固定的。

```go
5.計算總和與平均
目標：搭配 map 做簡單邏輯

sum := 0
for _, age := range person {
    sum += age
}
avg := float64(sum) / float64(len(person))
fmt.Println("總年齡:", sum)
fmt.Println("平均年齡:", avg)


```
_ 代表忽略 key。
可以做簡單統計或邏輯運算。

```go
6.統計字母出現次數
目標：Map 最常見用途

text := "hello golang"
count := make(map[rune]int) // 使用 rune 來支援單字母

for _, ch := range text {
    if ch != ' ' { // 忽略空格
        count[ch]++
    }
}

fmt.Println("字母統計結果:")
for ch, n := range count {
    fmt.Printf("%c: %d\n", ch, n)
}

```
Map 最常用來做計數統計。
使用 rune 來處理單個字符。



---

#### 1.7 錯誤處理 (Error Handling) ⚠️ (進階補充)

* **觀念：** Go 不使用 `try-catch`，而是將錯誤視為「值」。除了基礎回傳，實務上常搭配 `errors` 標準庫進行判斷。

#### 1. 哨兵錯誤 (Sentinel Errors)
預先定義特定的錯誤變數，方便在程式各處進行比對，這是 Go 最常見的模式。

```go
import (
    "errors"
    "fmt"
)

var ErrDataNotFound = errors.New("找不到資料")

func search(id int) error {  ///將錯誤視為function的回傳值
    if id != 101 {
        return ErrDataNotFound
    }
    return nil
}

func main() {
    err := search(1) ///呼叫此function時 需用一個變數去接function的回傳值
    if errors.Is(err, ErrDataNotFound) {
        fmt.Println("請重新檢查 ID 內容")
    }
}
```
```go
//函式導向 (Function-Based)
func StartExercise(weight int, eq Equipment) error

//呼叫
if err := StartExercise(120, benchPress); err != nil { ... }

寫法： 這是一個獨立的「工具函式」。

為什麼這樣寫： * 外部檢查： 這種寫法通常用於「第三方檢查」或是「多物件操作」。
低耦合： 函式本身不屬於器材（Equipment），也不屬於人。它像是一個裁判，把「重量」跟「器材」丟進去，由它來判定合不合格。
適用場景： 當邏輯涉及多個不同的 Struct，或者是一個通用的驗證工具時。


//方法導向 (Method-Based)
func (gc GymClass) CheckStatus(currentPeople int) error

//呼叫
if err := yoga.CheckStatus(3); err != nil { ... }

寫法： 這是附屬於 GymClass 結構體的「方法（Method）」。

為什麼這樣寫：
封裝（Encapsulation）： 這是物件導向的思維。課程「是否能開課」是課程自己的資訊（它知道自己的最低人數 MinParticipants），所以應該由課程自己來回答。
直覺性： 在 main 裡面呼叫時，寫成 yoga.CheckStatus(3) 非常直覺，就像在問這堂瑜珈課：「喂，你現在人數夠嗎？」
適用場景： 當邏輯高度依賴該物件內部的資料（如 gc.MinParticipants）時。
```


#### 2. 延遲執行與恢復 (Defer, Panic, Recover)
當發生嚴重不可逆的錯誤時會觸發 `panic`。我們可以使用 `defer` 搭配 `recover` 來攔截，避免程式直接崩潰。

* panic 是一個內建函數，它代表的是「程式發生了不可恢復的嚴重錯誤」。這與一般的 error 不同，error 是預期內的錯誤（例如檔案找不到），而 panic 通常是預期外的災難。
* **觀念：** `defer` 會將其後方的函數調用，延遲到「包含它的函數即將回傳（Return）」之前才執行。它最常用於資源釋放，確保無論程式中途發生什麼事，該做的事一定會做。

```go
func protect() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("系統已從錯誤中恢復: %v\n", r)
        }
    }()
    
    fmt.Println("開始執行...")
    panic("發生嚴重意外！") // 手動觸發崩潰
}
```

---

### 1.8 指標 (Pointers) 📍

* **觀念：** 指標儲存的是變數在記憶體中的 **位址 (Memory Address)**。Go 預設是「傳值 (Pass by Value)」，若想在函數內修改外部變數，就必須傳遞指標。


#### 1. 基礎操作符
* `&`：**取址**。取得變數所在的記憶體位址。
* `*`：**取值 (解引用)**。透過位址找到原本的資料。

```go
x := 10
ptr := &x      // ptr 現在指向 x 的位址

fmt.Println(ptr)  // 輸出位址 (如 0xc0000140a8)
fmt.Println(*ptr) // 輸出 10 (取值)

*ptr = 20         // 透過指標修改 x 的值
fmt.Println(x)    // x 變成了 20
```

#### 2. 傳值 vs. 傳指標
如果不傳指標，函數內部的修改將不會影響到外部原始變數。

```go
func updateByValue(n int) { //這邊傳入的參數可視為原本n的複製品
    n = 100 // 僅修改複製品
}

func updateByPointer(n *int) {
    *n = 100 // 直接修改該記憶體位址的值
}

func main() {
    num := 10
    updateByValue(num)
    fmt.Println(num) // 還是 10

    updateByPointer(&num)
    fmt.Println(num) // 變成 100
}
```
##### 2.1 深入探討：Pass by Value vs. Pass by Reference(重要 面試必考)

在程式語言理論中，這兩者的底層行為有顯著差異。雖然 Go 嚴格來說只有 Pass by Value，但我們通常會用指標來模擬 Pass by Reference。

| 特性 | 傳值 (Pass by Value) | 傳指標 (模擬 Pass by Reference) |
| :--- | :--- | :--- |
| **行為** | 複製一份完整的數據交給函數。 | 複製一份「記憶體位址」交給函數。 |
| **記憶體** | 佔用更多空間（若資料很大）。 | 佔用空間小（僅一個位址的大小）。 |
| **影響** | 函數內的修改不會影響原始變數。 | 函數內透過位址修改，會影響原始變數。 |
| **安全** | 較安全，數據不會被意外改動。 | 需謹慎，多人操作同一位址可能出錯。 |

#### 為什麼說 Go 只有 Pass by Value？
這是一個常見的誤解。當你把指標傳入函數時，Go 其實是**複製了那個「位址」**傳進去。

* **傳值：** 複製「整顆蘋果」給對方，對方咬一口，你的蘋果還在。
* **傳指標：** 複製「蘋果所在的位置地圖」給對方，對方順著地圖去咬一口，你的蘋果就缺了一塊。

#### 範例：記憶體視角
```go
func change(val int, ptr *int) {
    val = 99    // val 是 local 變數，有自己的記憶體空間
    *ptr = 99   // ptr 儲存的是位址，*ptr 是指去該位址改掉原本的值
}

func main() {
    a, b := 1, 1
    change(a, &b)
    
    // a 依然是 1：因為傳進去的是 a 的複製品
    // b 變成了 99：因為傳進去的是 b 的位址複製品，兩者指向同一個 b
}
```

> ⚠️ **注意：Slice 和 Map 的陷阱**
> 在 Go 中，Slice、Map 和 Channel 看起來像是 Pass by Reference（改了會影響外部），但它們本質上是**包含指標的結構體**。所以傳遞它們時，依然是傳值（複製了裡面的指標），這導致了「看起來像傳參照」的行為。

---

#### 3. 指標的零值 (nil)
當一個指標沒有指向任何地址時，它的值是 `nil`。

```go
var p *int
if p == nil {
    fmt.Println("此指標目前為空 (nil)")
}
```

> **什麼時候該用指標？**
> 1. **修改狀態：** 需要在函數中改變傳入參數的值。
> 2. **效能：** 傳遞大型結構 (Struct) 時，傳地址比複製整個資料結構快。
> 3. **表示空值：** 用 `nil` 來代表「資料不存在」或「尚未初始化」。

---

## 💻 第二章：工程師的核心工具與知識

### 2.1 資料庫語言：SQL (Structured Query Language) 💾

* **觀念：** **SQL** 是專門用來**管理和操作關聯式資料庫**的語言。在 PostgreSQL 中，資料以「資料表 (Table)」的形式儲存，每張表由行 (Row) 與列 (Column) 組成。


**基本結構執行順序**

```SQL
--SELECT 選取
--FROM 來源

SELECT * FROM students;
-----
SELECT 姓名, 班級, 成績 FROM students;

```
 
```SQL
--WHERE 條件
SELECT 姓名, 班級, 成績 
FROM students 
WHERE 姓名 LIKE '張％'('張＿');

(％零個或多個任意字元
＿一個字元)
-----

1. WHERE 成績 >= 80 AND 成績 < 90;
2. WHERE 成績 BETWEEN 80 AND 90;
3. WHERE 成績 BETWEEN 80 AND 90 AND 班級 = '1年1班';

-----

OR符合任一條件（AND語法優先層級比OR高）
WHERE 成績 BETWEEN 80 AND 90 AND 班級 = '1年1班' OR 班級 = '1年2班';
(會出現1年2班低於高於分數的都會出現)

改成加圓括弧
1. WHERE 成績 BETWEEN 80 AND 90 AND (班級 = '1年1班' OR 班級 = '1年2班');
2. WHERE 成績 BETWEEN 80 AND 90 AND (班級 IN ('1年1班', '1年2班'))
```
```SQL
--GROUP BY 將資料進行分組
--HAVING 篩選已分組的資料
--ORDER BY 順序
排序
ASC：小 → 大（預設）
DESC：大 → 小

WHERE 班級 <> '1年2班'
ORDER BY 班級, 成績 DSEC;
```


```SQL
---LIMIT 筆數限制
SELECT 姓名, 班級, 成績 FROM students LIMIT 5;

(查看接來五筆 使用OFFSET跳過指定筆數)

SELECT 姓名, 班級, 成績 FROM students LIMIT 5 OFFSET 5;
```


| 函數        | 功能   |
| --------- | ---- |
| `COUNT()` | 計算筆數 |
| `SUM()`   | 加總   |
| `AVG()`   | 平均值  |
| `MAX()`   | 最大值  |
| `MIN()`   | 最小值  |
| `ROUND`   | 四捨五入  |


#### 1. 建立資料表 (CREATE TABLE)
在操作資料前，我們必須先定義資料的結構。

```SQL
CREATE TABLE users (
    id SERIAL PRIMARY KEY,      -- 自動遞增的主鍵
    name TEXT NOT NULL,         -- 不可為空的文字
    email VARCHAR(100) UNIQUE,  -- 唯一且長度受限的字串
    age INT,                    -- 整數
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 預設為目前時間
);
```

#### 2. 新增資料 (INSERT) - Create
將新資料存入資料表中。

```SQL
-- 新增單筆資料
INSERT INTO users (name, email, age) 
VALUES ('Gemini', 'gemini@example.com', 25);

-- 新增多筆資料
INSERT INTO users (name, email, age) 
VALUES ('Alice', 'alice@test.com', 30),
       ('Bob', 'bob@test.com', 22);
```

#### 3. 查詢資料 (SELECT) - Read
從資料表中取出想要的資料。

```SQL
-- 查詢所有欄位
SELECT * FROM users;

-- 查詢特定欄位並篩選條件
SELECT name, email 
FROM users 
WHERE age >= 25 
ORDER BY age DESC; -- 依照年齡由大到小排序
```

#### 4. 修改資料 (UPDATE) - Update
更新現有的資料內容。**注意：務必搭配 WHERE，否則會更新整張表！**

```SQL
UPDATE users 
SET age = 26, name = 'Gemini Pro' 
WHERE id = 1;
```

#### 5. 刪除資料 (DELETE) - Delete
移除不再需要的資料。**注意：務必搭配 WHERE！**

```SQL
DELETE FROM users 
WHERE email = 'bob@test.com';

-- 若要清空整張表但保留結構
-- TRUNCATE TABLE users;
```

---

### 2.2 網際網路基礎知識 🌐

* **HTTP (HyperText Transfer Protocol)：** 網頁瀏覽器和伺服器之間傳輸資料的**主要協定**。
* **HTTPS (HTTP Secure)：** 在 HTTP 基礎上加入了 **SSL/TLS 加密層**，確保資料傳輸的安全性。
* **Domain (網域) 和 IP 位址：** **IP 位址**是設備的實際地址；**網域**是為了方便記憶而設計的名稱（例如 `google.com`）。

### 2.3 版本控制：Git 與平台 (GitHub/GitLab) 🌲

# Git 基礎與進階常用指令筆記

* **觀念：** **Git** 是一個分散式版本控制系統，用來**追蹤程式碼的變更歷史**，讓協同開發變得有條不紊。
* **教學資源：** [PAPAYA 電腦教室 - Git/GitHub 快速上手](https://www.youtube.com/watch?v=FKXRiAiQFiY)

---

## 📸 Git 工作流程圖解
在使用指令前，理解 Git 的四個核心區域：

1. **工作區 (Working Directory)**：你實際編輯檔案的地方。
2. **暫存區 (Staging Area)**：準備要提交的檔案存放處（攝影棚）。
3. **本地儲存庫 (Local Repository)**：儲存版本紀錄的地方（你的電腦）。
4. **遠端儲存庫 (Remote Repository)**：雲端共享平台（如 GitHub）。



---

## 🛠️ 核心與常用指令

### 1. 建立與取得
* `git init`: 在當前資料夾建立一個新的 Git 儲存庫。
* `git clone <URL>`: 複製遠端的儲存庫到本地。

### 2. 提交變更 (日常最常用)
* `git status`: 檢查目前檔案狀態（哪些已修改、哪些在暫存區）。
* `git add <檔案>`: 將檔案加入**暫存區**（準備拍照）。
    * `git add .` 代表加入全部變更。
* `git commit -m "訊息"`: 建立一個新的**版本紀錄**（按下快門）。

### 3. 查看歷史與比較
* `git log --oneline`: 以簡潔的一行格式列出版本歷史。
* `git diff`: 比對工作區與暫存區之間的內容差異。

### 4. 分支與協作 (Teamwork)
* `git branch`: 查看目前所有分支。
* `git checkout -b <分支名>`: 建立並切換到新分支（開啟遊戲新進度線）。
* `git merge <分支名>`: 將指定分支的內容合併回目前分支。

### 5. 與遠端同步
* `git push`: 將本地的變更上傳到遠端伺服庫。
* `git pull`: 從遠端下載最新變更並**自動合併**到本地。
* `git fetch`: 從遠端下載最新變更資訊，但**不自動合併**（較安全）。

### 6. 撤銷與還原 (後悔藥)
* `git checkout <檔案>`: 放棄目前的修改，還原成上個版本的狀態。
* `git reset --hard <版本ID>`: 強制退回到指定版本（之後的紀錄會消失，請謹慎使用）。

![image](https://hackmd.io/_uploads/HkAD60fXZl.png)


---

## 📄 忽略檔案 (.gitignore)
在專案根目錄建立 `.gitignore` 檔案，寫入不希望被 Git 追蹤的檔案（如密碼檔、大型暫存檔），可保持儲存庫乾淨並保護隱私。

### 2.4 API 知識：RESTful 風格 📲

* **觀念：** **API (Application Programming Interface)** 定義了兩個軟體系統如何互相溝通。
* **RESTful API：** 一種最流行的網頁 API 設計風格，它使用標準的 HTTP 方法對資源進行操作：
    * `GET`: **獲取**（查詢）。
    * `POST`: **新增**（創建）。
    * `PUT`/`PATCH`: **修改**（更新）。
    * `DELETE`: **刪除**。

## 🧠 第三章：工程師的內功心法：資料結構/演算法與作業系統基礎

### 3.1 資料結構 (Data Structures, DS) 📦

#### (1) 堆疊 (Stack)
* **觀念：** 遵循 **LIFO (Last-In, First-Out)** 原則。
* **Go 範例：** 用 `slice` 的 `append` (Push) 搭配索引與截取實現 Pop。

```go
package main
import "fmt"

func main() {
    stack := []string{}
    // Push
    stack = append(stack, "A")
    // Pop (取最後一個並移除)
    n := len(stack) - 1
    latestData := stack[n]
    stack = stack[:n]
    fmt.Println(latestData) // 輸出：A
}
```

#### (2) 佇列 (Queue)
* **觀念：** 遵循 **FIFO (First-In, First-Out)** 原則。
* **Go 範例：** 用 `slice` 的 `append` (Enqueue) 搭配索引與截取實現 Dequeue。

```go
package main
import "fmt"

func main() {
    queue := []string{"任務 1"}
    // Enqueue
    queue = append(queue, "任務 2")
    // Dequeue (取第一個並移除)
    firstTask := queue[0]
    queue = queue[1:]
    fmt.Println(firstTask) // 輸出：任務 1
}
```

---

### 3.2 演算法 (Algorithms) ⚙️

* **觀念：** 演算法是為了解決特定問題所設計的**明確步驟或指令集**。
* **時間複雜度 (Time Complexity)：** 衡量演算法效率的指標，用 **Big O 符號** ($O()$) 表示。
    * **重點：** 你需要追求更低的複雜度，例如 $O(1)$（最快）比 $O(n)$ 快。
![image](https://hackmd.io/_uploads/Sk6cr8lzZx.png)
* **Go 範例：**
```go
package main
import (
    "fmt"
    "sort"
)

func main() {
    numbers := []int{5, 2, 8, 1}
    // 使用 sort 套件內建的高效能排序演算法
    sort.Ints(numbers)
    fmt.Println(numbers) // 輸出：[1 2 5 8]
}
```
----
### 3.3 作業系統基本概念 (Operating System, OS) 🖥️

* **觀念：** 作業系統是電腦的**總管家**，它管理硬體資源（CPU、記憶體、硬碟）。

#### (1) 記憶體管理 (Memory Management)
* 作業系統負責分配和回收電腦的**主記憶體 (RAM)** 給正在運行的程式。

#### (2) 行程與執行緒 (Processes and Threads)
* **行程 (Process)：** 一個**正在執行中的應用程式**，擁有自己的記憶體空間。
* **執行緒 (Thread)：** 行程內的**最小執行單元**，多個執行緒可以**共享**行程的記憶體空間，常用於實現多工。

----
## 🗺️ 第四章：進階工程師職涯發展路線 (Roadmap)

學完上述基礎後，你已經具備了作為一個初級開發人員的知識。接著，你需要專注於提升開發流程的品質和效率。

1.  **單元測試 (Unit Testing) & 整合測試 (Integration Testing):** 學習為程式碼撰寫自動化測試，確保程式品質，避免引入錯誤。
2.  **Docker (容器化):** 學習使用 Docker 將你的應用程式及其所有依賴項**打包**在一個標準化的「容器」中，解決環境不一致的問題。
3.  **Kubernetes (K8s) (容器編排):** 學習使用 K8s **自動化部署、擴展和管理**數百個 Docker 容器，是處理大規模應用的利器。
4.  **CI/CD (持續整合/持續部署 - Continuous Integration/Continuous Deployment):** 學習自動化程式碼從提交、測試到部署上線的整個流程，實現快速、可靠的功能交付。