Skip to main content

Command Palette

Search for a command to run...

Syllabus học JavaScript

Updated
•80 min read•View as Markdown

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 dig hoặc nslookup tra 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 var hoạ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à 0 hoặ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ùng Object.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.is cho 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 this bị ảnh hưởng thế nào ở mỗi loại.

  • Lý thuyết: Function declaration, expression, arrow function; arrow function không có this riê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 this bị 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.defineProperty tạo 1 property read-only và 1 property ẩn khỏi for...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__ vs prototype, cách JS lookup property qua chain, Object.prototype là gốc.

  • Thực hành: Dùng Object.getPrototypeOf truy 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 new thực hiện.

  • Lý thuyết: new tạo object mới → gán prototype → bind this → 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ủa new bằng Object.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ết myMap bằng cách gọi myReduce.

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...of hoạt động với Array/Map/Set.

  • Lý thuyết: Iterable Protocol - object có Symbol.iterator trả về 1 iterator.

  • Thực hành: Biến 1 custom object (vd Range {start, end}) thành iterable để dùng được với for...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 Range iterable ngày 28, thêm Symbol.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 class trong JS chỉ là lớp vỏ cú pháp trên prototype.

  • Lý thuyết: class compile 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, Error object, kế thừa Error để tạo ValidationError, NotFoundError.

  • Thực hành: Viết 3 custom Error class kế thừa Error, dùng instanceof để 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.exports hoạ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 HttpRequest qua 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ó setTimeout lồ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.then và 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 queueMicrotask thay vì setTimeout(fn, 0).

  • Lý thuyết: queueMicrotask chạ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 queueMicrotask và 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/finally và 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/await là 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 MyPromise với constructor nhận executor, implement resolve/reject, và then cơ 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 MyPromise hỗ 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ùng queueMicrotask để giả lập hành vi bất đồng bộ.

  • Thực hành: Hoàn thiện MyPromise hỗ 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-size hoặ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 typeof operator, đọ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ề NewPromiseCapability và PromiseReactionJob, so sánh với MyPromise đã 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.childNodes so 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:none và 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 offsetHeight liê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/opacity mượt hơn thay đổi top/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ùng transform, 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 requestAnimationFrame và 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 fetch với các option phổ biến (method, headers, body).

  • Lý thuyết: fetch trả về Promise, cần check response.ok thủ 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ằng AbortController.

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ử fetch tớ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/json với PUT) tới API hỗ trợ CORS, quan sát request OPTIONS xuấ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á).

  • 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 HttpOnly và không có, thử đọc bằng document.cookie để thấy khác biệt.

  • 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 innerHTML từ input không escape), sau đó fix bằng cách dùng textContent hoặ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.readFile cùng lúc trên file lớn, thử tăng UV_THREADPOOL_SIZE và 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/setImmediate bên trong callback của fs.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ề false khi buffer đầy (backpressure), event drain.

  • 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ờ event drain.

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.stdout bằng pipe().

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 fs với cả API callback, Promise và sync.

  • Lý thuyết: fs.readFile (callback) vs fs/promises vs fs.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 .js trong 1 thư mục (đệ quy), dùng path.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, event uncaughtException.

  • 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 (vd ls hoặc git 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().length và log ra process.pid mỗ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 net module, echo lại dữ liệu client gửi lên (dùng telnet hoặc nc để 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: dgram module, 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.createServer nhậ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ự parse req.url và 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/res object 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 0x hoặc clinic flame profile 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 --prof sinh file log, node --prof-process phân tích thành báo cáo đọc được.

  • Thực hành: Chạy node --prof trê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: interface hỗ trợ declaration merging, type linh hoạt hơn với union/intersection.

  • Thực hành: Viết interface User và 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 ra CreateUserDto (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), mock fetch để 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: dependencies vs devDependencies, 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/utils và packages/app dù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.json cho 1 package production.

  • Lý thuyết: main, exports, types, engines, peerDependencies.

  • Thực hành: Viết package.json hoà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.log tự 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 pino hoặc winston và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-client expose 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 audit trê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 (vd zod) 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_hooks benchmark 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, p99 latency, 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.yml chạy npm install + npm test mỗ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.url vớ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/false và 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/:id param vs ?page=2&limit=10 query string; parse URLSearchParams.

  • 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 Router vớ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ọi next() để 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ới next(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 UserService phụ thuộc trực tiếp vào Database (hardcode), sau đó refactor để nhận Database qua 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 Container có .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 User và Post có 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/select cho 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/Post bằ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 Post dù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 ioredis thực hiện set/get/expire cơ 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 amqplib publish/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, jsonwebtoken library, 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 kafkajs viế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 PostCreated và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 HEALTHCHECK instruction.

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.yaml cho 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ặc kubectl 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 MyPromise xử lý đúng case resolve(anotherPromise), resolve(thenableObject).

Ngày 238: Implement Static Methods & Test Suite

  • Mục tiêu: Bổ sung Promise.all/race/allSettled/any và 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/off giống Node built-in.

  • Lý thuyết: EventEmitter lưu map eventName → listeners[], emit gọi tuần tự tất cả listener đăng ký.

  • Thực hành: Viết class MyEventEmitter vớ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: once tự độ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, Response wrapper.

Ngày 242: Request/Response Wrapper

  • Mục tiêu: Bọc req/res gốc của Node thành object tiện dụng hơn (giống req.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), parse req.body tự độ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 autocannon benchmark 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/parser tì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 require giả lập, map module ID tới function tương ứng.

  • Thực hành: Viết runtime require giả 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.json strict, 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.yml chạ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ó.

Knowledge

Part 1 of 50