Họ đang đo gì
Bạn có từng debug một bug chỉ xảy ra dưới tải không — loại bug không tái hiện được trên máy mình.
Trả lời ngắn~30 giây
Race condition là khi tính đúng đắn phụ thuộc vào thứ tự thực thi mà bạn không đảm bảo được. Mẫu phổ biến nhất là read-modify-write: hai luồng cùng đọc số dư 100, cùng trừ 30, cùng ghi 70 — mất một giao dịch. Điều khiến nó khó là nó thường ĐÚNG: cửa sổ đua chỉ vài micro giây, nên trên máy dev không bao giờ thấy, còn trên production với 1.000 request/giây thì mỗi ngày xảy ra vài lần.
Giải thích sâu
Có ba cách xử lý và chúng khác nhau về chi phí. Một là làm cho thao tác nguyên tử — UPDATE … SET n = n - 30 WHERE n >= 30 đẩy toàn bộ việc so sánh và ghi vào một câu lệnh, và database lo phần còn lại. Hai là khoá — chỉ một luồng vào được vùng găng, đúng nhưng làm chậm mọi người. Ba là loại bỏ trạng thái chia sẻ — mỗi luồng làm việc trên dữ liệu riêng rồi gộp lại. Cách thứ ba tốt nhất khi làm được, vì nó không có gì để đua.
Điều đáng nói là race condition không chỉ có trong code đa luồng. JavaScript chạy một luồng vẫn có: hai fetch cùng cập nhật một state, cái nào trả về sau thì ghi đè — nên người dùng gõ nhanh sẽ thấy kết quả của truy vấn cũ. Cửa sổ đua ở đây là mili giây chứ không phải micro giây, nên nó xảy ra thường xuyên hơn nhiều. Cách chữa là huỷ request cũ bằng AbortController, hoặc bỏ qua phản hồi không còn ứng với truy vấn hiện tại.
Câu hỏi tiếp theo họ sẽ hỏi
?Deadlock khác race condition thế nào?
Race là kết quả sai; deadlock là không có kết quả nào — hai bên chờ nhau vĩnh viễn. Deadlock cần bốn điều kiện đồng thời, và phá bỏ một điều kiện là đủ. Cách rẻ nhất trong thực tế là luôn lấy khoá theo một thứ tự cố định.
Trả lời thế này là mất điểm
- Nói “thêm
sleepđể tránh đua”. Nó chỉ thu hẹp cửa sổ, và làm bug khó tái hiện hơn chứ không biến mất.