Node.js

Ôn Node.js cho vị trí Senior Backend: từ kiến trúc V8 + libuv, 6 phase của event loop, microtask, thread pool, tới streams và bộ nhớ. Nên đọc theo thứ tự 1 → 6. Mọi output trong bài là output thật chạy trên Node 22.23.1 (libuv 1.51.0, V8 12.4).

Bài 1 · Nền tảng

Node.js chạy thế nào — V8, libuv, một thread JS và nhiều thread OS

Vì sao Node ra đời (C10K), process Node có bao nhiêu thread thật, I/O mạng đi qua epoll còn fs đi qua thread pool — chứng minh bằng strace.

Bài 2 · Event loop

Event loop — 6 phase, đi từng vòng bằng code libuv thật

timers, pending, idle/prepare, poll, check, close. Poll phase ngủ bao lâu, setTimeout vs setImmediate, cái gì giữ process sống.

Bài 3 · Event loop

Microtask — process.nextTick, Promise, queueMicrotask và nạn "bỏ đói" loop

Thứ tự thật giữa 2 hàng đợi, CJS khác ESM ra sao, đệ quy nextTick chặn I/O 500ms, unhandled rejection làm chết process.

Bài 4 · Hiệu năng

Thread pool và chặn event loop — đo, tìm, chữa

UV_THREADPOOL_SIZE, DNS chậm, pbkdf2, ReDoS, JSON.stringify chặn server 1 giây; đo bằng event loop delay/ELU; worker_threads và cluster.

Bài 5 · I/O

Streams và backpressure — xử lý dữ liệu lớn không nổ RAM

readFile 300MB vs stream, bỏ qua write() làm RAM lên 240MB, .pipe() rò file descriptor, pipeline() chữa thế nào.

Bài 6 · Bộ nhớ

Memory và GC của V8 — heap, rò rỉ, và OOM trong container

New space / old space, Scavenge vs Mark-Compact, heap limit theo cgroup, OOMKilled 137 không để lại log, tìm rò rỉ bằng heap snapshot.