Syllabus học JavaScript
PHASE 0 - Computer Science & Web Foundations (Ngày 1-10)
Tuần 1: Programming Fundamentals
Ngày 1: Variables, Functions & Call Stack
Mục tiêu: Hiểu cách chương trình thực thi tuần tự qua Call Stack, phân biệt được variable declaration vs function declaration.
Lý thuyết: Variables, Functions, Call Stack là gì, vì sao gọi hàm lồng nhau lại tạo ra "stack".
Thực hành: Vẽ tay call stack cho 3 hàm gọi lồng nhau (A gọi B gọi C), ghi lại thứ tự push/pop.
Ngày 2: Scope & Recursion
Mục tiêu: Phân biệt phạm vi biến trong các loại scope, hiểu recursion tạo stack frame thế nào.
Lý thuyết: Scope là gì, recursion base case/recursive case, stack overflow khi thiếu base case.
Thực hành: Viết hàm đệ quy tính factorial và Fibonacci, thử với input lớn để gây stack overflow và quan sát lỗi.
Ngày 3: Stack vs Heap Memory
Mục tiêu: Hiểu nơi lưu trữ dữ liệu primitive vs reference type.
Lý thuyết: Stack lưu giá trị cố định kích thước (primitive, con trỏ), Heap lưu object/array có kích thước động.
Thực hành: Vẽ sơ đồ Stack/Heap cho đoạn code có object lồng object, chỉ ra biến nào trỏ tới đâu.
Ngày 4: Pass by Value vs Pass by Reference
Mục tiêu: Giải thích chính xác vì sao sửa object trong hàm ảnh hưởng ra ngoài nhưng sửa primitive thì không.
Lý thuyết: JS thực chất là "pass by value của reference" - copy giá trị (địa chỉ) chứ không share biến.
Thực hành: Viết 2 hàm test: 1 hàm nhận number và cố sửa nó, 1 hàm nhận object và sửa property, so sánh kết quả.
Ngày 5: Execution Context - Ôn tập tuần 1
Mục tiêu: Tổng hợp Call Stack + Execution Context thành một mô hình thống nhất.
Lý thuyết: Global Execution Context vs Function Execution Context, mỗi context có Variable Environment riêng.
Thực hành: Trace tay execution context cho 1 đoạn code 4-5 hàm gọi nhau, viết lại thứ tự tạo/hủy context.
Tuần 2: Web Fundamentals
Ngày 6: HTTP Request/Response
Mục tiêu: Đọc hiểu một HTTP request/response thật.
Lý thuyết: Request line, Headers, Body; Response status code, Headers, Body.
Thực hành: Mở DevTools Network tab, gửi 1 request tới API bất kỳ, ghi chú lại toàn bộ headers quan trọng (Content-Type, Cache-Control...).
Ngày 7: Cookies & Sessions
Mục tiêu: Hiểu cơ chế duy trì trạng thái đăng nhập qua HTTP stateless.
Lý thuyết: Cookie là gì, Session lưu ở server, Set-Cookie header, session ID.
Thực hành: Đăng nhập 1 website bất kỳ, tìm cookie session trong DevTools, giải thích vòng đời của nó.
Ngày 8: DNS & TCP
Mục tiêu: Hiểu hành trình từ gõ URL đến khi trình duyệt nhận được bytes đầu tiên.
Lý thuyết: DNS resolution (recursive lookup), TCP 3-way handshake.
Thực hành: Dùng
dighoặcnslookuptra DNS của 1 domain, vẽ sơ đồ 3-way handshake bằng tay.
Ngày 9: TLS & Rendering Pipeline (tổng quan)
Mục tiêu: Hiểu tại sao HTTPS an toàn hơn HTTP, và tổng quan browser render trang thế nào.
Lý thuyết: TLS handshake cơ bản (certificate, key exchange); tổng quan pipeline HTML→DOM→Render→Paint.
Thực hành: Xem chi tiết TLS handshake của 1 site qua DevTools Security tab.
Ngày 10: Ôn tập & Tổng hợp Phase 0
Mục tiêu: Kết nối toàn bộ kiến thức CS + Web fundamentals thành 1 bức tranh.
Lý thuyết: Review toàn bộ Phase 0.
Thực hành: Viết 1 đoạn văn (hoặc vẽ sơ đồ) mô tả full hành trình từ "gõ URL" → "trang hiển thị", lồng ghép DNS/TCP/TLS/Call Stack.
PHASE 1 - Core JavaScript Language (Ngày 11-40)
Tuần 1: Syntax, Types, Operators, Equality
Ngày 11: const/let/var & Temporal Dead Zone
Mục tiêu: Giải thích chính xác sự khác biệt giữa var/let/const và TDZ.
Lý thuyết: Block scope vs function scope, Temporal Dead Zone.
Thực hành: Viết 5 đoạn code nhỏ minh hoạ lỗi TDZ, redeclare var, và const không thể reassign nhưng object vẫn mutate được.
Ngày 12: var Hoisting sâu
Mục tiêu: Giải thích chính xác
varhoạt động thế nào khi hoisted.Lý thuyết: var chỉ hoist declaration, không hoist assignment; hệ quả trong vòng lặp với closure.
Thực hành: Viết vòng
for(var i...)tạo 3 callback setTimeout, dự đoán rồi chạy thử kết quả in ra, giải thích vì sao.
Ngày 13: Primitive Types & typeof null
Mục tiêu: Kể đủ 7 primitive type và giải thích được vì sao
typeof null === "object".Lý thuyết: number, string, boolean, bigint, symbol, undefined, null; lịch sử bug typeof null trong JS.
Thực hành: Viết bảng liệt kê typeof cho 10 giá trị khác nhau (kể cả NaN, function, array) trước khi chạy để tự kiểm tra hiểu biết.
Ngày 14: Operators
Mục tiêu: Sử dụng thành thạo operator arithmetic/logical/bitwise/comparison, hiểu short-circuit.
Lý thuyết: Arithmetic, Logical (&&, ||, ??), Bitwise (&, |, ^, <<, >>), Comparison.
Thực hành: Viết hàm dùng
??và||để set giá trị default, so sánh khác biệt khi giá trị là0hoặc"".
Ngày 15: Equality sâu - Ôn tập tuần 1
Mục tiêu: Giải thích chính xác thuật toán Abstract Equality Comparison (
==) và khi nào nên dùngObject.is.Lý thuyết:
==coercion rules,===strict,Object.is(khác biệt với NaN và -0/+0).Thực hành: Viết bảng so sánh
==/===/Object.ischo 10 cặp giá trị "khó" (NaN vs NaN, 0 vs -0, null vs undefined...).
Tuần 2: Control Flow, Functions, Scope, Closure
Ngày 16: Control Flow
Mục tiêu: Viết code control flow rõ ràng, tránh fallthrough bug trong switch.
Lý thuyết: if/else, switch (fallthrough), các loại loop (for, while, for...of, for...in).
Thực hành: Refactor 1 chuỗi if/else dài thành switch, cố tình gây lỗi fallthrough rồi fix bằng
break.
Ngày 17: Function Types & this
Mục tiêu: Phân biệt 3 cách khai báo hàm và giải thích
thisbị ảnh hưởng thế nào ở mỗi loại.Lý thuyết: Function declaration, expression, arrow function; arrow function không có
thisriêng.Thực hành: Viết object có method dùng function thường và arrow function, gọi trong callback setTimeout, so sánh
thisbị mất thế nào.
Ngày 18: Scope Chain
Mục tiêu: Trace được scope chain của 1 biến qua nhiều lớp hàm lồng nhau.
Lý thuyết: Global/Function/Block scope, cách JS tìm biến qua scope chain.
Thực hành: Viết 4 hàm lồng nhau, mỗi hàm khai báo biến cùng tên, trace xem hàm trong cùng đọc biến của lớp nào.
Ngày 19: Closure
Mục tiêu: Hiểu closure là gì và tại sao hàm "nhớ" được biến sau khi hàm cha đã return.
Lý thuyết: Closure = function + lexical environment nó được tạo ra; use case đếm counter, private variable.
Thực hành: Viết hàm
createCounter()trả về object{increment, decrement, getValue}dùng closure để giữ state private.
Ngày 20: Memoization bằng Closure - Ôn tập tuần 2
Mục tiêu: Ứng dụng closure vào bài toán thực tế: cache kết quả hàm tốn kém.
Lý thuyết: Memoization pattern, trade-off giữa memory và speed.
Thực hành: Viết hàm
memoize(fn)generic dùng closure + Map để cache theo tham số đầu vào, test với hàm fibonacci đệ quy chậm.
Tuần 3: Objects, Prototype, Constructor, Inheritance
Ngày 21: Property Descriptor
Mục tiêu: Hiểu object property không chỉ có value mà còn có flags kiểm soát hành vi.
Lý thuyết:
writable,enumerable,configurable;Object.defineProperty,Object.getOwnPropertyDescriptor.Thực hành: Dùng
Object.definePropertytạo 1 property read-only và 1 property ẩn khỏifor...in, kiểm chứng bằng code.
Ngày 22: Prototype Chain
Mục tiêu: Vẽ được prototype chain của 1 object bất kỳ (array, function, object literal).
Lý thuyết:
__proto__vsprototype, cách JS lookup property qua chain,Object.prototypelà gốc.Thực hành: Dùng
Object.getPrototypeOftruy vết chain của[],{}, và 1 function, vẽ sơ đồ chain.
Ngày 23: Tự implement new
Mục tiêu: Hiểu chính xác 4 bước operator
newthực hiện.Lý thuyết:
newtạo object mới → gán prototype → bindthis→ return object (trừ khi hàm return object khác).Thực hành: Viết hàm
myNew(Constructor, ...args)tự implement lại behavior củanewbằngObject.create+apply.
Ngày 24: Inheritance - Prototype vs Composition
Mục tiêu: So sánh trade-off giữa kế thừa qua prototype và composition (has-a thay vì is-a).
Lý thuyết: Prototype inheritance chain nhiều lớp gây coupling; Composition linh hoạt hơn ("favor composition over inheritance").
Thực hành: Viết cùng 1 bài toán (Animal → Dog) 2 cách: prototype inheritance và composition (mixin), so sánh độ linh hoạt khi thêm behavior mới.
Ngày 25: Ôn tập tuần 3 - OOP tổng hợp
Mục tiêu: Kết hợp property descriptor + prototype + constructor thành 1 bài tập hoàn chỉnh.
Lý thuyết: Review toàn bộ tuần 3.
Thực hành: Xây 1 mini "class system" bằng tay (không dùng keyword
class) có constructor, prototype method, và 1 property readonly.
Tuần 4: Arrays, Iterables, Generator, Symbol
Ngày 26: Tự cài đặt map/filter/reduce
Mục tiêu: Hiểu cơ chế bên trong của 3 hàm array phổ biến nhất.
Lý thuyết: map/filter/reduce đều là dạng "fold" qua mảng, reduce là hàm tổng quát nhất.
Thực hành: Viết
Array.prototype.myMap,myFilter,myReduce; sau đó viếtmyMapbằng cách gọimyReduce.
Ngày 27: Iterator Protocol
Mục tiêu: Hiểu 1 object trở thành "iterator" cần implement interface gì.
Lý thuyết: Iterator Protocol - object có method
next()trả về{value, done}.Thực hành: Viết 1 iterator thủ công (không dùng generator) để duyệt số Fibonacci vô hạn.
Ngày 28: Iterable Protocol
Mục tiêu: Phân biệt Iterable vs Iterator, hiểu vì sao
for...ofhoạt động với Array/Map/Set.Lý thuyết: Iterable Protocol - object có
Symbol.iteratortrả về 1 iterator.Thực hành: Biến 1 custom object (vd
Range {start, end}) thành iterable để dùng được vớifor...of.
Ngày 29: Generator
Mục tiêu: Dùng
function*để đơn giản hoá việc viết iterator.Lý thuyết:
yield, generator tự động implement Iterator Protocol, lazy evaluation.Thực hành: Viết lại bài Fibonacci vô hạn ngày 27 bằng generator, so sánh độ ngắn gọn.
Ngày 30: Symbol & Symbol.iterator - Ôn tập tuần 4
Mục tiêu: Hiểu Symbol là primitive type dùng làm key ẩn/độc nhất, ứng dụng trong
Symbol.iterator.Lý thuyết: Symbol tạo giá trị unique, well-known symbols (
Symbol.iterator,Symbol.asyncIterator).Thực hành: Review lại bài
Rangeiterable ngày 28, thêmSymbol.asyncIteratorđể hỗ trợfor await...of.
Tuần 5: Classes, Error Handling, Modules
Ngày 31: Class là Syntax Sugar
Mục tiêu: Chứng minh
classtrong JS chỉ là lớp vỏ cú pháp trên prototype.Lý thuyết:
classcompile ra function + prototype method giống hệt cách viết tay ES5.Thực hành: Viết 1 class ES6 rồi viết lại chính xác behavior tương đương bằng constructor function + prototype (không dùng
class).
Ngày 32: Error Handling & Custom Error
Mục tiêu: Xử lý lỗi có cấu trúc, phân biệt được loại lỗi bằng custom Error class.
Lý thuyết:
try/catch/finally,Errorobject, kế thừaErrorđể tạoValidationError,NotFoundError.Thực hành: Viết 3 custom Error class kế thừa
Error, dùnginstanceofđể catch và xử lý khác nhau theo loại lỗi.
Ngày 33: CommonJS Modules
Mục tiêu: Hiểu cơ chế
require/module.exportshoạt động thế nào trong Node.Lý thuyết: CommonJS đồng bộ, mỗi file là 1 module wrapped trong function, cache module theo path.
Thực hành: Tạo 2 file CommonJS import lẫn nhau (circular dependency), quan sát object rỗng bị trả về khi bị vòng lặp.
Ngày 34: ESM Modules
Mục tiêu: Phân biệt ESM với CommonJS về cú pháp và cơ chế loading.
Lý thuyết:
import/export, static analysis, live binding (khác với CommonJS copy giá trị).Thực hành: Chuyển đổi bài tập ngày 33 sang ESM, quan sát live binding khi sửa biến export.
Ngày 35: Module Resolution - Ôn tập tuần 5
Mục tiêu: Hiểu Node tìm và load 1 module (
require('lodash')) qua các bước nào.Lý thuyết: Resolution: relative path → node_modules lookup lên từng cấp thư mục cha → package.json
main/exports.Thực hành: Tạo cấu trúc thư mục node_modules giả lập 2 cấp, trace tay xem Node tìm package theo thứ tự nào.
Tuần 6: Functional Programming & Design Patterns
Ngày 36: Pure Function & Immutability
Mục tiêu: Viết hàm pure và tránh mutation không chủ đích.
Lý thuyết: Pure function (không side effect), Immutability (spread,
Object.freeze).Thực hành: Refactor 1 hàm impure (mutate array đầu vào) thành pure function trả về array mới.
Ngày 37: Currying & Composition
Mục tiêu: Viết hàm currying và compose nhiều hàm nhỏ thành pipeline.
Lý thuyết: Currying biến hàm nhiều tham số thành chuỗi hàm 1 tham số;
compose/pipe.Thực hành: Viết hàm
curry(fn)generic vàpipe(...fns), dùng xử lý pipeline biến đổi string.
Ngày 38: Factory / Builder / Singleton Pattern
Mục tiêu: Nhận biết khi nào nên dùng Factory, Builder, hay Singleton.
Lý thuyết: Factory tạo object linh hoạt; Builder tách khởi tạo phức tạp thành từng bước; Singleton đảm bảo duy nhất 1 instance.
Thực hành: Viết Builder pattern để tạo object
HttpRequestqua chuỗi.setMethod().setUrl()...build().
Ngày 39: Observer & Strategy Pattern
Mục tiêu: Áp dụng 2 pattern phổ biến trong hệ thống event-driven và pluggable logic.
Lý thuyết: Observer (pub/sub), Strategy (thay đổi thuật toán runtime).
Thực hành: Viết mini EventEmitter theo Observer pattern; viết Strategy pattern cho tính phí ship.
Ngày 40: Adapter & Decorator - Ôn tập tổng hợp Phase 1
Mục tiêu: Áp dụng Adapter/Decorator, tổng kết toàn bộ Phase 1.
Lý thuyết: Adapter (chuyển đổi interface không tương thích), Decorator (bọc thêm behavior không sửa code gốc).
Thực hành: Viết Decorator function bọc quanh 1 hàm để log thời gian thực thi; tự đặt 15 câu hỏi review Phase 1 và tự trả lời không xem tài liệu.
PHASE 2 - JavaScript Internals (Ngày 41-70)
Tuần 7: Execution Context, Lexical Environment, Hoisting
Ngày 41: Execution Context sâu
Mục tiêu: Hiểu 2 giai đoạn Creation Phase và Execution Phase khi engine chạy 1 function.
Lý thuyết: Creation Phase (hoist + tạo scope) vs Execution Phase (chạy tuần tự, gán giá trị).
Thực hành: Trace tay Creation Phase cho 1 hàm có
var,let, và tham số, liệt kê giá trị từng biến trước khi dòng code đầu tiên chạy.
Ngày 42: Lexical Environment & Environment Record
Mục tiêu: Hiểu cấu trúc bên trong lưu trữ biến của mỗi context.
Lý thuyết: Lexical Environment = Environment Record + reference tới outer environment.
Thực hành: Vẽ sơ đồ Lexical Environment cho 3 hàm lồng nhau, chỉ rõ outer reference của từng cấp.
Ngày 43: Scope Chain chi tiết
Mục tiêu: Hiểu scope chain được resolve tại thời điểm định nghĩa hàm (lexical scoping), không phải lúc gọi.
Lý thuyết: Lexical scoping vs Dynamic scoping (JS dùng lexical).
Thực hành: Viết ví dụ chứng minh JS lexical scoping bằng cách gọi 1 hàm ở 2 vị trí scope khác nhau, xem biến resolve tới đâu.
Ngày 44: Hoisting var vs let/const
Mục tiêu: Giải thích khác biệt về hoisting giữa var/let/const dưới góc độ Environment Record.
Lý thuyết: var hoist + init
undefined; let/const hoist nhưng ở TDZ (uninitialized).Thực hành: Viết bảng so sánh timeline hoisting của var/let/const/function declaration trong cùng 1 block.
Ngày 45: Hoisting Function Declaration - Ôn tập tuần 7
Mục tiêu: Hiểu vì sao có thể gọi function declaration trước khi nó được định nghĩa trong code.
Lý thuyết: Function declaration được hoist toàn bộ (cả body); function expression thì không.
Thực hành: Viết code gọi 1 function declaration và 1 function expression trước dòng khai báo, so sánh kết quả và giải thích.
Tuần 8: Event Loop
Ngày 46: Call Stack & Task Queue
Mục tiêu: Hiểu Event Loop lấy task từ đâu khi Call Stack rỗng.
Lý thuyết: Call Stack, Task Queue (Macrotask), Event Loop kiểm tra Call Stack rỗng rồi mới lấy task tiếp theo.
Thực hành: Viết code có
setTimeoutlồng trong vòng lặp đồng bộ dài, quan sát vì sao callback bị delay hơn thời gian đặt.
Ngày 47: Microtask Queue
Mục tiêu: Phân biệt Microtask Queue với Task Queue (Macrotask) và độ ưu tiên giữa chúng.
Lý thuyết: Microtask Queue (Promise callbacks) luôn chạy hết trước khi lấy Macrotask tiếp theo.
Thực hành: Viết code trộn
Promise.thenvàsetTimeout(fn, 0), dự đoán thứ tự in ra trước khi chạy thử.
Ngày 48: Promise Execution Order
Mục tiêu: Trace chính xác thứ tự chạy khi có nhiều Promise chain lồng nhau.
Lý thuyết: Mỗi
.then()tạo 1 microtask mới, chain dài sẽ "chia nhỏ" qua nhiều vòng microtask.Thực hành: Viết 3 Promise chain lồng nhau khác độ sâu, dự đoán và kiểm chứng thứ tự log.
Ngày 49: setTimeout vs queueMicrotask
Mục tiêu: Hiểu khi nào nên dùng
queueMicrotaskthay vìsetTimeout(fn, 0).Lý thuyết:
queueMicrotaskchạy sớm hơn (trước khi nhường control cho render/IO), dùng cho việc cần chạy "ngay sau" code hiện tại.Thực hành: Viết ví dụ so sánh độ trễ giữa
queueMicrotaskvàsetTimeout(fn, 0)trong 1 vòng lặp có nhiều task.
Ngày 50: Bài tập trace Event Loop tổng hợp - Ôn tập tuần 8
Mục tiêu: Tự tin trace được thứ tự log của 1 đoạn code phức tạp trộn sync/async/microtask/macrotask.
Lý thuyết: Review toàn bộ Event Loop.
Thực hành: Giải 5 bài "đoán output" trộn
console.log,setTimeout,Promise,async/await(tự soạn hoặc tìm trên mạng), tự chấm điểm.
Tuần 9: Async Programming & Tự implement Promise
Ngày 51: Callback Pattern & Callback Hell
Mục tiêu: Nhận diện callback hell và hiểu vì sao nó khó maintain.
Lý thuyết: Callback pattern, "Pyramid of Doom", error-first callback convention của Node.
Thực hành: Viết 1 chuỗi 4 thao tác bất đồng bộ lồng callback (giả lập bằng setTimeout) để tự cảm nhận callback hell.
Ngày 52: Promise Cơ Bản
Mục tiêu: Sử dụng thành thạo
then/catch/finallyvà Promise combinators.Lý thuyết: Promise states (pending/fulfilled/rejected),
Promise.all,Promise.race,Promise.allSettled.Thực hành: Viết lại bài callback hell ngày 51 bằng Promise chain, thêm 1 ví dụ dùng
Promise.allđể chạy song song.
Ngày 53: Async/Await
Mục tiêu: Viết code bất đồng bộ trông giống đồng bộ, xử lý lỗi đúng cách với try/catch.
Lý thuyết:
async/awaitlà syntax sugar trên Promise, cách xử lý lỗi bằng try/catch thay vì.catch().Thực hành: Viết lại bài Promise chain ngày 52 bằng async/await, thêm xử lý lỗi bằng try/catch.
Ngày 54: Tự Implement Promise (Phần 1 - resolve/reject/then cơ bản)
Mục tiêu: Hiểu cơ chế bên trong Promise bằng cách tự viết class Promise đơn giản.
Lý thuyết: State machine của Promise (pending → fulfilled/rejected, không thể đổi ngược), lưu callback khi còn pending.
Thực hành: Viết class
MyPromisevới constructor nhận executor, implementresolve/reject, vàthencơ bản (chưa cần chaining).
Ngày 55: Tự Implement Promise (Phần 2 - chaining & microtask) - Ôn tập tuần 9
Mục tiêu: Hoàn thiện
MyPromisehỗ trợ chaining nhiều.then()và chạy callback bất đồng bộ đúng như Promise thật.Lý thuyết: Mỗi
.then()phải trả về 1 Promise mới để chain được; dùngqueueMicrotaskđể giả lập hành vi bất đồng bộ.Thực hành: Hoàn thiện
MyPromisehỗ trợ.then().then().catch()chaining, test với ví dụ ngày 52 để đảm bảo behavior giống Promise gốc.
Tuần 10: Memory Management & Garbage Collection
Ngày 56: Stack vs Heap Memory (nâng cao)
Mục tiêu: Ôn lại và đào sâu Stack/Heap dưới góc độ engine quản lý bộ nhớ thực tế.
Lý thuyết: V8 chia Heap thành các "space" (New Space, Old Space...), Stack có kích thước giới hạn cố định.
Thực hành: Dùng Node
--stack-sizehoặc gây stack overflow có chủ đích, quan sát error message và giải thích.
Ngày 57: Garbage Collection - Mark & Sweep
Mục tiêu: Hiểu thuật toán GC cơ bản nhất mà V8 dựa trên.
Lý thuyết: Mark & Sweep - đánh dấu object còn reachable từ root, quét dọn object không reachable.
Thực hành: Vẽ sơ đồ object graph có 1 vòng tham chiếu (circular reference) không còn root, giải thích vì sao Mark & Sweep vẫn dọn được (khác reference counting).
Ngày 58: Generational GC
Mục tiêu: Hiểu tại sao V8 chia Young Generation và Old Generation để tối ưu GC.
Lý thuyết: Generational hypothesis (đa số object chết trẻ), Scavenge GC cho Young Gen, Mark-Compact cho Old Gen.
Thực hành: Đọc 1 bài viết giải thích Generational GC của V8, tóm tắt lại bằng 5 gạch đầu dòng theo lời văn của mình.
Ngày 59: Debug Closure Leak
Mục tiêu: Nhận diện memory leak gây ra bởi closure giữ reference không cần thiết.
Lý thuyết: Closure leak - closure "vô tình" giữ tham chiếu tới object lớn không dùng tới.
Thực hành: Viết đoạn code có closure leak, dùng Chrome DevTools Memory tab chụp heap snapshot trước/sau để phát hiện.
Ngày 60: Debug Event Listener Leak - Ôn tập tuần 10
Mục tiêu: Nhận diện và fix leak do quên gỡ event listener.
Lý thuyết: Event listener leak phổ biến trong SPA khi component unmount nhưng không
removeEventListener.Thực hành: Viết ví dụ leak do add listener liên tục không remove, fix bằng cách lưu reference và cleanup đúng cách.
Tuần 11: V8 Engine
Ngày 61: Parser & AST
Mục tiêu: Hiểu bước đầu tiên V8 xử lý source code.
Lý thuyết: Parser biến source code thành Abstract Syntax Tree (AST); lazy parsing cho hàm chưa cần chạy ngay.
Thực hành: Dùng công cụ online (AST Explorer) paste 1 đoạn code JS, quan sát cấu trúc AST sinh ra.
Ngày 62: Ignition (Interpreter)
Mục tiêu: Hiểu vai trò của Ignition trong việc chạy code nhanh chóng ban đầu.
Lý thuyết: Ignition biên dịch AST thành bytecode và interpret trực tiếp, ưu tiên startup nhanh hơn tối ưu tối đa.
Thực hành: Tóm tắt bằng lời văn của mình sự khác biệt giữa interpreter và compiler dựa trên vai trò của Ignition.
Ngày 63: TurboFan (JIT Compiler)
Mục tiêu: Hiểu cách V8 tối ưu code "hot" (chạy nhiều lần) bằng JIT compilation.
Lý thuyết: TurboFan optimize code hot thành machine code; deoptimization khi giả định sai (vd type thay đổi).
Thực hành: Viết ví dụ 1 hàm bị deoptimize do thay đổi shape của tham số giữa các lần gọi (monomorphic → polymorphic).
Ngày 64: Inline Caching & Hidden Classes
Mục tiêu: Hiểu vì sao giữ object có "shape" cố định giúp code chạy nhanh hơn.
Lý thuyết: Hidden Classes (Shapes) V8 tạo ra để tối ưu truy cập property; Inline Caching cache lại vị trí property đã tra cứu.
Thực hành: Viết ví dụ 2 object cùng property nhưng khác thứ tự khởi tạo, giải thích vì sao chúng có hidden class khác nhau và ảnh hưởng performance.
Ngày 65: Đọc V8 Blog - Ôn tập tuần 11
Mục tiêu: Tổng hợp toàn bộ kiến thức V8 internals qua nguồn chính thống.
Lý thuyết: Review Parser/AST/Ignition/TurboFan/Hidden Classes.
Thực hành: Đọc 1 bài viết trên V8 Blog (v8.dev/blog) liên quan tới performance, viết tóm tắt 5-7 câu bằng lời văn của mình.
Tuần 12: ECMAScript Specification
Ngày 66: Cấu trúc ECMAScript Spec
Mục tiêu: Biết cách điều hướng trong tài liệu spec chính thức (tc39.es/ecma262).
Lý thuyết: Spec chia theo Abstract Operations, cấu trúc mỗi section mô tả step-by-step algorithm.
Thực hành: Mở spec, tìm section định nghĩa
typeofoperator, đọc qua các bước.
Ngày 67: Đọc Spec - Array.prototype.map
Mục tiêu: Đọc hiểu 1 spec algorithm thực tế của hàm quen thuộc.
Lý thuyết: Cách spec mô tả từng bước xử lý của
Array.prototype.map(kiểm tra callable, tạo array mới, loop qua index...).Thực hành: Đọc spec
Array.prototype.map, so sánh với implementation tự viết ở Ngày 26, liệt kê điểm khác biệt (vd xử lý sparse array).
Ngày 68: Đọc Spec - Promise
Mục tiêu: Đọc hiểu spec định nghĩa PromiseReactionJob và các Abstract Operation liên quan.
Lý thuyết: Spec định nghĩa Promise dựa trên các Job (giống khái niệm microtask).
Thực hành: Đọc phần spec về
NewPromiseCapabilityvàPromiseReactionJob, so sánh vớiMyPromiseđã viết ở Ngày 54-55.
Ngày 69: So Sánh Spec vs Implementation Thực Tế
Mục tiêu: Hiểu rằng V8 không nhất thiết implement y hệt spec từng bước, miễn observable behavior đúng.
Lý thuyết: Spec định nghĩa "observable behavior" chứ không bắt buộc implementation detail.
Thực hành: Chọn 1 hàm bất kỳ, so sánh giữa đọc spec và test hành vi thực tế trên V8 (Node), ghi chú điểm giống/khác.
Ngày 70: Ôn Tập Tổng Hợp Phase 2
Mục tiêu: Kết nối Execution Context + Event Loop + Memory + V8 Internals + Spec thành bức tranh hoàn chỉnh.
Lý thuyết: Review toàn bộ Phase 2.
Thực hành: Viết 1 bài "self-explainer" (dạng blog cá nhân, không cần publish) giải thích cho người mới vì sao hiểu Event Loop + GC quan trọng khi debug production.
PHASE 3 - Browser Runtime (Ngày 71-95)
Tuần 13: DOM & Event System
Ngày 71: DOM Tree Structure
Mục tiêu: Hiểu DOM là 1 cây object đại diện cho HTML, không phải chính HTML.
Lý thuyết: Node, Element, Text node, Document; cấu trúc cây cha-con.
Thực hành: Mở DevTools Elements tab, dùng
document.body.childNodesso sánh với những gì thấy trên UI, giải thích whitespace text node.
Ngày 72: DOM API Thao Tác
Mục tiêu: Thao tác DOM thành thạo bằng vanilla JS (không dùng framework).
Lý thuyết:
querySelector/querySelectorAll,createElement,appendChild,remove.Thực hành: Viết 1 to-do list đơn giản bằng vanilla JS thao tác DOM trực tiếp (không React/Vue).
Ngày 73: Event Capturing & Bubbling
Mục tiêu: Hiểu 3 pha của 1 sự kiện DOM: capturing → target → bubbling.
Lý thuyết:
addEventListener(type, handler, useCapture),stopPropagation.Thực hành: Viết 3 element lồng nhau, đăng ký listener ở cả capturing và bubbling phase, log thứ tự thực thi.
Ngày 74: Event Delegation
Mục tiêu: Áp dụng event bubbling để tối ưu số lượng listener cần đăng ký.
Lý thuyết: Event delegation - đăng ký 1 listener ở parent thay vì nhiều listener ở từng child.
Thực hành: Refactor to-do list ngày 72 để dùng event delegation (1 listener duy nhất ở
<ul>xử lý click xoá item).
Ngày 75: Ôn Tập Tuần 13
Mục tiêu: Củng cố DOM + Event system qua 1 bài tập tổng hợp.
Lý thuyết: Review DOM tree, Event capturing/bubbling, delegation.
Thực hành: Hoàn thiện to-do list thành app đầy đủ (add/toggle/delete/filter) chỉ dùng vanilla JS + event delegation.
Tuần 14: Browser Rendering Pipeline
Ngày 76: HTML Parsing → DOM
Mục tiêu: Hiểu trình duyệt biến HTML text thành DOM tree qua bước nào.
Lý thuyết: Tokenizing → Tree construction; xử lý HTML lỗi (tag không đóng) thế nào.
Thực hành: Viết 1 file HTML cố tình thiếu tag đóng, quan sát DOM tree kết quả trong DevTools để thấy trình duyệt tự sửa.
Ngày 77: CSSOM & Render Tree
Mục tiêu: Hiểu Render Tree là sự kết hợp giữa DOM và CSSOM.
Lý thuyết: CSSOM (CSS Object Model), Render Tree chỉ chứa node visible (loại bỏ
display: none).Thực hành: Viết ví dụ có element
display:nonevàvisibility:hidden, giải thích khác biệt của chúng trong Render Tree.
Ngày 78: Layout (Reflow)
Mục tiêu: Hiểu Layout tính toán vị trí/kích thước, và nguyên nhân gây reflow không cần thiết.
Lý thuyết: Layout (Reflow) - tính toán geometry; các thao tác JS đọc layout property (
offsetHeight) gây forced synchronous layout.Thực hành: Viết ví dụ vòng lặp đọc
offsetHeightliên tục trong lúc sửa style (layout thrashing), quan sát Performance tab.
Ngày 79: Paint & Composite
Mục tiêu: Phân biệt Paint và Composite, hiểu vì sao
transform/opacitymượt hơn thay đổitop/left.Lý thuyết: Paint (vẽ pixel), Composite (ghép layer trên GPU); property nào chỉ cần composite (không cần layout/paint lại).
Thực hành: Viết 2 animation cùng hiệu ứng di chuyển: 1 dùng
left, 1 dùngtransform, so sánh trong Performance tab (FPS, layer nào bị invalidate).
Ngày 80: Tối Ưu Rendering Performance - Ôn Tập Tuần 14
Mục tiêu: Áp dụng hiểu biết pipeline để viết code render mượt hơn.
Lý thuyết: Batch DOM read/write, tránh layout thrashing, ưu tiên property composite-only cho animation.
Thực hành: Refactor animation ngày 79 áp dụng
requestAnimationFramevà tách biệt đọc/ghi DOM.
Tuần 15: Networking & CORS
Ngày 81: Fetch API
Mục tiêu: Sử dụng thành thạo
fetchvới các option phổ biến (method, headers, body).Lý thuyết:
fetchtrả về Promise, cần checkresponse.okthủ công (fetch không tự throw khi status lỗi).Thực hành: Viết wrapper
apiFetch(url, options)tự động throw Error khi!response.ok, parse JSON, xử lý timeout bằngAbortController.
Ngày 82: XMLHttpRequest
Mục tiêu: Hiểu XHR - API cũ hơn fetch, vẫn còn dùng trong 1 số thư viện (vd upload progress).
Lý thuyết: XHR dùng callback/event thay vì Promise; ưu điểm hỗ trợ progress event mà fetch (cũ) không có.
Thực hành: Viết 1 request bằng XHR thuần, so sánh code với bản fetch tương đương ở Ngày 81.
Ngày 83: CORS - Origin
Mục tiêu: Hiểu khái niệm "same-origin" và vì sao trình duyệt chặn request cross-origin theo mặc định.
Lý thuyết: Origin = scheme + host + port; Same-Origin Policy là cơ chế bảo mật của trình duyệt (không phải server).
Thực hành: Gọi thử
fetchtới 1 API cross-origin không hỗ trợ CORS, đọc lỗi CORS trong console, giải thích chính xác nghĩa của lỗi.
Ngày 84: CORS - Preflight Request
Mục tiêu: Hiểu khi nào trình duyệt tự gửi preflight request (
OPTIONS) trước request thật.Lý thuyết: Simple request vs Preflighted request, header
Access-Control-Allow-*.Thực hành: Gửi 1 request có custom header (vd
Content-Type: application/jsonvới PUT) tới API hỗ trợ CORS, quan sát requestOPTIONSxuất hiện trước trong Network tab.
Ngày 85: Ôn Tập Tuần 15
Mục tiêu: Củng cố Networking + CORS qua 1 bài tập thực tế.
Lý thuyết: Review Fetch/XHR/CORS.
Thực hành: Viết 1 trang gọi API thật (public API bất kỳ), xử lý đầy đủ loading/error state và giải thích nếu gặp lỗi CORS thì cách nào để fix (server-side, không phải client-side).
Tuần 16: Browser Storage & Cookies
Ngày 86: localStorage & sessionStorage
Mục tiêu: Phân biệt và sử dụng đúng 2 loại Web Storage.
Lý thuyết: localStorage (persist vô hạn), sessionStorage (mất khi đóng tab); giới hạn ~5-10MB, đồng bộ (blocking).
Thực hành: Viết ví dụ lưu theme preference (dark/light) vào localStorage, giữ nguyên sau khi reload trang.
Ngày 87: IndexedDB
Mục tiêu: Hiểu khi nào cần IndexedDB thay vì localStorage (dữ liệu lớn, có cấu trúc, cần query).
Lý thuyết: IndexedDB là NoSQL database bất đồng bộ trong trình duyệt, object store, transaction.
Thực hành: Viết ví dụ cơ bản lưu 1 danh sách object vào IndexedDB và đọc lại (có thể dùng thư viện
idbđể đơn giản hoá).
Ngày 88: Cookie Attributes
Mục tiêu: Cấu hình cookie an toàn với các attribute quan trọng.
Lý thuyết:
Secure(chỉ gửi qua HTTPS),HttpOnly(JS không đọc được, chống XSS đánh cắp cookie).Thực hành: Viết 1 Node server nhỏ set cookie với
HttpOnlyvà không có, thử đọc bằngdocument.cookieđể thấy khác biệt.
Ngày 89: SameSite Cookie
Mục tiêu: Hiểu SameSite giúp chống CSRF thế nào.
Lý thuyết:
SameSite=Strict/Lax/None, ảnh hưởng tới cookie khi request cross-site.Thực hành: Đọc tài liệu MDN về SameSite, viết bảng so sánh 3 giá trị và tình huống nên dùng loại nào.
Ngày 90: Ôn Tập Tuần 16
Mục tiêu: Tổng hợp các cơ chế lưu trữ phía client.
Lý thuyết: Review Storage + Cookie.
Thực hành: Thiết kế bảng so sánh localStorage/sessionStorage/IndexedDB/Cookie theo tiêu chí: dung lượng, thời gian sống, gửi kèm request hay không, dùng cho trường hợp nào.
Tuần 17: Browser Security
Ngày 91: XSS (Cross-Site Scripting)
Mục tiêu: Nhận diện lỗ hổng XSS và cách phòng chống cơ bản.
Lý thuyết: Stored/Reflected/DOM-based XSS; nguyên nhân gốc là render input người dùng không escape.
Thực hành: Viết 1 trang demo lỗi XSS (render
innerHTMLtừ input không escape), sau đó fix bằng cách dùngtextContenthoặc escape HTML.
Ngày 92: CSRF (Cross-Site Request Forgery)
Mục tiêu: Hiểu cơ chế tấn công CSRF và cách phòng chống.
Lý thuyết: CSRF lợi dụng cookie tự động gửi kèm request; phòng chống bằng CSRF token, SameSite cookie.
Thực hành: Vẽ sơ đồ minh hoạ 1 kịch bản tấn công CSRF thực tế (vd form chuyển khoản), chỉ ra điểm phòng thủ.
Ngày 93: CSP (Content Security Policy)
Mục tiêu: Cấu hình CSP header để giảm thiểu rủi ro XSS.
Lý thuyết: CSP header khai báo nguồn được phép load script/style/image.
Thực hành: Viết 1 CSP header cơ bản (
default-src 'self') cho 1 trang demo, thử nghiệm nó chặn inline script như thế nào.
Ngày 94: Thực Hành Phòng Chống XSS/CSRF
Mục tiêu: Áp dụng tổng hợp các biện pháp phòng thủ vào 1 form thực tế.
Lý thuyết: Review kết hợp escape output + CSRF token + SameSite cookie + CSP.
Thực hành: Xây 1 form nhỏ (Node server) áp dụng đầy đủ: escape output, CSRF token, cookie SameSite=Strict.
Ngày 95: Ôn Tập Tổng Hợp Phase 3
Mục tiêu: Kết nối DOM + Rendering + Networking + Security thành bức tranh Browser Runtime hoàn chỉnh.
Lý thuyết: Review toàn bộ Phase 3.
Thực hành: Tự đặt và trả lời 10 câu hỏi phỏng vấn thường gặp về browser (event loop trong browser, CORS, XSS/CSRF, rendering pipeline).
PHASE 4 - Node.js Internals (Ngày 96-125)
Tuần 18: Node Architecture & Event Loop Phases
Ngày 96: Node Architecture Tổng Quan
Mục tiêu: Hiểu 3 thành phần cốt lõi tạo nên Node.js runtime.
Lý thuyết: V8 (chạy JS) + libuv (async I/O, thread pool, event loop) + Node bindings/APIs (fs, net, http...).
Thực hành: Vẽ sơ đồ kiến trúc Node (V8 + libuv + Node APIs) và giải thích luồng đi của 1 lệnh
fs.readFile.
Ngày 97: libuv & Thread Pool
Mục tiêu: Hiểu vì sao Node "single-threaded" nhưng vẫn xử lý I/O song song được.
Lý thuyết: libuv dùng thread pool (mặc định 4 thread) cho các tác vụ blocking (fs, crypto, DNS lookup...).
Thực hành: Viết code gọi 5
fs.readFilecùng lúc trên file lớn, thử tăngUV_THREADPOOL_SIZEvà so sánh thời gian hoàn thành.
Ngày 98: Event Loop Phases - Timers
Mục tiêu: Hiểu Node Event Loop có nhiều "phase" khác với model đơn giản của browser.
Lý thuyết: Phase Timers xử lý callback của
setTimeout/setIntervalđã đến hạn.Thực hành: Viết code với
setTimeout(fn, 0)vàsetImmediate(fn)gọi cùng lúc ở top-level, chạy nhiều lần quan sát thứ tự không cố định - giải thích vì sao.
Ngày 99: Event Loop Phases - Poll & Check
Mục tiêu: Hiểu phase Poll (xử lý I/O callback) và Check (setImmediate) diễn ra khi nào.
Lý thuyết: Poll phase chờ và xử lý I/O event; Check phase chạy ngay sau Poll, dành riêng cho
setImmediate.Thực hành: Đặt
setTimeout/setImmediatebên trong callback củafs.readFile, quan sát thứ tự cố định (setImmediate luôn chạy trước trong ngữ cảnh I/O).
Ngày 100: So Sánh Event Loop Browser vs Node - Ôn Tập Tuần 18
Mục tiêu: Tổng hợp khác biệt giữa Event Loop của trình duyệt và Node.
Lý thuyết: Review Timers/Poll/Check/Close callbacks phase của Node vs model Task/Microtask của browser.
Thực hành: Viết bảng so sánh 2 model, kèm 1 đoạn code ví dụ chạy khác nhau (nếu có) giữa 2 môi trường.
Tuần 19: Streams
Ngày 101: Readable Stream
Mục tiêu: Hiểu cách đọc dữ liệu lớn theo chunk thay vì load hết vào memory.
Lý thuyết: Readable Stream, event
data/end, flowing vs paused mode.Thực hành: Đọc 1 file lớn bằng
fs.createReadStream, log ra kích thước từng chunk nhận được.
Ngày 102: Writable Stream
Mục tiêu: Ghi dữ liệu theo stream, hiểu backpressure là gì.
Lý thuyết: Writable Stream,
write()trả vềfalsekhi buffer đầy (backpressure), eventdrain.Thực hành: Viết 1 file lớn bằng
fs.createWriteStream, xử lý backpressure đúng cách bằng cách chờ eventdrain.
Ngày 103: Duplex & Transform Stream
Mục tiêu: Hiểu Stream có thể vừa đọc vừa ghi, và biến đổi dữ liệu khi đi qua.
Lý thuyết: Duplex (đọc+ghi độc lập), Transform (đọc→biến đổi→ghi, vd
zlib.createGzip).Thực hành: Viết 1 Transform Stream tự custom để chuyển toàn bộ text thành uppercase khi pipe qua.
Ngày 104: Tự Viết cat Clone
Mục tiêu: Ứng dụng Readable +
pipe()để đọc và in nội dung file ra stdout.Lý thuyết:
pipe()tự động xử lý backpressure giữa Readable và Writable.Thực hành: Viết CLI script Node đọc file truyền qua argument và in ra
process.stdoutbằngpipe().
Ngày 105: Tự Viết grep Clone - Ôn Tập Tuần 19
Mục tiêu: Kết hợp Readable + Transform để lọc dòng theo pattern, giống lệnh
grep.Lý thuyết: Xử lý stream theo dòng (line-by-line) cần buffer tạm các chunk chưa đủ 1 dòng.
Thực hành: Viết CLI script nhận file + keyword, dùng Transform Stream lọc và chỉ in ra các dòng chứa keyword.
Tuần 20: Buffer, File System, Path
Ngày 106: Buffer & Binary Data
Mục tiêu: Hiểu Buffer là vùng nhớ nhị phân thô Node dùng để xử lý dữ liệu ngoài chuỗi (file, network).
Lý thuyết: Buffer là mảng byte cố định, khác với Array thông thường;
Buffer.from,Buffer.alloc.Thực hành: Viết code chuyển đổi qua lại giữa string và Buffer, thử ghi từng byte vào Buffer và đọc ra bằng các encoding khác nhau.
Ngày 107: Encoding
Mục tiêu: Hiểu các loại encoding phổ biến (utf8, base64, hex) và khi nào dùng loại nào.
Lý thuyết: UTF-8 (text), Base64 (truyền dữ liệu nhị phân qua kênh text), Hex (debug/hash).
Thực hành: Viết hàm mã hoá 1 ảnh nhỏ sang base64 string và giải mã lại thành file, so sánh checksum trước/sau.
Ngày 108: fs Module
Mục tiêu: Sử dụng thành thạo
fsvới cả API callback, Promise và sync.Lý thuyết:
fs.readFile(callback) vsfs/promisesvsfs.readFileSync; khi nào chấp nhận dùng sync (chỉ ở startup script).Thực hành: Viết script đọc/ghi/xoá file dùng
fs/promises, xử lý lỗi bằng try/catch với async/await.
Ngày 109: path Module
Mục tiêu: Xử lý đường dẫn file cross-platform đúng cách.
Lý thuyết:
path.join,path.resolve,path.extname,__dirname/import.meta.url.Thực hành: Viết hàm liệt kê toàn bộ file
.jstrong 1 thư mục (đệ quy), dùngpath.joinđể tránh lỗi separator giữa Windows/Linux.
Ngày 110: Ôn Tập Tuần 20
Mục tiêu: Kết hợp Buffer + fs + path vào 1 bài tập thực tế.
Lý thuyết: Review Buffer/Encoding/fs/path.
Thực hành: Viết script đọc 1 thư mục ảnh, convert từng ảnh sang base64 và lưu thành 1 file JSON manifest.
Tuần 21: Process, Worker Threads, Cluster
Ngày 111: process Object
Mục tiêu: Sử dụng
processđể tương tác với môi trường chạy Node (env, argv, exit).Lý thuyết:
process.env,process.argv,process.exit, eventuncaughtException.Thực hành: Viết CLI script đọc argument và biến môi trường, xử lý graceful shutdown khi nhận
SIGINT.
Ngày 112: child_process
Mục tiêu: Chạy 1 tiến trình con từ Node (vd gọi lệnh shell hoặc script khác).
Lý thuyết:
exec,spawn,fork- khác biệt về buffer output và use case.Thực hành: Viết script dùng
spawnđể chạy 1 lệnh hệ thống (vdlshoặcgit status) và stream output real-time ra console.
Ngày 113: Worker Threads
Mục tiêu: Chạy CPU-bound task song song mà không block Event Loop chính.
Lý thuyết: Worker Threads chạy trên thread riêng, giao tiếp qua message passing (không share memory trực tiếp trừ SharedArrayBuffer).
Thực hành: Viết 1 tác vụ tính toán nặng (vd tính số Fibonacci lớn), so sánh thời gian block Event Loop chính khi chạy trực tiếp vs chạy trong Worker Thread.
Ngày 114: Cluster API
Mục tiêu: Tận dụng multi-core CPU bằng cách fork nhiều process Node.
Lý thuyết: Cluster tạo nhiều worker process share cùng port, load balance theo round-robin (trên Linux).
Thực hành: Viết 1 HTTP server đơn giản, dùng Cluster fork theo số CPU core, kiểm tra bằng
os.cpus().lengthvà log raprocess.pidmỗi request.
Ngày 115: Ôn Tập Tuần 21
Mục tiêu: Phân biệt rõ khi nào dùng Worker Threads vs Cluster vs child_process.
Lý thuyết: Review 3 cơ chế parallel/concurrency của Node.
Thực hành: Viết bảng so sánh Worker Threads/Cluster/child_process theo tiêu chí: use case, chia sẻ memory, overhead khởi tạo.
Tuần 22: Networking & HTTP Server
Ngày 116: TCP Module
Mục tiêu: Hiểu Node xử lý kết nối TCP thô thế nào (nền tảng của HTTP).
Lý thuyết:
net.createServer, socket connection event, TCP là stream 2 chiều.Thực hành: Viết 1 TCP server đơn giản dùng
netmodule, echo lại dữ liệu client gửi lên (dùngtelnethoặcncđể test).
Ngày 117: UDP Module
Mục tiêu: Hiểu khác biệt giữa TCP (reliable, connection-based) và UDP (connectionless, không đảm bảo).
Lý thuyết:
dgrammodule, use case của UDP (streaming, gaming, DNS).Thực hành: Viết 1 cặp UDP sender/receiver đơn giản dùng
dgram, gửi vài message và log lại.
Ngày 118: Tự Viết HTTP Server (Phần 1 - Parse Request)
Mục tiêu: Hiểu HTTP server thực chất được xây trên nền TCP server.
Lý thuyết:
http.createServernhận request/response object đã được Node parse sẵn từ raw TCP data.Thực hành: Viết 1 HTTP server dùng
http.createServer(), tự parsereq.urlvàreq.methodđể route thủ công (chưa dùng framework).
Ngày 119: Tự Viết HTTP Server (Phần 2 - Routing đơn giản)
Mục tiêu: Thêm khả năng routing cơ bản (GET/POST theo path) cho HTTP server tự viết.
Lý thuyết: So sánh method + path để quyết định handler nào xử lý.
Thực hành: Hoàn thiện server ngày 118 thành 1 mini REST API có 3-4 route (GET/POST) trả JSON, không dùng Express.
Ngày 120: Ôn Tập Tuần 22
Mục tiêu: Củng cố hiểu biết networking layer dưới HTTP framework.
Lý thuyết: Review TCP/UDP/HTTP server thủ công.
Thực hành: Viết sơ đồ minh hoạ luồng dữ liệu từ TCP socket → HTTP parser →
req/resobject trong Node.
Tuần 23: Diagnostics & Debugging
Ngày 121: heapdump
Mục tiêu: Chụp snapshot bộ nhớ heap của 1 Node process đang chạy để phân tích leak.
Lý thuyết: Heap snapshot ghi lại toàn bộ object graph tại 1 thời điểm, dùng để so sánh tìm object tăng bất thường.
Thực hành: Cài package
heapdump(hoặc dùng--inspect+ Chrome DevTools), chụp 2 snapshot cách nhau sau khi chạy code có leak, so sánh.
Ngày 122: Flamegraph
Mục tiêu: Đọc hiểu flamegraph để tìm hàm tốn CPU nhất.
Lý thuyết: Flamegraph biểu diễn call stack theo thời gian, chiều rộng = thời gian chạy.
Thực hành: Dùng
0xhoặcclinic flameprofile 1 script CPU-bound, đọc flamegraph sinh ra và xác định hàm chiếm nhiều thời gian nhất.
Ngày 123: Node Profiler
Mục tiêu: Dùng built-in profiler (
--prof) của Node để phân tích performance.Lý thuyết:
node --profsinh file log,node --prof-processphân tích thành báo cáo đọc được.Thực hành: Chạy
node --proftrên 1 script tính toán nặng, phân tích output bằng--prof-process.
Ngày 124: Node Inspector Debugging
Mục tiêu: Debug Node app bằng Chrome DevTools thay vì chỉ
console.log.Lý thuyết:
node --inspect/--inspect-brk, breakpoint, step over/into/out, watch expression.Thực hành: Chạy 1 script có bug bằng
node --inspect-brk, kết nối Chrome DevTools, đặt breakpoint và trace giá trị biến để tìm bug.
Ngày 125: Ôn Tập Tổng Hợp Phase 4
Mục tiêu: Kết nối Node Architecture + Streams + Process model + Diagnostics thành năng lực debug production thực sự.
Lý thuyết: Review toàn bộ Phase 4.
Thực hành: Viết 1 checklist cá nhân "Khi gặp Node app chạy chậm/leak memory ở production, tôi sẽ kiểm tra theo thứ tự nào" dựa trên công cụ đã học.
PHASE 5 - Production JavaScript (Ngày 126-165)
Tuần 24: TypeScript
Ngày 126: Type System Cơ Bản
Mục tiêu: Nắm được các kiểu dữ liệu cơ bản và cách TypeScript suy luận type (type inference).
Lý thuyết:
string/number/boolean/array/tuple/enum, type inference vs explicit annotation.Thực hành: Chuyển đổi 1 file JS đơn giản (đã viết ở các phase trước) sang TypeScript, thêm annotation cho toàn bộ tham số hàm.
Ngày 127: Interface & Type Alias
Mục tiêu: Định nghĩa shape của object bằng
interface/type, hiểu khi nào dùng loại nào.Lý thuyết:
interfacehỗ trợ declaration merging,typelinh hoạt hơn với union/intersection.Thực hành: Viết
interface Uservàtype ApiResponse<T>cho 1 API response mẫu, áp dụng vào hàm fetch dữ liệu.
Ngày 128: Generics
Mục tiêu: Viết hàm/type generic tái sử dụng được cho nhiều kiểu dữ liệu.
Lý thuyết: Generic type parameter
<T>, constraint (T extends ...).Thực hành: Viết hàm
getProperty<T, K extends keyof T>(obj: T, key: K)generic an toàn kiểu, test với vài object khác nhau.
Ngày 129: Utility Types
Mục tiêu: Sử dụng các utility type built-in để biến đổi type có sẵn.
Lý thuyết:
Partial,Pick,Omit,Readonly,Record.Thực hành: Từ 1
interface Userđầy đủ, tạo raCreateUserDto(Omit id),UpdateUserDto(Partial) bằng utility type thay vì viết lại type mới.
Ngày 130: Ôn Tập Tuần 24
Mục tiêu: Củng cố TypeScript qua việc type hoá 1 module thực tế.
Lý thuyết: Review Type System/Interface/Generics/Utility Types.
Thực hành: Chuyển toàn bộ mini HTTP server đã viết ở Phase 4 (Ngày 118-119) sang TypeScript với type đầy đủ cho request/response.
Tuần 25: Testing & TDD
Ngày 131: Jest Cơ Bản
Mục tiêu: Viết unit test cơ bản với Jest.
Lý thuyết:
describe/it/expect, matcher phổ biến, test lifecycle (beforeEach/afterEach).Thực hành: Viết test cho hàm
memoizeđã viết ở Ngày 20, cover cả case cache hit và cache miss.
Ngày 132: Vitest
Mục tiêu: So sánh Vitest với Jest, biết khi nào nên chọn loại nào.
Lý thuyết: Vitest tương thích API với Jest nhưng chạy nhanh hơn (dùng Vite/esbuild), phù hợp project dùng Vite.
Thực hành: Setup Vitest cho 1 project nhỏ, chạy lại đúng bộ test đã viết ở Ngày 131 và so sánh tốc độ.
Ngày 133: Mocking & Spies
Mục tiêu: Cô lập unit test khỏi dependency bên ngoài (API call, database).
Lý thuyết:
jest.mock,jest.fn(), spy theo dõi số lần gọi hàm.Thực hành: Viết test cho hàm gọi API (dùng
fetch), mockfetchđể test không cần gọi network thật.
Ngày 134: TDD Workflow
Mục tiêu: Thực hành chu trình Red-Green-Refactor.
Lý thuyết: Test-Driven Development - viết test fail trước, code vừa đủ để pass, refactor sau.
Thực hành: Chọn 1 bài toán nhỏ (vd: validate email), viết test trước khi viết implementation, theo đúng chu trình Red-Green-Refactor.
Ngày 135: Thực Hành TDD Module Nhỏ - Ôn Tập Tuần 25
Mục tiêu: Áp dụng TDD cho 1 module có logic phức tạp hơn.
Lý thuyết: Review toàn bộ Testing/TDD.
Thực hành: Dùng TDD viết module tính giá giỏ hàng (áp dụng discount rule), đảm bảo coverage các edge case (giỏ rỗng, discount vượt quá tổng).
Tuần 26: Packaging & SemVer
Ngày 136: npm Cơ Bản
Mục tiêu: Sử dụng npm thành thạo cho việc quản lý dependency.
Lý thuyết:
dependenciesvsdevDependencies,package-lock.json, npm scripts.Thực hành: Khởi tạo 1 project mới, cài vài dependency, viết npm script tuỳ chỉnh trong
package.json.
Ngày 137: pnpm & Workspace
Mục tiêu: Hiểu ưu điểm của pnpm so với npm, đặc biệt trong monorepo.
Lý thuyết: pnpm dùng content-addressable store tiết kiệm disk, hỗ trợ workspace cho monorepo.
Thực hành: Setup 1 monorepo nhỏ bằng pnpm workspace gồm 2 package (vd
packages/utilsvàpackages/appdùng chung utils).
Ngày 138: SemVer
Mục tiêu: Đọc hiểu version number và ký hiệu range trong
package.json.Lý thuyết:
MAJOR.MINOR.PATCH, ký hiệu^/~, breaking change convention.Thực hành: Viết bảng liệt kê 5 version range khác nhau (
^1.2.3,~1.2.3,1.x...) và giải thích version nào được phép install.
Ngày 139: package.json Chi Tiết
Mục tiêu: Hiểu đầy đủ các field quan trọng trong
package.jsoncho 1 package production.Lý thuyết:
main,exports,types,engines,peerDependencies.Thực hành: Viết
package.jsonhoàn chỉnh cho 1 package thư viện nhỏ dự định publish lên npm (kể cả chưa publish thật).
Ngày 140: Ôn Tập Tuần 26
Mục tiêu: Củng cố toàn bộ kiến thức packaging.
Lý thuyết: Review npm/pnpm/SemVer/package.json.
Thực hành: Tự publish thử 1 package đơn giản lên npm registry (dùng tên scope riêng để tránh trùng) hoặc dry-run bằng
npm pack.
Tuần 27: Build Tools & Bundlers
Ngày 141: Babel
Mục tiêu: Hiểu vai trò của Babel trong việc transpile code mới sang code tương thích trình duyệt cũ.
Lý thuyết: Babel dùng AST transform (giống Ngày 61), plugin/preset (
@babel/preset-env).Thực hành: Viết 1 file dùng optional chaining
?., cấu hình Babel transpile xuống ES5, so sánh output.
Ngày 142: SWC & esbuild
Mục tiêu: Hiểu vì sao các công cụ build thế hệ mới (viết bằng Rust/Go) nhanh hơn Babel (viết bằng JS).
Lý thuyết: SWC (Rust), esbuild (Go) - native compiled nên nhanh hơn nhiều so với JS-based tool.
Thực hành: Benchmark transpile cùng 1 codebase bằng Babel vs esbuild, so sánh thời gian.
Ngày 143: Webpack Cơ Bản
Mục tiêu: Cấu hình Webpack cơ bản để bundle 1 ứng dụng.
Lý thuyết: Entry, Output, Loader, Plugin.
Thực hành: Setup Webpack config từ đầu (không dùng CLI generator) để bundle 1 app JS + CSS nhỏ.
Ngày 144: Rollup
Mục tiêu: Hiểu Rollup phù hợp hơn Webpack khi build thư viện (library).
Lý thuyết: Rollup tối ưu cho ESM output và tree-shaking sạch hơn cho library.
Thực hành: Dùng Rollup build package thư viện đã tạo ở Ngày 139 thành cả CJS và ESM output.
Ngày 145: Vite - Ôn Tập Tuần 27
Mục tiêu: Hiểu vì sao Vite trở thành lựa chọn phổ biến cho dev experience (dùng esbuild cho dev, Rollup cho build).
Lý thuyết: Vite dev server dùng native ESM (không cần bundle full khi dev), build production dùng Rollup.
Thực hành: Setup 1 project Vite từ đầu, so sánh tốc độ dev server so với Webpack ở Ngày 143.
Tuần 28: Observability
Ngày 146: Structured Logging
Mục tiêu: Viết log có cấu trúc (JSON) thay vì
console.logtự do.Lý thuyết: Structured logging giúp log dễ parse/search ở production (vd bằng ELK, Datadog).
Thực hành: Tích hợp
pinohoặcwinstonvào 1 Node app, log request đến kèm requestId, method, path, duration.
Ngày 147: Metrics
Mục tiêu: Thu thập metrics cơ bản (request count, latency) cho ứng dụng.
Lý thuyết: Metrics dạng Counter/Gauge/Histogram, chuẩn Prometheus exposition format.
Thực hành: Dùng
prom-clientexpose endpoint/metricsđếm số request và latency histogram cho 1 Express app nhỏ.
Ngày 148: Distributed Tracing
Mục tiêu: Hiểu khái niệm trace/span để theo dõi 1 request đi qua nhiều service.
Lý thuyết: Trace ID, Span, parent-child span relationship.
Thực hành: Đọc tài liệu OpenTelemetry, vẽ sơ đồ 1 request đi qua 3 service (API Gateway → Service A → Service B) với trace/span tương ứng.
Ngày 149: Thực Hành Setup Logging + Metrics
Mục tiêu: Tích hợp logging và metrics vào cùng 1 ứng dụng thực tế.
Lý thuyết: Review Structured logging + Metrics.
Thực hành: Hoàn thiện 1 Express/Fastify app nhỏ có đầy đủ logging (pino) + metrics endpoint (prom-client).
Ngày 150: Ôn Tập Tuần 28
Mục tiêu: Củng cố 3 trụ cột Observability (Log/Metric/Trace).
Lý thuyết: Review toàn bộ tuần 28.
Thực hành: Viết tài liệu ngắn (runbook) mô tả "khi API latency tăng đột biến, tôi sẽ nhìn vào log/metric/trace nào trước".
Tuần 29: Security & Dependency Scanning
Ngày 151: OWASP Top 10 (Phần 1)
Mục tiêu: Nắm 5 lỗ hổng đầu trong danh sách OWASP Top 10.
Lý thuyết: Injection, Broken Authentication, Sensitive Data Exposure, XML External Entities, Broken Access Control.
Thực hành: Với mỗi lỗ hổng, viết 1 ví dụ code JS/Node dễ mắc lỗi và cách fix tương ứng.
Ngày 152: OWASP Top 10 (Phần 2)
Mục tiêu: Nắm 5 lỗ hổng còn lại trong danh sách OWASP Top 10.
Lý thuyết: Security Misconfiguration, XSS, Insecure Deserialization, Vulnerable Components, Insufficient Logging.
Thực hành: Kiểm tra 1 project Node thực tế của bạn theo checklist 10 mục OWASP, ghi chú điểm nào chưa đạt.
Ngày 153: npm audit & Dependency Scanning
Mục tiêu: Phát hiện lỗ hổng bảo mật trong dependency của project.
Lý thuyết:
npm audit, Snyk, Dependabot - quét CVE trong dependency tree.Thực hành: Chạy
npm audittrên 1 project cũ, đọc report và thửnpm audit fix.
Ngày 154: Thực Hành Fix Lỗ Hổng Bảo Mật
Mục tiêu: Áp dụng kiến thức OWASP để hardening 1 API thực tế.
Lý thuyết: Review OWASP checklist.
Thực hành: Thêm middleware
helmet, rate limiting, input validation (vdzod) vào 1 Express app có sẵn.
Ngày 155: Ôn Tập Tuần 29
Mục tiêu: Tổng hợp security checklist cho production Node app.
Lý thuyết: Review toàn bộ tuần 29.
Thực hành: Viết security checklist cá nhân (10-15 mục) để tự audit trước khi deploy bất kỳ Node service nào.
Tuần 30: Performance & Load Testing
Ngày 156: Benchmarking
Mục tiêu: Đo performance của 1 đoạn code JS chính xác.
Lý thuyết:
console.time,perf_hooks, tránh sai lầm benchmark phổ biến (JIT warmup, GC ảnh hưởng kết quả).Thực hành: Dùng
perf_hooksbenchmark 2 cách viết khác nhau của cùng 1 bài toán (vd loop for vs.reduce()), so sánh kết quả.
Ngày 157: Profiling Node App
Mục tiêu: Áp dụng lại kỹ năng profiling (Ngày 122-124) vào 1 API thực tế.
Lý thuyết: Review flamegraph + Node Inspector.
Thực hành: Profile 1 API endpoint chạy chậm (giả lập bằng vòng lặp nặng), tìm và tối ưu bottleneck.
Ngày 158: k6 Load Testing Cơ Bản
Mục tiêu: Viết script load test cơ bản với k6.
Lý thuyết: Virtual Users (VU), stages (ramp-up/ramp-down), threshold.
Thực hành: Viết script k6 đơn giản gửi GET request tới 1 API local, chạy với 10 VU trong 30 giây.
Ngày 159: Thực Hành Load Test 1 API
Mục tiêu: Đọc hiểu kết quả load test và xác định giới hạn của hệ thống.
Lý thuyết: Đọc metrics
p95,p99latency, error rate.Thực hành: Load test API đã tối ưu ở Ngày 157, tăng dần VU tới khi latency/error rate tăng vọt, xác định ngưỡng chịu tải.
Ngày 160: Ôn Tập Tuần 30
Mục tiêu: Tổng hợp quy trình đo lường và tối ưu performance.
Lý thuyết: Review Benchmarking/Profiling/Load Testing.
Thực hành: Viết báo cáo ngắn (trước/sau) mô tả quá trình tìm bottleneck và cải thiện latency của API ở Ngày 157-159.
Tuần 31: CI/CD & Docker
Ngày 161: GitHub Actions Cơ Bản
Mục tiêu: Viết 1 workflow CI cơ bản chạy test tự động.
Lý thuyết:
workflow,job,step, trigger theo event (push,pull_request).Thực hành: Viết file
.github/workflows/ci.ymlchạynpm install+npm testmỗi khi push code.
Ngày 162: CI Pipeline Cho Node Project
Mục tiêu: Mở rộng pipeline CI với lint, test, build nhiều bước.
Lý thuyết: Matrix build (test nhiều Node version), cache dependency để tăng tốc CI.
Thực hành: Mở rộng workflow ngày 161 thêm bước lint + build, cấu hình cache
node_modules.
Ngày 163: Docker Multi-Stage Build
Mục tiêu: Viết Dockerfile tối ưu, giảm kích thước image production.
Lý thuyết: Multi-stage build - stage build (cài devDependencies, compile) tách biệt stage runtime (chỉ copy artifact cần thiết).
Thực hành: Viết Dockerfile multi-stage cho 1 app TypeScript (build ở stage 1, chạy JS đã compile ở stage 2).
Ngày 164: Distroless vs Alpine Images
Mục tiêu: Chọn base image phù hợp cho production, cân bằng giữa kích thước và khả năng debug.
Lý thuyết: Alpine (nhỏ, dùng musl libc có thể gây khác biệt hành vi), Distroless (không có shell, tối giản attack surface).
Thực hành: Build cùng 1 app với 3 base image khác nhau (
node:20,node:20-alpine, distroless), so sánh kích thước image.
Ngày 165: Ôn Tập Tổng Hợp Phase 5
Mục tiêu: Kết nối TypeScript + Testing + Build + Observability + Security + Performance + CI/CD thành quy trình production hoàn chỉnh.
Lý thuyết: Review toàn bộ Phase 5.
Thực hành: Vẽ sơ đồ pipeline hoàn chỉnh từ "code push" tới "chạy ở production" cho 1 Node service, đánh dấu bước nào đã thực hành trong Phase này.
PHASE 6 - Framework Agnostic Backend Engineering (Ngày 166-195)
Tuần 32: Routing
Ngày 166: Routing Cơ Bản (Path Matching)
Mục tiêu: Hiểu cách 1 router match
req.urlvới pattern đã đăng ký.Lý thuyết: Exact match vs pattern match (
:id, wildcard), so khớp method + path.Thực hành: Viết hàm
matchRoute(pattern, url)trả vềtrue/falsevà extract param, test với vài pattern có dynamic segment.
Ngày 167: Route Params & Query
Mục tiêu: Extract được cả path param và query string từ URL.
Lý thuyết:
/users/:idparam vs?page=2&limit=10query string; parseURLSearchParams.Thực hành: Mở rộng hàm ngày 166 để trả về object
{params, query}đầy đủ từ 1 URL thực tế.
Ngày 168: Tự Viết Express Mini Router (Phần 1)
Mục tiêu: Xây dựng class Router hỗ trợ đăng ký route theo method.
Lý thuyết: Router lưu danh sách route dạng
{method, pattern, handler}, duyệt tuần tự tìm match đầu tiên.Thực hành: Viết class
Routervới method.get(path, handler),.post(path, handler), lưu vào mảng nội bộ.
Ngày 169: Tự Viết Express Mini Router (Phần 2) - Kết Nối HTTP Server
Mục tiêu: Gắn Router vào HTTP server thật (dựa trên bài Ngày 118-119) để xử lý request thực tế.
Lý thuyết: Khi request đến, server gọi
router.handle(req, res)để tìm route match và gọi handler tương ứng.Thực hành: Hoàn thiện mini router có thể chạy được ít nhất 4 route CRUD (GET/POST/PUT/DELETE) trả JSON.
Ngày 170: Ôn Tập Tuần 32
Mục tiêu: Củng cố routing engine tự viết.
Lý thuyết: Review Path Matching + Router class.
Thực hành: Thêm route 404 fallback (không match route nào) cho mini router, viết test cho vài case match/không match.
Tuần 33: Middleware
Ngày 171: Middleware Pattern
Mục tiêu: Hiểu middleware pattern - chuỗi hàm xử lý request trước khi tới handler chính.
Lý thuyết: Middleware nhận
(req, res, next), gọinext()để chuyển sang middleware tiếp theo.Thực hành: Vẽ sơ đồ pipeline middleware minh hoạ request đi qua logger → auth → handler.
Ngày 172: Tự Viết app.use()
Mục tiêu: Implement cơ chế đăng ký và chạy tuần tự middleware giống Express.
Lý thuyết: Middleware array được lưu và chạy tuần tự bằng đệ quy hoặc vòng lặp gọi
next.Thực hành: Thêm method
.use(middlewareFn)vào Router ở Ngày 168, implement cơ chế chạy tuần tự middleware trước khi tới route handler.
Ngày 173: Error-Handling Middleware
Mục tiêu: Xử lý lỗi tập trung thay vì try/catch lặp lại ở từng handler.
Lý thuyết: Middleware 4 tham số
(err, req, res, next)trong Express, hoặc convention tự định nghĩa vớinext(err).Thực hành: Thêm error-handling middleware vào mini framework, test với 1 handler cố tình throw lỗi.
Ngày 174: Middleware Chaining Thực Chiến
Mục tiêu: Áp dụng middleware cho các nhu cầu thực tế: logging, auth, validation.
Lý thuyết: Thứ tự đăng ký middleware quan trọng (auth phải chạy trước handler cần bảo vệ).
Thực hành: Viết 3 middleware thực tế (request logger, simple auth check header, JSON body parser thủ công) áp dụng vào mini framework.
Ngày 175: Ôn Tập Tuần 33
Mục tiêu: Hoàn thiện mini framework với middleware đầy đủ.
Lý thuyết: Review Middleware pattern.
Thực hành: Viết 1 API nhỏ hoàn chỉnh (3-4 route) dùng chính mini framework tự viết, có logging + auth middleware.
Tuần 34: Dependency Injection
Ngày 176: DI Concept
Mục tiêu: Hiểu Dependency Injection giải quyết vấn đề gì (giảm coupling, dễ test).
Lý thuyết: Constructor injection, Inversion of Control (IoC).
Thực hành: Viết 1 class
UserServicephụ thuộc trực tiếp vàoDatabase(hardcode), sau đó refactor để nhậnDatabasequa constructor.
Ngày 177: Inversify
Mục tiêu: Sử dụng 1 DI container thực tế (Inversify) trong TypeScript.
Lý thuyết:
@injectable,@inject, Container binding.Thực hành: Setup Inversify cho ví dụ
UserService/Databaseở Ngày 176, đăng ký binding và resolve qua container.
Ngày 178: NestJS DI Internals (tổng quan, không cần cài NestJS)
Mục tiêu: Hiểu nguyên lý DI container của NestJS dựa trên decorator + reflect-metadata.
Lý thuyết: NestJS dùng
reflect-metadatađể đọc type của constructor param lúc runtime và tự động inject.Thực hành: Đọc source code (hoặc tài liệu) phần DI của NestJS, tóm tắt luồng resolve dependency bằng lời văn của mình.
Ngày 179: Thực Hành DI Container Đơn Giản
Mục tiêu: Tự viết 1 DI container tối giản để hiểu cơ chế bên dưới các thư viện lớn.
Lý thuyết: Container lưu map
token → factory/instance, resolve đệ quy dependency.Thực hành: Viết class
Containercó.register(token, factory)và.resolve(token), test với 2-3 service phụ thuộc lẫn nhau.
Ngày 180: Ôn Tập Tuần 34
Mục tiêu: Củng cố DI qua việc áp dụng vào mini framework đã xây.
Lý thuyết: Review DI concept + Inversify + Container tự viết.
Thực hành: Refactor API ở Ngày 175 để
UserServiceđược inject qua Container tự viết thay vì khởi tạo trực tiếp trong handler.
Tuần 35: ORM
Ngày 181: Prisma Cơ Bản
Mục tiêu: Setup Prisma và định nghĩa schema cho 1 database đơn giản.
Lý thuyết:
schema.prisma, model definition, Prisma Client generate tự động.Thực hành: Setup Prisma với SQLite/PostgreSQL local, định nghĩa model
UservàPostcó quan hệ 1-nhiều.
Ngày 182: Prisma Migration & Query
Mục tiêu: Thực hiện migration và query dữ liệu qua Prisma Client.
Lý thuyết:
prisma migrate dev, CRUD qua Prisma Client,include/selectcho relation.Thực hành: Chạy migration cho schema Ngày 181, viết script tạo vài user + post, query kèm relation bằng
include.
Ngày 183: TypeORM Cơ Bản
Mục tiêu: So sánh cách tiếp cận decorator-based của TypeORM với Prisma.
Lý thuyết: Entity decorator (
@Entity,@Column), Repository pattern.Thực hành: Định nghĩa lại model
User/Postbằng TypeORM Entity, thực hiện CRUD tương đương bài Ngày 182.
Ngày 184: So Sánh Prisma vs TypeORM
Mục tiêu: Đưa ra quyết định chọn ORM phù hợp cho 1 dự án cụ thể.
Lý thuyết: Review trade-off: Prisma (type-safety mạnh, schema riêng) vs TypeORM (decorator, gần OOP truyền thống hơn).
Thực hành: Viết bảng so sánh 2 ORM theo tiêu chí: type safety, migration workflow, độ phức tạp relation, performance overhead.
Ngày 185: Ôn Tập Tuần 35
Mục tiêu: Củng cố kỹ năng làm việc với ORM trong 1 API thực tế.
Lý thuyết: Review Prisma/TypeORM.
Thực hành: Tích hợp Prisma vào mini framework (Ngày 175/180), viết route CRUD cho resource
Postdùng Prisma Client thật.
Tuần 36: Cache & Queue
Ngày 186: Redis Cơ Bản
Mục tiêu: Kết nối và thao tác cơ bản với Redis từ Node.
Lý thuyết: Redis là in-memory key-value store, các kiểu dữ liệu cơ bản (string, hash, list, set).
Thực hành: Chạy Redis local (Docker), dùng thư viện
ioredisthực hiệnset/get/expirecơ bản từ Node script.
Ngày 187: Redis Caching Strategies
Mục tiêu: Áp dụng Redis để cache kết quả query tốn kém.
Lý thuyết: Cache-aside pattern, TTL, cache invalidation là "1 trong 2 việc khó nhất trong CS".
Thực hành: Thêm cache-aside cho route GET post ở Ngày 185 (check cache Redis trước, miss thì query DB rồi set cache).
Ngày 188: BullMQ
Mục tiêu: Xử lý tác vụ nền (background job) bằng queue dựa trên Redis.
Lý thuyết: Producer/Consumer, Job, Queue dựa trên Redis (BullMQ).
Thực hành: Setup BullMQ, viết 1 queue xử lý gửi email giả lập (delay 2s), producer thêm job và worker xử lý riêng biệt.
Ngày 189: RabbitMQ Cơ Bản
Mục tiêu: Hiểu message broker dạng AMQP khác với Redis-based queue thế nào.
Lý thuyết: Exchange, Queue, Binding, Routing key trong RabbitMQ.
Thực hành: Chạy RabbitMQ local (Docker), viết producer/consumer đơn giản dùng
amqplibpublish/consume 1 message.
Ngày 190: Ôn Tập Tuần 36
Mục tiêu: So sánh và chọn công cụ cache/queue phù hợp cho từng bài toán.
Lý thuyết: Review Redis Cache + BullMQ + RabbitMQ.
Thực hành: Viết bảng so sánh khi nào dùng Redis cache đơn giản, khi nào cần queue thật sự (BullMQ/RabbitMQ) cho hệ thống của bạn.
Tuần 37: Auth
Ngày 191: JWT
Mục tiêu: Hiểu cấu trúc JWT và cách ký/verify token.
Lý thuyết: Header.Payload.Signature,
jsonwebtokenlibrary, access token vs refresh token.Thực hành: Viết route login trả về JWT, viết middleware verify JWT bảo vệ route cần auth.
Ngày 192: OAuth2
Mục tiêu: Hiểu luồng Authorization Code Flow của OAuth2 (vd "Login with Google").
Lý thuyết: Authorization Server, Resource Server, Access Token, Authorization Code Flow.
Thực hành: Vẽ sơ đồ đầy đủ luồng Authorization Code Flow, đánh số thứ tự từng bước redirect.
Ngày 193: OIDC
Mục tiêu: Phân biệt OIDC (identity/xác thực ai đó là ai) với OAuth2 (authorization/cấp quyền truy cập).
Lý thuyết: OIDC xây trên nền OAuth2, thêm ID Token (JWT chứa thông tin identity).
Thực hành: Đọc 1 ID Token mẫu (decode tại jwt.io hoặc thủ công base64), liệt kê các claim quan trọng (
sub,iss,aud).
Ngày 194: Thực Hành Auth Flow Đầy Đủ
Mục tiêu: Xây dựng hệ thống auth hoàn chỉnh với access + refresh token.
Lý thuyết: Refresh token rotation, lưu trữ refresh token an toàn (HttpOnly cookie).
Thực hành: Hoàn thiện auth module cho mini framework: login trả access token (JWT) + refresh token (cookie HttpOnly), route refresh token mới.
Ngày 195: Ôn Tập Tổng Hợp Phase 6
Mục tiêu: Kết nối Routing + Middleware + DI + ORM + Cache/Queue + Auth thành 1 backend framework-agnostic hoàn chỉnh.
Lý thuyết: Review toàn bộ Phase 6.
Thực hành: Hoàn thiện mini framework tự viết thành 1 API đầy đủ: routing, middleware, DI container, Prisma, Redis cache, JWT auth - đây chính là nền tảng cho Capstone Project 5.
PHASE 7 - Advanced Topics (Ngày 196-235)
Tuần 38: Architecture
Ngày 196: Monolith
Mục tiêu: Hiểu ưu/nhược điểm thực sự của kiến trúc Monolith (không phải lúc nào cũng "xấu").
Lý thuyết: Monolith - toàn bộ ứng dụng deploy như 1 đơn vị; ưu điểm đơn giản, nhược điểm khó scale từng phần.
Thực hành: Liệt kê 1 hệ thống bạn từng dùng/xây, phân tích nó là Monolith và điểm nào đang gây khó khăn khi scale team/code.
Ngày 197: Modular Monolith
Mục tiêu: Hiểu Modular Monolith là bước trung gian hợp lý trước khi (nếu cần) tách microservice.
Lý thuyết: Chia code thành module có boundary rõ ràng nhưng vẫn deploy chung 1 process.
Thực hành: Vẽ sơ đồ chia mini framework đã xây ở Phase 6 thành các module rõ ràng (auth, user, post) với boundary interface.
Ngày 198: Microservice
Mục tiêu: Hiểu khi nào Microservice thực sự cần thiết, và cái giá phải trả (network, consistency, ops complexity).
Lý thuyết: Mỗi service độc lập deploy, giao tiếp qua network (HTTP/gRPC/message queue).
Thực hành: Vẽ sơ đồ tách hệ thống ở Ngày 197 thành 3 microservice riêng biệt (Auth Service, User Service, Post Service), chỉ ra service nào gọi service nào.
Ngày 199: So Sánh & Trade-off
Mục tiêu: Đưa ra quyết định kiến trúc dựa trên ngữ cảnh cụ thể (team size, traffic, độ phức tạp domain).
Lý thuyết: Review 3 kiến trúc, "đừng bắt đầu bằng microservice" (Conway's Law liên quan tới cấu trúc team).
Thực hành: Viết bảng quyết định (decision matrix) với tiêu chí team size/traffic/domain complexity để chọn giữa 3 kiến trúc.
Ngày 200: Ôn Tập Tuần 38
Mục tiêu: Củng cố tư duy kiến trúc tổng thể.
Lý thuyết: Review Monolith/Modular Monolith/Microservice.
Thực hành: Viết 1 trang "Architecture Decision Record" (ADR) giả lập cho việc chọn kiến trúc cho mini framework của bạn, kèm lý do.
Tuần 39: Event Driven Architecture
Ngày 201: EDA Concept
Mục tiêu: Hiểu Event-Driven Architecture khác gì với Request-Response truyền thống.
Lý thuyết: Producer publish event, Consumer subscribe xử lý bất đồng bộ, decoupling giữa các service.
Thực hành: Vẽ sơ đồ 1 flow "user đặt hàng" theo EDA: event
OrderCreatedđược publish, 3 service khác nhau subscribe xử lý (inventory, payment, notification).
Ngày 202: Kafka Cơ Bản
Mục tiêu: Setup Kafka local và publish/consume message đầu tiên.
Lý thuyết: Topic, Producer, Consumer, Broker.
Thực hành: Chạy Kafka local (Docker), dùng
kafkajsviết producer publish message và consumer đọc lại từ 1 topic.
Ngày 203: Kafka Partition & Consumer Group
Mục tiêu: Hiểu cách Kafka scale việc xử lý message song song.
Lý thuyết: Partition (đơn vị song song), Consumer Group (nhiều consumer chia nhau đọc partition).
Thực hành: Tạo topic có 3 partition, chạy 2 consumer cùng group, quan sát cách Kafka phân chia partition cho từng consumer.
Ngày 204: NATS
Mục tiêu: So sánh NATS (nhẹ, đơn giản) với Kafka (mạnh, phức tạp hơn).
Lý thuyết: NATS phù hợp pub/sub đơn giản, độ trễ thấp; Kafka phù hợp khi cần durability + replay message.
Thực hành: Chạy NATS local, viết ví dụ pub/sub đơn giản, so sánh độ phức tạp setup với Kafka ở Ngày 202.
Ngày 205: Ôn Tập Tuần 39
Mục tiêu: Củng cố EDA qua việc áp dụng vào hệ thống thực tế.
Lý thuyết: Review EDA/Kafka/NATS.
Thực hành: Thêm event
PostCreatedvào mini framework (Phase 6), publish qua Kafka khi tạo post thành công, viết 1 consumer đơn giản log lại event.
Tuần 40: Distributed Systems
Ngày 206: Consistency Models
Mục tiêu: Phân biệt Strong Consistency và Eventual Consistency.
Lý thuyết: Strong Consistency (đọc luôn thấy ghi mới nhất), Eventual Consistency (cuối cùng sẽ đồng bộ, có độ trễ).
Thực hành: Liệt kê 3 hệ thống thực tế bạn biết, phân loại chúng theo consistency model và giải thích trade-off.
Ngày 207: CAP Theorem & Vì Sao Nó Quan Trọng Với Message Broker
Mục tiêu: Giải thích được vì sao mọi broker (Kafka, RabbitMQ) đều phải đánh đổi giữa Consistency và Availability khi có Network Partition.
Lý thuyết: Consistency, Availability, Partition Tolerance; ví dụ thực tế CP (Kafka với
min.insync.replicas) vs AP (RabbitMQ classic mirrored queue cũ).Thực hành: Vẽ sơ đồ CAP cho 3 hệ thống bạn từng dùng (kể cả không phải messaging), tự phân loại và giải thích bằng 1 tình huống network partition cụ thể.
Ngày 208: Consensus (Raft/Paxos Tổng Quan)
Mục tiêu: Hiểu ở mức tổng quan vì sao hệ phân tán cần thuật toán đồng thuận để bầu leader/đồng bộ state.
Lý thuyết: Raft (leader election, log replication) dễ hiểu hơn Paxos, dùng trong etcd/Kafka Controller (KRaft).
Thực hành: Xem 1 visualization Raft online (raft.github.io), mô phỏng tay quá trình leader election khi leader cũ mất kết nối.
Ngày 209: Distributed Transactions
Mục tiêu: Hiểu vì sao transaction truyền thống (ACID) khó áp dụng khi dữ liệu nằm ở nhiều service khác nhau.
Lý thuyết: 2-Phase Commit (2PC), Saga pattern (choreography vs orchestration).
Thực hành: Vẽ sơ đồ Saga pattern cho flow "đặt hàng" ở Ngày 201, thêm bước compensating transaction khi payment thất bại.
Ngày 210: Ôn Tập Tuần 40
Mục tiêu: Củng cố tư duy hệ phân tán.
Lý thuyết: Review Consistency/CAP/Consensus/Distributed Transaction.
Thực hành: Viết 1 bài phân tích ngắn: hệ thống ở Ngày 205 (Kafka event) đang thuộc CP hay AP, và Saga pattern nên áp dụng thế nào nếu 1 trong 3 service downtime.
Tuần 41: Resilience
Ngày 211: Retry Pattern
Mục tiêu: Implement retry an toàn (tránh gây "retry storm").
Lý thuyết: Exponential backoff, jitter để tránh nhiều client retry cùng lúc gây quá tải server.
Thực hành: Viết hàm
retryWithBackoff(fn, maxRetries)generic, test với 1 hàm giả lập fail 2 lần đầu rồi thành công.
Ngày 212: Circuit Breaker
Mục tiêu: Ngăn hệ thống liên tục gọi 1 service đang down, tránh cascading failure.
Lý thuyết: 3 trạng thái Closed/Open/Half-Open, threshold để chuyển trạng thái.
Thực hành: Viết class
CircuitBreakerđơn giản wrap quanh 1 hàm gọi API, test kịch bản service fail liên tục khiến breaker mở.
Ngày 213: Bulkhead Pattern
Mục tiêu: Cô lập tài nguyên (connection pool, thread) để lỗi ở 1 phần không kéo sập toàn hệ thống.
Lý thuyết: Bulkhead - chia resource pool riêng cho từng loại tác vụ, giống khoang tàu thuỷ chống chìm toàn bộ.
Thực hành: Vẽ sơ đồ minh hoạ 1 service dùng chung connection pool DB cho cả tác vụ quan trọng và không quan trọng, đề xuất cách chia bulkhead.
Ngày 214: Timeout Strategies
Mục tiêu: Cấu hình timeout hợp lý ở mọi lớp (network, DB, external API).
Lý thuyết: Timeout quá dài gây nghẽn resource, quá ngắn gây fail oan; timeout nên giảm dần qua từng lớp gọi (client > gateway > service).
Thực hành: Rà soát mini framework đã xây, thêm timeout cho: DB query, external API call (dùng
AbortController), và toàn bộ request.
Ngày 215: Ôn Tập Tuần 41
Mục tiêu: Kết hợp Retry + Circuit Breaker + Bulkhead + Timeout thành resilience layer hoàn chỉnh.
Lý thuyết: Review toàn bộ tuần 41.
Thực hành: Áp dụng cả 4 pattern vào 1 hàm gọi external API trong mini framework, viết test giả lập service down để kiểm chứng hệ thống không sập theo.
Tuần 42: Scaling
Ngày 216: Horizontal Scaling
Mục tiêu: Hiểu khác biệt giữa Horizontal Scaling (thêm instance) và Vertical Scaling (tăng tài nguyên 1 instance).
Lý thuyết: Horizontal scaling cần app stateless (không lưu session trong memory local).
Thực hành: Rà soát mini framework, xác định phần nào đang stateful (vd session in-memory) cần sửa để scale horizontal được (chuyển sang Redis).
Ngày 217: Load Balancer
Mục tiêu: Hiểu Load Balancer phân phối traffic tới nhiều instance thế nào.
Lý thuyết: Round-robin, Least Connections, health check.
Thực hành: Setup Nginx làm load balancer đơn giản cho 2 instance của mini framework (chạy ở 2 port khác nhau), test bằng cách gửi nhiều request và quan sát phân phối.
Ngày 218: Database Scaling
Mục tiêu: Hiểu 2 chiến lược chính để scale database: sharding và replication.
Lý thuyết: Replication (đọc từ replica, ghi vào primary), Sharding (chia dữ liệu theo key).
Thực hành: Vẽ sơ đồ replication read/write split cho database của mini framework, chỉ ra route nào nên đọc từ replica.
Ngày 219: Thực Hành Scale 1 Service
Mục tiêu: Áp dụng tổng hợp horizontal scaling + load balancer cho service thực tế.
Lý thuyết: Review toàn bộ tuần 42.
Thực hành: Chạy mini framework với Cluster API (Ngày 114) kết hợp Nginx load balancer, load test để chứng minh throughput tăng theo số instance.
Ngày 220: Ôn Tập Tuần 42
Mục tiêu: Củng cố tư duy scaling tổng thể.
Lý thuyết: Review Horizontal Scaling/Load Balancer/DB Scaling.
Thực hành: Viết checklist "điều kiện cần" để 1 service scale horizontal an toàn (stateless, session ngoài, DB chịu tải được...).
Tuần 43: Observability
Ngày 221: OpenTelemetry Cơ Bản
Mục tiêu: Setup OpenTelemetry SDK cho 1 Node app.
Lý thuyết: OTel SDK, Exporter, Instrumentation (auto vs manual).
Thực hành: Cài
@opentelemetry/sdk-node, tự động instrument 1 Express app, export trace ra console.
Ngày 222: Tracing Setup
Mục tiêu: Xem trace thực tế của 1 request đi qua nhiều lớp (HTTP → DB query).
Lý thuyết: Span cha-con tự động được tạo bởi auto-instrumentation.
Thực hành: Export trace từ Ngày 221 ra Jaeger (chạy local bằng Docker), xem trace UI của 1 request có DB call.
Ngày 223: Metrics & Dashboard
Mục tiêu: Trực quan hoá metrics đã thu thập ở Ngày 147 bằng dashboard thực tế.
Lý thuyết: Prometheus scrape metrics endpoint, Grafana visualize.
Thực hành: Setup Prometheus + Grafana local (Docker Compose), tạo dashboard hiển thị request rate và latency của mini framework.
Ngày 224: Thực Hành Full Observability Stack
Mục tiêu: Tích hợp đầy đủ Log + Metrics + Trace cho 1 service.
Lý thuyết: Review 3 trụ cột Observability.
Thực hành: Hoàn thiện mini framework với pino logging + Prometheus metrics + OpenTelemetry tracing chạy đồng thời.
Ngày 225: Ôn Tập Tuần 43
Mục tiêu: Củng cố observability stack hoàn chỉnh.
Lý thuyết: Review toàn bộ tuần 43.
Thực hành: Giả lập 1 lỗi (vd DB query chậm) và thử dùng chính dashboard/trace đã setup để tìm ra nguyên nhân, như 1 buổi "incident response" thật.
Tuần 44-45: Cloud Deployment
Ngày 226: Docker Images (Ôn tập & nâng cao)
Mục tiêu: Đóng gói mini framework thành image production sẵn sàng deploy.
Lý thuyết: Review multi-stage build (Ngày 163), thêm healthcheck trong Dockerfile.
Thực hành: Hoàn thiện Dockerfile production cho mini framework, thêm
HEALTHCHECKinstruction.
Ngày 227: Kubernetes Cơ Bản (Pod/Deployment/Service)
Mục tiêu: Hiểu 3 resource cơ bản nhất của Kubernetes.
Lý thuyết: Pod (đơn vị chạy container nhỏ nhất), Deployment (quản lý replica + rolling update), Service (expose network ổn định).
Thực hành: Setup Kubernetes local (minikube/kind), viết manifest Deployment + Service cho image ở Ngày 226, deploy thử.
Ngày 228: K8s ConfigMap/Secret
Mục tiêu: Quản lý config và dữ liệu nhạy cảm tách biệt khỏi image.
Lý thuyết: ConfigMap (config thường), Secret (dữ liệu nhạy cảm, base64 encode).
Thực hành: Tạo ConfigMap chứa biến môi trường và Secret chứa DB password, mount vào Pod ở Ngày 227.
Ngày 229: AWS Cơ Bản Cho Node Deploy
Mục tiêu: Hiểu 2 lựa chọn phổ biến để deploy Node app trên AWS.
Lý thuyết: EC2 (tự quản lý VM) vs ECS (managed container orchestration).
Thực hành: Đọc tài liệu AWS ECS, vẽ sơ đồ kiến trúc deploy mini framework lên ECS Fargate (không cần deploy thật nếu chưa có tài khoản).
Ngày 230: GCP Cơ Bản (Cloud Run)
Mục tiêu: Hiểu Cloud Run - nền tảng serverless container phù hợp cho app stateless.
Lý thuyết: Cloud Run tự động scale theo traffic (kể cả về 0), pay-per-use.
Thực hành: Nếu có tài khoản GCP free tier, thử deploy image Docker ở Ngày 226 lên Cloud Run; nếu không, đọc kỹ tài liệu và ghi chú các bước.
Ngày 231: Helm Charts
Mục tiêu: Đóng gói Kubernetes manifest thành template tái sử dụng được.
Lý thuyết: Helm Chart - templating cho K8s YAML, values.yaml cho từng environment.
Thực hành: Chuyển đổi manifest ở Ngày 227-228 thành 1 Helm chart cơ bản với
values.yamlcho dev/prod.
Ngày 232: K8s Scaling & HPA
Mục tiêu: Cấu hình tự động scale Pod theo tải (CPU/Memory).
Lý thuyết: Horizontal Pod Autoscaler (HPA) dựa trên metrics.
Thực hành: Thêm HPA config cho Deployment ở Ngày 227, load test để quan sát Pod tự động tăng số lượng.
Ngày 233: CI/CD to K8s
Mục tiêu: Tự động hoá việc deploy lên K8s mỗi khi code được merge.
Lý thuyết: CI build + push image → CD apply manifest/Helm chart lên cluster.
Thực hành: Mở rộng GitHub Actions workflow (Ngày 161-162) thêm bước build Docker image, push registry, và
helm upgrade(hoặckubectl apply).
Ngày 234: Thực Hành Deploy Full Stack Lên K8s
Mục tiêu: Deploy toàn bộ hệ thống (app + Redis + DB) lên Kubernetes.
Lý thuyết: Review toàn bộ tuần 44-45.
Thực hành: Viết manifest/Helm chart đầy đủ cho mini framework + Redis + Postgres (StatefulSet hoặc dùng managed DB), deploy trên minikube/kind.
Ngày 235: Ôn Tập Tổng Hợp Phase 7
Mục tiêu: Kết nối Architecture + EDA + Distributed Systems + Resilience + Scaling + Observability + Cloud thành năng lực production engineer hoàn chỉnh.
Lý thuyết: Review toàn bộ Phase 7.
Thực hành: Viết 1 tài liệu kiến trúc (architecture doc) đầy đủ cho hệ thống mini framework: sơ đồ service, resilience pattern áp dụng, scaling strategy, observability stack - đây là nền tảng chuẩn bị cho Capstone Project 5.
CAPSTONE PROJECTS (Ngày 236-265)
Project 1: Tự Implement Promise Hoàn Chỉnh (Ngày 236-238)
Ngày 236: Promises/A+ Spec - Đọc & Lên Kế Hoạch
Mục tiêu: Đọc và hiểu spec Promises/A+ chính thức trước khi code lại từ đầu (khác bản đơn giản ở Ngày 54-55).
Lý thuyết: Promises/A+ quy định chặt chẽ hành vi
then, resolution procedure khi resolve bằng 1 Promise/thenable khác.Thực hành: Đọc spec Promises/A+ (promisesaplus.com), viết pseudo-code cho toàn bộ resolution procedure.
Ngày 237: Implement Đầy Đủ State Machine & Chaining
Mục tiêu: Viết
MyPromiseđầy đủ, xử lý đúng cả case resolve bằng 1 Promise khác (thenable).Lý thuyết: Resolution Procedure - nếu resolve value là thenable, phải "adopt" trạng thái của nó thay vì coi nó là giá trị thường.
Thực hành: Hoàn thiện
MyPromisexử lý đúng caseresolve(anotherPromise),resolve(thenableObject).
Ngày 238: Implement Static Methods & Test Suite
Mục tiêu: Bổ sung
Promise.all/race/allSettled/anyvà validate bằng test suite chuẩn.Lý thuyết: Mỗi static method có logic khác nhau khi 1 trong các promise reject.
Thực hành: Implement
MyPromise.all/race/allSettled/any, chạy thửpromises-aplus-tests(npm package) để kiểm chứng implementation đạt chuẩn.
Project 2: Tự Implement EventEmitter (Ngày 239-240)
Ngày 239: EventEmitter Cơ Bản
Mục tiêu: Viết class EventEmitter hỗ trợ
on/emit/offgiống Node built-in.Lý thuyết: EventEmitter lưu map
eventName → listeners[],emitgọi tuần tự tất cả listener đăng ký.Thực hành: Viết class
MyEventEmittervới.on(event, fn),.emit(event, ...args),.off(event, fn).
Ngày 240: EventEmitter Nâng Cao
Mục tiêu: Bổ sung
once, giới hạn max listener, và xử lý lỗi khi listener throw.Lý thuyết:
oncetự động unsubscribe sau lần gọi đầu; Node giới hạn 10 listener mặc định để cảnh báo leak.Thực hành: Thêm
.once(event, fn), cảnh báo console khi 1 event có quá 10 listener, viết test đầy đủ cho toàn bộ class.
Project 3: Tự Implement Express Mini Framework (Ngày 241-245)
Ngày 241: Kiến Trúc Tổng Thể
Mục tiêu: Thiết kế lại kiến trúc framework dựa trên toàn bộ kiến thức Routing + Middleware + DI đã học ở Phase 6.
Lý thuyết: Review Ngày 166-180.
Thực hành: Viết sơ đồ class diagram cho framework:
App,Router,Request,Responsewrapper.
Ngày 242: Request/Response Wrapper
Mục tiêu: Bọc
req/resgốc của Node thành object tiện dụng hơn (giốngreq.body,res.json()).Lý thuyết: Extend behavior của IncomingMessage/ServerResponse bằng cách gán thêm method/property.
Thực hành: Viết
res.json(data),res.status(code), parsereq.bodytự động khi Content-Type là JSON.
Ngày 243: Router & Middleware Hoàn Chỉnh
Mục tiêu: Tích hợp lại toàn bộ Router + Middleware đã xây ở Phase 6 vào framework thống nhất.
Lý thuyết: Review Ngày 166-175.
Thực hành: Đảm bảo hỗ trợ nested router (
app.use('/api', apiRouter)), middleware toàn cục và theo route.
Ngày 244: Error Handling & Static File Serving
Mục tiêu: Hoàn thiện framework với xử lý lỗi tập trung và serve static file.
Lý thuyết: Review error-handling middleware Ngày 173; serve static dùng Readable Stream (Ngày 101) pipe thẳng vào response.
Thực hành: Thêm
app.use(express.static-like(dir))tự viết, dùng stream để serve file thay vì đọc hết vào memory.
Ngày 245: Test & Benchmark So Với Express Thật
Mục tiêu: Kiểm chứng framework tự viết hoạt động đúng và đo hiệu năng so với Express thật.
Lý thuyết: Review toàn bộ Project 3.
Thực hành: Viết test suite cho framework, dùng
autocannonbenchmark framework tự viết vs Express thật trên cùng 1 route đơn giản.
Project 4: Tự Implement Webpack Mini Bundler (Ngày 246-250)
Ngày 246: Module Graph & Dependency Resolution
Mục tiêu: Xây dựng bước đầu tiên của bundler - quét entry file và tìm toàn bộ dependency.
Lý thuyết: Bundler cần parse AST (dùng lại kiến thức Ngày 61) để tìm câu lệnh
require/import.Thực hành: Viết hàm đọc 1 file, dùng
@babel/parsertìm toàn bộrequire(...)call, đệ quy xây dựng dependency graph.
Ngày 247: Module Wrapping
Mục tiêu: Bọc mỗi module thành 1 function riêng biệt để tránh xung đột scope khi gộp chung 1 file.
Lý thuyết: Mỗi module được wrap dạng
function(module, exports, require) {...}, giống cách Node CommonJS hoạt động thật (Ngày 33).Thực hành: Viết code transform nội dung mỗi file thành dạng wrapped function string.
Ngày 248: Bundle Generation
Mục tiêu: Ghép toàn bộ module đã wrap thành 1 file output duy nhất chạy được.
Lý thuyết: Bundle output cần có 1 runtime nhỏ implement
requiregiả lập, map module ID tới function tương ứng.Thực hành: Viết runtime
requiregiả lập, generate file bundle cuối cùng từ module graph Ngày 246-247, chạy thử bằng Node.
Ngày 249: Loader System Cơ Bản
Mục tiêu: Hỗ trợ import file không phải JS (vd JSON, hoặc CSS đơn giản) giống hệ thống loader của Webpack thật.
Lý thuyết: Loader transform nội dung file thành JS module trước khi đưa vào graph.
Thực hành: Viết 1 loader đơn giản cho phép
require('./data.json')trả về object JS.
Ngày 250: Tree Shaking Cơ Bản & Tổng Kết Project 4
Mục tiêu: Hiểu nguyên lý tree shaking ở mức cơ bản (loại bỏ export không dùng tới).
Lý thuyết: Tree shaking dựa trên static analysis của ESM (import/export tĩnh, khác CommonJS động).
Thực hành: Viết bundler xử lý ESM đơn giản, loại bỏ 1 export không được import ở đâu, so sánh kích thước output trước/sau.
Project 5: Backend Production-Grade Hoàn Chỉnh (Ngày 251-265)
Ngày 251: Thiết Kế Kiến Trúc & DB Schema
Mục tiêu: Lên kế hoạch kiến trúc tổng thể cho hệ thống production cuối khoá.
Lý thuyết: Áp dụng Ngày 196-200 (chọn Modular Monolith là hợp lý cho quy mô 1 người xây).
Thực hành: Vẽ ERD cho domain cụ thể (vd hệ thống đặt hàng), viết Architecture Decision Record cho kiến trúc đã chọn.
Ngày 252: Setup TypeScript + Fastify Project
Mục tiêu: Khởi tạo project với cấu trúc thư mục rõ ràng, TypeScript strict mode.
Lý thuyết: Review Phase 5 Tuần 24 (TypeScript) + chọn Fastify (hoặc dùng lại mini framework tự viết ở Project 3).
Thực hành: Setup project skeleton, cấu hình
tsconfig.jsonstrict, cấu trúc thư mục theo module (routes/services/repositories).
Ngày 253: PostgreSQL Integration + Prisma
Mục tiêu: Kết nối database thật và định nghĩa schema đầy đủ cho domain đã thiết kế.
Lý thuyết: Review Ngày 181-182.
Thực hành: Viết Prisma schema đầy đủ theo ERD Ngày 251, chạy migration, viết seed script tạo dữ liệu mẫu.
Ngày 254: Auth Module (JWT)
Mục tiêu: Tích hợp module đăng ký/đăng nhập hoàn chỉnh.
Lý thuyết: Review Ngày 191-194.
Thực hành: Viết route register/login/refresh-token, middleware bảo vệ route, hash password bằng
bcrypt.
Ngày 255: Redis Caching Layer
Mục tiêu: Thêm cache cho các query đọc nhiều, ghi ít.
Lý thuyết: Review Ngày 186-187.
Thực hành: Cache danh sách sản phẩm/dữ liệu ít thay đổi vào Redis với TTL hợp lý, đo cải thiện latency trước/sau.
Ngày 256: RabbitMQ Integration Cho Async Jobs
Mục tiêu: Xử lý tác vụ nặng/không cần realtime bằng queue (vd gửi email xác nhận đơn hàng).
Lý thuyết: Review Ngày 188-189.
Thực hành: Publish event khi có action quan trọng (vd
OrderCreated), viết consumer riêng xử lý gửi email/notification.
Ngày 257: OpenTelemetry Tracing Setup
Mục tiêu: Đảm bảo mọi request có thể trace end-to-end.
Lý thuyết: Review Ngày 221-222.
Thực hành: Setup tracing xuyên suốt: HTTP request → DB query → publish message queue, xem trace hoàn chỉnh trên Jaeger.
Ngày 258: Testing (Unit + Integration)
Mục tiêu: Đạt coverage hợp lý cho các module quan trọng (auth, business logic chính).
Lý thuyết: Review Phase 5 Tuần 25 (Testing/TDD).
Thực hành: Viết unit test cho service layer (mock DB), integration test cho ít nhất 3 API endpoint chính (dùng test database riêng).
Ngày 259: Dockerize Multi-Stage
Mục tiêu: Đóng gói toàn bộ app thành image production sẵn sàng.
Lý thuyết: Review Ngày 163-164.
Thực hành: Viết Dockerfile multi-stage tối ưu cho app, kèm
docker-compose.ymlchạy cùng Postgres + Redis + RabbitMQ cho local dev.
Ngày 260: Kubernetes Manifests
Mục tiêu: Chuẩn bị đầy đủ manifest để deploy hệ thống lên K8s.
Lý thuyết: Review Ngày 227-231.
Thực hành: Viết Deployment/Service/ConfigMap/Secret cho app, hoặc Helm chart nếu muốn tái sử dụng.
Ngày 261: CI/CD Pipeline
Mục tiêu: Tự động hoá toàn bộ quy trình từ push code tới deploy.
Lý thuyết: Review Ngày 161-162, 233.
Thực hành: Viết pipeline GitHub Actions đầy đủ: lint → test → build image → push registry → deploy (kubectl/helm).
Ngày 262: Load Testing & Performance Tuning
Mục tiêu: Xác định giới hạn hệ thống và tối ưu nếu cần trước khi coi là "production-ready".
Lý thuyết: Review Ngày 156-159.
Thực hành: Chạy k6 load test toàn bộ flow chính (vd đặt hàng), tối ưu bottleneck phát hiện được (query N+1, thiếu index...).
Ngày 263: Security Hardening (OWASP Checklist)
Mục tiêu: Rà soát bảo mật lần cuối trước khi coi là hoàn thiện.
Lý thuyết: Review Ngày 151-155.
Thực hành: Chạy qua checklist OWASP đã viết ở Ngày 155 cho toàn bộ hệ thống, fix các điểm chưa đạt (helmet, rate limit, input validation).
Ngày 264: Documentation & Code Review
Mục tiêu: Viết tài liệu đầy đủ để người khác (hoặc chính bạn 6 tháng sau) hiểu và maintain được hệ thống.
Lý thuyết: Tài liệu tốt gồm: kiến trúc tổng quan, cách setup local, API docs, runbook xử lý sự cố.
Thực hành: Viết README đầy đủ, tự review lại toàn bộ code như thể đang review PR của người khác, liệt kê 5 điểm có thể cải thiện thêm.
Ngày 265: Demo & Retrospective - Tổng Kết Toàn Bộ Syllabus
Mục tiêu: Nhìn lại toàn bộ hành trình 265 ngày và xác định hướng đi tiếp theo (React/Next.js/NestJS/Bun/Deno).
Lý thuyết: Review lại mục tiêu ban đầu đặt ra ở Phase 0.
Thực hành: Tự demo toàn bộ hệ thống Project 5 (record lại nếu muốn), viết retrospective 1 trang: đã học được gì, phần nào còn yếu cần ôn lại, và chọn framework tiếp theo để học dựa trên nền tảng đã có.