Bài viết mới nhất

Tổng 2300 bài
Lập trình 22/09/2026 5 phút

HTTP keep-alive: vì sao 500 request chỉ nên mở 1 kết nối, không phải 500

Bài 1 cho thấy bắt tay TCP tốn một RTT mỗi kết nối. Keep-alive giải đúng chuyện đó ở tầng HTTP: giữ kết nối mở để nhiều request dùng chung, bắt tay đúng một lần. Bài này chạy thật trong Go và đếm kết nối TCP thực: 500 request với keep-alive mở đúng 1 kết nối và nhanh hơn 3,9 lần so với tắt keep-alive mở 500 — cùng những cái bẫy vô tình làm mất keep-alive.

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

Connection pool: vì sao pool mặc định 2 làm bạn mở 546 kết nối cho 2000 request

Keep-alive tái dùng một kết nối cho các request tuần tự, nhưng khi nhiều request chạy song song, mỗi luồng cần một kết nối cùng lúc — đó là việc của connection pool. Bài này chạy thật trong Go: 2000 request song song 50 luồng với pool mặc định (2) mở tới 546 kết nối vì churn, còn pool đủ lớn chỉ mở 50 và nhanh hơn. Giải thích cách chọn kích cỡ pool đúng.

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

DNS resolution: chuyến đi mạng ẩn xảy ra trước cả bắt tay TCP

Trước khi net.Dial kịp bắt tay TCP, có một bước vô hình phải xong: phân giải tên miền thành IP. Bài này chạy thật trong Go: DNS cold tốn 6,97ms (có lúc vọt lên 140ms), cached chỉ 794µs (~9 lần nhanh hơn), còn /etc/hosts thì 1µs không đi mạng. Và httptrace tách được DNS chiếm bao nhiêu trong một request — vì sao DNS chậm/timeout là nguyên nhân 'app chậm' hay bị bỏ sót.

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

Trạng thái socket TCP: đọc /proc/net/tcp để phân biệt TIME_WAIT bình thường với CLOSE_WAIT là bug

Một kết nối TCP đi qua nhiều trạng thái, và hai trong số đó hay gây sự cố: TIME_WAIT và CLOSE_WAIT. Bài này chạy thật trong Go đọc /proc/net/tcp: mở 3000 kết nối ngắn để lại 3091 TIME_WAIT (ăn cổng cục bộ), còn server quên gọi Close để lại đúng 200 CLOSE_WAIT (rò rỉ fd). Giải thích vì sao TIME_WAIT là bình thường còn CLOSE_WAIT tăng không giảm luôn là bug.

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

CBOR: người anh em chuẩn hóa của MessagePack, và vì sao IETF cần thêm một định dạng

CBOR (RFC 8949) gần như MessagePack: nhị phân, tự mô tả, cùng ý tưởng byte format. Vậy sao IETF lại chuẩn hóa thêm một định dạng? Bài này đo thật: cùng đơn hàng, CBOR 339 byte nhỏ hơn cả MessagePack 392 và JSON 440, mã hóa nhanh nhất trong ba. Nhưng khác biệt lớn nhất là CBOR có tag ngữ nghĩa và là chuẩn IETF — nền tảng của WebAuthn, COSE, CWT, IoT.

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

Băng thông vs độ trễ: vì sao đường 'nhanh' vẫn có thể truyền chậm

Băng thông và độ trễ là hai đại lượng khác nhau nhưng hay bị gộp làm 'nhanh'. Bài này chạy thật trong Go: đo throughput 10,5 GB/s và RTT 3µs riêng biệt, tính Bandwidth-Delay Product, và chứng minh cửa sổ nhỏ làm throughput sụt từ 12 GB/s xuống gần 0 — dù băng thông vật lý không đổi. Giải thích vì sao đường dài băng thông cao vẫn chậm nếu cửa sổ nhỏ hơn BDP.