Cà Phê & Code

Nhấp một ngụm cà phê, viết thêm một dòng code

Cà Phê & Code là blog dành cho những người yêu công nghệ và lập trình. Nơi chia sẻ kiến thức coding, công cụ hữu ích, xu hướng công nghệ, kinh nghiệm phát triển phần mềm và những câu chuyện phía sau màn hình — tất cả được kể theo cách gần gũi, dễ hiểu, như một cuộc trò chuyện bên tách cà phê.

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

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

Giới hạn tần suất API: đo thật trên Redis — bản đọc-rồi-ghi cho qua 50/50 khi giới hạn là 20, fixed window lọt gấp đôi ở biên cửa sổ, và client phớt lờ 429 gửi 52.853 request để lấy 100 thành công

Token bucket trên Redis 7 viết hai cách: hai lệnh rời (HMGET rồi HSET) và một script Lua nguyên tử. 50 request đến cùng lúc với giới hạn 20: bản rời cho qua 50/50 ở hai trên ba lần chạy, bản Lua đúng 20/50 mọi lần. Fixed window cho lọt 200 request trong 0,6 giây quanh biên cửa sổ khi giới hạn là 100/10 giây; sliding log đúng 100. Server trả RateLimit-Limit, RateLimit-Remaining và Retry-After: client cần 100 request thành công ở 20 request/giây — phớt lờ 429 gửi 52.853 request, retry cố định 50 ms gửi 175, tôn trọng Retry-After gửi 104, cả ba cùng mất 4 giây.

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

Test giòn đo thật: năm nguồn kinh điển chạy 100 lần — đua dữ liệu đỏ 91% trên 10 CPU, 0% trên 1 CPU, 100% với -race; trạng thái cấp gói đỏ 0% theo thứ tự mặc định, 54% khi -shuffle; goroutine rò làm test hàng xóm đỏ 97%; bản sửa 0/100

Cấy năm nguồn test giòn vào một gói Go: TTL đo bằng đồng hồ thật, trạng thái cấp gói dùng chung, bộ đếm không mutex, worker nền quên dừng, JSON ghép theo thứ tự duyệt map. Chạy 100 lần và đếm: thời gian đỏ 2% bình thường nhưng 26% khi bóp còn 1 CPU; đua đỏ 91% trên 10 CPU, 0% trên 1 CPU, 100% với -race kèm hai dòng DATA RACE; test phụ thuộc thứ tự đỏ 0% theo thứ tự mặc định qua 100 tiến trình riêng và 54% khi -shuffle=on; worker rò làm test hàng xóm đỏ 97% và goleak chỉ đích danh; map order đỏ 14 đến 25%. Tỉ lệ đỏ là của cặp test và cách chạy. Bản sửa: 0/100 với shuffle và race.

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

Raft trong etcd ba node: đo thật — mất một follower không chậm đi, giết leader là 1,07 giây không ghi được, mất hai node là 0/20 lần ghi nhưng đọc serializable vẫn 20/20

Cụm etcd 3.5.16 ba node, bench Go dùng cả ba endpoint, dừng và giết node bằng docker từ shell. Ba node sống: ghi p50 0,38 ms, đọc linearizable 0,22 ms, serializable 0,08 ms. Dừng một follower: ghi 300/300, p50 0,29 ms, không chậm đi vì đa số vẫn còn. Giết leader giữa lúc ghi liên tục: 1,07 giây không ghi được rồi tự hồi phục với leader mới. Dừng hai node: ghi 0/20, đọc linearizable 0/20, nhưng đọc serializable 20/20 — node sót lại vẫn trả bản cuối nó có. Khởi động lại: ghi được sau 0,45 giây. Cái giá của đồng thuận: 3 node 0,37 ms so với 1 node 0,15 ms, và fsync trên đĩa ảo chỉ 0,06 ms.

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

Validation và hợp đồng đầu vào: đo thật — để lỗi lọt tới database là 1.000 rollback, kiểm-rồi-chèn tạo 48 dòng trùng cho một email, và gom lỗi giảm 6 vòng gửi còn 2

Cùng một request sai, 1.000 lần: để database bắt bằng CHECK tốn 110 µs và 1.000 rollback thật đếm từ pg_stat_database, thân lỗi mang tên constraint; kiểm ở biên tốn 41 µs, 0 rollback, thân lỗi mang tên trường. Form sai 5 trường: dừng ở lỗi đầu bắt client gửi 6 vòng, gom mọi lỗi còn 2. Nhưng kiểm ở biên không thay được ràng buộc: 50 request đăng ký cùng email đến cùng lúc, có bước băm bcrypt 60 ms giữa SELECT và INSERT, tạo 48 dòng trùng; UNIQUE trong database giữ đúng 1 và trả 409. Thân 20 MB: không giới hạn thì đọc hết rồi mới chê sau 66,6 ms, MaxBytesReader 1 MB trả 413 sau 2,1 ms.

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

Secret trong tiến trình đo thật: os.Unsetenv không xoá được /proc/pid/environ nhưng chặn được tiến trình con, log %+v và docker inspect lộ nguyên văn, core dump 118 MB giữ mọi bản sao trừ []byte đã zero, 0400 và tmpfs không cản root

Một binary Go cầm secret qua env, file 0400, tmpfs và argv, chạy hai chế độ rồi đi tìm nó ở chín chỗ. Log %+v in nguyên mật khẩu, kiểu Redacted in [REDACTED]. /proc/pid/environ vẫn giữ ENV_SECRET sau os.Unsetenv, nhưng tiến trình con không còn thấy. Quét /proc/pid/mem: 5 bản sao ở chế độ xấu, 2 ở chế độ tốt. Core dump 118 MB chứa env, mount, argv và bản file cũ nếu không zero, 0 nếu đã zero; ulimit -c 0 thì không có core. uid 65534 bị từ chối đọc file 0400, root đọc bình thường. docker inspect và docker top từ host lộ -e và argv. Watcher mtime tải lại secret sau 400 đến 467 ms, SIGHUP tức thì.

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

Hết hạn chứng chỉ đo thật với vòng đời 60 giây: gia hạn khi còn 1/3 vòng đời thì 1.222 kết nối mới không lỗi nào, gia hạn trễ 5 giây mất đúng 4,97 giây, 200 kết nối đang mở sống 68 giây sau hạn, client chậm 30 giây mất 80% nếu không lùi NotBefore

CA nội bộ cấp chứng chỉ sống 60 giây, server Go tự gia hạn bằng GetCertificate, client probe mỗi 100 ms. Gia hạn khi còn 20 giây: 3 lần xoay, 1.222 probe, 0 lỗi, kết nối mới thấy chứng chỉ mới sau 28 đến 80 ms. Gia hạn trễ 5 giây: 47 kết nối mới bị từ chối, khoảng trống 4,97 giây, lỗi certificate has expired. 200 kết nối mở trước đó sống 200/200 suốt 68 giây sau hạn. Client chậm 30 giây: chứng chỉ có NotBefore bằng lúc cấp gây lỗi not yet valid 30 giây sau mỗi lần xoay, 753/943 probe hỏng; lùi NotBefore 60 giây thì 0 lỗi. Kèm bộ kiểm tra hạn chạy trên coffeecode.vn và badssl.com.