Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2312 bài viết · Website
Lập trình 22/09/2026 6 phút

Rate limiting với Redis: fixed window, sliding window và token bucket — ba thuật toán, ba mức mượt

Giới hạn số request để chống lạm dụng là bài toán backend kinh điển, và Redis là công cụ lý tưởng nhờ các thao tác nguyên tử. Bài này đo thật trong redis-lab ba thuật toán: fixed window (INCR+EXPIRE, đơn giản nhưng burst ở ranh giới), sliding window (sorted set theo timestamp, mượt hơn, không burst), và token bucket (cho phép burst có kiểm soát). Với limit 5, cả hai đều cho 5 request qua và chặn request 6-7 — nhưng khác nhau ở độ chính xác quanh ranh giới cửa sổ.

Lập trình 22/09/2026 7 phút

Histogram và percentile: vì sao latency trung bình 45ms là lời nói dối, và p99 mới là sự thật

Sếp hỏi 'API nhanh không?', bạn trả lời 'trung bình 45ms'. Cả hai đều sai lầm — vì không ai trải nghiệm cái trung bình đó. Bài này đo thật trên 100.000 mẫu latency lệch: mean 44.9ms nhưng p50 chỉ 15.3ms và p99 tới 725ms — trung bình rơi vào khoảng trống không ai gặp. Kèm cách dựng histogram kiểu Prometheus để ước lượng percentile với O(1) bộ nhớ, và đo thẳng sai số của nó (p95 lệch tới -34%).

Lập trình 22/09/2026 6 phút

Quy hoạch động: vì sao fib(45) mất 2,74 giây với đệ quy nhưng 625 nano giây với memoization

Đệ quy ngây thơ tính Fibonacci gọi hàm 3,67 tỉ lần cho fib(45) và mất gần 3 giây — vì nó tính đi tính lại cùng một giá trị. Bài này đo thật trong go-lab: thêm một mảng nhớ (memoization) biến O(2^n) thành O(n), nhanh hơn ~4 triệu lần, và giải được fib(90) trong 667 ns. Kèm so sánh memoization với tabulation và đánh đổi bộ nhớ.

Lập trình 22/09/2026 6 phút

Read Committed vs Repeatable Read: cùng code, kết quả khác — và lost update âm thầm

Hai mức cô lập trông giống nhau cho đến khi có ghi đồng thời. Bài này đo thật trên pg-lab mẫu đọc-tính-ghi kinh điển: ở Read Committed, hai giao dịch cùng +10 cho kết quả 110 thay vì 120 — lost update âm thầm, không báo lỗi. Ở Repeatable Read, PostgreSQL phát hiện và báo could not serialize access, buộc thử lại — và lần thử lại cho đúng 120.

Lập trình Go 22/09/2026 10 phút

Batch insert trong Go: vì sao chèn từng dòng chậm gấp trăm lần

Chèn N dòng bằng N lệnh Exec là N vòng đi-về mạng, mỗi vòng trả giá độ trễ cố định. Nút thắt là SỐ round-trip, không phải tốc độ chèn một dòng. Đo thật trong Go: chèn 2000 dòng từng cái mất 2.6s (2000 round-trip); multi-row INSERT gộp lô 200 chỉ 14ms (10 round-trip) — nhanh 193 lần.