M12 · Game day + mock interview

5 câu hỏi~2–3 ngày (1 ngày game day, 1 buổi phỏng vấn, phần còn lại viết tài liệu)Từ khóa: game day, chaos, runbook, incident, postmortem, blameless, mock interview, rubric

Mình làm xong M11 rồi. Giờ là bài thi cuối đúng không? Mình muốn AI tự gây sự cố mà không báo trước, rồi phỏng vấn mình như thật.

Đúng. M12 không có code mới. Bạn được kiểm tra hai việc: xử lý sự cố khi không biết trước và trình bày toàn bộ hệ thống trước người phỏng vấn.

1. Bối cảnh & bài toán

2. Ôn lại trước khi bắt đầu

3. Đề bài

Phần A: Game day. Chạy k6 tải nền 20 RPS liên tục. AI chọn ngẫu nhiên 3 thẻ trong 8 thẻ dưới đây, gây sự cố vào thời điểm không báo trước (hoặc đưa lệnh cho bạn nhờ người khác chạy mà bạn không xem). Bạn chỉ được nhìn alert, dashboard, trace, log, và phải tuyên bố incident trong 5 phút.

#Thẻ sự cốCách AI gây raDấu hiệu bạn nên thấyMitigate mong đợi
1PSP chậmToxiproxy latency 4s, jitter 2s cho payment → PSPp99 confirm tăng, payment_psp_calls_total{outcome="timeout"} tăng, circuit breaker mởCB fail fast, booking ở PENDING, reconciliation xử lý UNKNOWN
2Kafka broker chếtdocker stop kafka-N (hoặc 2 broker)Under-replicated partitions, outbox pending tăngXác nhận ISR, khởi động lại broker, theo dõi outbox xả hết
3Redis failoverdocker stop redis-masterLỗi kết nối Redis ngắn, rate limit tạm fail-open/fail-closedXác nhận master mới, kiểm tra không trùng ghế
4Cạn connection DBScript mở 100 transaction pg_sleep giữ connection, hoặc hạ max_connectionsHikari pending tăng, connection is not available timeoutTìm và kill session giữ connection, giảm tải, xem lại pool size
5Poison messagePublish 1 message JSON hỏng vào payment.events / queue notificationConsumer lỗi lặp, lag tăng, DLQ có messageMessage vào DLQ/skip, consumer tiến lên, sửa và replay
6Clock skewlibfaketime lệch +10 phút trên 1 instance bookingHold hết hạn sớm/bất thường, JWT nbf/exp lỗi 401Xác định instance lệch, gỡ khỏi traffic; thời hạn hold tính theo giờ DB
7Bad deployDeploy image có bug (vd confirm luôn 500 với 10% request) qua HelmError rate tăng ngay sau deploy, trùng thời điểm rollouthelm rollback trước, tìm bug sau
8Traffic spikek6 tăng từ 20 lên 500 RPS trong 30sRate limit 429, HPA scale, p99 tăngHệ thống từ chối có kiểm soát, không bán trùng, không sập

Với mỗi thẻ bạn phải có sẵn runbook trong docs/runbooks/ theo khung:

# Runbook: <tên>
Triệu chứng / alert nào bắn:
Dashboard / query cần mở:
Kiểm tra nhanh (lệnh):
Mitigate (theo thứ tự, an toàn trước):
Xác nhận đã hồi phục:
Khi nào escalate:

Phần B: Postmortem cho mỗi sự cố, docs/postmortems/YYYY-MM-DD-<slug>.md:

# Postmortem: <tiêu đề>
Trạng thái: Draft | Reviewed        Mức độ: SEV1/2/3
## Tóm tắt (3 câu)
## Tác động: bao nhiêu request lỗi, bao nhiêu booking ảnh hưởng, error budget tiêu hao
## Timeline (UTC): phát hiện → tuyên bố → mitigate → hồi phục
## Phát hiện bằng gì (alert/dashboard), mất bao lâu (TTD)
## Root cause (5 Whys)
## Điều gì tốt / điều gì chưa tốt / may mắn ở đâu
## Action items: | việc | loại (prevent/detect/mitigate) | owner | hạn |
## Bằng chứng: ảnh dashboard, traceId, lệnh đã chạy

Phần C: Mock interview 45 phút: "Thiết kế hệ thống đặt vé sự kiện". AI đóng vai interviewer, bạn không mở code.

PhútNội dung
0–5Làm rõ yêu cầu, số liệu (người dùng, đỉnh RPS, số ghế/event), SLO
5–10Capacity estimate, API chính
10–20Kiến trúc tổng thể, data model (events, seats, bookings, payments, outbox, inbox)
20–35Deep dive do interviewer chọn: chống bán trùng, giữ ghế hết hạn, payment UNKNOWN, saga, flash sale
35–42Sự cố, HA, observability, "tải x10 thì sao?", multi-region
42–45Trade-off, điều sẽ làm khác, câu hỏi ngược

Rubric (mỗi mục 1–4 điểm, đạt khi ≥ 24/32 và không mục nào 1):

Tiêu chí4 điểm trông như thế nào
Làm rõ yêu cầuHỏi đúng câu, ra số liệu và SLO trước khi vẽ
Ước lượngTừ số liệu ra RPS, storage, số instance, có làm tròn hợp lý
Kiến trúcRanh giới service rõ, giải thích vì sao tách
Dữ liệu & tính đúngChống bán trùng bằng DB, idempotency, outbox/inbox, state machine
Chịu lỗiTimeout, retry, CB, saga bù trừ, payment UNKNOWN
Scale & HABiết điểm nghẽn, số liệu benchmark thật từ M9/M11
Vận hànhSLO, alert, trace, kể được sự cố từ game day
Giao tiếp & trade-offNói được "chọn A vì…, chấp nhận mất B", trả lời bằng tiếng Anh được

4. Acceptance criteria

  1. Có 8 runbook, mỗi thẻ một bản, theo đúng khung.
  2. Với 3 sự cố AI gây: tuyên bố incident ≤ 5 phút (TTD), mitigate ≤ 15 phút (TTM).
  3. Sau mọi sự cố: 0 ghế bán trùng, 0 payment bị trừ tiền mà booking không CONFIRMED (đối soát bằng SQL).
  4. Mỗi sự cố có postmortem đủ mục, có ít nhất 2 action item, có số liệu tác động.
  5. Ít nhất 1 action item được làm ngay (vd thêm alert còn thiếu) và có commit.
  6. Mock interview đạt ≥ 24/32 theo rubric, không mục nào 1 điểm.
  7. Kể được 1 sự cố theo STAR bằng tiếng Anh trong 2 phút.

5. Test cases

IDKịch bảnĐiều kiệnKỳ vọng
G1Đối soát sau game dayKết thúc 3 sự cốQuery bán trùng và query payment lệch đều 0 dòng
G2Alert đúngMỗi thẻCó ít nhất 1 alert bắn hoặc ghi vào postmortem là "phát hiện thủ công" + action item
G3Runbook dùng đượcNgười khác (hoặc AI) làm theo runbookMitigate được không cần hỏi tác giả
G4RollbackThẻ 7Error rate về baseline ≤ 5 phút sau rollback
G5Poison messageThẻ 5Consumer lag về 0, message lỗi nằm trong DLQ
-- reconciliation.sql: chạy sau mỗi sự cố
-- 1. ghế bán trùng
SELECT seat_id, count(*) FROM bookings WHERE status='CONFIRMED' GROUP BY seat_id HAVING count(*)>1;
-- 2. payment thành công nhưng booking không CONFIRMED
-- TODO: viết query join payments ↔ bookings (khác DB thì export rồi so, hoặc gọi API)
-- 3. hold đã hết hạn mà ghế vẫn HELD
-- TODO

6. Failure scenarios

Chính là 8 thẻ ở mục 3. Thêm luật chơi:

Biến thểCách tạoMong đợi
Hai sự cố chồng nhauThẻ 1 + thẻ 8 cùng lúcƯu tiên đúng: ổn định tải trước, không đổi nhiều thứ cùng lúc
Alert im lặngAI tắt 1 alert rule trước khi gây sự cốBạn vẫn phát hiện từ dashboard/SLO, ghi action item cho detection
Mitigate saiBạn restart nhầm serviceGhi thật vào timeline, blameless

7. Số liệu cần thu

docs/benchmarks/m12-gameday.md: bảng mỗi sự cố với TTD, TTM, số request lỗi, error budget tiêu hao, có alert hay không. Điểm rubric mock interview và nhận xét của AI lưu ở docs/interview/mock-1.md.

8. Checklist hoàn thành (M12)

Checklist cuối cho toàn project

Lúc AI gây sự cố, mình thấy error rate tăng nhưng không biết bắt đầu từ đâu, mở lung tung mất 10 phút.

Không đưa đáp án, chỉ đưa thứ tự câu hỏi để bạn tự đi:

Hãy biến danh sách này thành panel "First 5 minutes" ở đầu dashboard. Đó là một action item tốt.

Root cause của mình ghi là "mình quên cấu hình DLQ cho queue". Vậy có được không?

Chưa đủ. Blameless nghĩa là hỏi tiếp: vì sao hệ thống cho phép quên? Gợi ý: có test nào bắt được queue thiếu DLQ không? Cấu hình queue có được khai báo bằng code/review không? Alert nào lẽ ra phải báo lag tăng? Action item tốt là thứ làm cho lần sau không thể quên, không phải "lần sau cẩn thận hơn".

Mình tập thử thì 20 phút đầu đã đi vào chi tiết @Version với SQL, chưa kịp vẽ kiến trúc tổng thể.

Gợi ý: luyện "đi rộng trước, sâu sau". Mỗi khối trong sơ đồ nói 1 câu, rồi hỏi interviewer "Anh muốn em đi sâu vào phần nào?". Chuẩn bị sẵn 3 deep dive mỗi cái 5 phút (chống bán trùng, payment UNKNOWN, flash sale), mỗi cái kèm 1 con số thật từ project. Bấm giờ khi tập.

Mình làm xong rồi, review và phỏng vấn mình đi.

Checklist review AI sẽ soi

Câu hỏi phỏng vấn

1. Kể một sự cố bạn đã xử lý.

🇻🇳 Theo STAR: tình huống (PSP chậm 4s trong lúc tải), việc của mình (on-call), hành động (thấy p99 tăng, trace chỉ span PSP, CB mở, booking chờ, reconciliation xử lý UNKNOWN), kết quả (0 trừ tiền sai, X request lỗi, thêm alert cho timeout PSP).

🇬🇧 During a game day the payment provider slowed to four seconds. Traces pointed to the PSP span, the circuit breaker opened, bookings stayed pending and reconciliation resolved unknown payments. No customer was double charged, and we added an alert on PSP timeouts.

2. Khi có sự cố, bạn mitigate trước hay tìm root cause trước?

🇻🇳 Mitigate trước: rollback, giảm tải, gỡ instance lỗi. Root cause tìm sau khi đã ổn định, bằng postmortem.

🇬🇧 Mitigate first: roll back, shed load or remove the bad instance. Root cause analysis comes after the system is stable, in the postmortem.

3. Blameless postmortem là gì, vì sao cần?

🇻🇳 Tập trung vào hệ thống và quy trình đã cho phép lỗi xảy ra, không đổ lỗi cá nhân. Nhờ vậy mọi người khai thật và action item sửa được tận gốc.

🇬🇧 It focuses on how the system allowed the failure rather than who caused it, so people share honestly and the action items fix the system.

4. Nếu được làm lại Ticket Booking, bạn đổi gì?

🇻🇳 Trả lời bằng trade-off có số liệu: ví dụ bỏ Redis lock vì DB constraint đã đủ ở tải đo được, hoặc dùng CDC thay outbox polling khi lag cao. Luôn kèm điều kiện "nếu tải x10 thì...".

🇬🇧 Answer with measured trade-offs, for example dropping the Redis lock because the database constraint was enough at our measured load, and say what would change at ten times the traffic.

Cách nhớ ngắn gọn

Game day: tải nền → sự cố bất ngờ → tuyên bố ≤5' → mitigate ≤15' → đối soát
Thứ tự nhìn: khi nào · ở đâu · latency hay lỗi · trace · lag/pool
Postmortem: tác động · timeline · 5 Whys · action item có owner
Phỏng vấn 45': yêu cầu → ước lượng → kiến trúc → deep dive → vận hành → trade-off

Tự kiểm tra

TTD và TTM là gì, đo bằng cách nào trong game day?

Time to detect và time to mitigate. Lấy từ timeline: lúc AI gây sự cố, lúc bạn tuyên bố incident, lúc error rate về baseline.

Poison message ảnh hưởng gì nếu không có DLQ?

Consumer lỗi lặp vô hạn trên cùng message, chặn cả partition/queue, lag tăng mãi.

Vì sao thời hạn giữ ghế nên tính theo giờ DB chứ không theo giờ của từng instance?

Clock các máy có thể lệch; dùng một nguồn thời gian chung giúp mọi instance đánh giá hết hạn giống nhau.

Bad deploy: rollback hay fix forward?

Mặc định rollback để dừng thiệt hại nhanh, fix forward chỉ khi rollback không an toàn (vd migration không lùi được).

Action item tốt khác action item xấu thế nào?

Tốt: cụ thể, có owner, có hạn, thay đổi hệ thống (test, alert, guardrail). Xấu: "cẩn thận hơn".