DEV Community

Đạt Trương Thành
Đạt Trương Thành

Posted on

Chia sẽ câu hỏi pv backend dev

Hôm trước mình vừa trải qua một buổi phỏng vấn vị trí Backend Developer Intern tại FPT Telecom. Và mình được tech lead hỏi 3 bài toán sau. Mình đưa ra được solution cho case 1, case 2 thì dự án mình chưa xử lý đến mức đó =)))), case 3 thì mình có dùng Redis nhưng không solve cho case này =))), nên cũng cook luôn

Nay mình viết bài này để chia sẽ đến mọi người 3 case này và solution của nó như sau:

Case 1: Xử lý Race Condition

Câu hỏi: Giả sử trong kho chỉ còn đúng 1 sản phẩm cuối cùng. Có 2 người dùng cùng lúc ấn nút thanh toán ở cùng 1 thời điểm thì điều gì sẽ xảy ra và làm sao để xử lý chuyện kho bị âm?

Và đây là cách mình giải quyết:

Lúc này mình đã nhớ đến quy tắc isolation và consistency trong ACID để xử lý transaction. Và mình đã dùng perssimistic locking trong database transaction để giải quyết.

Nói nôm na cho dễ hiểu, isolation giống như việc bạn đi mua đồ vậy. Khi user A bắt đầu quá trình mua hàng, hệ thống sẽ mở một transaction và dùng lệnh SQL để locking dòng dữ liệu của sản phẩm đó lại.

  • Lúc này, user B cũng gửi request tới, nhưng vì dòng dữ liệu đang bị locking, request của B buộc phải đứng ngoài đợi.
  • Khi A thanh toán xong, số lượng cập nhật thành 0 và transaction đóng lại.
  • Lúc này B mới được phép vào đọc dữ liệu, nhưng kho đã về 0 nên hệ thống sẽ ném exception (throw exception) hết hàng.

Nhờ việc cô lập 2 user này, dữ liệu kho hàng không bao giờ bị âm, từ đó giữ vững được tính consistency cho hệ thống.

Case 2: Xử lý mất Webhook IPN

Câu hỏi: Hệ thống có tích hợp cổng thanh toán VNPay. Khách hàng đã thanh toán thành công, ngân hàng trừ tiền rồi, VNPay chuẩn bị gọi API về server để báo kết quả thì rớt mạng ở browse của client. Vậy hệ thống đã xử lý như nào để đơn hàng của khách không ở mãi ở trạng thái "Chờ thanh toán"?

Và đây là cách mình giải quyết (mình có hỏi Gemini để hỗ trợ case này):

Bản chất của Webhook là một luồng giao tiếp thụ động. Chờ người ta gọi tới thì mới biết kết quả.

Để giải quyết triệt để, backend phải thiết kế thêm một luồng chủ động. Giải pháp ở đây là dùng Cron job.

  • Cứ mỗi 5-10 phút, Cron job sẽ âm thầm quét trong database, tìm ra những đơn hàng nào đang "Chờ thanh toán" quá lâu.
  • Sau đó, hệ thống sẽ mang cái transaction_id đó, chủ động gọi API ngược sang phía VNPay để hỏi đơn hàng này đã thanh toán hay chưa.
  • Nếu VNPay check và báo "Thành công", server của mình sẽ tự động cập nhật trạng thái đơn hàng cho khách hàng.

Case 3: Xử lý High Traffic vào các ngày flash sale

Câu hỏi: Cứ đến các ngày lễ, đặc biệt hay flash sale thì hàng trăm ngàn người dùng truy cập vào app cùng lúc. Database chắc chắn sẽ quá tải và sập. Thì em có giải pháp gì cho vấn đề này?"

Và đây là cách mình giải quyết (tham khảo thêm Gemini):

Với lượng request spike traffic như vậy, nếu bắt database tính toán, truy vấn ổ cứng liên tục thì chắc sẽ cook mất =))))

Giải pháp ở đây là sử dụng CachingRate Limiting

  • Caching: Thực hiện sao lưu những dữ liệu tĩnh từ database lên in-memory cache (ví dụ như Redis). Redis lưu dữ liệu trên RAM, nên khi cả ngàn request ập tới, backend chỉ cần vào Redis lấy dữ liệu trả về ngay lập tức, giảm tải áp lực truy cập vào database để querry data.
  • Rate Limiting: Dùng trong trường hợp bị spam bot hoặc tấn công DDoS. Mình sẽ cấu hình giới hạn số lượng request/s từ một địa chỉ IP. Nếu IP nào bấm tải lại trang liên tục vượt quá con số này, chặn ngay để bảo vệ server.

Kết luận:
Hi vọng bài viết này sẽ giúp các bác nào phỏng vấn backend dev có thể dùng để ôn tập nhé, ngoài phần solve problem này ra, các bác cần phải ôn thêm DSA, SQL,... và đừng fake CV. Chúc may mắn!!!

À mình còn được hỏi một câu so sánh stateful và stateless trong xử lý user session nhưng bài viết đã khá dài nên mình chia sẽ sau nhé

Top comments (0)