Học dùng AI – Claude Code

Chào mọi người 👋 Sau một thời gian dài sử dụng AI cho lập trình, mình bắt đầu nhận ra rằng: biết dùng AI thôi là chưa đủ, mà cần phải dùng cho đúng cách và hiệu quả. Thế là mình quyết định dành thêm thời gian để học cách làm việc với AI agent bài bản hơn. Tuần vừa rồi, ngoài giờ làm ban ngày thì buổi tối mình cày thêm một khoá học về Claude Code. Học cũng hơi chậm 🐌 nhưng không sao — miễn là không bỏ cuộc 😆. Bài viết này chủ yếu là để khoe nhẹ thành quả sau 1 tuần cố gắng. ...

February 23, 2026 · 2 min

Phân biệt Message Queue - Pub/Sub - Message Broker

Chào mọi người đầu xuân năm mới 2026 👋 Cùng mình ôn tập lại một vài khái niệm trong lập trình mà anh em backend rất hay gặp phải nhưng đôi khi dễ bị nhầm lẫn nhé. Nào, let’s go 🚀 Hôm nay chúng ta sẽ cùng phân biệt: Message Queue Pub-Sub Message Broker Ba khái niệm này thường bị đánh tráo hoặc hiểu sai, nhưng thực tế chúng được thiết kế để giải quyết những bài toán kiến trúc khác nhau. ...

February 22, 2026 · 3 min

Chương 16: Failure Cases — Phân tích sự cố Production

← Chương trước | Mục lục | Chương sau → Đây là chương quan trọng nhất của toàn bộ tài liệu. Mọi kiến thức về giao thức, message broker, resilience pattern ở các chương trước chỉ thực sự có giá trị khi bạn đứng trước một dashboard đỏ rực lúc 2 giờ sáng và phải trả lời ba câu hỏi: chuyện gì đang xảy ra, tại sao, và làm gì ngay bây giờ. ...

February 22, 2026 · 74 min

Chương 15. Principal Architecture — Multi-Region, Cross-DC và Large Scale

← Chương trước | Mục lục | Chương sau → 15.1. Business problem: khi công ty vượt qua biên giới một region Hãy bắt đầu từ một tình huống có thật ở hầu hết các công ty tăng trưởng nhanh. Công ty của bạn khởi đầu với toàn bộ hệ thống đặt tại một region — giả sử us-east-1 (Virginia). Ba năm sau, business mở rộng ra ba châu lục: Bắc Mỹ, châu Âu, và Đông Nam Á. Ngay lập tức, ba loại áp lực xuất hiện cùng lúc, và cả ba đều không giải quyết được bằng cách “tối ưu code”: ...

February 22, 2026 · 49 min

Chương 14 — Microservices Communication: API Gateway và Service Mesh

← Chương trước | Mục lục | Chương sau → Mở đầu: Bài toán kinh doanh Hãy bắt đầu từ một câu chuyện quen thuộc. Công ty của bạn có một monolith, 50 developer, deploy 1 lần/tuần. Mỗi lần deploy là một “sự kiện”: freeze code từ thứ Tư, QA regression 2 ngày, deploy đêm thứ Sáu, và cả team on-call cuối tuần. Feature nhỏ nhất cũng mất 2 tuần để ra production vì phải xếp hàng chung chuyến tàu release. Ban lãnh đạo hỏi: “Đối thủ ship feature mỗi ngày, tại sao chúng ta mất 2 tuần?” ...

February 22, 2026 · 32 min

Chương 12: Resilience Patterns — Giao tiếp ổn định trong hệ thống không ổn định

← Chương trước | Mục lục | Chương sau → 12.1. First principles: partial failure là trạng thái bình thường Trong monolith, một lời gọi hàm hoặc thành công hoặc ném exception — và cả hai đều xảy ra trong cùng một process, cùng một số phận. Khoảnh khắc bạn tách hàm đó ra sau một network call, bạn nhận về một tập kết quả hoàn toàn mới: thành công, thất bại, và mọi trạng thái lửng lơ ở giữa — request đến nơi nhưng response thất lạc, request đang xếp hàng ở đâu đó và sẽ được xử lý sau 30 giây nữa, downstream đã xử lý xong nhưng bạn đã bỏ đi. ...

February 22, 2026 · 41 min

Chương 11: API Design — Thiết kế API cho tuổi thọ 10 năm

← Chương trước | Mục lục | Chương sau → 11.1. Vì sao API design là quyết định khó đảo ngược nhất Bắt đầu từ một sự thật mà mọi engineer đều học được theo cách đau đớn: code là tài sản riêng của bạn, còn API là hợp đồng công khai với người khác. Bạn có thể refactor toàn bộ internal implementation vào thứ Ba tuần sau mà không ai hay biết. Nhưng một field đã xuất hiện trong response, một URI đã có người gọi, một status code đã có người viết if để bắt — những thứ đó không còn thuộc về bạn nữa. Chúng thuộc về mọi consumer đang phụ thuộc vào chúng. ...

February 22, 2026 · 40 min

Chương 10: So sánh Communication Pattern và Framework quyết định

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Chín chương vừa qua đã mổ xẻ từng công nghệ. Bây giờ là câu hỏi mà mọi architect phải trả lời hàng tuần, và là câu hỏi bị trả lời sai nhiều nhất: “Service A cần nói chuyện với Service B / với client. Dùng cái gì?” Cách câu hỏi này thường bị trả lời sai trong thực tế: ...

February 22, 2026 · 20 min

Chương 9: Event Streaming — Log phân tán và xử lý sự kiện quy mô lớn

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Hãy bắt đầu bằng một bài toán thật, không phải định nghĩa sách giáo khoa. Bạn vận hành một nền tảng thương mại điện tử. Mỗi hành động của người dùng — xem sản phẩm, thêm vào giỏ, tìm kiếm, click banner — sinh ra một event. Ở quy mô 10 triệu người dùng hoạt động, hệ thống của bạn sinh 2–5 triệu event mỗi giây vào giờ cao điểm. Và đây là danh sách những bên muốn tiêu thụ dòng event đó: ...

February 22, 2026 · 41 min

Chương 8: Message Queue — Tách rời thời gian giữa các hệ thống

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Hãy bắt đầu từ một luồng nghiệp vụ mà mọi hệ thống e-commerce đều có: khách hàng đặt hàng thành công. Khi đơn hàng được tạo, hệ thống phải làm ít nhất bốn việc: Gửi email xác nhận cho khách. Cộng điểm tích lũy (loyalty). Cập nhật tồn kho (inventory). Đẩy dữ liệu sang hệ thống analytics. Cách tiếp cận ngây thơ nhất — và cũng là cách hầu hết các hệ thống bắt đầu — là gọi synchronous tất cả trong cùng một request: ...

February 22, 2026 · 34 min

Chương 7: Server-Sent Events — Push đơn giản trên HTTP

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Ba bài toán rất phổ biến có chung một hình dạng: Dashboard giá / telemetry: server đẩy giá mới, số liệu mới xuống hàng nghìn màn hình. Client chỉ nhìn, không gửi gì (ngoài vài thao tác lọc hiếm hoi qua REST). Notification feed: “bạn có comment mới” — server phát, client nhận. LLM token streaming: model sinh token, server đẩy từng token xuống UI ngay khi có. Client gửi đúng một prompt lúc đầu (qua POST), sau đó chỉ nhận. Điểm chung: dữ liệu chảy một chiều, server → client. Chiều ngược lại hoặc không tồn tại, hoặc thưa thớt tới mức một HTTP request bình thường phục vụ tốt. ...

February 22, 2026 · 23 min

Chương 6: WebSocket — Kênh song công cho Realtime

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Bạn đang xây một collaboration app: chat nhóm, cursor tracking, comment realtime. Yêu cầu nghiệp vụ rất rõ ràng: khi user A gõ một tin nhắn, user B phải thấy nó trong vòng dưới 200ms; đồng thời client của B cũng liên tục gửi trạng thái của chính nó lên server (typing indicator, cursor position). Nghĩa là dữ liệu chảy cả hai chiều, liên tục, với tần suất cao và độ trễ thấp. ...

February 22, 2026 · 35 min

Chương 5: gRPC — RPC hiệu năng cao cho Internal Services

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Hãy bắt đầu từ một hệ thống thật. Bạn đang vận hành một nền tảng thương mại điện tử với khoảng 200 internal service. Mỗi request từ người dùng — ví dụ “đặt hàng” — kích hoạt một chuỗi gọi nội bộ: api-gateway → order-service → inventory-service → pricing-service → promotion-service → payment-service → notification-service. Fan-out trung bình 1 request bên ngoài thành 15–30 lời gọi nội bộ. Ở mức 5.000 request/giây từ phía người dùng, hệ thống nội bộ đang xử lý hơn 100.000 lời gọi service-to-service mỗi giây. ...

February 22, 2026 · 37 min

Chương 4: GraphQL — Query Language cho API

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Hãy bắt đầu bằng một tình huống mà gần như mọi team backend phục vụ mobile app đều gặp phải. Công ty bạn có một mobile app thương mại điện tử. App có màn hình Home, màn hình Profile, màn hình Order History, màn hình Order Detail. Backend đã có sẵn một bộ REST API được thiết kế “chuẩn resource-oriented”: ...

February 22, 2026 · 47 min

Chương 3. REST — Kiến trúc tài nguyên trên HTTP

← Chương trước | Mục lục | Chương sau → 3.1. Problem Statement — bài toán trước khi có giải pháp Hãy bắt đầu từ một tình huống rất thật. Công ty bạn có một hệ thống quản lý đơn hàng. Ban đầu chỉ có một web app nội bộ gọi thẳng vào database. Sau 18 tháng, bức tranh thay đổi: Team mobile cần đọc/ghi đơn hàng từ iOS và Android. Đối tác logistics cần truy vấn trạng thái đơn qua máy chủ của họ. Team data cần kéo dữ liệu định kỳ để làm báo cáo. Một team khác xây admin portal, cũng cần cùng dữ liệu nhưng thao tác khác. Bốn client, bốn ngôn ngữ, bốn vòng đời release khác nhau — tất cả cần truy cập cùng một tập dữ liệu qua HTTP. Câu hỏi kỹ thuật đặt ra: ...

February 22, 2026 · 41 min

Chương 2: HTTP — Nền tảng của giao tiếp hiện đại

← Chương trước | Mục lục | Chương sau → 1. Problem Statement Hãy bắt đầu bằng một tình huống production quen thuộc. Hệ thống e-commerce của bạn có 40 microservice. Một buổi sáng thứ Hai, sau đợt flash sale, team on-call báo cáo: service checkout gọi service pricing với p99 latency tăng từ 15ms lên 800ms, dù CPU của pricing chỉ 30%. Không có deploy mới. Không có query chậm. Metrics của pricing hoàn toàn bình thường. ...

February 22, 2026 · 47 min

Chương 1: Communication Fundamentals — Vì sao hệ thống cần giao tiếp

← Mục lục | Chương sau → 1. Problem Statement: Từ một function call đến một network call Hãy bắt đầu từ một tình huống kinh doanh có thật, không phải từ định nghĩa. Công ty của bạn vận hành một hệ thống thương mại điện tử. Ba năm trước, toàn bộ hệ thống là một monolith viết bằng Go: module order gọi module inventory bằng một function call, module payment gọi module notification bằng một method trên struct. Mọi thứ chạy trong cùng một process, cùng một address space, cùng một failure domain. Một lời gọi hàm mất vài chục nanosecond, không bao giờ “mất gói tin”, không bao giờ trả về một nửa kết quả, và hoặc là cả process sống, hoặc là cả process chết — không có trạng thái lưng chừng. ...

February 22, 2026 · 35 min

Chương 17 — Kiến trúc thực tế: Linux dưới các hệ thống bạn chạy hằng ngày

Chương tổng kết: mỗi hệ thống lớn là một tập lựa chọn trên các trade-off đã học. Đọc mỗi mục và tự kiểm tra: bạn có chỉ ra được chương nào của tài liệu đứng sau từng quyết định không? 17.1. PostgreSQL — đặt cược vào Page Cache của kernel Kiến trúc trên OS: process-per-connection (fork — chương 04; lý do connection đắt và PgBouncer gần như bắt buộc ở connection count cao); shared_buffers là shared memory giữa các process; double buffering có chủ đích: dữ liệu nằm cả ở shared_buffers và Page Cache (Postgres đọc ghi qua buffered IO — tin kernel làm cache tầng hai, khác Oracle/MySQL-InnoDB dùng O_DIRECT tự quản 100%). ...

February 22, 2026 · 8 min

Chương 16 — Production Failure Cases (2): IO, Network & Concurrency

Tiếp nối khung phân tích của chương 15. Case 10 — File Descriptor Exhausted Triệu chứng: accept: too many open files / EMFILE; connection mới bị từ chối trong khi connection cũ vẫn chạy; có thể lan cả máy (ENFILE — trần toàn hệ thống). Bên trong kernel: mỗi process có bảng FD (chương 04, files_struct) giới hạn bởi RLIMIT_NOFILE (mặc định soft 1024 lịch sử — quá thấp cho server!); toàn máy bởi fs.file-max. FD không chỉ là file: socket, pipe, epoll, timerfd, eventfd — mọi thứ là FD. Cạn FD thường là leak: quên close socket khi lỗi giữa chừng, response body không đóng (Go resp.Body.Close() — bug số một của HTTP client Go), connection pool cấu hình vô hạn. ...

February 21, 2026 · 13 min

Chương 15 — Production Failure Cases (1): CPU & Memory

Mỗi case theo khung: Triệu chứng → Root cause phổ biến → Bên trong kernel → Metric & Dashboard → Điều tra từng bước → Khắc phục → Phòng tránh. Các lệnh mặc định chạy được trên mọi máy Linux; công cụ eBPF (bcc-tools) khi có càng tốt. Kiến thức nền: chương tương ứng ghi trong ngoặc. Case 1 — CPU 100% Triệu chứng: %CPU chạm trần; latency tăng; có thể kèm autoscale bùng nổ chi phí. ...

February 21, 2026 · 10 min

Chương 14 — Security: từ "root hoặc không" đến quyền chi li từng syscall

1. Problem Statement Mô hình Unix nguyên thủy chỉ có hai hạng người: root (uid 0) — làm được tất cả, và còn lại — bị giới hạn bởi quyền file. Hai vấn đề chết người: (1) nhiều tác vụ chỉ cần một mẩu quyền root (bind port 80, đổi giờ) nhưng phải trao cả root — ping từng phải setuid-root chỉ để mở raw socket; (2) quyền file không nói gì về hành vi: một process bị khai thác (RCE trong thư viện parse ảnh) được làm mọi thứ user đó làm được — đọc DB credential, mở kết nối ra ngoài, fork shell. ...

February 21, 2026 · 7 min

Chương 13 — Container: không phải máy ảo, mà là ảo ảnh do kernel dựng

1. Problem Statement Bài toán kinh doanh: đóng gói app + dependency thành một đơn vị chạy được ở mọi nơi, khởi động trong milli-giây, nhét hàng chục cái vào một máy, cô lập vừa đủ để không giẫm chân nhau. VM giải được cô lập nhưng trả giá: mỗi VM một kernel + OS riêng (GB memory, khởi động chục giây, density thấp). Câu trả lời của Linux: không cần máy ảo — chỉ cần nói dối process một cách có hệ thống. Container = process bình thường + ba lớp cơ chế kernel: namespace (thấy gì), cgroup (dùng bao nhiêu), capability/seccomp/LSM (làm được gì — chương 14). Không có “Container Kernel Object” nào cả — docker chỉ là trình lắp ráp các cơ chế này. ...

February 21, 2026 · 9 min

Chương 12 — Linux Performance Tools: công cụ hoạt động thế nào, không chỉ dùng thế nào

1. Problem Statement Production chậm. Bạn có 30 phút và một máy 64 core đang chạy 200 process. Câu hỏi không phải “gõ lệnh gì” mà là: mỗi công cụ nhìn hệ thống qua cửa sổ nào, trả giá bao nhiêu để nhìn, và nói dối ở đâu. Không hiểu cơ chế thì: dùng strace làm sập production (overhead 100x), đọc %util của NVMe như HDD (sai), tin flame graph thiếu frame (vì thiếu frame pointer), hay đo latency bằng trung bình (che mất tail). ...

February 21, 2026 · 9 min

Chương 11 — Network Stack: hành trình một packet xuyên kernel

1. Problem Statement NIC là phần cứng nhận/gửi frame Ethernet thô. Ứng dụng muốn một thứ hoàn toàn khác: “một kết nối đáng tin cậy tới host X, gửi byte theo thứ tự, đừng làm mất, đừng làm nghẽn mạng”. Khoảng cách giữa hai thế giới đó — checksum, định tuyến, phân mảnh, retransmit, congestion control, ghép kênh theo port — chính là network stack trong kernel. Đây là mã đường-nóng lớn nhất và được tối ưu khốc liệt nhất của Linux: mọi request tới backend của bạn đi qua nó hai lần (vào và ra). ...

February 21, 2026 · 9 min

Chương 10 — IO Models: từ blocking đến io_uring, tiến hóa của câu hỏi "chờ thế nào"

1. Problem Statement Server có 10.000 connection. Tại mỗi thời điểm chỉ vài trăm connection có dữ liệu; còn lại im lặng. Câu hỏi định hình cả một thế hệ kiến trúc backend: làm sao biết connection nào sẵn sàng mà không tốn một thread cho mỗi connection và không đốt CPU quay vòng hỏi? Đây là “bài toán C10K” (1999) — và mỗi IO model là một câu trả lời ở một thời kỳ. ...

February 21, 2026 · 9 min

Chương 09 — Filesystem: biến mảng block thô thành dữ liệu bền vững

1. Problem Statement Disk (NVMe/SSD/HDD) là một mảng block 512B/4KB đánh số từ 0 đến N. Không tên file, không thư mục, không quyền, không đảm bảo gì khi mất điện giữa chừng. Filesystem phải dựng trên đó: không gian tên phân cấp, quyền sở hữu, cấp phát không phân mảnh, và quan trọng nhất — tính toàn vẹn khi crash (crash consistency). Cộng thêm yêu cầu hiệu năng: disk chậm hơn RAM 100-1000 lần → phải cache quyết liệt — và cache chính là nơi sinh ra khoảng cách giữa “đã ghi” và “đã bền vững”, khoảng cách gây ra nhiều sự cố mất dữ liệu nhất trong nghề backend. ...

February 21, 2026 · 10 min

Chương 08 — Synchronization: cái giá của việc chia sẻ

1. Problem Statement Hai thread cùng chạy counter++. Lệnh này thực chất là ba bước: load → add → store. Xen kẽ giữa hai thread → mất update. Đây là data race — nguồn bug khó tái hiện bậc nhất, và với CPU hiện đại còn tệ hơn trực giác: compiler đảo lệnh, CPU thực thi out-of-order, mỗi core có store buffer riêng — không có “thứ tự toàn cục” tự nhiên nào giữa các core cả. Muốn có, phải trả tiền để mua nó, bằng các primitive của chương này. ...

February 21, 2026 · 8 min

Chương 07 — Memory Management: ảo ảnh lớn nhất và đắt giá nhất

1. Problem Statement RAM là một mảng byte vật lý hữu hạn, phẳng, ai cũng thấy như nhau. Ta cần: (1) mỗi process một không gian địa chỉ riêng, cô lập; (2) tổng memory các process tưởng mình có được phép vượt RAM thật; (3) cấp phát/thu hồi linh hoạt không phân mảnh chết; (4) tận dụng RAM thừa làm cache cho disk. Virtual memory giải cả bốn — với cái giá là mọi truy cập memory đều phải qua một tầng dịch địa chỉ. ...

February 21, 2026 · 10 min

Chương 06 — CPU Scheduling: chia thời gian CPU như thế nào cho công bằng

1. Problem Statement Máy có 32 core; tại một thời điểm có 80 task muốn chạy (runnable). Ai chạy? Chạy bao lâu? Trên core nào? Sai câu trả lời nào cũng có hậu quả: task quan trọng chờ lâu (latency), CPU nhảy task liên tục (mất throughput vì context switch + cache nguội), task nào đó đói vĩnh viễn (starvation), core này 100% core kia rảnh (mất tiền). Nếu không có scheduler: quay lại chương 01 — while(1) chiếm CPU mãi mãi. Scheduler + timer interrupt là bộ đôi biến “một CPU” thành “ảo ảnh nhiều CPU”. ...

February 21, 2026 · 9 min

Chương 05 — Thread: nhiều dòng thực thi, một không gian địa chỉ

1. Problem Statement Process cô lập tốt nhưng trả giá: hai process muốn chia sẻ dữ liệu phải đi đường vòng (pipe, socket, shared memory — đều qua kernel hoặc setup phức tạp), và tạo/chuyển process tương đối đắt. Nhiều bài toán cần điều ngược lại: nhiều dòng thực thi đồng thời trên cùng một khối dữ liệu — web server xử lý 10.000 connection, database xử lý nhiều query cùng chạm một buffer pool. ...

February 21, 2026 · 9 min