#engineering
38 bài viết về chủ đề này
Idempotency key — Chống trừ tiền 2 lần khi API bị retry
Idempotency key giúp API xử lý an toàn khi client retry: trùng request vẫn trả kết quả cũ, không bao giờ trừ tiền 2 lần.
Go pprof thực chiến — Tìm bottleneck và rò rỉ memory
Profile CPU, heap và goroutine bằng pprof trong Go: cách bật endpoint, đọc flame graph và kinh nghiệm bắt bottleneck thực tế.
Hexagonal Architecture — Kiến trúc đặt domain làm trung tâm
Hiểu Hexagonal Architecture (Ports & Adapters) qua ví dụ Go: tách business logic khỏi framework và database, code dễ test và dễ thay đổi hơn hẳn.
Đổi schema database không downtime — Expand & Contract thực chiến
Migrate schema Postgres an toàn trên production: expand & contract, backfill theo batch, chuyển code từng phase — không cần tắt service.
TypeScript Generics thực chiến — Viết code tổng quát mà vẫn an toàn
Generics trong TypeScript qua ví dụ thực tế: generic function, extends, keyof, infer và cách tránh over-engineering khi áp dụng vào dự án.
Thundering Herd — Khi cache hết hạn là cả hệ thống sụp
Thundering herd là gì? Khi một key cache 'nóng' hết hạn, hàng chục nghìn request cùng đổ vào database. Kèm cách chặn: singleflight, Redis lock và jitter TTL.
Docker multi-stage build — Cắt image từ 1.2GB xuống 90MB
Học multi-stage build trong Docker để giảm image từ 1.2GB xuống 90MB — kèm Dockerfile mẫu, tricks layer cache và kinh nghiệm deploy VPS thực tế.
Testcontainers — Hết cảnh mock database khi viết integration test
Testcontainers chạy PostgreSQL, Redis thật trong Docker cho integration test — hết cảnh mock giả, test sát production hơn. Kèm ví dụ Go.
Pragmatic Programmer – Topic 47: Working Together — Code chung
Topic 47 Pragmatic Programmer: pair programming và mob programming — vì sao code chung lại cho kết quả tốt hơn, và làm sao để pair thật sự hiệu quả.
Goroutine Leak trong Go — Kẻ giết RAM thầm lặng
Goroutine leak âm thầm ăn hết RAM của bạn. Nhận diện 3 pattern leak kinh điển và fix bằng context + select + goleak.
Pragmatic Programmer – Topic 46: Solving Impossible Puzzles — Phá bẫy
Topic 46 Pragmatic Programmer: bài toán 'bất khả thi' thường chỉ bị giới hạn bởi suy nghĩ của chính mình. Cách nhận diện ràng buộc tự đặt và phá bẫy.
Kafka, RabbitMQ hay Redis Streams? Chọn message queue cho backend
So sánh Kafka, RabbitMQ và Redis Streams: ưu nhược điểm, khi nào dùng cái nào, kèm code Go consumer với retry và dead letter queue.
Pragmatic Programmer – Topic 45: The Requirements Pit — Đào bới yêu cầu
Yêu cầu hiếm khi nằm trên bề mặt — Topic 45: đào bới yêu cầu thật, biến requirements thành hội thoại, dùng project glossary.
API Gateway — Cánh cửa duy nhất của backend hiện đại
API Gateway là cửa ngõ duy nhất cho mọi request: routing, auth tập trung, aggregation. Kèm code Go thực chiến và khi nào KHÔNG nên dùng.
PostgreSQL Indexing thực chiến — B-tree, GIN và cái bẫy hay gặp
Index là con dao hai lưỡi: đúng thì query chạy như gió, sai thì database phình to. Học B-tree, GIN, partial index và cách tránh bẫy thực tế.
Pragmatic Programmer – Topic 44: Naming Things — Đặt Tên Cho Đúng
Cái tên quyết định code dễ đọc hay ác mộng. Topic 44 Pragmatic Programmer — đặt tên theo ý định, không theo cách thực hiện.
Observability cho Backend — OTel, Metrics & Tracing thực chiến
Log chỉ kể chuyện gì xảy ra, metrics & tracing mới trả lời vì sao. Setup OpenTelemetry trong Go: tracer, span, histogram — kèm bài học thực tế.
Integration Testing với Testcontainers — Test thật, không mock
Học cách dùng Testcontainers để viết integration test với dependency thật (Postgres, Redis) trong Go — không mock, chạy CI mượt, code an tâm hơn.
Pragmatic Programmer – Topic 43: Stay Safe Out There — Bảo Vệ Code Trước Thế Giới Bên Ngoài
Topic 43 — Stay Safe Out There: bảo vệ code của bạn khỏi thế giới bên ngoài với nguyên tắc validate input, least privilege, defense in depth, và encryption.
Pragmatic Programmer – Topic 42: Property-Based Testing — Để Framework Tự Tìm Bug Cho Bạn
Property-based testing giúp phát hiện edge case mà example-based test không bao giờ thấy — trải nghiệm với fast-check, Hypothesis và QuickCheck.
Graceful Shutdown trong Go — Signal, Context & bài học thực tế
Học cách graceful shutdown HTTP server, worker pool và background jobs trong Go bằng signal.Notify, context và sync.WaitGroup từ kinh nghiệm production thực tế.
Test to Code — Nếu Không Test, Thì Code Của Bạn Không Hoạt Động (Pragmatic Programmer #41)
Testing không phải là giai đoạn riêng — nó là một phần của coding. Cảm nhận về Topic 41 từ Pragmatic Programmer.
Redis Caching — Cache Aside, Read Through và chiến lược cho production
Tìm hiểu chiến lược cache với Redis: Cache Aside, Read Through, Write Through kèm code Go thực tế và kinh nghiệm production.
Pragmatic Programmer – Topic 40: Refactoring — Dám đụng vào code cũ
Refactoring trong Pragmatic Programmer — cách tiếp cận code cũ như khu vườn cần chăm sóc, không phải toà nhà chỉ xây một lần
Docker Multi-Stage Builds — Từ 1.2GB xuống 15MB
Học cách dùng multi-stage build trong Docker để giảm kích thước image Go app từ 1.2GB xuống chỉ 15MB — nhanh hơn, an toàn hơn khi deploy.
Error Handling trong Rust — Result, Option và câu chuyện `?`
Rust không có exception, chỉ có Result và Option. Mình chia sẻ cách xử lý lỗi trong Rust — từ unwrap tới error chains với anyhow và thiserror.
PostgreSQL EXPLAIN ANALYZE & Composite Index — Cặp bài trùm query chậm
Học cách đọc EXPLAIN ANALYZE và thiết kế composite index trong PostgreSQL — tăng tốc query từ 12 giây xuống còn 45ms.
Consistent Hashing — Thuật toán phân phối tải đồng đều
Consistent Hashing giúp distributed systems thêm/xoá node mà không cần rehash toàn bộ. Từ Redis Cluster đến load balancer — tất cả đều dùng.
Table-Driven Tests trong Go — Viết test sạch, maintain dễ
Table-driven tests giúp Go tests gọn gàng, dễ thêm case mới. Học pattern này qua ví dụ thực tế và kinh nghiệm production.
JavaScript Event Loop — Microtask vs Macrotask trong async
Hiểu rõ Event Loop, Microtask và Macrotask trong JavaScript — cách Node.js và browser xử lý code bất đồng bộ.
.NET Middleware Pipeline — request đi qua đâu trước Controller?
Tìm hiểu Middleware Pipeline trong .NET — cách request HTTP chạy qua từng lớp middleware, custom middleware và exception handling thực tế.
PostgreSQL Index Types — B-tree, Hash, GiST, GIN và cách chọn
PostgreSQL có nhiều loại index hơn bạn nghĩ. Từ B-tree đến BRIN — học cách chọn đúng index cho từng loại query với EXPLAIN ANALYZE thực tế.
Docker Multi-Stage Builds — image Go từ 1GB xuống 20MB
Docker multi-stage builds giảm image Go từ 1GB xuống 20MB. Học cách build nhẹ, an toàn, nhanh với Dockerfile mẫu và kinh nghiệm production.
Redis Caching — Cache Aside, Read Through & Write Through trong production
Cache là chìa khóa performance cho hệ thống backend. Tìm hiểu 3 pattern caching phổ biến nhất với Redis: Cache Aside, Read Through, Write Through — code kèm ví dụ thực tế.
PgBouncer & Connection Pooling — vì sao app chậm dù DB vẫn xanh?
Connection pooling không chỉ là chuyện "mở nhiều kết nối". Học cách dùng PgBouncer, tune pool size đúng cách và tránh 5 sai lầm thường gặp.
Circuit Breaker Pattern — đừng để một service chết kéo sập cả hệ thống
Tìm hiểu Circuit Breaker pattern — cách ngăn chặn cascade failure trong microservices với code Go thực tế.
gRPC — Khi REST không còn đủ nhanh cho microservices
Khám phá gRPC — giao thức giao tiếp microservices nhanh hơn REST nhờ HTTP/2, Protobuf và streaming, kèm code Go thực tế.
Testcontainers — integration test với database thật, không cần mock
Testcontainers giúp bạn chạy integration test với PostgreSQL, Redis, Kafka thật trong container. Tạm biệt mock, tạm biệt những bug chỉ xuất hiện ở production.