# 面試準備
基本計算機概念
---
### Process / Thread
- Process(進程):獨立記憶體空間,擁有自己的記憶體空間。
Process間的通訊(Queue, Pipe)較為複雜但彼此不受影響
適合CPU密集型的任務,如大規模數據運算
- Thread(線程):共享記憶體,較輕量,適合多工處理
共享記憶體容易導致(race condition)
### Deadlock
兩個或多個程序互相等待資源而陷入無限等待的情況
死結成立四個必要條件
1. 互斥(Mutual Exclusion)
2. 佔有且等待(Hold and Wait)
3. 不可搶佔(No Preemption)
4. 循環等候(Circular Wait)
### 📌 **什麼是 Deadlock (死結)?**
**Deadlock** 指的是兩個或多個程序在執行過程中,由於競爭資源而造成互相等待的現象,導致程序無法繼續執行。
#### **🔄 死結的典型情境:**
假設有兩個程序 **P1** 和 **P2**,以及兩個資源 **R1** 和 **R2**:
1. **P1** 獲取 **R1**,然後請求 **R2**。
2. **P2** 獲取 **R2**,然後請求 **R1**。
3. 兩個程序都在等待對方釋放資源,造成死結。
---
### 📋 **死結發生的四個必要條件(Coffman 條件):**
1. **互斥(Mutual Exclusion):**
至少有一個資源是不可共享的(一次只能被一個程序使用)。
2. **佔有且等待(Hold and Wait):**
一個程序已經佔有至少一個資源,並且在等待其他被其他程序佔用的資源。
3. **不剝奪(No Preemption):**
資源不能被強制回收,只能由佔有者自願釋放。
4. **循環等待(Circular Wait):**
存在一個程序集合 {P1, P2, ..., Pn},其中 **P1** 等待 **P2** 佔有的資源,**P2** 等待 **P3**,依此類推,最終 **Pn** 等待 **P1** 的資源。
**✅ 當這四個條件同時成立時,系統就會發生死結。**
---
### 🛠️ **死結的解決方法:**
#### **1. 死結預防(Prevention):**
透過破壞四個必要條件中的至少一個來避免死鎖:
- **破壞「佔有且等待」** → 程序必須在請求資源前釋放所有已持有的資源。
- **破壞「循環等待」** → 為資源賦予全域序號,程序必須依序請求資源。
#### **2. 死結避免(Avoidance):**
- **銀行家演算法(Banker’s Algorithm):**
只有當系統進入安全狀態時,才分配資源。
#### **3. 死結偵測與回復(Detection and Recovery):**
- 允許死鎖發生,使用演算法(如資源分配圖)定期檢測死鎖,發現後採取措施,如強制終止程序或回收資源。
#### **4. 忽略死結(Ignore):**
- 在某些情境下(如大多數 UNIX 系統),系統選擇不處理死鎖,稱為 **鴕鳥策略(Ostrich Algorithm)**。
---
### 🧮 **程式範例:使用 Python 模擬死結**
#### **🔴 模擬死結:**
```python
import threading
import time
lock1 = threading.Lock()
lock2 = threading.Lock()
def task1():
with lock1:
print("Task 1 acquired lock1")
time.sleep(1)
with lock2:
print("Task 1 acquired lock2")
def task2():
with lock2:
print("Task 2 acquired lock2")
time.sleep(1)
with lock1:
print("Task 2 acquired lock1")
t1 = threading.Thread(target=task1)
t2 = threading.Thread(target=task2)
t1.start()
t2.start()
t1.join()
t2.join()
```
### 📖 Deadlock 面試常見問題與解答
#### ✅ **Q1. 什麼是死結(Deadlock)?**
**A:**
死結是指多個程序在執行過程中,因為競爭資源而導致互相等待的現象。當程序進入死結狀態後,若沒有外力介入,這些程序將無法繼續執行。
---
#### ✅ **Q2. 死結發生的必要條件是什麼?**
**A:**
根據 **Coffman 條件**,死結發生需同時滿足以下四個條件:
1. **互斥(Mutual Exclusion):** 至少有一個資源是不可共享的(一次只能被一個程序使用)。
2. **佔有且等待(Hold and Wait):** 程序已佔有至少一個資源,同時在等待其他被佔用的資源。
3. **不剝奪(No Preemption):** 已分配的資源不能被強制回收,只能由程序自行釋放。
4. **循環等待(Circular Wait):** 存在一組程序,彼此形成資源等待的環狀鏈。
---
#### ✅ **Q3. 如何預防死結?**
**A:**
為了預防死結,可以破壞上述四個條件中的至少一個:
- **避免佔有且等待:** 程序請求資源前必須一次性獲取所有所需資源。
- **資源分配順序:** 給資源編號,程序按照資源順序請求,避免循環等待。
- **限制資源請求:** 限制同時佔有的資源數量,減少死結發生機率。
---
#### ✅ **Q4. 如何偵測與處理死鎖?**
**A:**
1. **死結偵測:**
- 使用 **資源分配圖** 或 **等待圖** 偵測是否存在循環等待的情況。
- 使用演算法(如銀行家演算法)來檢查系統的安全性。
2. **死結處理方法:**
- **強制終止程序:** 終止其中一個或多個程序以解除死結。
- **資源回收:** 強制回收部分資源,使其他程序得以繼續執行。
- **循環檢測:** 系統定期進行死結偵測,發現死結後即採取補救措施。
---
#### ✅ **Q5. 死結與競爭條件(Race Condition)的差異?**
| | **Deadlock(死結)** | **Race Condition(競爭條件)** |
|:--|:------------------|:--------------------------|
| **定義** | 程序彼此相互等待資源,造成無限期阻塞。 | 多個程序同時操作共享資源,導致不可預期結果。 |
| **結果** | 程序永遠無法繼續執行。 | 程序可能繼續執行,但結果錯誤或不一致。 |
| **觸發時機** | 資源互相等待形成循環。 | 程序執行順序導致結果不同。 |
| **解決方法** | 避免循環等待、使用鎖等同步機制。 | 使用鎖、原子操作等方式確保一致性。 |
---
#### ✅ **Q6. 描述一種處理死結的真實案例。**
**A:**
**案例:銀行轉帳系統**
假設有兩個帳戶 **A** 和 **B**,當兩個轉帳操作同時發生時:
1. 程序 **P1** 鎖住帳戶 **A**,然後請求鎖帳戶 **B**。
2. 程序 **P2** 鎖住帳戶 **B**,然後請求鎖帳戶 **A**。
此時,兩個程序互相等待彼此的資源,形成死鎖。
**💡 解決方法:**
- **設定全域鎖順序:** 例如,要求轉帳程序總是先鎖帳號編號較小的帳戶,再鎖編號較大的帳戶。
- **使用超時機制:** 若請求鎖超過一定時間仍未成功,程序會釋放已獲得的鎖並重新嘗試。
---
---
### 虛擬記憶體(Virtual Memory)

虛擬記憶體允許程式使用比實體記憶體更多的空間,透過分頁(Paging)和分段(Segmentation)實現
當需要的資料不在主記憶體時,透過頁面置換算法 (LRU, FIFO) 將資料載入
### 記憶體分配 Stack / Heap
Stack:用於函數調用和局部變數的分配,記憶體空間較小但速度快
Heap:用於動態記憶體分配,空間較大但分配和釋放速度較慢
### 排成演算法(Scheduling Algorithms)
FCFS(先來先服務)
SJF(最短作業優先)
Round Robin(時間片輪轉)
Priority Scheduling(優先權排程)
### Array / Linked List
Array:記憶體連續、支援隨機存取(O(1)),但插入/刪除效率差(O(n))
```python=
class Node:
def __init__(self, data):
self.data = data
self.next = next
# Creating Nodes
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)
# Linking Nodes
node1.next = node2
node2.next = node3
```
Linked List:記憶體不連續,插入/刪除效率較好(O(1)),但不支援隨機存取
### Stack / Queue
Stack:(Last In First Out),常用於函數呼叫堆疊與遞迴
```python=
# Using list as stack
stack = []
# Pushing elements
stack.append(1)
stack.append(2)
# Popping elements
print(stack.pop())
```
Queue:(First In First Out),常用於排程、緩衝區
```python=
from collections import deque
# Creating a queue
queue = deque()
# Enqueueing elements
queue.append(1)
queue.append(2)
# Dequeueing elements
print(queue.popleft())
```
### Tree Structure
```python=
class TreeNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# Creating nodes
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
```
- Binary Search Tree:左子樹比節點小,右子樹比節點大
複雜度最佳:O(log n)
複雜度最差:O(n)
```python=
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
# Example usage
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
target = 5
print(binary_search(arr, target))
```
二元搜尋樹插入及搜尋
```python=
class Node:
def __init__(self, key):
self.left = None
self.right = None
self.val = key
def insert(root, key):
if root is None:
return Node(key)
if key < root.val:
root.left = insert(root.left, key)
else:
root.right = insert(root.right, key)
return root
def inorder(root):
if root:
inorder(root.left)
print(root.val, end=" ")
inorder(root.right)
```
- AVL Tree:自動保持高度平衡以優化查詢速度
複雜度最佳:
複雜度最差:
- Heap Tree:(Max-Heap), (Min-Heap),常用於優先佇列
複雜度最佳:
複雜度最差:
### 常見排序演算法
| 排序方法 | 平均時間 | 最差時間 | 穩定性 |
| -------- | -------- | -------- | --------|
| Bubble Sort | O(n^2) | O(n^2) | V |
| Selection Sort | O(n^2) | O(n^2) | X |
| Insertion Sort | O(n^2) | O(n^2) | V |
| Quick Sort | O(n log n) | O(n^2) | X |
| Merge Sort | O(n log n) | O(n log n) | V |
| Heap Sort | O(n log n) | O(n log n) | X |
軟體工程師
---
### TCP Window

TCP Window是用來控制資料流量的機制,確保接收端有足夠的緩衝區處理傳輸的資料,避免過載。可調整Window Size調整傳輸能力
- Sliding Window機制
滑動視窗允許多個封包在未被確認的情況下同時傳送,提高傳輸效率
---
### TCP流量控制(Flow Control) / TCP 壅塞控制(Congestion Control)
- 流量控制調整接收端回傳的Window Size
- 壅塞控制使用 慢啟動Slow Start, 壅塞避免Congestion Avoidance, 快速重傳Fast Restransmit, 快速恢復Fast Recovery
---
#### Slow Start / Congestion Avoidance
Slow Start 以指數增長方式提升傳輸速率
達到閥值後改用線性增長的Congestion Avoidance
---
### Python Web Crawler 遇到網頁 Redirect
爬蟲使用requests時可透過 allow_redirects=True 自動跟隨重新導頁,也可透過Session物件保持連線狀態
---
#### 處理需要登入的網站
使用Session模擬登入,並攜帶Cookie跟Header進行後續request
---
#### 避免爬蟲被封鎖
使用 User-Agent 偽裝、設定延遲時間、使用Proxy
---
### TCP/UDP的差異

TCP:需要可靠的傳輸協定應用 (HTTP, FTP, SMTP)
UDP:即時性高但容忍遺失的應用 (VoIP, Streaming)
---
### UDP廣播
UDP支援IP廣播與多傳播,可在區域網路內同時傳送資料給多個設備
---
### C語言 Structure Alignment
是為了讓CPU更高效存取記憶體,將結構體中的成員變數依照期對其要求填充(Padding),可以減少CPU存取記憶體的次數,提高效能。
### C Structure sizeof 問題
sizeof為計算結構體的總大小,包括因對齊而產生的Padding。
```cpp=
struct {
char a;
int b;
}
```
以上大小可能是8而不是5
原因:int為 4 byte , 4 * 2 = 8
---
### 什麼是 race condition
當多個執行緒同時共享資源而未正確同步時,會導致不可預期的問題產生。
---
### TLS Protocol(Transport Layer Security)
用於加密網路傳輸。使用非對稱加密交換金鑰後,再使用對稱加密進行資料傳輸。
---
### 什麼是 FPGA(Field-Programmable Gate Array)
是可編程邏輯元件,可根據需求重新配置邏輯電路,適用於高速運算、訊號處理等應用。
---
### C/C++ Pointer / Virtual
指標:儲存變數記憶體位址的變數
Virtual:在C++ 中用於虛擬函數,實現多型(Polymorphism)
---
### DHCP / DNS / IPv4 / AJAX 用途
DHCP:自動分配IP、子網路遮罩、閘道器等網路設定
DNS:將網域名稱轉換為IP位址
IPv4:第四版IP協議,使用 32-bit 位址
AJAX:(Asynchronous JavaScript and XML),實現網頁的非同步請求,常搭配RESTful API使用
---
### Socket
Socket是網路通信的端點,允許不同設備之間進行資料交換。
支援 TCP / UDP 協議
---
### 三向交握(Three-way Handshake)
SYN:客戶端傳送SYN封包請求連線
SYN-ACK:伺服器回應
ACK:客戶端再次回覆ACK建立連線
---
### Hashing Algorithm
將任意長度的輸入映射成固定長度的輸出 (Ex:MD5, SHA-256)
---
### HTTP/1.1 vs HTTP/2

HTTP/2:支援多路複用(Multiplexing),減少延遲。
壓縮標頭(Header Compression) 加快傳輸速度。
---
### WebSocket運作

支援雙向通訊,適合即時應用(聊天、線上遊戲)
使用TCP,建立持久連線
---
### Ajax
- 如何處理錯誤
使用 onerror或是在 fetch/axios 中使用 catch 處理錯誤回應
### JSONP
是早期的跨域解決方案但安全性較差
### CORS(Cross-Origin Resource Sharing)
是現行的跨域解決方案標準解法
---
網頁工程師
---
### MVC Architecture
Model:負責資料邏輯型態和資料庫互動
View:負責UI介面顯示
Controller:負責處理資料流控制和用戶輸入邏輯
### Session / Cookie
Session:儲存在伺服器端的用戶狀態資訊,透過Cookie中的 Session ID 維持連線狀態
Cookie:儲存在用戶端的小型文字檔案,保存用戶狀態
### RESTful API(Representational State Transfer Application Programming Interface)
基於 HTTP 協議 的 API 設計風格,使用統一的介面進行資源的存取與操作。將每個資源透過 URL 標識,並使用標準的 HTTP 方法 來執行操作
- 無狀態性(Stateless):每次請求都是獨立的,伺服器不會記住前一次請求的狀態
- 統一介面(Uniform Interface):使用HTTP標準方法
GET -> 讀取資源
POST -> 新增資源
PUT / PATCH -> 更新資源
DELETE -> 刪除資源
- 資源導向(Resource-Oriented):
```
GET https://api.example.com/users/123 → 獲取 ID 為 123 的使用者資訊
POST https://api.example.com/users → 新增新使用者
```
- 格式
通常使用 JSON 或 XML 資料傳輸
### Docker
- Docker Engine
* Docker Daemon -> 負責管理容器與映像檔
* Docker CLI -> 命令列工具,用於跟 Docker Daemon 溝通
- 映像檔(Image)
具有應用程式與其依賴的封裝檔案,是建立容器的基礎
- 容器(Container)
執行中的映像檔,相當於輕量化的虛擬機
- Docker Hub
公開的映像倉庫,用來下載與分享映像檔
運作流程:
1. 撰寫Dockerfile -> 定義環境與指令
```dockerfile=
# 使用官方 Node.js 映像檔
FROM node:14
# 設定工作目錄
WORKDIR /app
# 複製專案檔案
COPY . .
# 安裝依賴套件
RUN npm install
# 啟動應用程式
CMD ["node", "app.js"]
# 開放 3000 埠口
EXPOSE 3000
```
2. 建立映像檔
```dockerfile=
docker build -t myapp .
```
3. 啟動容器
```dockerfile=
docker run -d -p 8080:80 myapp
```
4. 查看運行狀態
```dockerfile=
docker ps
```
5. 執行
```dockerfile=
# 建立映像檔
docker build -t mynodeapp .
# 運行容器
docker run -d -p 3000:3000 mynodeapp
```
測試工程師
---
### 黑箱測試 / 白箱測試
黑箱測試:只看輸入輸出,不考慮內部邏輯
白箱測試:深入檢查內部流程及邏輯
### TDD(Test-Driven Development)
先寫測試再寫程式碼,強調單元測試
1. 撰寫失敗的測試
2. 開發程式碼讓測試通過
3. 重構程式碼
### BDD(Behavior-Driven Development)
從使用者角度撰寫測試案例,強調行為描述
APP開發工程師
---
### Android Lifecycle
- onCreate()
- onStart()
- onResume()
- onPause()
- onStop()
- onDestroy()
資安工程師
---
### OSI 七層架構與範例協定
- **實體層 (Physical Layer)**
範例協定:Ethernet 乙太網路、RS-232、光纖 (Fiber-optic)、橋接器 (Bridge)
- **資料連結層 (Data Link Layer)**
範例協定:PPP、HDLC、802.11、Frame Relay
- **網路層 (Network Layer)**
範例協定:IP、ICMP、IGMP、OSPF、RIP
- **傳輸層 (Transport Layer)**
範例協定:TCP、UDP、SCTP、DCCP、RUDP
- **會議層 (Session Layer)**
範例協定:NetBIOS、RPC、PPTP
- **表示層 (Presentation Layer)**
範例協定:TLS/SSL、MIME、XDR、JPEG、ASCII
- **應用層 (Application Layer)**
範例協定:HTTP、FTP、SMTP、DNS、Telnet
---
### 常見 TCP/UDP Port 用途
**TCP Port:**
- `21`:FTP 控制連線
- `22`:SSH (Secure Shell) 遠端管理
- `23`:Telnet 遠端登入 (明文傳輸)
- `53`:DNS 伺服器
- `80`:HTTP 網頁服務
- `88`:Kerberos 驗證服務
- `139`:NetBIOS Session Service
- `443`:HTTPS 安全加密網頁服務
- `445`:Windows 檔案分享
- `1433`:Microsoft SQL Server 預設 port
- `3306`:MySQL 資料庫服務
- `3389`:RDP 遠端桌面連線
**UDP Port:**
- `111`:RPC (Remote Procedure Call)
- `161`:SNMP (Simple Network Management Protocol)
---
### 程式源碼檢測方法
- **SAST (Static Application Security Testing)**
- 靜態分析源碼,找出安全漏洞與不良設計
- 常用工具:Checkmarx、SonarQube
- **SCA (Software Composition Analysis)**
- 分析開源套件的安全性與授權風險
- 常用工具:WhiteSource、Black Duck
- **DAST (Dynamic Application Security Testing)**
- 模擬攻擊程式運行狀態,檢測安全漏洞
- 常用工具:OWASP ZAP、Acunetix
---
### 滲透測試程序與工具
1. **資訊收集**:使用網域查詢、端口掃描、WHOIS 查詢等方式蒐集目標資訊
2. **威脅建模與漏洞分析**:分析系統架構,找出可能存在的漏洞
3. **漏洞利用**:實際利用已知漏洞進行入侵測試
4. **後期提權與持久化**:獲取更高權限並維持系統存取
5. **報告撰寫**:彙整測試過程、結果及改進建議
**常用工具:**
- **Nmap 指令範例 (針對 192.168.1.0/24 網段):**
- **IP 掃描:**
```bash
nmap -sn 192.168.1.0/24 > ip.txt
```
- **開放 Port 掃描:**
```bash
nmap -sS 192.168.1.0/24 > open_ports.txt
```
- **服務掃描:**
```bash
nmap -sV 192.168.1.0/24 > service.txt
```
- **作業系統偵測:**
```bash
nmap -O 192.168.1.0/24 > os.txt
```
---
### SQL Injection 的六種攻擊手法
- **Error-based SQL Injection**
- **Union-based SQL Injection**
- **Boolean-based SQL Injection**
- **Time-based SQL Injection**
- **Out-of-band SQL Injection**
- **Second-order SQL Injection**
---
### Kubernetes 故障排除常用指令
- **查看 Pod 狀態:**
```bash
kubectl get pods --all-namespaces
```
- **查看 Pod 日誌:**
```bash
kubectl logs [pod-name] -n [namespace]
```
- **查看 Pod 內部:**
```bash
kubectl exec -it [pod-name] -n [namespace] -- /bin/bash
```
- **查看集群事件:**
```bash
kubectl get events --all-namespaces
```
- **查看節點狀態:**
```bash
kubectl get nodes
```
---
### 常見 HTTP Status Codes
- 200:伺服器正常回應
- 400:請求格式錯誤或參數異常
- 401:請求未通過身份認證
- 403:伺服器拒絕提供服務
- 404:找不到請求資源
- 500:伺服器內部錯誤
- 503:服務暫時無法使用
- 504:代理伺服器未收到上游伺服器的回應
---
電腦視覺工程師
---
### Convolutional Layer
| 參數 | Pytorch | Tensorflow |
| -------- | -------- | -------- |
| 卷積層 | torch.nn.Conv2d | tf.keras.layers.Conv2D |
| Kernel | kernel_size=3 | kernel_size=3 |
| Stride | stride=1 | strides=1 |
| Padding | padding=1 or 'same' | padding='same' or padding='valid' |
透過卷積核(Kernel)在影像上滑動,提取特徵
而特徵圖大小取決於kernel size, stride and padding
```python=
import torch
import torch.nn as nn
# Torch
conv_layer = nn.Conv2d(
in_channels=3,
out_channels=16,
kernel_size=3,
stride=1,
padding=1 #填充以保持尺寸一致
)
input_tensor = torch.randn(1, 3, 32, 32) # (batch_size=1, channels=3, height=32, width=32)
output = conv_layer(input_tensor)
print("output: ", output.shape) # output: (1, 16, 32, 32)
```
```python=
import tensorflow as tf
# Tensorflow
conv_layer = tf.keras.layers.Conv2D(
filters=16,
kernel_size=3,
strides=1,
padding='same', #填充以保持尺寸一致
input_shape(32, 32, 3)
)
model = tf.keras.Sequential([conv_layer])
input_tensor = tf.random.normal([1, 32, 32, 3]) # (batch_size, height, width, channels)
output = model(input_tensor)
print("output: ", output.shape) # output: (1, 32, 32, 16)
```
### Kernel Size
卷積核是用來在影像上滑動並提取特徵的小矩陣
常見大小:3x3 5x5 7x7
公式(無Padding): 輸出尺寸 = ((輸入尺寸 - Kernel Size) / Stride) + 1
### Stride
卷積核在影像上每次移動的像素數量,預設stride=1
- Stride = 1 -> 輸出尺寸較大,特徵圖詳細
- Stride > 1 -> 輸出尺寸變小,特徵圖較粗糙,計算量減少
### Padding
在輸入影像的邊緣補零,使卷積核可以覆蓋到邊緣像素
- Valid Padding(Padding=0):不進行填充 -> 輸出尺寸縮小
- Same Padding:填充像素,使輸出尺寸與輸入相同
公式(包含Padding): 輸出尺寸 = ((輸入尺寸 - Kernel Size + 2 * Padding) / Stride) + 1
### 常用電腦視覺函式 (Tensorflow, torch)
- 基本操作
| 功能 | **TensorFlow** | **PyTorch** |
|----------------------------|------------------------------------------|------------------------------------------|
| **匯入套件** | `import tensorflow as tf` | `import torch` |
| **建立張量** | `tf.constant()`, `tf.Variable()` | `torch.tensor()`, `torch.Tensor()` |
| **隨機數生成** | `tf.random.normal()` | `torch.randn()` |
| **矩陣運算** | `tf.matmul()`, `tf.add()`, `tf.multiply()`| `torch.matmul()`, `torch.add()`, `torch.mul()` |
| **取維度** | `tf.shape(tensor)` | `tensor.shape` |
| **轉換數據型別** | `tf.cast()` | `tensor.type()` or `tensor.to()` |
| **轉置矩陣** | `tf.transpose()` | `tensor.transpose()` |
| **調整張量形狀** | `tf.reshape()` | `tensor.view()` or `tensor.reshape()` |
| **將 NumPy 轉換為張量** | `tf.convert_to_tensor()` | `torch.from_numpy()` |
| **將張量轉換為 NumPy** | `tensor.numpy()` | `tensor.numpy()` |
- 資料處理
| 功能 | **TensorFlow** | **PyTorch** |
|----------------------------|------------------------------------------|------------------------------------------|
| **數據增強** | `tf.image.flip_left_right()`, `tf.image.resize()` | `torchvision.transforms` |
| **正規化** | `tf.keras.layers.Normalization()` | `torchvision.transforms.Normalize()` |
| **數據讀取** | `tf.data.Dataset.from_tensor_slices()` | `torch.utils.data.Dataset` + `DataLoader`|
| **數據亂序與批次處理** | `Dataset.shuffle().batch()` | `DataLoader(shuffle=True, batch_size=32)`|
| **圖像處理** | `tf.image.decode_jpeg()`, `tf.image.resize()` | `torchvision.transforms`
- 模型建立
| 功能 | **TensorFlow** | **PyTorch** |
|----------------------------|------------------------------------------|------------------------------------------|
| **建立模型** | `tf.keras.Sequential()` | `torch.nn.Sequential()` or `nn.Module` |
| **自定義模型** | 繼承 `tf.keras.Model` | 繼承 `torch.nn.Module` |
| **卷積層 (Conv2D)** | `tf.keras.layers.Conv2D()` | `torch.nn.Conv2d()` |
| **池化層 (Pooling)** | `tf.keras.layers.MaxPooling2D()` | `torch.nn.MaxPool2d()` |
| **全連接層 (Dense/Linear)** | `tf.keras.layers.Dense()` | `torch.nn.Linear()` |
| **丟棄層 (Dropout)** | `tf.keras.layers.Dropout()` | `torch.nn.Dropout()` |
| **正規化層 (BatchNorm)** | `tf.keras.layers.BatchNormalization()` | `torch.nn.BatchNorm2d()` |
| **激活函數 (ReLU, Sigmoid)** | `tf.keras.layers.ReLU()`, `tf.nn.sigmoid()` | `torch.nn.ReLU()`, `torch.sigmoid()` |
- 訓練與優化
| 功能 | **TensorFlow** | **PyTorch** |
|----------------------------|------------------------------------------|------------------------------------------|
| **損失函數 (Loss)** | `tf.keras.losses.MeanSquaredError()`, `CategoricalCrossentropy()` | `torch.nn.MSELoss()`, `torch.nn.CrossEntropyLoss()` |
| **優化器 (Optimizer)** | `tf.keras.optimizers.Adam()`, `SGD()` | `torch.optim.Adam()`, `torch.optim.SGD()`|
| **計算梯度** | `tf.GradientTape()` | `loss.backward()` |
| **更新權重** | `optimizer.apply_gradients()` | `optimizer.step()` |
| **清除梯度** | 自動處理 | `optimizer.zero_grad()` |
| **學習率調整** | `tf.keras.callbacks.LearningRateScheduler()` | `torch.optim.lr_scheduler.StepLR()` |
| **早停 (EarlyStopping)** | `tf.keras.callbacks.EarlyStopping()` | 需自定義邏輯或使用 `torchtools` |
- 評估與預測
| 功能 | **TensorFlow** | **PyTorch** |
|----------------------------|------------------------------------------|------------------------------------------|
| **預測** | `model.predict()` | `model(input)` |
| **評估模型** | `model.evaluate()` | 自定義計算 Loss 與準確率 |
| **儲存模型** | `model.save('path')` | `torch.save(model.state_dict(), 'path')` |
| **讀取模型** | `tf.keras.models.load_model('path')` | `model.load_state_dict(torch.load('path'))` |
| **設定模型為評估模式** | 自動處理 | `model.eval()` |
| **設定模型為訓練模式** | 自動處理 | `model.train()` |
- 深度學習
🔷 卷積與池化
| 功能 | TensorFlow | PyTorch |
|----------------------|----------------------------------|--------------------------------------|
| 2D 卷積 | `tf.keras.layers.Conv2D()` | `torch.nn.Conv2d()` |
| 2D 反卷積 (轉置卷積) | `tf.keras.layers.Conv2DTranspose()` | `torch.nn.ConvTranspose2d()` |
| 2D 最大池化 | `tf.keras.layers.MaxPooling2D()` | `torch.nn.MaxPool2d()` |
| 2D 平均池化 | `tf.keras.layers.AveragePooling2D()` | `torch.nn.AvgPool2d()` |
| 全局平均池化 | `tf.keras.layers.GlobalAveragePooling2D()` | `torch.nn.AdaptiveAvgPool2d()` |
🔷 正規化與正則化
| 功能 | TensorFlow | PyTorch |
|--------------------|----------------------------------|--------------------------------------|
| Batch Normalization | `tf.keras.layers.BatchNormalization()` | `torch.nn.BatchNorm2d()` |
| Dropout | `tf.keras.layers.Dropout()` | `torch.nn.Dropout()` |
| L2 正則化 | `tf.keras.regularizers.l2()` | 透過 `weight_decay` 參數於 Optimizer |
🔷 激活函數
| 功能 | TensorFlow | PyTorch |
|--------------------|-----------------------------------|--------------------------------------|
| ReLU | `tf.keras.layers.ReLU()` | `torch.nn.ReLU()` |
| Sigmoid | `tf.keras.layers.Activation('sigmoid')` | `torch.nn.Sigmoid()` |
| Tanh | `tf.keras.layers.Activation('tanh')` | `torch.nn.Tanh()` |
| Softmax | `tf.keras.layers.Softmax()` | `torch.nn.Softmax()` |
| LeakyReLU | `tf.keras.layers.LeakyReLU()` | `torch.nn.LeakyReLU()` |
### 激活函數
| **激活函數** | **公式** | **輸出範圍** | **對稱性** | **梯度消失** | **死神經元問題** | **計算成本** | **優點** | **缺點** | **適用場景** | **TensorFlow 語法** | **PyTorch 語法** |
|--------------|----------|--------------|------------|--------------|----------------|--------------|----------|----------|--------------|-------------------|----------------|
| **ReLU** | $f(x) = \max(0, x)$ | (0, ∞) | 否 | 否 | 是 | 低 | 計算簡單,收斂快 | 死神經元問題 | CNN | `tf.keras.layers.ReLU()` | `torch.nn.ReLU()` |
| **Leaky ReLU** | $f(x) = \begin{cases}x & x > 0 \\ \alpha x & x \leq 0\end{cases}$ | (-∞, ∞) | 否 | 否 | 否 | 低 | 解決死神經元問題 | 需調整 α | 深度網路 | `tf.keras.layers.LeakyReLU(alpha=0.01)` | `torch.nn.LeakyReLU(0.01)` |
| **Sigmoid** | $f(x) = \frac{1}{1 + e^{-x}}$ | (0, 1) | 否 | 是 | 否 | 中 | 輸出概率值 | 梯度消失、非0中心 | 二分類問題 | `tf.keras.layers.Activation('sigmoid')` | `torch.nn.Sigmoid()` |
| **Tanh** | $f(x) = \tanh(x)$ | (-1, 1) | 是 | 是 | 否 | 中 | 0 中心、收斂快於 Sigmoid | 梯度消失 | RNN、序列模型 | `tf.keras.layers.Activation('tanh')` | `torch.nn.Tanh()` |
| **Softmax** | $f(x_i) = \frac{e^{x_i}}{\sum_j e^{x_j}}$ | (0, 1) | 否 | 是 | 否 | 中 | 概率分佈輸出 | 易被極大值主導 | 多分類問題輸出層 | `tf.keras.layers.Softmax()` | `torch.nn.Softmax(dim=1)` |
| **ELU** | $f(x) = \begin{cases}x & x > 0 \\ \alpha (e^x - 1) & x \leq 0\end{cases}$ | (-α, ∞) | 是 | 否 | 否 | 高 | 更平滑的輸出,減少梯度消失 | 計算量較大 | 深度神經網路 | `tf.keras.layers.ELU(alpha=1.0)` | `torch.nn.ELU(alpha=1.0)` |
| **Swish** | $f(x) = x \cdot \sigma(x)$ | (-∞, ∞) | 是 | 否 | 否 | 中 | 性能超越 ReLU,平滑性好 | 計算較複雜 | 深層模型 (如 EfficientNet) | `tf.keras.activations.swish` | `torch.nn.SiLU()` |
### **什麼是 Support Vector Machine (SVM)?**
**Support Vector Machine (SVM)** 是一種監督式學習演算法,用於分類和回歸分析。其主要思想是找到一條「超平面(Hyperplane)」來最大化資料點之間的間隔(Margin),以達到最佳的分類效果。
- **關鍵概念:**
- **超平面 (Hyperplane):** 將資料分割成不同類別的決策邊界。
- **支持向量 (Support Vectors):** 距離超平面最近的資料點,決定了超平面的邊界。
- **間隔 (Margin):** 支持向量與超平面的距離,SVM 目標是最大化此間隔。
- **公式:**
- 對於二分類問題,超平面可表示為:
$$
w^T x + b = 0
$$
其中,$w$ 為權重向量,$b$ 為偏置。
- **優點:**
- 適用於高維數據。
- 能處理非線性分類(使用核函數,如 RBF Kernel)。
- **缺點:**
- 對於大型資料集效率較低。
- 對噪聲敏感,特別是在資料不可分的情況下。
---
### **解釋 CNN、RNN 差別,ResNet 原理以及好處**
| 模型 | **CNN (Convolutional Neural Network)** | **RNN (Recurrent Neural Network)** |
|---------|------------------------------------------------------|------------------------------------------------------|
| **用途** | 影像處理、物體辨識、影像分類 | 序列資料處理(如語音辨識、自然語言處理) |
| **特徵** | 使用卷積層提取局部特徵,適合靜態資料 | 具有記憶性,能處理時間序列資料 |
| **問題** | 難以處理時間相關性 | 易出現梯度消失或爆炸問題 |
#### ✅ **1. Random Forest(隨機森林)**
- **類型:** 集成學習(Ensemble Learning)、分類與回歸。
- **原理:**
- 隨機森林透過結合多棵決策樹的預測結果來提高模型的準確性和穩定性。
- 使用 **Bagging(Bootstrap Aggregating)** 技術:
- 從原始數據中隨機有放回抽樣生成多個子數據集。
- 每棵樹在這些子數據集上進行訓練。
- 最後對分類問題使用**多數表決法(Majority Voting)**,對回歸問題使用**平均法**來獲得最終預測。
- **優點:**
- 有效減少過擬合現象。
- 支援多種資料類型(分類、回歸等)。
- 可以衡量特徵重要性。
- **缺點:**
- 訓練和預測時間相對較長。
- 難以解釋模型決策過程。
---
#### ✅ **2. Logistic Regression(邏輯迴歸)**
- **類型:** 監督式學習、二分類/多分類。
- **原理:**
- 使用 Sigmoid 函數將線性迴歸結果轉換為機率值:
$$
p = \frac{1}{1 + e^{-(w^Tx + b)}}
$$
- 透過**交叉熵損失函數(Cross-Entropy Loss)**最小化誤差:
$$
L = -[y \log(p) + (1 - y) \log(1 - p)]
$$
- **優點:**
- 簡單易實現,計算成本低。
- 對特徵影響解釋性強。
- **缺點:**
- 只能解決線性可分問題。
- 對於多分類問題需要使用 Softmax 或 One-vs-Rest。
---
#### ✅ **3. SVM(Support Vector Machine,支持向量機)**
- **類型:** 監督式學習、分類/回歸。
- **原理:**
- 尋找一個能夠最大化類別間隔(Margin)的超平面。
- 對於非線性問題,使用核函數(Kernel Function)將數據映射到高維空間(如 RBF、Polynomial)。
- **核心公式:**
$$
f(x) = w^T x + b
$$
- 其中 $w$ 是權重向量,$b$ 是偏差。
- 損失函數使用 **Hinge Loss**:
$$
L = \sum \max(0, 1 - y(w^T x + b))
$$
- **優點:**
- 能處理高維資料。
- 能應對非線性分類問題(使用核方法)。
- **缺點:**
- 計算成本高,尤其在大數據下。
- 參數(如 C、Kernel)的選擇較為敏感。
---
#### ✅ **4. Decision Tree(決策樹)**
- **類型:** 監督式學習、分類與回歸。
- **原理:**
- 透過樹狀結構進行決策,每個節點基於特徵做二元分裂。
- 常用的分裂依據:
- **Gini Impurity:** 測量數據集的純度。
- **Entropy(資訊增益):** 衡量特徵對資料集的不確定性降低程度。
- **優點:**
- 易於理解與視覺化。
- 可處理類別型和數值型資料。
- **缺點:**
- 容易過擬合。
- 對異常值敏感。
---
#### ✅ **5. K-Means(K 均值聚類)**
- **類型:** 非監督式學習、聚類分析。
- **原理:**
1. 隨機選取 K 個初始中心點。
2. 將數據點分配到距離最近的中心點。
3. 計算每個群集的平均值作為新的中心點。
4. 重複步驟 2 和 3 直到收斂。
- **損失函數:**
$$
L = \sum_{i=1}^{k} \sum_{x \in C_i} \|x - \mu_i\|^2
$$
其中 $\mu_i$ 為第 $i$ 群的中心。
- **優點:**
- 演算法簡單且效率高。
- 適用於大規模數據集。
- **缺點:**
- 需事先指定 K 值。
- 對初始中心敏感,可能陷入局部最優。
---
#### ✅ **6. PCA(Principal Component Analysis,主成分分析)**
- **類型:** 降維、特徵擷取。
- **原理:**
- 找出數據的主要變異方向(主成分),將數據投影到新的坐標系上。
- 使用特徵值分解或奇異值分解(SVD)計算主成分。
- **步驟:**
1. 中心化數據(減去平均值)。
2. 計算協方差矩陣。
3. 計算特徵向量和特徵值。
4. 挑選具有最大特徵值的主成分。
- **優點:**
- 減少資料維度,提升運算效率。
- 可視化高維數據。
- **缺點:**
- 降維後失去部分信息。
- 不適合非線性數據。
---
#### 📊 **機器學習演算法比較表**
| **演算法** | **類型** | **適用場景** | **優點** | **缺點** |
|------------------|----------|--------------------|--------------------|------------------|
| Random Forest | 分類/回歸 | 特徵重要性分析、分類問題 | 抗過擬合、準確性高 | 訓練慢、模型難解釋 |
| Logistic Regression | 分類 | 二分類問題 | 簡單、可解釋性強 | 僅適用線性問題 |
| SVM | 分類/回歸 | 二分類問題、小數據集 | 效果佳、處理非線性問題 | 訓練慢、需調整參數 |
| Decision Tree | 分類/回歸 | 簡單決策問題 | 易理解、可視化 | 易過擬合、對噪聲敏感 |
| K-Means | 聚類 | 客群分析、影像分割 | 簡單高效、適用大數據 | 需設定 K 值、對初始值敏感 |
| PCA | 降維 | 特徵擷取、資料可視化 | 降低維度、保留主要資訊 | 不適用非線性數據 |
---
#### 🔸 **ResNet (Residual Network) 原理與好處:**
- **原理:** 引入「殘差結構 (Residual Block)」,透過「捷徑連接 (Skip Connection)」直接將輸入加到輸出,公式如下:
$$
y = F(x) + x
$$
其中,$F(x)$ 是卷積層的輸出,$x$ 是輸入。
- **好處:**
- **解決深度網路的梯度消失問題。**
- **允許建構更深層的網絡(如 ResNet-50、ResNet-101)。**
- **加快收斂速度,提高準確率。**
---
### **解釋 Cross-Entropy(交叉熵)**
- **Cross-Entropy** 是分類問題常用的損失函數,衡量預測值與實際值之間的差距。
- **公式(對於二分類問題):**
$$
L = -[y \log(p) + (1 - y) \log(1 - p)]
$$
其中:
- $y$:實際標籤(0 或 1)
- $p$:預測為正類的機率
- **特性:**
- 預測越準確,交叉熵越小。
- 預測錯誤時懲罰較大,能有效促使模型修正錯誤。
---
### **推導 Backpropagation**
**反向傳播 (Backpropagation)** 是透過鏈式法則計算誤差對權重的偏導數,進而更新權重。
#### 🔸 **步驟:**
1. **正向傳播 (Forward Pass):** 計算預測值。
2. **計算損失 (Loss Function):** 使用 MSE 或 Cross-Entropy。
3. **反向傳播:**
- 計算損失對每層權重的偏導數:
$$
\frac{\partial L}{\partial w} = \frac{\partial L}{\partial o} \cdot \frac{\partial o}{\partial z} \cdot \frac{\partial z}{\partial w}
$$
其中,$o$ 為輸出,$z$ 為權重加權後的線性組合。
4. **更新權重:**
- 使用梯度下降法:
$$
w := w - \eta \frac{\partial L}{\partial w}
$$
其中,$\eta$ 為學習率。
---
### **為什麼需要正則化?L1 和 L2 正則化差異**
**正則化 (Regularization)** 是用來防止過擬合的方法。
- **L1 正則化(Lasso):**
- 加入權重的絕對值懲罰項:
$$
L = Loss + \lambda \sum |w|
$$
- **效果:** 會將部分權重推為 0,實現特徵選擇。
- **L2 正則化(Ridge):**
- 加入權重平方的懲罰項:
$$
L = Loss + \lambda \sum w^2
$$
- **效果:** 減少大權重值,防止模型對訓練數據過於敏感。
---
### **什麼是 Confusion Matrix?如何計算 Sensitivity 和 Precision?**
- **Confusion Matrix(混淆矩陣):** 衡量分類模型效能的矩陣。
| | **預測為真** | **預測為假** |
|--------------|----------------|----------------|
| **實際為真** | True Positive (TP) | False Negative (FN) |
| **實際為假** | False Positive (FP) | True Negative (TN) |
- **Sensitivity(靈敏度,召回率):**
$$
Sensitivity = \frac{TP}{TP + FN}
$$
→ 模型正確預測正類的能力。
- **Precision(精確率):**
$$
Precision = \frac{TP}{TP + FP}
$$
→ 模型預測為正類時的準確性。
---
### **偏差(Bias)與變異(Variance)差別,哪個更重要?**
| **指標** | **定義** | **特性** |
|----------|----------|----------|
| **Bias** | 預測值與真實值之間的偏差,反映模型的擬合程度 | 高偏差 → 欠擬合 |
| **Variance** | 模型對不同資料集的敏感度 | 高變異 → 過擬合 |
**➡️ 平衡偏差與變異是關鍵(Bias-Variance Trade-off)**。
**訓練過程中,兩者同等重要,需視具體問題選擇優先考慮的指標。**
---
### **如何做 Hyper-parameter Tuning?**
**超參數調整(Hyper-parameter Tuning)**是優化模型效能的關鍵步驟。
#### 🔸 **方法:**
1. **Grid Search(網格搜尋):** 遍歷所有組合,找到最佳參數。
2. **Random Search(隨機搜尋):** 隨機選取超參數組合,比 Grid Search 效率高。
3. **Bayesian Optimization(貝葉斯優化):** 使用貝葉斯定理來選擇最可能的優化參數。
4. **Hyperopt、Optuna 等工具:** 進行自動化超參數調整。
---
### **KNN 和 Multi-nominal Logistic Regression 差異**
| **項目** | **KNN** | **Multi-nominal Logistic Regression** |
|--------------------------|-----------------------------------|---------------------------------------|
| **類型** | 非參數方法 | 參數方法 |
| **計算方式** | 距離度量(如歐氏距離) | 最大化機率 |
| **對資料分佈的假設** | 無需假設 | 假設類別邊界為線性 |
| **適用場合** | 小型數據集 | 大型數據集 |
| **優缺點** | 簡單但計算量大 | 可擴展性強,但對異常值敏感 |
---
### **何時需要降維?請描述 2 種方法**
**降維(Dimension Reduction)**可用於:
- 特徵數量過多(高維災難)。
- 資料噪聲大,影響模型效能。
#### 🔸 **常見降維方法:**
1. **PCA(主成分分析):**
- 透過線性變換將資料映射到低維空間。
- 選擇最大化資料變異性的主成分。
2. **t-SNE(t-Distributed Stochastic Neighbor Embedding):**
- 透過非線性方式將高維資料降到 2D 或 3D,適合視覺化。
- 優點:能保留局部結構。
- 缺點:不適合大數據集,計算成本高。
---
### **如何評估回歸模型(除 MSE 外)?**
- **MAE(Mean Absolute Error):** 平均絕對誤差。
- **RMSE(Root Mean Squared Error):** MSE 開根號後的值,更重視較大誤差。
- **$R^2$ Score(決定係數):** 衡量模型解釋變異的能力,取值範圍 [0, 1],越接近 1 越好。
- **MAPE(Mean Absolute Percentage Error):** 平均絕對百分比誤差,反映預測相對誤差。
---
### 📡 **訊號處理 (Signal Processing)**
#### 1. **傅利葉轉換差異:FS, FT, DTFT, DFT, FFT**
| **術語** | **全名** | **特性** |
|----------|----------------------------|-------------------------|
| **FS** | Fourier Series(傅立葉級數) | 用於分析週期性信號 |
| **FT** | Fourier Transform(傅立葉轉換) | 將非週期信號轉換為頻域 |
| **DTFT** | Discrete-Time Fourier Transform(離散時間傅立葉轉換) | 適用於離散時間的連續頻率 |
| **DFT** | Discrete Fourier Transform(離散傅立葉轉換) | 將有限離散訊號轉換為頻域 |
| **FFT** | Fast Fourier Transform(快速傅立葉轉換) | 高效計算 DFT 的演算法 |
---
#### 2. **如何評估訊號的 SNR(訊雜比)**
- **SNR 公式:**
$$
SNR = 10 \log_{10}\left(\frac{P_{signal}}{P_{noise}}\right)
$$
其中:
- $P_{signal}$:信號功率
- $P_{noise}$:雜訊功率
- **方法:**
1. 使用傅立葉轉換分離信號與雜訊頻段。
2. 透過能量或功率計算出 SNR。
---
#### 3. **如何對無限訊號應用低通濾波器**
1. **傅立葉轉換**將訊號轉換到頻域。
2. **設計濾波器**(例如 Butterworth、Chebyshev)。
3. **濾波器應用**:在頻域內濾掉高頻訊號。
4. **反傅立葉轉換**:將濾波後訊號轉換回時域。
---
#### 4. **如何找到或偵測訊號中的某種模式**
- **方法:**
- **交叉相關(Cross-Correlation):** 用來測量訊號相似度。
- **卷積神經網絡(CNN):** 適用於影像與訊號模式辨識。
- **小波轉換(Wavelet Transform):** 偵測訊號的時間-頻率特性。
---
#### 5. **Convolution 和 Correlation 差別**
| **特性** | **Convolution** | **Correlation** |
|------------------|----------------|----------------|
| **數學運算** | 核心函數反轉後滑動 | 直接滑動 |
| **使用場景** | 神經網絡、影像處理 | 模式匹配、統計分析 |
| **相同情境** | 若核函數對稱時兩者結果相同 | - |
---
### ⚠️ **其他問題**
#### 1. **資料極度不平衡時的問題**
- **99% 的準確率可能是假象**,因為模型可能只是偏向預測多數類別。
- **解決方法:**
- 使用 F1-score、ROC-AUC 等衡量指標。
- 應用過採樣(SMOTE)、欠採樣等方法。
---
#### 2. **訊號與影像分類所需資料與流程**
- **所需資料:**
- 標註良好的訓練數據。
- 噪聲數據以強化模型的魯棒性。
- 不同來源的資料以提升泛化能力。
- **分類流程:**
1. 數據預處理(去噪、正規化)。
2. 特徵提取(CNN、PCA 等)。
3. 模型訓練與調參。
4. 模型評估與優化。
---
#### 3. **舉例一項熟悉的理論或演算法**
**範例:卷積神經網絡(CNN)**
- **適用場景:** 影像分類、物件偵測、醫療影像分析等。
- **核心概念:**
- 卷積層提取特徵。
- 池化層降維。
- 全連接層負責分類。
---
#### 4. **傳統影像處理演算法範例**
- **邊緣檢測:** Canny、Sobel
- **特徵提取:** SIFT、HOG
- **濾波器:** Gaussian Blur、Median Filter
- **圖像分割:** Otsu Thresholding、Watershed
### 🔶 機器學習與深度學習的差異
| **特徵** | **機器學習 (Machine Learning)** | **深度學習 (Deep Learning)** |
|------------------|----------------------------|-------------------------|
| **資料需求** | 少量數據即可訓練 | 需要大量數據 |
| **特徵工程** | 需要手動特徵擷取 | 自動從數據中擷取特徵 |
| **模型解釋性** | 模型較易解釋 | 模型解釋性較差 |
| **運算資源需求** | 較低 | 需要高效能硬體(GPU/TPU) |
| **常用演算法** | 決策樹、SVM、KNN、隨機森林等 | CNN、RNN、LSTM、Transformer 等 |
| **適用場景** | 結構化數據(表格數據等) | 非結構化數據(影像、語音、文字等) |
---
### 🔶 神經網路的工作原理
1. **輸入層 (Input Layer)**:接收原始數據作為輸入。
2. **隱藏層 (Hidden Layers)**:
- 每個神經元進行線性組合計算:
$$
z = w^T x + b
$$
- 接著通過非線性激活函數(如 ReLU、Sigmoid、Tanh)。
3. **輸出層 (Output Layer)**:
- 輸出最終預測結果(例如 Softmax 用於多分類問題)。
4. **損失函數 (Loss Function)**:衡量預測值與實際值的差距。
5. **反向傳播 (Backpropagation)**:利用梯度下降法來更新權重,以最小化損失。
---
### 🔶 正向傳播與反向傳播的概念
#### ✅ **正向傳播 (Forward Propagation)**:
- 數據由輸入層經過每一層的加權和與激活函數計算,最終輸出預測值。
- 公式:
$$
a^{(l)} = f(W^{(l)}a^{(l-1)} + b^{(l)})
$$
其中,$a^{(l)}$ 為第 $l$ 層的輸出,$f$ 為激活函數。
#### ✅ **反向傳播 (Backpropagation)**:
- 計算損失函數對各層權重的偏導數,以進行權重更新。
- 使用**鏈式法則 (Chain Rule)** 計算誤差的傳遞。
- **權重更新公式**:
$$
w := w - \eta \frac{\partial L}{\partial w}
$$
其中,$\eta$ 為學習率,$L$ 為損失函數。
---
### 🔶 損失函數(Loss Function)
- **損失函數** 衡量模型預測結果與實際標籤的差距,常見損失函數如下:
| **損失函數** | **公式** | **應用場景** |
|------------------------|----------------------------------------|--------------|
| **均方誤差 (MSE)** | $L = \frac{1}{n}\sum (y - \hat{y})^2$ | 回歸問題 |
| **平均絕對誤差 (MAE)** | $L = \frac{1}{n}\sum \|y - \hat{y}\|$ | 回歸問題 |
| **交叉熵 (Cross-Entropy)** | $L = -\sum y \log(\hat{y})$ | 分類問題 |
| **Hinge 損失** | $L = \sum \max(0, 1 - y\hat{y})$ | 支持向量機 (SVM) |
---
### 🔶 梯度下降法(Gradient Descent)
- **目的**:最小化損失函數,找到最佳權重。
- **更新公式**:
$$
w := w - \eta \frac{\partial L}{\partial w}
$$
其中,$\eta$ 為學習率。
#### ✅ **常見的梯度下降法:**
| **方法** | **特性** |
|---------------------|---------------------------------|
| **批量梯度下降 (BGD)** | 使用整個數據集計算梯度,收斂穩定但速度慢 |
| **隨機梯度下降 (SGD)** | 每次使用一筆數據更新,速度快但不穩定 |
| **小批量梯度下降 (Mini-Batch)** | 介於 BGD 與 SGD 之間,綜合兩者優點 |
| **Adam 優化器** | 結合動量與自適應學習率的優化方法,常用於深度學習 |
---
### 🔶 Overfitting 與 Underfitting
| **問題** | **描述** | **解決方法** |
|------------|-----------------------------------------|--------------------------|
| **過擬合 (Overfitting)** | 模型在訓練集表現良好,但在測試集表現差,過度學習噪音。 | 使用正則化、資料擴增、Dropout |
| **欠擬合 (Underfitting)** | 模型無法擬合訓練數據,表現不佳,模型太簡單。 | 增加模型複雜度、調整超參數 |
---
### 🔶 L1 與 L2 正規化
| **正規化方法** | **公式** | **效果** |
|------------|---------------------------------|--------------------------|
| **L1 正規化** | $L = Loss + \lambda \sum \|w\|$ | 產生稀疏矩陣,適合特徵選擇 |
| **L2 正規化** | $L = Loss + \lambda \sum w^2$ | 防止過擬合,使權重較為平滑 |
- **L1 正規化 (Lasso Regression)** → 會將部分權重變為 0,適用於特徵篩選。
- **L2 正規化 (Ridge Regression)** → 會抑制過大的權重,提升模型泛化能力。
---
### 🔶 常見機器學習演算法比較
| **演算法** | **類型** | **適用場景** | **優點** | **缺點** |
|----------------------|----------|--------------------|-----------------------------|---------------------------|
| **Random Forest** | 分類/回歸 | 特徵重要性分析、分類問題 | 抗過擬合、準確性高 | 訓練速度慢、模型不易解釋 |
| **Logistic Regression** | 分類 | 二分類問題 | 計算簡單、解釋性好 | 只能處理線性問題 |
| **SVM** | 分類/回歸 | 二分類問題、小數據集 | 效果佳、能處理非線性問題 | 訓練慢、對參數敏感 |
| **Decision Tree** | 分類/回歸 | 簡單決策問題 | 簡單易懂、可視化 | 易過擬合、對資料敏感 |
| **K-Means** | 聚類 | 客群分析、影像分割 | 簡單高效、適用大數據 | 需預先設定 K 值、對初始值敏感 |
| **PCA** | 降維 | 特徵降維、資料可視化 | 降低維度、保留主要資訊 | 難以解釋降維後的特徵意義 |
---
### 🔶 CNN、RNN、LSTM 比較
| **架構** | **用途** | **優點** | **缺點** |
|----------|--------------|----------------------------|------------------|
| **CNN** | 影像識別、物件偵測 | 擅長處理影像數據,具局部感知能力 | 無法處理時間序列數據 |
| **RNN** | 時間序列、語音辨識 | 適合處理序列數據 | 易有梯度消失/爆炸問題 |
| **LSTM** | 自然語言處理、翻譯系統 | 解決 RNN 的長期依賴問題 | 複雜度高、訓練時間長 |
### ✅ **CNN(Convolutional Neural Network,卷積神經網絡)**
- **適用場景:** 影像分類、物件檢測、醫療影像分析等。
- **核心概念:**
- **卷積層(Convolutional Layer):** 提取局部特徵。
- **池化層(Pooling Layer):** 降低維度,減少計算量。
- **激活函數(如 ReLU):** 增強非線性表達能力。
- **全連接層(Fully Connected Layer):** 將特徵映射到輸出空間。
- **優點:**
- 能自動提取影像特徵。
- 參數量相對較少,避免過擬合。
- **缺點:**
- 不適合處理時間序列數據。
---
### ✅ **RNN(Recurrent Neural Network,循環神經網絡)**
- **適用場景:** 時間序列預測、語音辨識、自然語言處理等。
- **核心概念:**
- 每個時間步的輸出依賴於當前輸入與前一步的隱藏狀態。
- 公式:
$$
h_t = f(W_h h_{t-1} + W_x x_t + b)
$$
- **優點:**
- 擅長處理序列數據。
- 能捕捉時間上的依賴性。
- **缺點:**
- 容易出現梯度消失/爆炸問題。
- 訓練時間較長。
---
### ✅ **LSTM(Long Short-Term Memory,長短期記憶網絡)**
- **適用場景:** 語音辨識、機器翻譯、情感分析等。
- **核心概念:**
- LSTM 使用 **記憶單元(Memory Cell)** 和 **門控機制(Gates)** 控制信息流:
- **遺忘門 (Forget Gate):** 決定遺忘多少過去資訊。
- **輸入門 (Input Gate):** 決定保留多少新資訊。
- **輸出門 (Output Gate):** 決定輸出的資訊。
- **優點:**
- 能捕捉長期依賴關係。
- 有效解決梯度消失問題。
- **缺點:**
- 複雜度高,訓練時間長。
---
### 📊 **深度學習架構比較表**
| **架構** | **適用場景** | **優點** | **缺點** |
|---------|----------------|---------------------|--------------------|
| CNN | 影像識別、物件偵測 | 擅長提取空間特徵、參數少 | 不適合處理序列數據 |
| RNN | 時間序列、語音辨識 | 擅長序列資料處理 | 易有梯度消失問題 |
| LSTM | 語言模型、機器翻譯 | 擅長長期依賴、解決梯度消失問題 | 訓練時間長、參數較多 |
---
### 🔶 Transformer 架構詳解
#### ✅ **核心概念:**
- **Transformer** 是基於 **自注意力機制 (Self-Attention)** 的模型架構,用於處理序列數據,如自然語言處理。
- **完全拋棄 RNN 結構**,可並行處理數據,加速訓練。
#### ✅ **架構組成:**
1. **Encoder-Decoder 結構**:
- **Encoder:** 將輸入序列轉換為特徵表示。
- **Decoder:** 根據特徵表示生成輸出序列。
2. **Self-Attention 機制**:
- 每個詞透過「注意力分數」關注序列中其他詞的重要性。
- **Scaled Dot-Product Attention**:
$$
Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right)V
$$
3. **Positional Encoding(位置編碼):**
- 因為 Transformer 無序列結構,使用位置編碼來保留序列順序資訊。
4. **Multi-Head Attention(多頭注意力):**
- 同時進行多次注意力機制,學習資料中不同子空間的資訊。
#### ✅ **優點:**
- 支援並行運算,訓練速度快。
- 能捕捉長距依賴關係。
- 在 NLP 領域取得極佳成績(如 BERT、GPT 等模型基於 Transformer)。
### 🔢 **向量與矩陣運算**
### ✅ **矩陣乘法**
**題目:**
已知矩陣 $A$ 和 $B$:
$$
A = \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix}, \quad B = \begin{bmatrix}5 & 6\\7 & 8\end{bmatrix}
$$
求 $A \times B$。
**解答:**
$$
A \times B = \begin{bmatrix}(1*5 + 2*7) & (1*6 + 2*8)\\(3*5 + 4*7) & (3*6 + 4*8)\end{bmatrix}
= \begin{bmatrix}19 & 22\\43 & 50\end{bmatrix}
$$
---
### ✅ **內積與外積**
**題目:**
已知向量 $u = [1, 2, 3]$ 和 $v = [4, 5, 6]$:
1. 求內積(Dot Product)。
2. 求外積(Cross Product)。
**解答:**
1. **內積:**
$$
u \cdot v = 1*4 + 2*5 + 3*6 = 4 + 10 + 18 = 32
$$
2. **外積:**
$$
u \times v = \begin{vmatrix}
i & j & k \\
1 & 2 & 3 \\
4 & 5 & 6
\end{vmatrix}
= i(2*6 - 3*5) - j(1*6 - 3*4) + k(1*5 - 2*4)
= i(-3) - j(-6) + k(-3)
= [-3, 6, -3]
$$
---
### 📈 **機器學習基礎運算**
### ✅ **計算均方誤差(MSE)**
**題目:**
實際值 $y = [3, -0.5, 2, 7]$
預測值 $\hat{y} = [2.5, 0.0, 2, 8]$
計算 **均方誤差(MSE)**。
**解答:**
$$
MSE = \frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2
$$
$$
= \frac{1}{4}[(3-2.5)^2 + (-0.5-0)^2 + (2-2)^2 + (7-8)^2]
= \frac{1}{4}[0.25 + 0.25 + 0 + 1] = \frac{1.5}{4} = 0.375
$$
---
### ✅ **計算交叉熵損失(Cross-Entropy Loss)**
**題目:**
二元分類問題:
實際標籤 $y = [1, 0, 1]$
預測機率 $\hat{y} = [0.9, 0.2, 0.8]$
計算交叉熵損失。
**解答:**
交叉熵公式:
$$
L = -\frac{1}{n}\sum_{i=1}^{n} \left[y_i \log(\hat{y}_i) + (1 - y_i)\log(1 - \hat{y}_i)\right]
$$
代入數值:
$$
L = -\frac{1}{3}\left[\log(0.9) + \log(1 - 0.2) + \log(0.8)\right]
$$
$$
= -\frac{1}{3}[\log(0.9) + \log(0.8) + \log(0.8)]
$$
近似計算(以 $\log$ 的自然對數為基準):
$$
= -\frac{1}{3}[-0.1054 - 0.2231 - 0.2231] = 0.1839
$$
---
### 📊 **機器學習模型相關運算**
### ✅ **K-Means 群心更新**
**題目:**
有以下數據點:
$$
A(1, 2), B(2, 1), C(4, 5), D(5, 4)
$$
初始群心為:
- 群 1: (1, 1)
- 群 2: (5, 5)
使用 **K-Means** 進行一次迭代,計算新的群心。
**解答:**
1. **分配群集:**
- 距離群 1 較近:A、B
- 距離群 2 較近:C、D
2. **更新群心:**
- 群 1 新群心:
$$
\frac{(1,2) + (2,1)}{2} = (1.5, 1.5)
$$
- 群 2 新群心:
$$
\frac{(4,5) + (5,4)}{2} = (4.5, 4.5)
$$
---
### ✅ **決策樹的基尼不純度**
**題目:**
一資料集共有 10 筆數據,分為正類(6 筆)與負類(4 筆)。
計算其 **基尼不純度(Gini Impurity)**。
**解答:**
基尼不純度公式:
$$
Gini = 1 - \sum p_i^2
$$
其中 $p_i$ 為各類別的機率。
$$
Gini = 1 - \left[\left(\frac{6}{10}\right)^2 + \left(\frac{4}{10}\right)^2\right]
= 1 - [0.36 + 0.16] = 1 - 0.52 = 0.48
$$
---
### 🧮 **深度學習基礎運算**
### ✅ **簡單的反向傳播(Backpropagation)**
**題目:**
考慮單層神經元,輸入 $x = 1$,權重 $w = 0.5$,偏差 $b = 0.1$,目標輸出 $y = 1$。
使用均方誤差(MSE)作為損失函數,求權重的梯度。
**解答:**
1. **前向傳播:**
$$
\hat{y} = wx + b = 0.5*1 + 0.1 = 0.6
$$
2. **損失計算(MSE):**
$$
L = \frac{1}{2}(y - \hat{y})^2 = \frac{1}{2}(1 - 0.6)^2 = 0.08
$$
3. **反向傳播:**
- 對權重求偏導:
$$
\frac{\partial L}{\partial w} = (y - \hat{y})(-x) = (1 - 0.6)(-1) = -0.4
$$
4. **權重更新(學習率 $\eta = 0.1$):**
$$
w_{new} = w - \eta \frac{\partial L}{\partial w} = 0.5 - 0.1*(-0.4) = 0.54
$$
---
### 📉 **機器學習常見指標運算**
### ✅ **計算混淆矩陣相關指標**
**題目:**
給定混淆矩陣:
| | **預測正確** | **預測錯誤** |
|---------------|-------------|-------------|
| **實際正確** | 50 (TP) | 10 (FN) |
| **實際錯誤** | 5 (FP) | 35 (TN) |
計算:
- 準確率(Accuracy)
- 精確率(Precision)
- 召回率(Recall)
- F1 分數(F1-Score)
**解答:**
- **準確率 (Accuracy):**
$$
\frac{TP + TN}{TP + TN + FP + FN} = \frac{50 + 35}{50 + 35 + 5 + 10} = \frac{85}{100} = 0.85
$$
- **精確率 (Precision):**
$$
\frac{TP}{TP + FP} = \frac{50}{50 + 5} = \frac{50}{55} = 0.909
$$
- **召回率 (Recall):**
$$
\frac{TP}{TP + FN} = \frac{50}{50 + 10} = \frac{50}{60} = 0.833
$$
- **F1 分數 (F1-Score):**
$$
F1 = \frac{2 \times Precision \times Recall}{Precision + Recall}
= \frac{2 \times 0.909 \times 0.833}{0.909 + 0.833} \approx 0.87
$$
---
### 電腦視覺的圖片與影片預處理方式
#### 1. 圖片預處理(Image Preprocessing)
在電腦視覺領域,圖片的預處理能夠提升模型的準確性與效率。常見的方法包括:
##### (a) 影像縮放(Resizing)
- **原因**:
- 計算機視覺模型通常需要固定尺寸輸入(如 224×224)。
- 縮放方法:
- **最近鄰插值(Nearest Neighbor Interpolation)**
- **雙線性插值(Bilinear Interpolation)**
- **雙三次插值(Bicubic Interpolation)**
- **區域插值(Area Interpolation)**(適用於縮小影像)
##### (b) 正規化(Normalization)
- **像素值歸一化**([0,1] 或 [-1,1]):
- 避免某些通道數值過大影響梯度更新。
- 常見方法:
$$
x' = \frac{x - \mu}{\sigma}
$$
- `\mu` 為均值,`\sigma` 為標準差。
- **均值標準化(Mean Normalization)**
- 減去 ImageNet 均值:
- `\mu` = [0.485, 0.456, 0.406]
- `\sigma` = [0.229, 0.224, 0.225]
##### (c) 資料增強(Data Augmentation)
- 目標:提升模型的泛化能力。
- 方法:
- **隨機翻轉(Random Flip)**
- **隨機旋轉(Random Rotation)**
- **顏色抖動(Color Jitter)**
- **隨機裁剪(Random Crop)**
- **高斯模糊(Gaussian Blur)**
- **Cutout / Mixup / CutMix**
##### (d) 去噪(Denoising)
- **高斯濾波(Gaussian Filtering)**
- **雙邊濾波(Bilateral Filtering)**
- **中值濾波(Median Filtering)**
##### (e) 邊緣檢測(Edge Detection)
- **Sobel 運算子**
- **Canny 邊緣檢測**
- **Laplacian 運算子**
##### (f) 色彩空間轉換(Color Space Conversion)
- RGB ↔ 灰階(Grayscale)
- RGB ↔ HSV / LAB
- 影像通道調整(Channel Swapping)
---
#### 2. 影片預處理(Video Preprocessing)
影片的預處理涉及多幀處理,主要包含:
##### (a) 幀擷取(Frame Extraction)
- **均勻取樣(Uniform Sampling)**
- **隨機取樣(Random Sampling)**
- **關鍵幀提取(Keyframe Extraction)**
##### (b) 光流計算(Optical Flow Estimation)
- 用於運動分析,方法:
- **Farneback 光流**
- **Lucas-Kanade 光流**
- **DeepFlow(基於深度學習)**
##### (c) 時序降維(Temporal Downsampling)
- 目標:降低計算負擔。
- 方法:
- 平均池化(Average Pooling)
- 最大池化(Max Pooling)
##### (d) 背景建模(Background Subtraction)
- **Mixture of Gaussians(MOG)**
- **KNN Background Subtraction**
- **Deep Learning-based Background Subtraction**
---
LLM工程師
---
### **基礎 NLP 問題**
- 文本分類(Spam detection, Sentiment analysis)
- 命名實體識別(NER)(提取人名、地點、組織等)
- 機器翻譯(Google Translate)
- 問答系統(QA)(KBQA, IRQA)
- 語音識別與語音合成(Siri, Google Assistant)
- 文本摘要(新聞摘要、自動摘要生成)
- 文本相似度分析(Similar Document Matching)
- 自動標註與推薦標籤(Auto-Classification Model)
### **NLP 中的 Tokenization 是什麼?常見的方法有哪些?**
1. 基於規則(Whitespace Tokenization, Word-based Tokenization)
2. 基於統計(N-gram, Byte Pair Encoding(BPE))
3. 基於深度學習(SentencePiece, WordPiece)
### **什麼是 Word Embedding?常見的方法有哪些?**
1. Word2Vec(CBOW & Skip-gram)
Word2Vec(CBOW vs. Skip-Gram)
**核心概念:**
- **CBOW**:利用上下文詞預測目標詞。
- **Skip-Gram**:利用目標詞預測上下文詞。
**數學模型:**
$$
P(w_o \mid w_c) = \frac{\exp(\mathbf{v}_{w_o} \cdot \mathbf{v}_{w_c})}{\sum_{w' \in V} \exp(\mathbf{v}_{w'} \cdot \mathbf{v}_{w_c})}
$$
**詞向量的幾何性質:**
- 內積表示語義關係,例如:
$$ \mathbf{v}_{king} - \mathbf{v}_{man} + \mathbf{v}_{woman} \approx \mathbf{v}_{queen} $$
- 餘弦相似度衡量詞語相似性:
$$ \cos(\theta) = \frac{\mathbf{v}_a \cdot \mathbf{v}_b}{\|\mathbf{v}_a\| \|\mathbf{v}_b\|} $$
**問題:**
- **無法處理同詞異義(Polysemy)**,例如「bank」的不同語境。
- **靜態向量**,無法根據上下文改變語義。
2. GloVe
3. FastText
4. Transformer-based embeddings(BERT, GPT, T5, etc.)
### **TF-IDF vs Word Embedding**
| 特性 | TF-IDF | Word Embedding |
| ---- | ------ | -------------- |
| 方法 | 統計權重 | 神經網路學習 |
| 語義關係 | 無 | 有 |
| 計算方法 | 基於詞頻 | 基於語境 |
| 適用場景 | 傳統NLP(檢索) | 深度學習(語義分析) |
傳統詞袋模型 (Bag of Words, BoW)
**核心概念:**
- 將文本轉換為詞頻(TF, Term Frequency)向量。
- 可搭配 TF-IDF 降低高頻詞影響。
**問題:**
- **維度災難**:詞彙數量龐大,向量維度過高。
- **缺乏語義關係**:無法捕捉詞彙之間的相似性。
### **什麼是 BERT?它如何工作?**
BERT(Bidirectional Encoder Representations from Transformers)是一種基於 Transformer 的 NLP 預訓練模型,主要特點:
1. 雙向訓練:與傳統 LSTM/GRU 不同,BERT 同時考慮單詞的前後文資訊。
2. Masked Language Model(MLM):隨機遮罩部分單詞,讓模型學習上下文關係。
- 訓練過程:
1. 在輸入文本中,隨機選擇 **15% 的單詞**進行遮罩(用 `[MASK]` 取代)。
2. 模型需要根據周圍單詞預測被遮罩的詞。
3. 例如:
```
輸入:「I love [MASK] learning.」
目標:「I love deep learning.」
```
3. Next Sentence Prediction(NSP):判斷兩個句子是否連續。
- 訓練過程:
1. 提供**一組句子對**(A, B):
- **50% 的機率**,B 是 A 的真實後續句子。
- **50% 的機率**,B 是隨機選擇的句子。
2. BERT 學習判別這兩個句子是否相關。
3. 例如:
```
- A: "The cat sat on the mat."
B: "It was very comfortable." ✅(True Pair)
- A: "The cat sat on the mat."
B: "I went to the market." ❌(False Pair)
```
Contextualized Word Embeddings (ELMo, BERT)
**核心概念:**
- **BERT** 透過 Transformer 自注意力機制(Self-Attention)學習詞的上下文語義。
**關鍵技術:**
- **雙向 Transformer**:同時考慮詞的左右文。
- **預訓練目標**:
- **Masked Language Model (MLM)**:隨機遮蔽部分詞,根據上下文填補。
- **Next Sentence Prediction (NSP)**:預測兩個句子是否相關。
**優勢:**
- 可解決 **靜態詞向量** 問題,使詞的語義依據上下文變化。
- 處理 **同詞異義**,如「bank」在不同語境中擁有不同向量。
**缺點:**
- **計算量大**,推理成本高。
- **訓練資料需求大**,不適用低資源語言。
### **深度學習與模型訓練**
|類型 | 特性 | 應用
| ---- | ------ | -------------- |
|CNN | 適合提取局部特徵 | 文本分類, NER |
|RNN | 適合處理序列數據 | 機器翻譯, 語音識別 |
|Transformer | 高度並行, 捕捉長距離依賴 | BERT, GPT, T5, Chatbot |
### **如何處理文本數據的過擬合問題?**
1. 正則化(L1/L2 Regularization, Dropout)
2. 數據增強(Back-translation, Synonym Replacement)
3. Early Stopping
4. 使用預訓練模型進行遷移學習
5. 減少模型參數
### **如何進行 NLP 模型的評估?常見指標有哪些?**
1. 分類任務(Text Classification, NER)
- Accuracy, Precision, Recall, F1-score
2. 生成任務(Summarization, Machine Translation)
- BLEU, ROUGE, METEOR
### 生成任務(Summarization, Machine Translation)
在自然語言處理中,生成任務(Generative Tasks)包括摘要生成(Summarization)、機器翻譯(Machine Translation)等。這些任務的評估指標包括 **BLEU、ROUGE、METEOR**。
#### 1. BLEU(Bilingual Evaluation Understudy)
- **用途**:機器翻譯、摘要生成的質量評估。
- **計算方法**:
- BLEU 衡量生成文本與參考文本之間的 n-gram 匹配程度。
- 計算 n-gram 的精確率(Precision),再通過幾何平均進行綜合評估。
**公式**:
$$
BLEU = BP \cdot \exp \left( \sum_{n=1}^{N} w_n \log P_n \right)
$$
其中:
- \( BP \)(Brevity Penalty)是長度懲罰,防止過短的輸出獲得高分。
- \( P_n \) 是不同 n-gram 的精確率。
- \( w_n \) 是權重(通常對 1-gram, 2-gram, 3-gram, 4-gram 取等權)。
- **問題**:
- BLEU 偏向較短的文本。
- 無法考慮語義,僅關注詞序和匹配率。
#### 2. ROUGE(Recall-Oriented Understudy for Gisting Evaluation)
- **用途**:摘要生成、文本摘要比較。
- **計算方法**:
- **ROUGE-N**:計算 n-gram 召回率(Recall)。
$$
ROUGE-N = \frac{\text{候選摘要中匹配的 n-grams 數量}}{\text{參考摘要中的 n-grams 總數}}
$$
- **ROUGE-L**:基於長度最長公共子序列(LCS)。
- **ROUGE-W**:考慮連續匹配權重。
- **優勢**:
- 更適合摘要任務,因為它關注召回率。
- 允許詞語間存在順序變化。
#### 3. METEOR(Metric for Evaluation of Translation with Explicit ORdering)
- **用途**:機器翻譯評估。
- **計算方法**:
- 考慮詞形變化(如「run」與「running」)
- 計算加權 F1 分數,並加入語義匹配。
**公式**:
$$
METEOR = F_{mean} \times (1 - Penalty)
$$
其中:
- `F_{mean}` 是精確率和召回率的加權平均。
- 懲罰因子 `Penalty` 考慮詞序。
- **優勢**:
- 比 BLEU 更能捕捉語義。
- 適用於多語言機器翻譯。
3. 排序任務(IR, Recommendation)
- MRR, MAP, NDCG
#### 1. MRR(Mean Reciprocal Rank)
- **用途**:評估查詢結果是否快速返回相關答案。
- **計算方法**:
- 計算第一個相關結果的倒數排名。
- 平均所有查詢的倒數排名。
**公式**:
$$
MRR = \frac{1}{|Q|} \sum_{i=1}^{|Q|} \frac{1}{rank_i}
$$
其中:
- `Q` 是所有查詢。
- `rank_i` 是第 `i` 個查詢中第一個相關結果的排名。
- **優勢**:
- 簡單直觀,適合評估 QA 系統。
- 缺點是僅考慮第一個相關結果。
#### 2. MAP(Mean Average Precision)
- **用途**:資訊檢索中評估多個查詢的準確性。
- **計算方法**:
- 針對每個查詢,計算所有相關文檔的平均精確率。
**公式**:
$$
MAP = \frac{1}{|Q|} \sum_{q=1}^{|Q|} \frac{1}{|R_q|} \sum_{k=1}^{|R_q|} P(k)
$$
其中:
- `R_q` 是查詢 `q` 的相關文檔集合。
- `P(k)` 是排名前 `k` 個結果的精確率。
- **優勢**:
- 衡量排名列表的整體質量。
- 但當相關結果數量少時,MAP 可能不穩定。
#### 3. NDCG(Normalized Discounted Cumulative Gain)
- **用途**:評估推薦系統、資訊檢索的結果排序。
- **計算方法**:
- 計算 DCG(Discounted Cumulative Gain),根據相關性分數調整排名權重。
- DCG 公式:
$$
DCG_k = \sum_{i=1}^{k} \frac{rel_i}{\log_2(i+1)}
$$
- 然後對其進行標準化,得到 **NDCG**:
$$
NDCG_k = \frac{DCG_k}{IDCG_k}
$$
其中,IDCG 是理想的 DCG,代表最優排序。
- **優勢**:
- 考慮結果的排序與相關性,適用於個性化推薦。
- NDCG 比 MAP 更適合非二元(非 0/1)相關性標註。
---
### **機器學習應用與 MLOps**
1. 模型保存:使用 TorchScript, ONNX, TensorFlow SavedModel
2. 開發 API:Flask, FastAPI, gRPC
3. 容器化:Docker
4. 雲端部署:AWS Lambda, Google Cloud Run, Kubernetes
---
### **如何優化 NLP 模型的推理速度?**
1. 量化(Quantization):使用 int8 而非 float32
#### 1. 量化(Quantization):使用 int8 而非 float32
- **核心概念**:
- 量化是將浮點數(float32)轉換為較低精度的整數(int8),減少模型大小並提高運算速度。
- 主要用於**推理(Inference)**場景,尤其是在資源受限的設備上(如邊緣設備和移動設備)。
- **量化方法**:
1. **後訓練量化(Post-Training Quantization, PTQ)**
- 在訓練後將權重從 float32 轉換為 int8。
- 透過校準數據(Calibration Data)來調整數值範圍,保持精度。
2. **量化感知訓練(Quantization-Aware Training, QAT)**
- 在訓練過程中模擬 int8 運算,允許模型學習量化後的分佈。
- 減少量化帶來的精度損失,適用於高精度應用場景。
- **量化演算法**:
- **對稱量化(Symmetric Quantization)**:
- 使用固定零點,將值映射至 int8 範圍內。
- **非對稱量化(Asymmetric Quantization)**:
- 允許動態調整零點,提高精度但計算較複雜。
- **優勢**:
- **減少計算開銷**:int8 運算比 float32 運算更快。
- **降低存儲需求**:模型大小可減少約 **75%**。
- **提高推理吞吐量**:適用於 CPU 和嵌入式設備。
- **挑戰**:
- 量化可能導致精度下降,特別是在 NLP 生成任務中。
- 需要進行 QAT 來減少精度損失。
2. 剪枝(Pruning):刪除冗餘神經元
#### 2. 剪枝(Pruning):刪除冗餘神經元
- **核心概念**:
- 剪枝透過刪除權重較小的神經元來減少模型大小。
- 可分為:
1. **非結構化剪枝(Unstructured Pruning)**:
- 移除個別權重(Weight Pruning),保留稀疏性。
- 使用 L1/L2 正則化來剪除小權重。
2. **結構化剪枝(Structured Pruning)**:
- 移除完整的通道、神經元或層,減少計算需求。
- **剪枝演算法**:
- **權重修剪(Weight Pruning)**:基於權重大小刪除較小權重。
- **動態剪枝(Dynamic Pruning)**:根據推理時的重要性動態刪除。
- **漸進剪枝(Gradual Pruning)**:逐步降低冗餘權重,以減少對模型影響。
- **優勢**:
- **減少計算量**,加速推理。
- **降低記憶體占用**,適用於資源受限環境。
- **挑戰**:
- 過度剪枝可能影響模型表現。
- 需要 **重新訓練(Fine-tuning)** 來恢復性能。
3. 知識蒸餾(Knowledge Distillation):用小模型學習大模型
#### 3. 知識蒸餾(Knowledge Distillation):用小模型學習大模型
- **核心概念**:
- 透過大模型(Teacher)訓練較小的學生模型(Student),保留部分能力但減少計算開銷。
- **軟標籤學習(Soft Labeling)**:讓小模型學習大模型的**概率分佈**,而不只是硬標籤。
- **蒸餾過程**:
1. 用大模型生成**軟標籤**(Soft Targets)。
2. 學生模型學習這些機率分佈,而不僅是正確答案。
3. 透過 **蒸餾損失函數(Distillation Loss)** 進行優化:
$$
L = \alpha L_{hard} + (1 - \alpha) L_{soft}
$$
- `L_{hard}`:基於標準交叉熵的標籤學習。
- `L_{soft}`:基於大模型的軟標籤學習。
- `\alpha` 為調節係數。
- **優勢**:
- **減少推理時間**,適用於資源受限環境。
- **可遷移至較小架構**,如將 GPT-3 精簡至 DistilBERT。
- **應用**:
- 生成小型 NLP 模型(如 TinyBERT、DistilBERT)。
- 目標檢測、語音識別等計算密集型任務。
4. 使用 FasterTransformer / TensorRT / ONNX Runtime
#### 4. 使用 FasterTransformer / TensorRT / ONNX Runtime
- **FasterTransformer**
- **核心概念**:
- NVIDIA 針對 Transformer 模型的高效推理庫。
- **支援自注意力優化(Self-Attention Optimization)**,提高 GPU 計算效率。
- **應用**:BERT、GPT 等大規模語言模型。
- **TensorRT**
- **核心概念**:
- NVIDIA 開發的 **深度學習推理優化工具**。
- **支援 FP16/INT8 量化**,提高推理速度。
- **適用場景**:適用於 GPU 部署,可顯著加快 CNN、NLP 推理。
- **ONNX Runtime**
- **核心概念**:
- 微軟開發的通用深度學習推理框架。
- 支援多種硬體(CPU、GPU、TPU)。
- **應用**:
- 可將 PyTorch、TensorFlow 模型轉換為 ONNX 格式。
- 適用於雲端與邊緣設備。
---
### **如何設計 Similar Document Matching?**
1. 文本表示:
- TF-IDF / Word Embeddings / BERT Embeddings
#### 1. 文本表示(Text Representation)
文本表示是自然語言處理(NLP)的基礎,常見方法包括:
##### (a) TF-IDF(Term Frequency-Inverse Document Frequency)
- **核心概念**:
- 計算詞語在文檔中的頻率,並根據整個語料庫的詞頻調整其權重。
- 常用於資訊檢索(IR)、文本分類。
- **公式**:
$$
TF-IDF(w, d) = TF(w, d) \times IDF(w)
$$
其中:
- `TF(w, d)` 是詞 `w` 在文檔`d`中的頻率。
- `IDF(w) = \log \frac{N}{DF(w)}`, `N` 為文檔總數, `DF(w)` 為包含詞 `w` 的文檔數。
- **優勢**:
- 簡單高效,適用於資訊檢索。
- **劣勢**:
- 無法捕捉詞語之間的語義關係。
##### (b) Word Embeddings(詞向量)
- **核心概念**:
- 透過神經網絡學習詞的密集向量表示,如 Word2Vec、GloVe。
- **詞的語義可以用向量空間來表示**,如:
$$
\text{King} - \text{Man} + \text{Woman} \approx \text{Queen}
$$
- **優勢**:
- 能夠捕捉詞與詞之間的關係。
- **劣勢**:
- 仍然是靜態向量,無法根據上下文變化。
##### (c) BERT Embeddings(上下文相關的詞表示)
- **核心概念**:
- 使用 Transformer 模型來學習詞的語義,**根據上下文產生動態向量**。
- BERT 通過 **雙向自注意力(Bidirectional Self-Attention)** 來捕捉上下文信息。
- **優勢**:
- 能夠應對詞的多義性(如 "bank" 在不同語境下有不同向量)。
- **劣勢**:
- 計算成本高,需要強大硬體支持。
2. 相似度計算:
- 餘弦相似度(Cosine Similarity)
- 歐式距離(Euclidean Distance)
- 余弦哈希(LSH)
#### 2. 相似度計算(Similarity Measures)
文本相似度度量對於資訊檢索、推薦系統等應用至關重要。
##### (a) 餘弦相似度(Cosine Similarity)
- **核心概念**:
- 計算兩個向量之間的夾角,數值範圍在 **[-1,1]**。
- **公式**:
$$
\cos(\theta) = \frac{A \cdot B}{\|A\| \|B\|}
$$
- 當結果接近 1,代表兩者高度相似。
- 當結果接近 0,代表兩者幾乎無關。
- **適用場景**:
- 文本分類、相似文檔檢索。
##### (b) 歐式距離(Euclidean Distance)
- **核心概念**:
- 計算兩個向量之間的直線距離。
- **公式**:
$$
d(A, B) = \sqrt{\sum_{i=1}^{n} (A_i - B_i)^2}
$$
- **適用場景**:
- 短文本比對、圖片檢索。
- **缺點**:
- 無法應對高維度稀疏向量的問題。
##### (c) 局部敏感哈希(Locality-Sensitive Hashing, LSH)
- **核心概念**:
- 利用哈希函數,使得相似的向量映射到相同的桶(Bucket)中,從而快速查詢相似向量。
- **優勢**:
- 計算效率高,適合大規模數據。
- **應用場景**:
- 快速文本檢索、近似最近鄰搜索(ANN)。
3. 召回策略:
- FAISS / Annoy(高效相似搜索)
#### 3. 召回策略(Efficient Similarity Search)
當文本數據量巨大時,**高效檢索相似文本** 成為關鍵問題。
##### (a) FAISS(Facebook AI Similarity Search)
- **核心概念**:
- 由 Facebook 開發的高效相似搜索庫,適用於高維數據。
- **技術點**:
- 使用 **IVF(Inverted File Index)** 進行向量分區,提高檢索效率。
- 使用 **PQ(Product Quantization)** 來降低存儲需求。
- **優勢**:
- 能處理 **億級向量搜索**,比傳統最近鄰搜索(k-NN)快數十倍。
##### (b) Annoy(Approximate Nearest Neighbors Oh Yeah)
- **核心概念**:
- 由 Spotify 開發的近似最近鄰搜索(ANN)工具。
- **技術點**:
- 使用 **隨機投影樹(Random Projection Trees)** 來加速檢索。
- **優勢**:
- 記憶體占用少,適合 **內存受限設備**(如推薦系統)。
**總結**
| 技術 | 主要作用 | 優勢 | 缺點 |
|------|---------|------|------|
| TF-IDF | 文本權重表示 | 計算簡單 | 無法考慮語境 |
| Word Embeddings | 靜態詞向量 | 捕捉詞義關係 | 無法應對多義詞 |
| BERT Embeddings | 上下文詞表示 | 動態調整語義 | 運算成本高 |
| 餘弦相似度 | 角度相似度 | 適用高維向量 | 無法應對絕對長度 |
| 歐式距離 | 數值距離 | 簡單易懂 | 不適用高維稀疏數據 |
| LSH | 快速相似搜索 | 適用於大規模數據 | 精度不如精確方法 |
| FAISS | 高效檢索 | 優化 GPU 運算 | 需構建索引 |
| Annoy | 內存優化檢索 | 適合推薦系統 | 檢索速度比 FAISS 慢 |
---
### **大型語言模型前處理方式**
#### (a) Tokenization(分詞)
- **基於規則**:
- **空格分詞(Whitespace Tokenization)**
- **標點符號分詞(Punctuation-based Tokenization)**
- **正則表達式分詞(Regex-based Tokenization)**
- **基於統計**:
- **N-gram**
- **Byte Pair Encoding(BPE)**
- **Unigram Language Model(SentencePiece)**
- **基於深度學習**:
- **SentencePiece(BERT)**
- **WordPiece(GPT)**
- **FastText Subword Embeddings**
#### (b) Stopword Removal(停用詞去除)
- 移除 "the"、"is"、"and" 等常見但影響不大的詞。
- 自訂停用詞列表以適應不同的應用場景(如資訊檢索、情感分析)。
#### (c) Normalization(正規化)
- **大小寫轉換(Lowercasing)**
- **詞形還原(Lemmatization)**
- **詞幹提取(Stemming)**(如 Porter Stemmer、Lancaster Stemmer)
- **去除重音符號(Accents Removal)**
- **數字與符號正則化**(如 "$5.00" → "five dollars")
#### (d) Subword Tokenization(子詞分解)
- **BPE(Byte Pair Encoding)**
- **Unigram Language Model(SentencePiece)**
- **Hybrid Tokenization(結合字詞與子詞模型)**
#### (e) Embedding Lookup(向量查找)
- **Word2Vec(CBOW / Skip-Gram)**
- **GloVe(基於詞共現矩陣的詞向量)**
- **FastText(能夠處理 OOV 和子詞拆解)**
- **BERT Embeddings(上下文相關詞向量)**
---
### 2. 演算法(Algorithms)
#### (a) Transformer 模型核心
- **多頭自注意力機制(Multi-head Self-Attention)**
- 計算 Query-Key-Value 相關性:
$$
Attention(Q, K, V) = softmax\left(\frac{QK^T}{\sqrt{d_k}}\right) V
$$
- 能夠捕捉遠程依賴(Long-range dependencies)。
- **位置編碼(Positional Encoding)**
- 由於 Transformer 不具有序列信息,因此加入位置編碼:
$$
PE_{(pos, 2i)} = \sin(pos / 10000^{2i/d_{model}})
$$
$$
PE_{(pos, 2i+1)} = \cos(pos / 10000^{2i/d_{model}})
$$
- 這樣可以保留詞語順序信息。
#### (b) 訓練技巧
- **Masked Language Model(MLM)**(BERT):
- 隨機遮蔽部分詞,讓模型學習上下文。
- **Causal Language Model(CLM)**(GPT):
- 只關注先前詞語的資訊。
- **Next Sentence Prediction(NSP)**(BERT):
- 預測兩個句子是否連續。
- **Permutation Language Model(XLNet)**
- 考慮所有可能的單詞排列來學習序列依賴關係。
- **Contrastive Learning(對比學習)**
- 在無監督學習中用於語義相似性建模(SimCSE、MoCo)。
#### (c) 加速推理
- **量化(Quantization)**
- 將浮點數(float32)轉換為 int8 以加快計算。
- **剪枝(Pruning)**
- 移除冗餘的神經元以減少計算量。
- **知識蒸餾(Knowledge Distillation)**
- 用小模型學習大模型的行為,例如 DistilBERT。
- **高效檢索技術(Efficient Retrieval)**
- FAISS(快速向量檢索)
- Annoy(近似最近鄰搜索)
- LSH(局部敏感哈希)
---
---
C#程式語言
---
### 🔷 **變數與資料型別**
```csharp
int number = 10;
double pi = 3.14;
string message = "Hello, World!";
bool isActive = true;
char grade = 'A';
var autoType = 100; // 自動推斷型別
const double gravity = 9.8; // 常數
```
### 🔷 **if-else條件判斷**
```csharp
int score = 85;
if (score >= 90) {
Console.WriteLine("A");
} else if (score >= 80) {
Console.WriteLine("B");
} else {
Console.WriteLine("C");
}
```
### 🔷 **switch條件判斷**
```csharp
char grade = 'B';
switch (grade) {
case 'A':
Console.WriteLine("Excellent");
break;
case 'B':
Console.WriteLine("Good");
break;
default:
Console.WriteLine("Try Harder");
break;
}
```
### 🔷 **迴圈結構**
```csharp
// for 迴圈
for (int i = 0; i < 5; i++) {
Console.WriteLine(i);
}
// while 迴圈
int j = 0;
while (j < 5) {
Console.WriteLine(j);
j++;
}
// foreach 迴圈
string[] fruits = { "Apple", "Banana", "Cherry" };
foreach (var fruit in fruits) {
Console.WriteLine(fruit);
}
```
### 🔷 **Function**
```csharp
// 無回傳值方法
void Greet(string name) {
Console.WriteLine($"Hello, {name}!");
}
// 有回傳值方法
int Add(int a, int b) {
return a + b;
}
// 呼叫方法
Greet("Alice");
int sum = Add(3, 5);
Console.WriteLine($"Sum: {sum}");
```
### 🔷 **物件導向**
```csharp
public class Person {
public string Name { get; set; }
public int Age { get; set; }
public void Introduce() {
Console.WriteLine($"Hi, I'm {Name}, {Age} years old.");
}
}
// 實例化物件
Person person = new Person { Name = "John", Age = 30 };
person.Introduce();
```
### 🔷 **繼承與多型**
```csharp
public class Animal {
public virtual void Speak() {
Console.WriteLine("Animal speaks");
}
}
public class Dog : Animal {
public override void Speak() {
Console.WriteLine("Dog barks");
}
}
// 多型呼叫
Animal myDog = new Dog();
myDog.Speak(); // 輸出: Dog barks
```
### 🔷 **介面(Interface)**
```csharp
public interface IShape {
double GetArea();
}
public class Circle : IShape {
public double Radius { get; set; }
public double GetArea() {
return Math.PI * Radius * Radius;
}
}
```
### 🔷 **抽象類別**
```csharp
public abstract class Shape {
public abstract double GetArea();
}
public class Rectangle : Shape {
public double Width { get; set; }
public double Height { get; set; }
public override double GetArea() {
return Width * Height;
}
}
```
### 🔷 **集合(Collection)**
```csharp
using System.Collections.Generic;
// 陣列
int[] numbers = { 1, 2, 3 };
// List
List<string> names = new List<string> { "Alice", "Bob" };
names.Add("Charlie");
// Dictionary
Dictionary<string, int> ages = new Dictionary<string, int> {
{ "Alice", 25 },
{ "Bob", 30 }
};
Console.WriteLine(ages["Alice"]); // 輸出: 25
```
### 🔷 **集合操作**
```csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 遍歷
foreach (var num in numbers) {
Console.WriteLine(num);
}
// 查詢
bool hasThree = numbers.Contains(3); // true
// 排序
numbers.Sort();
// 移除元素
numbers.Remove(3);
```
### 🔷 **LINQ(Language Integrated Query)**
```csharp
using System.Linq;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 篩選偶數
var evenNumbers = numbers.Where(n => n % 2 == 0);
// 取出大於 3 的數字並排序
var result = numbers.Where(n => n > 3).OrderBy(n => n);
// 輸出結果
foreach (var num in result) {
Console.WriteLine(num);
}
```
### 🔷 **LINQ(Language Integrated Query)**
```csharp
using System.Linq;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 篩選偶數
var evenNumbers = numbers.Where(n => n % 2 == 0);
// 取出大於 3 的數字並排序
var result = numbers.Where(n => n > 3).OrderBy(n => n);
// 輸出結果
foreach (var num in result) {
Console.WriteLine(num);
}
```
### 🔷 **例外處理**
```csharp
try {
int[] arr = { 1, 2, 3 };
Console.WriteLine(arr[5]); // 會產生例外
} catch (IndexOutOfRangeException ex) {
Console.WriteLine("錯誤: " + ex.Message);
} finally {
Console.WriteLine("執行完畢");
}
```
### 🔷 **委派(Delegate)與事件(Event)**
```csharp
public delegate void Notify(string message);
public class Program {
public static void Main() {
Notify notify = DisplayMessage;
notify("Hello from delegate!");
}
public static void DisplayMessage(string message) {
Console.WriteLine(message);
}
}
```
### 🔷 **(Async/Await)**
```csharp
using System.Threading.Tasks;
public async Task<string> GetDataAsync() {
await Task.Delay(1000); // 模擬非同步操作
return "Data Loaded";
}
public async Task Main() {
string data = await GetDataAsync();
Console.WriteLine(data);
}
```
### 🔷 **單例模式(Singleton Pattern)**
```csharp
public class Singleton {
private static Singleton instance;
private static readonly object lockObj = new object();
private Singleton() { }
public static Singleton Instance {
get {
lock (lockObj) {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
}
}
```
### 🔷 **工廠模式(Factory Pattern)**
```csharp
public interface IShape {
void Draw();
}
public class Circle : IShape {
public void Draw() => Console.WriteLine("Drawing Circle");
}
public class Square : IShape {
public void Draw() => Console.WriteLine("Drawing Square");
}
public class ShapeFactory {
public IShape GetShape(string shapeType) {
if (shapeType == "Circle") return new Circle();
if (shapeType == "Square") return new Square();
return null;
}
}
// 使用工廠
ShapeFactory factory = new ShapeFactory();
IShape shape = factory.GetShape("Circle");
shape.Draw();
```
---
### 🔷 **.NET Framework / .NET Core 內建函式庫**
### ✅ **System 基礎命名空間**
- `System.Console` — 控制台輸入與輸出。
- `System.Math` — 數學運算(如開根號、三角函數)。
- `System.String` — 字串處理相關方法。
- `System.DateTime` — 時間與日期操作。
- `System.IO` — 檔案與資料流操作。
- `System.Text` — 編碼(Encoding)、字串處理。
### ✅ **常用命名空間與方法**
| **命名空間** | **用途** | **常用方法** |
|---------------|---------------------------|----------------------------------|
| `System.Math` | 數學運算 | `Math.Abs()`, `Math.Sqrt()`, `Math.Pow()` |
| `System.IO` | 檔案與資料流操作 | `File.ReadAllText()`, `File.WriteAllText()`, `Directory.GetFiles()` |
| `System.Text` | 編碼與字串處理 | `Encoding.UTF8.GetBytes()`, `StringBuilder.Append()` |
| `System.Linq` | 集合查詢與操作 | `.Where()`, `.Select()`, `.OrderBy()` |
| `System.Threading` | 多執行緒與同步機制 | `Thread.Sleep()`, `Task.Run()`, `Semaphore` |
| `System.Net` | 網路相關功能(HTTP、Socket) | `WebClient.DownloadString()`, `HttpClient.GetAsync()` |
| `System.Data` | 資料庫操作 | `SqlConnection`, `SqlCommand`, `DataTable` |
---
### 🔷 **資料結構與集合相關套件**
#### ✅ **System.Collections 與 System.Collections.Generic**
- **List\<T\>** — 動態陣列,常用於儲存資料集。
- **Dictionary\<TKey, TValue\>** — 鍵值對集合。
- **HashSet\<T\>** — 儲存唯一值集合,查找速度快。
- **Queue\<T\>** — 先進先出(FIFO)結構。
- **Stack\<T\>** — 後進先出(LIFO)結構。
#### ✅ **範例:**
```csharp
using System.Collections.Generic;
List<string> names = new List<string> { "Alice", "Bob", "Charlie" };
Dictionary<string, int> ageMap = new Dictionary<string, int> {
{ "Alice", 25 },
{ "Bob", 30 }
};
Queue<int> numbers = new Queue<int>();
numbers.Enqueue(1);
numbers.Enqueue(2);
int first = numbers.Dequeue(); // 1
```
### 🔷 **資料結構與集合相關套件**
- 強大的查詢語法,可用於資料庫、集合、XML 等。
- 常用方法:.Where(), .Select(), .OrderBy(), .GroupBy()
#### ✅ **範例:**
```csharp
using System.Linq;
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// 篩選偶數
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
// 計算總和
int sum = numbers.Sum();
```
### 🔷 **非同步程式設計與多執行緒**
#### ✅ **System.Threading**
- Thread — 建立與控制執行緒。
- Mutex / Semaphore — 同步機制。
- ThreadPool — 執行緒池管理。
#### ✅ **System.Threading**
- Task — 執行非同步操作。
- async/await — 簡化非同步程式設計。
- Parallel — 平行運算(如 Parallel.For)。
#### ✅ **範例:**
```csharp
using System.Threading.Tasks;
public async Task<string> GetDataAsync() {
await Task.Delay(1000); // 模擬耗時操作
return "Data Loaded";
}
public async Task Main() {
string data = await GetDataAsync();
Console.WriteLine(data);
}
```
### 🔷 **網路應用與 API 呼叫**
#### ✅ **System.Net.Http**
- HttpClient — 發送 HTTP 請求。
- WebClient — 簡單的下載/上傳檔案功能。
- HttpListener — 建立本地伺服器。
#### ✅ **範例:**
```csharp
using System.Net.Http;
using System.Threading.Tasks;
public async Task GetApiData() {
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("https://api.github.com/");
string data = await response.Content.ReadAsStringAsync();
Console.WriteLine(data);
}
```
### 🔷 **資料庫存取與 ORM**
#### ✅ **System.Data.SqlClient**
- 用於連接 SQL Server 資料庫。
- 搭配 ADO.NET 執行 SQL 查詢。
#### ✅ **Entity Framework Core**
- ORM 框架,簡化資料庫操作。
- 支援 Code-First、Database-First 等模式。
#### ✅ **範例:**
```csharp
using System.Data.SqlClient;
string connectionString = "Server=myServer;Database=myDB;User Id=myUser;Password=myPass;";
using (SqlConnection connection = new SqlConnection(connectionString)) {
connection.Open();
SqlCommand command = new SqlCommand("SELECT * FROM Users", connection);
SqlDataReader reader = command.ExecuteReader();
while (reader.Read()) {
Console.WriteLine(reader["Username"]);
}
}
```
### 🔷 **檔案與資料處理**
#### ✅ **System.IO**
- File — 讀取與寫入檔案。
- Directory — 操作資料夾。
- FileStream / StreamReader / StreamWriter — 處理資料流。
#### ✅ **範例:**
```csharp
using System.IO;
// 讀取檔案
string text = File.ReadAllText("example.txt");
// 寫入檔案
File.WriteAllText("output.txt", "Hello, World!");
// 檢查檔案是否存在
if (File.Exists("example.txt")) {
Console.WriteLine("檔案存在");
}
```
### 🔷 **JSON/XML**
#### ✅ **Newtonsoft.Json(Json.NET)**
- 最常用的 JSON 解析套件。
- 支援序列化與反序列化。
#### 安裝 Newtonsoft.Json
dotnet add package Newtonsoft.Json
#### ✅ **範例:**
```csharp
using Newtonsoft.Json;
var person = new { Name = "John", Age = 30 };
string json = JsonConvert.SerializeObject(person);
var obj = JsonConvert.DeserializeObject<dynamic>(json);
Console.WriteLine(obj.Name); // John
```
#### ✅ **System.Xml**
- 處理 XML 檔案。
- 支援 LINQ to XML (System.Xml.Linq)。
### 🔷 **影像處理與機器視覺**
#### ✅ **Emgu CV (C# 封裝的 OpenCV)**
- 影像處理、電腦視覺常用套件。
- 支援影像過濾、邊緣偵測、人臉辨識等功能。
#### ✅ **範例:**
```csharp
using Emgu.CV;
using Emgu.CV.Structure;
Image<Bgr, Byte> img = new Image<Bgr, Byte>("image.jpg");
CvInvoke.CvtColor(img, img, Emgu.CV.CvEnum.ColorConversion.Bgr2Gray);
CvInvoke.Imshow("Gray Image", img);
CvInvoke.WaitKey(0);
```
### 🔷 **常用第三方套件(NuGet)**
| **套件名稱** | **用途** | **安裝指令** |
|----------------|----------------|-------------------------------------|
| **Newtonsoft.Json** | JSON 序列化/反序列化 | `dotnet add package Newtonsoft.Json` |
| **EntityFramework** | ORM 資料庫操作 | `dotnet add package Microsoft.EntityFrameworkCore` |
| **Dapper** | 輕量級 ORM | `dotnet add package Dapper` |
| **NLog / Serilog** | 日誌紀錄工具 | `dotnet add package NLog` 或 `dotnet add package Serilog` |
| **RestSharp** | API 呼叫封裝 | `dotnet add package RestSharp` |
| **AutoMapper** | 物件映射(DTO 轉換) | `dotnet add package AutoMapper` |
| **FluentValidation** | 物件驗證工具 | `dotnet add package FluentValidation` |
| **MediatR** | CQRS 與中介者模式實作 | `dotnet add package MediatR` |
| **Polly** | 重試策略與容錯機制 | `dotnet add package Polly` |
| **Quartz.NET** | 排程任務工具 | `dotnet add package Quartz` |
| **Hangfire** | 後台任務排程 | `dotnet add package Hangfire` |
| **NUnit / xUnit** | 單元測試框架 | `dotnet add package NUnit` 或 `dotnet add package xUnit` |
| **Moq** | 單元測試中的 Mock 工具 | `dotnet add package Moq` |
| **Swashbuckle** | Swagger API 文件生成 | `dotnet add package Swashbuckle.AspNetCore` |
| **SignalR** | 即時通訊框架 | `dotnet add package Microsoft.AspNetCore.SignalR` |
### ✅ **總結**
| **功能範疇** | **套件/函式庫** |
|------------|----------------------------------------|
| 基礎語法 | `System`, `System.Text`, `System.IO` |
| 資料結構與集合 | `System.Collections`, `System.Collections.Generic` |
| 資料庫操作 | `System.Data.SqlClient`, `EntityFramework`, `Dapper` |
| 網路通訊 | `HttpClient`, `System.Net.Sockets`, `RestSharp` |
| 非同步程式設計 | `System.Threading.Tasks`, `async/await` |
| JSON 處理 | `Newtonsoft.Json`, `System.Text.Json` |
| 機器視覺 | `EmguCV`, `OpenCvSharp` |
| 測試框架 | `xUnit`, `NUnit`, `MSTest`, `Moq` |
| API 文件生成 | `Swashbuckle`, `NSwag` |
| 日誌紀錄 | `Serilog`, `NLog`, `log4net` |
| 錯誤處理 | `Polly` |
| 任務排程 | `Quartz.NET`, `Hangfire` |
| 即時通訊 | `SignalR` |
| 物件映射 | `AutoMapper` |
| 驗證工具 | `FluentValidation` |
---
C程式語言
---
### 🟢 **C 語言常用函式與語法**
#### ✅ **1. 基本輸入/輸出 (I/O)**
#### **輸出:`printf()`**
```c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
```
- %d → 整數
- %f → 浮點數
- %s → 字串
- %c → 字元
#### **輸入:`scanf()`**
```c
#include <stdio.h>
int main() {
int age;
printf("請輸入年齡: ");
scanf("%d", &age); // 使用 & 取得變數位址
printf("你輸入的年齡是: %d\n", age);
return 0;
}
```
#### **流程控制**
```c
#include <stdio.h>
int main() {
int num = 10;
if (num > 0) {
printf("正數\n");
} else if (num < 0) {
printf("負數\n");
} else {
printf("零\n");
}
return 0;
}
```
#### **迴圈**
```c
// for 迴圈
for(int i = 0; i < 5; i++) {
printf("%d ", i);
}
// while 迴圈
int i = 0;
while(i < 5) {
printf("%d ", i);
i++;
}
// do...while 迴圈
int j = 0;
do {
printf("%d ", j);
j++;
} while(j < 5);
```
#### **一維陣列**
```c
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
for(int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
```
#### **字串處理`**
```c
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
strcat(str1, " "); // 加入空格
strcat(str1, str2); // 合併字串
printf("%s\n", str1); // 輸出: Hello World
printf("字串長度: %lu\n", strlen(str1)); // 輸出字串長度
return 0;
}
```
#### **指標`**
```c
#include <stdio.h>
int main() {
int num = 10;
int *ptr = # // 指標儲存變數位址
printf("變數的值: %d\n", num);
printf("變數的位址: %p\n", &num);
printf("指標儲存的位址: %p\n", ptr);
printf("透過指標取得的值: %d\n", *ptr); // 使用 * 取值
return 0;
}
```
#### **函式`**
```c
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int result = add(5, 3);
printf("5 + 3 = %d\n", result);
return 0;
}
```
#### **傳值、傳址`**
```c
#include <stdio.h>
// 傳值:不會改變原變數
void byValue(int x) {
x = 20;
}
// 傳址:會改變原變數
void byReference(int *x) {
*x = 20;
}
int main() {
int num = 10;
byValue(num);
printf("傳值後: %d\n", num); // 輸出 10
byReference(&num);
printf("傳址後: %d\n", num); // 輸出 20
return 0;
}
```
#### **動態記憶體分配`**
```c
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
ptr = (int*)malloc(sizeof(int) * 5); // 分配 5 個整數空間
for(int i = 0; i < 5; i++) {
ptr[i] = i + 1;
printf("%d ", ptr[i]);
}
free(ptr); // 釋放記憶體
return 0;
}
```
C++程式語言
---
### 📖 C++ 面試常用函式與語法整理
---
### 🟡 **C++ 常用函式與語法**
#### ✅ **1. 輸入/輸出 (I/O)**
#### **使用 `cin` 和 `cout`:**
```cpp
#include <iostream>
using namespace std;
int main() {
int age;
cout << "請輸入年齡: ";
cin >> age;
cout << "你的年齡是: " << age << endl;
return 0;
}
```
#### **類別與物件**
```cpp
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
void introduce() {
cout << "我是 " << name << ",今年 " << age << " 歲。" << endl;
}
};
int main() {
Person p;
p.name = "小明";
p.age = 20;
p.introduce();
return 0;
}
```
#### **物件導向編程 OPP**
```cpp
#include <iostream>
using namespace std;
class Person {
public:
string name;
int age;
void introduce() {
cout << "我是 " << name << ",今年 " << age << " 歲。" << endl;
}
};
int main() {
Person p;
p.name = "小明";
p.age = 20;
p.introduce();
return 0;
}
```
#### **建構元與解構元**
```cpp
#include <iostream>
using namespace std;
class Person {
public:
Person() {
cout << "建構子被呼叫" << endl;
}
~Person() {
cout << "解構子被呼叫" << endl;
}
};
int main() {
Person p;
return 0;
}
```
#### **繼承與多型**
```cpp
#include <iostream>
using namespace std;
class Animal {
public:
void speak() {
cout << "動物發出聲音" << endl;
}
};
class Dog : public Animal {
public:
void speak() {
cout << "狗狗汪汪叫" << endl;
}
};
int main() {
Dog d;
d.speak(); // 輸出: 狗狗汪汪叫
return 0;
}
```
#### **虛擬函式與多型**
```cpp
#include <iostream>
using namespace std;
class Animal {
public:
virtual void speak() { // 虛擬函式
cout << "動物叫聲" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "貓咪喵喵叫" << endl;
}
};
int main() {
Animal* a = new Cat();
a->speak(); // 輸出: 貓咪喵喵叫
delete a;
return 0;
}
```
#### **向量**
```cpp
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<int> v = {1, 2, 3, 4, 5};
// 遍歷 Vector
for(int num : v) {
cout << num << " ";
}
cout << endl;
// 加入元素
v.push_back(6);
// 刪除最後元素
v.pop_back();
return 0;
}
```
#### **映射**
```cpp
#include <iostream>
#include <map>
using namespace std;
int main() {
map<string, int> ageMap;
ageMap["小明"] = 20;
ageMap["小華"] = 25;
for(auto& pair : ageMap) {
cout << pair.first << ": " << pair.second << " 歲" << endl;
}
return 0;
}
```
#### **例外處理**
```cpp
#include <iostream>
using namespace std;
int main() {
try {
int a = 5;
int b = 0;
if (b == 0) {
throw "除數不可為零!";
}
cout << a / b << endl;
} catch(const char* msg) {
cout << "錯誤: " << msg << endl;
}
return 0;
}
```
---
演算法工程師
---