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 7 phút

Serializable và write skew: lỗi đồng thời mà Repeatable Read không bắt được

Có một loại bug đồng thời tinh vi hơn lost update: hai giao dịch đọc chung một điều kiện rồi ghi hai hàng khác nhau, phá vỡ một ràng buộc mà không cái nào tự biết. Bài này đo thật trên pg-lab ví dụ hai bác sĩ cùng xin nghỉ: ở Repeatable Read cả hai thành công và còn 0 người trực (sai), ở Serializable một giao dịch bị hủy với lỗi read/write dependencies và ràng buộc được giữ.

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

WAL trong PostgreSQL: vì sao ghi log trước khi ghi dữ liệu, và đo lượng WAL mỗi thao tác sinh ra

Độ bền của PostgreSQL đến từ WAL (write-ahead log): mọi thay đổi ghi vào log tuần tự và fsync xuống đĩa trước, trang dữ liệu ghi sau. Bài này đo thật trên pg-lab lượng WAL sinh ra: INSERT 10.000 hàng tạo 861 kB, COPY cùng dữ liệu chỉ 357 kB, UPDATE nặng nhất 1.645 kB, còn SELECT không sinh WAL. Kèm đánh đổi fsync và synchronous_commit.

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

Bốn loại metric Prometheus: counter, gauge, histogram, summary — và khi nào dùng cái nào

Counter, gauge, histogram, summary nghe na ná nhau nhưng trả lời bốn câu hỏi khác hẳn. Bài này instrument một Go app với cả bốn, bắn 150 request thật rồi đọc thẳng output /metrics: counter dừng ở 150, gauge vọt lên 51 lúc tải rồi về 0, histogram chia bucket cộng dồn, summary tự tính quantile phía client. Kèm bẫy chọn sai loại khiến số liệu thành vô dụng.

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

p50, p95, p99: vì sao trung bình độ trễ nói dối và percentile mới nói thật

Dashboard báo độ trễ trung bình 36ms — service khoẻ? Bài này chạy thật một app có phân bố lệch (95% nhanh, 5% chậm) rồi đo bằng histogram_quantile: trung bình 36ms và p95 25ms đều đẹp, nhưng p99 là 778ms — cứ 100 user thì 1 người chờ gần 0.8 giây. Và một bất ngờ: p99 đo được cao hơn cả giá trị chậm nhất thật, vì bucket chọn quá rộng.

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

Event sourcing: lưu chuỗi sự kiện thay vì trạng thái, và dựng lại mọi thứ bằng replay

Thay vì lưu 'số dư = 200' rồi ghi đè mỗi lần đổi, event sourcing lưu từng sự kiện (nạp 100, rút 30, nạp 50...) và tính trạng thái bằng cách replay chúng. Bài này chạy thật trên Kafka: replay toàn bộ event log dựng lại balance 200, time-travel về quá khứ cho balance 100 tại thời điểm cũ, thêm event rồi replay vẫn đúng 700, và toàn bộ 7 sự kiện còn nguyên làm audit. Đổi lại là chi phí replay.

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

sync.Pool trong Go: cơ chế, bẫy làm nó chậm hơn, và vì sao GC dọn sạch nó

sync.Pool tái dùng object giữa các goroutine, nhưng không phải lúc nào cũng nhanh hơn. Đo thật: pool []byte khi buffer không thoát heap còn CHẬM hơn (compiler để stack + boxing); pool *bytes.Buffer khi object thật sự cấp phát thì nhanh 28%. Và GC dọn sạch pool sau hai chu kỳ. Go 1.23.