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 Go 22/09/2026 10 phút

Go memory model và happens-before: vì sao data race là hành vi không xác định, không phải giá trị cũ

Go memory model định nghĩa khi nào một goroutine nhìn thấy ghi của goroutine khác qua quan hệ happens-before. Đo thật: race detector bắt 2 data race, channel sửa được, và chi phí thiết lập happens-before — mutex 1,5 ns, channel 14,5 ns. Năm quy tắc happens-before. Go 1.23.

Cơ sở dữ liệu 22/09/2026 6 phút

GIN index trong PostgreSQL: đánh chỉ mục bên trong jsonb, mảng và văn bản

B-tree đánh chỉ mục cả giá trị; GIN đánh chỉ mục từng thành phần bên trong nó — mỗi khoá jsonb, mỗi phần tử mảng, mỗi từ trong văn bản. Đo thật ba truy vấn trên bảng 1 triệu dòng: jsonb nhanh gấp 27 lần, full-text gấp 18 lần, và cái giá phải trả.

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

cgroups v2 giới hạn CPU đo thật: --cpus=0.5 đặt cpu.max 50000/100000 chứ không giấu bớt lõi, một khối việc 6 giây phình thành 77 giây ở --cpus=0.2, nproc vẫn báo đủ 10 lõi host, cpu.stat cho thấy luồng bị ghìm 50 trên 51 chu kỳ

cgroups giới hạn cái container dùng, khác namespace cô lập cái nó thấy. --cpus=X đặt cpu.max = quota/period: --cpus=0.5 là 50 ms chạy mỗi 100 ms rồi bị ghìm. Nhưng nproc vẫn báo đủ 10 lõi host, nên Go đặt GOMAXPROCS=10 và Java tính pool theo 10 lõi. Một luồng busy 5 giây ở --cpus=0.5 chỉ chạy 2,55 giây, bị ghìm 50 trên 51 chu kỳ, chờ 2,5 giây dù host rảnh, đọc qua cpu.stat. Cùng khối việc 6 giây chạy như nhau ở 1, 2 hay unlimited CPU nhưng thành 12 giây ở 0.5 và 77 giây ở 0.2. Một request 1 giây CPU biến thành 12 giây.