分享到plurk 分享到twitter 分享到facebook

版本 acd8d628397a74516f4978ba71f232cf9863e47b

User/Jordymalone

Changes from acd8d628397a74516f4978ba71f232cf9863e47b to 13f11ed5df3cd5ff4cc200b750d999a7a4766ceb

---
title: Jordymalone (邱家浩)
categories: User
...

# 簡介

- 國立成功大學 資訊工程研究所 113 級
- Github: [`Jordymalone`](https://github.com/Jordymalone)
- Hackmd: [`Jordymalone`](https://hackmd.io/@JordyMalone)
- Linkedin: [Jordan (Chia-Hao) Chiu](https://www.linkedin.com/in/jordan871130/)

# 2025 Linux 核心設計 春季班 自我評量

## 成果發表和貢獻

- 貢獻
  - [sysprog21/lab0-c](https://github.com/sysprog21/lab0-c): [`#259`](https://github.com/sysprog21/lab0-c/pull/259)
  - [sysprog21/kxo](https://github.com/sysprog21/kxo): [`#9`](https://github.com/sysprog21/kxo/pull/9)
  - [sysprog21/khttpd](https://github.com/sysprog21/khttpd): [`#13`](https://github.com/sysprog21/khttpd/pull/13), [`#14`](https://github.com/sysprog21/khttpd/pull/14),[`#15`](https://github.com/sysprog21/khttpd/pull/15)
  - [《The Linux Kernel Module Programming Guide》](https://github.com/sysprog21/lkmpg): [`#303`](https://github.com/sysprog21/lkmpg/pull/303)

評分: 8 分

這部分給予自己 8 分。起初我對 Git 毫無概念,但如今已能熟練操作並成功提交 PR 至課程教材與專案,且內容已被實際採納。這段從零開始、逐步參與實作的過程,讓我深感成就。未來,我也會持續投入開源專案的貢獻,秉持著「路見不平,拿 patch 來補」的精神,不斷精進、回饋社群。
這部分我給予自己 8 分。起初我對 Git 幾乎一無所知,只會 `git clone` 這個最基本的指令。但在第一次作業中,老師特別強調 Git 的重要性,並推薦閱讀 [如何撰寫良好的 Git Commit Message](https://blog.louie.lu/2017/03/21/%E5%A6%82%E4%BD%95%E5%AF%AB%E4%B8%80%E5%80%8B-git-commit-message/)。我從撰寫自己作業的 commit 開始練習,刻意遵循標題最多只有 50 字元、內文每行最多 72 字元、以祈使句撰寫標題、說明「做了什麼、為什麼要做」,逐步養成了良好的紀錄習慣。這為我後來提交 PR 奠定了基礎,也時刻記著老師提到的「commit 是寫給三個人的: 過去的你、現在的你、未來的你」。

在實際參與開源專案 (如 lab0-c、kxo、khttpd 等) 的 PR 過程中,我逐漸理解 code review 並不只是檢查程式碼正不正確,更是一種溝通。於 khttpd 提交的 [#13](https://github.com/sysprog21/khttpd/pull/13) PR 中,老師也提醒我「要專注於提供具有實質價值的程式碼審查意見,並且用清楚、可執行的語言來溝通。」,避免那些客套的開場或結尾語。這段經驗讓我體會到工程師之間的溝通不應流於形式,而應聚焦在具體行為改善與設計判斷的交流上。

感謝這堂課讓我從一個只會 `git clone` 的人,成長為能在實作中反思版本控制意義、撰寫清晰紀錄、參與有效溝通的貢獻者。我也會持續投入開源專案的貢獻,秉持著「路見不平,拿 patch 來補」的精神,不斷精進、回饋社群。

## 作業/隨堂測驗

- [2025q1 Homework1 (lab0)](https://hackmd.io/@JordyMalone/linux2025-homework1)
- [2025q1 Homework2 (quiz1+2)](https://hackmd.io/@JordyMalone/linux2025-homework2)
- [2025q1 Homerwork3 (kxo)](https://hackmd.io/@JordyMalone/linux2025-homework3)
- [2025q1 Homework4 (quiz3+4)](https://hackmd.io/@JordyMalone/linux2025-homework4)
- [2025q1 Homework5 (assessment)](https://hackmd.io/@JordyMalone/linux2025-homework5)

評分: 6 分

這部分給予自己 6 分。當時面對第一份作業,受到了強烈的衝擊,不僅意識到自己對 C 語言的理解不足,許多工具(如 valgrind、git 等)也是首次接觸,甚至有些細節是我從未思考過的。也因此,在老師所提倡的「誠實面對自己」的學習環境下,我重新審視了自己的學習方式,拾起 C99 規格書開始啃,不倚靠二手資料,而是從原始文獻中理解。這段過程雖然艱辛,但也讓我逐步建立起更扎實的基礎,並培養出主動學習與獨立解決問題的能力。

## 期末專題

* [Linux 核心專題: 高度並行的核心模式網頁伺服器](https://hackmd.io/@sysprog/SJYvYX_Wxl)

評分: 7 分

這部分給予自己 7 分。過去從未接觸過網路相關的知識,到如今能夠修改核心模組、導入 workqueue 架構,甚至實作出支援 directory listing、檔案傳輸與 MIME 類型處理的網頁伺服器,對我而言是一段非常扎實的學習旅程。在這個過程中,我學會了如何使用 CMWQ 重構原本以 thread 為基礎的結構,有效改善資源使用與吞吐效能,也實際實作了 chunked transfer encoding,進一步理解 HTTP 協定中處理動態資料時的設計考量。

原本我以為「網頁伺服器」是偏應用層的開發工作,但這次的專題讓我看見了從核心層面支撐 HTTP request 的各種機制,包括如何列出目錄內容、處理靜態檔案、依副檔名指定正確的 Content-Type 等,這些經驗讓我對系統層與應用層之間的關係有了更清楚的認識。我也學習到如何撰寫 kernel module 時善用各種 API,如 `workqueue`、`dir_context`、`filp_open`、`container_of` 等,這些能力成為我邁向 kernel 開發的重要起點。
過去我對網路協定與核心模組開發毫無實作經驗,這次期末專題讓我第一次從核心出發,實作出一個在核心模式下運作的簡易 HTTP 伺服器。專案中我完成了下列幾項功能:

過程中雖然遇到不少挫折與卡關,但也學會了如何一步步釐清問題、查找資料、反覆實驗與修正。這段學習讓我理解:「不懂並不可怕,卡住才是進步的起點。」只要持續面對、努力釐清,總有一天能真正掌握背後的原理與脈絡。
- 使用 CMWQ (concurrency-managed workqueue) 重構原先由 thread 直接處理的請求邏輯,避免每個請求都需建立 kernel thread,並利用 htstress 去測試比較前後效能。
- 實作 directory listing,使瀏覽器能接收正確格式的目錄清單 (以 chunked encoding 傳輸)。
- 根據副檔名對應 MIME type,依 RFC 9110 傳回正確 Content-Type header。
- 補上 HTTP 1.1 中支援的 chunked transfer encoding,處理目錄與大檔案的動態傳輸。

我給自己 7 分,是因為目前的專案仍有進一步擴充與優化的空間,我也期許自己持續投入改進與貢獻,讓這個專案不只是一份課程作業,而是我踏入 Linux kernel 與網路系統世界的敲門磚,為未來更深入的核心開發與系統研究奠定紮實的起點。
除以上功能之外,我也學會透過用 ftrace 去進行效能分析,發現請求處理流程中的 HTTP 回應傳送階段是最主要的延遲來源。特別是當伺服器準備好回應內容並送出時,實際的資料傳輸操作會耗費大量時間,因為涉及封包分段、記憶體分配、TCP 緩衝區檢查,以及訊框送出等一連串處理。這導致整體處理流程被迫等待網路 I/O 完成,無法並行處理下一筆請求,也進一步說明此專案仍有可觀的優化空間。而我將持續投入這個專案,讓這個專案不只是一份課程作業,並作為我探索 Linux networking 與核心 I/O 架構的起點。

## 與授課教師的互動

- 一對一討論: 5/16

討論 I/O model 及 `select` 系統呼叫。
探討 I/O model 及 `select` 系統呼叫。

評分: 6 分

這部分給予自己 6 分。這次的討論經驗雖然讓我釐清了一些原本模糊的概念,也促使我回去補強了先前的薄弱環節,但整體而言,我的表現仍未達到理想的標準。透過與老師的庫動,我更加意識到自己在某些核心觀念上的理解仍不夠紮實,表達上也欠缺自信。這段經歷提醒我,若要在深入的交流中真正獲得成長,除了加強課前的理解與準備,更應該**主動參與**、**勇於提問**,善用與老師互動的每一個機會,讓討論不只是過程,更成為深化學習的契機。
這部分給予自己 6 分。在一對一討論中,與老師針對 [事件驅動伺服器: 原理和實例](https://hackmd.io/@sysprog/linux-io-model/https%3A%2F%2Fhackmd.io%2F%40sysprog%2Fevent-driven-server) 中所提到的 Asynchronous I/O 機制進行了深入的探討。原本我對非同步 I/O 的理解是:「能夠在等待結果的同時進行其他工作」,但老師點出這其實只是 Non-blocking I/O 就能實現的效果,並非 Asynchronous I/O 的核心本質。真正讓我重新理解非同步機制的,是老師對其流程角色的描述及精美的圖片。Asynchronous I/O 的精髓在於「處理者與完成者可以是不同的實體」。這個模型中,submission (任務提交)、processing (任務處理)、completion (結果交付) 可以由三個獨立的執行單元分別負責。而另一個關鍵在於 **offload**,也就是將任務明確地交由其他執行單元 (如 kernel thread) 處理,而不是自己一手包辦。這樣的 offload 設計,讓整個系統有比較大的彈性,只需專注於任務的提交與結果的接收,由系統在適當時機主動通知完成狀態。

另外老師也幫我釐清了對 `select` 系統呼叫的理解錯誤,根本原因在於我當初沒有仔細閱讀 [man page](https://man7.org/linux/man-pages/man2/select.2.html)。select 的本質仍是 blocking,即使監控的 fd 是 non-blocking,整體呼叫仍會阻塞當前執行緒。而 Linux 提供 timeout 作為補救機制,讓我們能設定等待上限,但無論是否使用 timeout,select 依然是同步阻塞的。
此外,select 採用 level-triggered 模式,只有當某個 fd 處於特定狀態才會被通知。與其相比,epoll 的一大改進是可以讓開發者主動指定感興趣的事件類型,例如 EPOLLIN 或 EPOLLOUT。
這次討論讓我理解到,很多系統呼叫若只靠直覺,很容易混淆行為與設計初衷,唯有回頭讀官方文檔,才能真正掌握底層機制

## 所見所聞所感

參與 Linux 核心設計課程的這段時間,對我來說既扎實又充滿挑戰。在完成作業與閱讀老師提供的材料時,我常常在心裡反覆問自己:「我真的理解了嗎?」雖然表面上能照著步驟完成,但對於其中的設計原則與細節,卻往往無法清楚解釋出來。這讓我開始意識到,「會做」和「知道為什麼要這樣做」,其實是兩個完全不同的層次。

尤其在卡關的時候,我常去參考其他同學的成果。他們清晰的邏輯與細緻的實作不只讓我佩服,也讓我產生不少壓力與懷疑:「我是不是還差得很遠?」這樣的比較曾經讓我感到焦慮與沮喪,但也因此推動我去反思自己的學習方式──我是否只是為了交出結果,而忽略了真正的理解與內化?

直到後來,在閱讀《因為自動飲料機而延畢的那一年》這系列文章,才讓我對「卡住」這件事有了新的看法。Jserv 在其中提到:「你該學習的不是看到事情要完蛋了就去避免失敗,而是應該學習如何處理與承受失敗,你才能變得比以前更強大。」這句話深深打動我,讓我明白: 卡住不是能力不足的證明,而是成長正在發生的跡象,會懷疑自己,是因為我正在認真看待每一個細節。

因此,這段時間我學到的不只是技術,更重要的是學會怎麼在迷惘中調整步伐、在壓力中整理思緒、在錯誤中補強理解。即使現在的作業還有許多可以改進的地方,但就像老師說的:「**缺什麼補什麼**」,我會持續補上自己的不足,把每一次卡關與修正都當成學習的節點,讓這個過程成為真正屬於自己的成長軌跡。
因此,這段時間我學到的不只是技術,更重要的是學會怎麼在迷惘中調整步伐、在壓力中整理思緒、在錯誤中補強理解。就如老師說的:「**缺什麼補什麼**」,我會持續補上自己的不足,把每一次卡關與修正都當成學習的節點,讓這個過程成為真正屬於自己的成長軌跡。

所以,這部分我給予自己 10 分。
所以,這部分我給予自己 10 分。另外,老師課堂上講的笑話是真的很好笑,推薦大家一定要上課。

## 自我評量 (1 ~ 10)

- GEOMEAN = $\sqrt[5]{8+6+7+6+10} \approx 7.26$
- 方案 A : 8 + floor(0.3 * GEOMEAN) = 8 + floor(0.3 * 7.26) = 10
- 方案 B : 1 + floor(GEOMEAN) = 1 + floor(7.26) = 8