DOCS · v1.0 · 10 chương

Giáo trình OS
Hệ điều hành — từ kernel đến memory

Tài liệu mô tả chi tiết toàn bộ nội dung 10 chương Hệ điều hành: process, thread, concurrency, deadlock, memory, file system. Đọc trước để có cái nhìn tổng quan, sau đó vào từng chương để học sâu. Mỗi chương kèm ví dụ Linux/Node.js, bài tập, quiz và sơ đồ ASCII.

⚙️ Triết lý học OS của giáo trình
  1. Hiểu tại sao trước hiểu cái gì. Mọi cơ chế OS sinh ra để giải quyết bài toán cụ thể (vd: virtual memory ra đời vì RAM quá ít cho nhiều process).
  2. Nối với code thật. Mỗi khái niệm có ví dụ shell command (Linux) hoặc Node.js — không trừu tượng.
  3. Phỏng vấn-oriented. Tập trung vào câu hỏi hay xuất hiện: process vs thread, deadlock, virtual memory, GC...
  4. Thực hành trên máy thật. Mở terminal mà thử ps, top, strace. OS không phải lý thuyết suông.

📚 Mục lục — 10 chương

CH.01

OS là gì? Kernel & System Calls

Foundation

Cơ sở của tất cả. Hiểu vai trò OS, ranh giới user space / kernel space, và system call — cầu nối giữa app và kernel.

🎯 Mục tiêu học tập

  • Hiểu OS làm gì và 4 chức năng chính (process management, memory, file, I/O)
  • Phân biệt User Space vs Kernel Space, vì sao cần ranh giới đó
  • Hiểu System Call — code chạy ở user space muốn làm gì với phần cứng đều phải qua syscall
  • Phân loại OS: monolithic kernel (Linux) vs microkernel (Minix, seL4)
  • Hiểu CPU mode bit (ring 0/3 trên x86)

📖 Nội dung chi tiết

  • 1.1 OS là gì? Vai trò trung gian giữa app và phần cứng
  • 1.2 User Space vs Kernel Space — tại sao tách
  • 1.3 System Call — cách user app "yêu cầu" kernel làm việc
  • 1.4 Ví dụ syscall thường: read, write, open, fork, execve
  • 1.5 Trace syscall với strace trên Linux
  • 1.6 Kernel architectures: monolithic, microkernel, hybrid
  • 1.7 Boot process: BIOS/UEFI → bootloader → kernel → init
  • 1.8 Mode bit, privilege rings (ring 0 vs ring 3)

💡 Câu hỏi phỏng vấn kinh điển

  • Tại sao app không gọi trực tiếp hardware mà phải qua kernel?
  • Mode switch khác Context switch như thế nào?
  • Kernel panic khác segfault thế nào?
  • Linux dùng monolithic hay microkernel?
CH.02

Process & PCB

Process

Process = chương trình đang chạy. Đây là khái niệm cốt lõi nhất. Hiểu vòng đời, PCB, fork/exec là phải thuộc.

🎯 Mục tiêu học tập

  • Phân biệt Program (file trên disk) vs Process (chạy trong RAM)
  • Hiểu memory layout của 1 process: text, data, heap, stack
  • Vẽ được Process State Diagram (5 states: New, Ready, Running, Blocked, Terminated)
  • Hiểu PCB (Process Control Block) chứa gì
  • Cài đặt được fork() / exec() trong C hoặc Node.js child_process
  • Hiểu process tree, parent/child, zombie/orphan process

📖 Nội dung chi tiết

  • 2.1 Program vs Process
  • 2.2 Memory layout: text, data, BSS, heap, stack
  • 2.3 Process Control Block (PCB) — kernel "thẻ" cho mỗi process
  • 2.4 Process states & state transitions
  • 2.5 Tạo process: fork() trong Linux — copy parent
  • 2.6 exec() — thay thế bằng program khác
  • 2.7 Process termination, exit codes, wait()
  • 2.8 Zombie process & orphan process
  • 2.9 Quan sát process: ps, top, htop, /proc
  • 2.10 Node.js child_process API

💡 Câu hỏi phỏng vấn kinh điển

  • Khi fork() trả về 0 nghĩa là gì?
  • Sau fork, parent và child có chia sẻ heap/stack không?
  • Zombie process là gì? Tại sao xảy ra? Cách xử lý?
  • Khi terminal đóng, process con có chết không?
CH.03

Thread & Concurrency Models

Process

Process "nặng", thread "nhẹ". Đây là chương cực hay hỏi: process vs thread, threading models, JS event loop.

🎯 Mục tiêu học tập

  • Phân biệt Thread vs Process — đâu là chia sẻ, đâu là riêng
  • Hiểu User-level vs Kernel-level thread, mô hình M:1, 1:1, M:N
  • Hiểu Thread Pool — vì sao mọi web server đều dùng
  • Hiểu cách Node.js đơn luồng nhưng vẫn xử lý được hàng nghìn request: Event Loop + libuv
  • Phân biệt Concurrency vs Parallelism

📖 Nội dung chi tiết

  • 3.1 Thread là gì? "Lightweight process"
  • 3.2 Thread chia sẻ gì, không chia sẻ gì
  • 3.3 Process vs Thread — bảng đối chiếu
  • 3.4 User-level threads vs Kernel-level threads
  • 3.5 Threading models: M:1, 1:1, M:N
  • 3.6 Thread Pool — thread tái sử dụng
  • 3.7 Node.js Event Loop — single-threaded JavaScript + libuv worker pool
  • 3.8 Worker Threads trong Node.js (CPU-bound work)
  • 3.9 Concurrency vs Parallelism — khác biệt cốt lõi
  • 3.10 Async/await, callback, Promise — cùng một bài toán

💡 Câu hỏi phỏng vấn kinh điển

  • Process vs Thread khác nhau ở đâu? (kinh điển)
  • Tại sao tạo thread nhanh hơn tạo process?
  • Node.js single-threaded vậy xử lý concurrent request thế nào?
  • Concurrency vs Parallelism khác nhau ra sao?
  • Khi nào dùng worker_threads, khi nào dùng cluster?
CH.04

CPU Scheduling

Process

Khi nhiều process cùng cần CPU, OS phải chọn ai chạy. Đây là chương về thuật toán quyết định "ai chạy tiếp theo".

🎯 Mục tiêu học tập

  • Hiểu các tiêu chí scheduling: throughput, turnaround time, waiting time, response time, fairness
  • Phân biệt Preemptive vs Non-preemptive scheduling
  • Cài đặt được FCFS, SJF, Priority, Round Robin
  • Hiểu MLFQ (Multi-Level Feedback Queue) — gần với Linux CFS
  • Hiểu hiện tượng "convoy effect", "starvation" và cách giải quyết

📖 Nội dung chi tiết

  • 4.1 Bài toán scheduling — tại sao cần?
  • 4.2 Tiêu chí đánh giá: throughput, turnaround, waiting, response time
  • 4.3 Preemptive vs Non-preemptive
  • 4.4 FCFS (First-Come First-Served) — đơn giản nhưng có convoy effect
  • 4.5 SJF (Shortest Job First) — tối ưu nhưng cần biết trước
  • 4.6 Priority Scheduling — và bài toán starvation, aging
  • 4.7 Round Robin (RR) — time quantum
  • 4.8 Multilevel Queue
  • 4.9 MLFQ — combination, tự "học" priority
  • 4.10 Linux CFS (Completely Fair Scheduler)

💡 Câu hỏi phỏng vấn kinh điển

  • Round Robin với quantum quá nhỏ thì sao? Quá lớn thì sao?
  • Starvation là gì? Cách khắc phục?
  • Linux dùng scheduler nào?
  • Tại sao Priority + Aging?
CH.05

Inter-Process Communication (IPC)

IPC

Process tách biệt nhau, vậy chúng "nói chuyện" thế nào? Đây là chương về pipes, signals, shared memory, sockets, message queue.

🎯 Mục tiêu học tập

  • Hiểu các cơ chế IPC: pipe, named pipe (FIFO), shared memory, message queue, signal, socket
  • So sánh ưu/nhược của từng cơ chế
  • Cài đặt được pipe trong Node.js (child_process stdio)
  • Hiểu Unix domain socket vs network socket

📖 Nội dung chi tiết

  • 5.1 Tại sao cần IPC? Process bị isolated bộ nhớ
  • 5.2 Pipe (anonymous): ls | grep .txt dùng pipe
  • 5.3 Named Pipe (FIFO): mkfifo
  • 5.4 Shared Memory: nhanh nhất, cần sync thủ công
  • 5.5 Message Queue: kernel queue messages
  • 5.6 Signal: SIGTERM, SIGKILL, SIGINT, SIGCHLD
  • 5.7 Socket: Unix domain socket vs TCP/UDP
  • 5.8 Node.js IPC: child.send() trong fork
  • 5.9 So sánh các cơ chế

💡 Câu hỏi phỏng vấn kinh điển

  • Khác nhau giữa Pipe và Message Queue?
  • Shared memory cần đồng bộ thế nào?
  • SIGKILL khác SIGTERM?
  • Tại sao Ctrl+C kill được process?
CH.06

Synchronization (Mutex, Semaphore, Monitor)

Concurrency

Khi nhiều thread đọc/ghi cùng dữ liệu, chuyện gì xảy ra? Race condition. Đây là chương cực kỳ kinh điển.

🎯 Mục tiêu học tập

  • Hiểu Race Condition và Critical Section
  • Hiểu các cơ chế đồng bộ: Mutex, Semaphore (counting, binary), Monitor, Spinlock, Read/Write lock
  • Giải bài Producer-Consumer, Reader-Writer, Dining Philosophers
  • Hiểu atomic operation, memory barrier, lock-free data structure (cơ bản)

📖 Nội dung chi tiết

  • 6.1 Race condition — ví dụ counter increment
  • 6.2 Critical section, mutual exclusion
  • 6.3 Peterson's algorithm — software-only mutex
  • 6.4 Mutex — lock/unlock
  • 6.5 Semaphore — counting và binary
  • 6.6 Monitor — high-level abstraction
  • 6.7 Spinlock — busy waiting; khi nào dùng?
  • 6.8 Read/Write Lock — nhiều reader, một writer
  • 6.9 Bài Producer-Consumer (Bounded Buffer)
  • 6.10 Bài Reader-Writer Problem
  • 6.11 Bài Dining Philosophers
  • 6.12 Atomic operations (TAS, CAS)

💡 Câu hỏi phỏng vấn kinh điển

  • Mutex vs Semaphore khác nhau ở đâu?
  • Spinlock có lợi gì so với Mutex? Khi nào nên dùng?
  • Atomic operation là gì? Tại sao cần?
  • Code "counter++" trong multithread có an toàn không?
CH.07

Deadlock

Concurrency

Một trong những bug khó tìm nhất. Học chương này, bạn nhận diện được dấu hiệu deadlock và biết cách phòng tránh từ đầu.

🎯 Mục tiêu học tập

  • Hiểu 4 điều kiện cần để deadlock xảy ra (Coffman conditions)
  • Phân biệt: prevention, avoidance, detection, recovery
  • Hiểu Banker's Algorithm
  • Áp dụng được "lock ordering" để phòng tránh deadlock thực tế
  • Phân biệt Deadlock vs Livelock vs Starvation

📖 Nội dung chi tiết

  • 7.1 Deadlock là gì? Ví dụ trực quan
  • 7.2 4 điều kiện Coffman: Mutex, Hold & Wait, No Preemption, Circular Wait
  • 7.3 Resource Allocation Graph (RAG)
  • 7.4 Prevention — phá 1 trong 4 điều kiện
  • 7.5 Avoidance — Banker's Algorithm
  • 7.6 Detection — RAG cycle
  • 7.7 Recovery — kill process, rollback
  • 7.8 Lock ordering — best practice trong code
  • 7.9 Deadlock vs Livelock vs Starvation
  • 7.10 Database deadlock và cách DB tự xử lý

💡 Câu hỏi phỏng vấn kinh điển

  • 4 điều kiện deadlock là gì?
  • Cách phòng tránh deadlock trong production code?
  • Livelock khác deadlock ra sao?
  • MySQL/PostgreSQL xử lý deadlock thế nào?
CH.08

Memory Management & Virtual Memory

Memory

RAM hữu hạn nhưng nhiều process, mỗi process tưởng mình có cả "vũ trụ" RAM. Đây là phép màu của Virtual Memory.

🎯 Mục tiêu học tập

  • Hiểu Stack vs Heap — cách OS cấp phát memory cho mỗi process
  • Hiểu Virtual Memory: tại sao mỗi process tưởng mình có 4GB ảo
  • Phân biệt Logical address (virtual) vs Physical address
  • Hiểu cơ chế Paging cơ bản, Page Table
  • Hiểu khái niệm Segmentation (cũ hơn paging)
  • Hiểu Memory Mapping (mmap)

📖 Nội dung chi tiết

  • 8.1 Stack vs Heap — đặc điểm, vùng cấp phát
  • 8.2 Stack overflow vs Heap overflow vs Memory leak
  • 8.3 Virtual Memory — illusion mà OS tạo ra
  • 8.4 Logical (virtual) address vs Physical address
  • 8.5 MMU (Memory Management Unit) — phần cứng dịch địa chỉ
  • 8.6 Paging — chia memory thành page (thường 4KB)
  • 8.7 Page Table — bản đồ virtual → physical page
  • 8.8 Multi-level page table (vd 4-level trên x86_64)
  • 8.9 Segmentation — old approach
  • 8.10 Memory mapping (mmap), shared mapping
  • 8.11 Garbage Collection (vì JS có GC)

💡 Câu hỏi phỏng vấn kinh điển

  • Stack vs Heap khác nhau thế nào?
  • Tại sao mỗi process "thấy" 4GB nhưng RAM thực chỉ 8GB cho cả máy?
  • Virtual address được dịch sang physical address ra sao?
  • Mark-and-sweep vs Generational GC?
CH.09

Paging & Page Replacement

Memory

Khi RAM hết chỗ cho page mới, đẩy page nào ra disk? Đây là chương về thuật toán page replacement và TLB.

🎯 Mục tiêu học tập

  • Hiểu Page Fault — major vs minor
  • Hiểu TLB (Translation Lookaside Buffer) — cache cho page table
  • Cài đặt được FIFO, LRU, Clock, Optimal
  • Hiểu Belady's Anomaly
  • Hiểu Working Set, Thrashing
  • Liên hệ tới CPU cache (L1/L2/L3)

📖 Nội dung chi tiết

  • 9.1 Page Fault — hành trình từ instruction tới khi page có mặt
  • 9.2 Major vs Minor page fault
  • 9.3 TLB — cache page table entries
  • 9.4 Page replacement — bài toán
  • 9.5 FIFO — đơn giản nhất, có Belady's Anomaly
  • 9.6 LRU (Least Recently Used)
  • 9.7 Clock (Second Chance) — xấp xỉ LRU rẻ hơn
  • 9.8 Optimal (Belady's) — không thể implement, dùng để so sánh
  • 9.9 Working Set model
  • 9.10 Thrashing — khi page fault quá nhiều
  • 9.11 CPU Cache hierarchy (L1/L2/L3) — analog của paging

💡 Câu hỏi phỏng vấn kinh điển

  • TLB là gì? Tại sao cần TLB?
  • LRU vs LFU?
  • Belady's Anomaly là gì?
  • Thrashing và cách khắc phục?
CH.10

File System & I/O

I/O

File system là cách OS quản lý dữ liệu trên disk. Hiểu inode, file descriptor, blocking vs non-blocking I/O là nền tảng của backend dev.

🎯 Mục tiêu học tập

  • Hiểu file system layout: superblock, inode, data blocks
  • Hiểu hard link vs symbolic link
  • Hiểu File Descriptor (fd) — số nguyên tham chiếu file mở
  • Phân biệt Blocking I/O, Non-blocking I/O, I/O Multiplexing (select/poll/epoll), Async I/O
  • Hiểu Buffering, Page Cache
  • Liên hệ với Node.js fs API và event loop

📖 Nội dung chi tiết

  • 10.1 File system tổng quan: tree, directory, files
  • 10.2 Inode — metadata của file
  • 10.3 Hard link vs Symbolic link
  • 10.4 File Descriptor (fd) — và bảng fd của process
  • 10.5 Standard fd: 0 stdin, 1 stdout, 2 stderr
  • 10.6 Open/read/write/close — syscall lifecycle
  • 10.7 Blocking I/O — đơn giản nhưng chặn thread
  • 10.8 Non-blocking I/O + polling
  • 10.9 I/O Multiplexing: select, poll, epoll (Linux), kqueue (BSD)
  • 10.10 Async I/O (io_uring trên Linux)
  • 10.11 Page Cache — kernel buffer file content
  • 10.12 fsync() và data durability
  • 10.13 Node.js I/O model: libuv + thread pool

💡 Câu hỏi phỏng vấn kinh điển

  • Inode chứa gì?
  • Hard link vs symbolic link?
  • epoll khác select/poll thế nào?
  • Tại sao Node.js xử lý I/O nhanh dù single-threaded?
  • fsync() để làm gì?
⚠️ Lời khuyên cuối

OS không học một lần là xong. Đọc xong, hãy mở terminal Linux/macOS mà thử thực tế: strace ls để xem syscall, ps -eLf để xem thread, top để xem state, vmstat để xem memory. Hiểu OS qua việc quan sát hệ thống đang chạy sẽ hiệu quả gấp nhiều lần đọc lý thuyết suông.

Sách kinh điển: "Operating Systems: Three Easy Pieces" (free PDF, cực dễ đọc) và "Modern Operating Systems" (Tanenbaum).

← Quay lại Trang chủ OS Bắt đầu học Chương 01: Kernel & Syscalls →