Topics overview · Universal Clarify · 3 mock design Q · Quick-fire. Topics chi tiết ở BE page.
Hỏi 5-8 câu từ checklist (không hỏi cả 14 — sẽ lan man). Mặc định lấy từ Functional + Scale + 1-2 câu phù hợp context.
① Functional scope
② Scale & load
③ Latency / performance
④ Consistency
⑤ Multi-tenant
⑥ Auth & permissions
⑦ Real-time
⑧ Data lifecycle
⑨ Mobile / offline
⑩ Integration
⑪ Compliance & security
⑫ Availability / DR
⑬ Cost & constraints
⑭ Team & stack
💡 Cách mở đầu interview
"Trước khi em design, em muốn clarify vài điểm: (1) MVP scope là... (2) scale dự kiến...? (3) đây là single hay multi-tenant? (4) consistency yêu cầu strong hay eventual? Sau khi rõ những cái này em sẽ pick approach phù hợp."
💡 Luôn nói ra suy nghĩ. Interviewer chấm reasoning, không phải đáp án đúng.
Time-box 30 phút/câu, verbalize từng step.
Brief: Tasks có project, assignee, comments, attachments. Multi-tenant. Notify khi assigned.
Specific clarify (ngoài Universal):
Data model:
tenants(id, name, plan)
users(id, tenant_id, email, role)
projects(id, tenant_id, name)
tasks(id, tenant_id, project_id, assignee_id, title, status, due_date)
comments(id, task_id, author_id, body, created_at)
attachments(id, task_id, s3_key, mime, size)
idx_tasks_assignee_status (assignee_id, status)
idx_tasks_project_created (project_id, created_at DESC)
API:
Architecture:
Client → API (NestJS) → Postgres. Redis cache cho task list. BullMQ cho notification. Worker push WebSocket nếu cần real-time comment.
Trade-offs:
Brief: Multi-channel. User preference. Retry on failure. Multi-tenant.
Specific clarify:
Data model:
notifications(id, tenant_id, user_id, type, payload_json, channel, status, retry_count)
user_preferences(user_id, channel, type, enabled, frequency)
templates(id, type, channel, subject, body_html, body_text)
idx_notif_user_status (user_id, status, created_at DESC)
idx_notif_retry (status, retry_count) WHERE status='failed'
Flow:
App emit event → Notification Service → check preferences → write DB (pending) → enqueue BullMQ per channel → Worker render template → send via provider → update status, retry exponential backoff nếu fail
Trade-offs:
Brief: Employee submit, manager approve. Calendar tích hợp. Approval chain (manager → director nếu > 5 ngày).
Specific clarify:
Data model:
leave_types(id, tenant_id, name, paid, max_days_per_year)
leave_balances(user_id, leave_type_id, year, allocated, used)
leave_requests(id, tenant_id, user_id, type_id, start_date, end_date, days, status)
approvals(id, request_id, approver_id, level, status, decided_at)
approval_rules(tenant_id, type_id, min_days, approver_role)
State machine:
draft → submitted → manager_pending → director_pending → approved
↓ ↓
rejected rejected
Trade-offs:
SQL: JOIN/transaction + schema ổn định. NoSQL: write-heavy + schema linh hoạt + sharding.
Lock (single-flight) + stale-while-revalidate + jittered TTL.
Document tự nhiên, không JOIN nặng, schema thay đổi nhiều.
Replication lag. Fix: route "read-after-write" về primary.
JWT cho stateless+mobile. Session-Redis cho web+revoke. Hybrid: JWT short + refresh.
Gọi nhiều = 1 lần. GET/PUT/DELETE idempotent. POST → idempotency-key header.
Data leak. Mitigate: ORM middleware + RLS + integration test.
Team > 2-3 + scale độc lập + deploy độc lập. Đừng start với MS.