Base.vn Prep

2026-05-19 · Middle-level

PHASE 3

Mock Questions

23 câu chia 6 nhóm. Click từng câu để xem hint. Verbalize ra mồm trước gương.

▌React / Frontend

Sự khác nhau giữa useMemouseCallback?

A: Cùng concept (memoize). useMemo cache giá trị. useCallback cache function reference. useCallback(fn, deps) ≡ useMemo(() => fn, deps).

Khi nào dùng React.memo?

A: Child re-render nhiều mà props ít đổi. Chỉ effective khi props primitive hoặc reference stable. Đo bằng DevTools Profiler trước — KHÔNG memoize mọi component.

Controlled vs uncontrolled form, pick cái nào?

A: Controlled — validate realtime, re-render mỗi keystroke. Uncontrolled (ref) — perf tốt cho form lớn. Thực tế: React Hook Form hoặc TanStack Form — uncontrolled internal + dev UX controlled.

Server Component vs Client Component (Next.js 13+)?

A: Server Component (default trong app dir) — render server, không state/event, không ship JS. Bundle nhỏ, data fetch trực tiếp DB. Client Component — "use client". Rule: leaf interactive = client, parent = server.

Tránh re-render không cần thiết?

A: (1) State local nhất có thể. (2) Split component giới hạn scope. (3) React.memo + stable props. (4) Context split (data vs dispatcher). (5) Đo Profiler trước, đừng premature.

▌TanStack Query / Data Layer

staleTime vs gcTime khác gì?

A: staleTime = data còn fresh bao lâu (không auto-refetch). gcTime = giữ trong memory bao lâu sau khi không dùng (default 5m). Stale ≠ deleted — vẫn show cache, chỉ refetch background.

Invalidate query sau mutation?

A: queryClient.invalidateQueries({queryKey:['tasks']}) trong onSuccess. Dùng key factory để invalidate chính xác. Optimistic: onMutate set cache trước, onError rollback.

Khi nào dùng useInfiniteQuery?

A: Pagination kiểu "load more" hoặc infinite scroll. API trả cursor hoặc page number. getNextPageParam trả key cho lần fetch tiếp.

TanStack Query có thay được Redux?

A: Cho server state — có (cache, sync tốt hơn). Cho UI state (modal, theme, form draft) — không. Dùng useState/Zustand. 80% Redux trong app thật ra là server state.

▌Backend / API / Auth

Vì sao access token nên short-lived?

A: JWT không revoke được. Leak = hijack đến khi exp. Short-lived (5-15m) giới hạn exploit window. Refresh token dài hơn nhưng revoke được (lưu DB) + rotate mỗi lần dùng.

JWT lưu ở đâu cho web?

A: Access: memory — KHÔNG localStorage (XSS). Refresh: httpOnly + Secure + SameSite cookie. JS không đọc được. Reload page → /refresh → access mới.

PUT vs PATCH?

A: PUT thay thế toàn bộ (full replace, idempotent). PATCH update partial. Cả 2 idempotent theo spec nhưng PATCH dễ implement non-idempotent.

N+1 query, phát hiện + fix?

A: Phát hiện: log SQL trong dev (Prisma log:['query']). Fix: include/select để JOIN. DataLoader cho GraphQL. Materialized view nếu query phức tạp lặp.

Enforce multi-tenant isolation ở Prisma?

A: (1) Table có tenant_id. (2) Prisma middleware inject where:{tenantId} từ AsyncLocalStorage. (3) Postgres RLS làm safety net. (4) Integration test verify.

Rate limiting handle thế nào?

A: Redis INCR + TTL cho fixed window. Sliding window log chính xác hơn. Token bucket cho burst-friendly. Key = userId/IP. Trả 429 + Retry-After.

401 vs 403?

A: 401 — bạn là ai (chưa auth, token sai/hết hạn). 403 — biết bạn là ai nhưng không có quyền. FE: 401 → redirect login, 403 → "không có quyền".

▌Architecture / Patterns

SOLID là gì, ví dụ thực tế?

A: Single responsibility, Open/closed, Liskov, Interface segregation, Dependency inversion. Xem page principles hoặc design patterns.

Repository pattern khi nào over-engineering?

A: App nhỏ < 5 tables, không swap ORM, team 1-2 người. Prisma trực tiếp trong service đủ. Repository thừa layer, slow phát triển.

Monolith vs microservices?

A: Default monolith. Split khi (1) team > 2-3 squad độc lập, (2) scale khác nhau (video vs API), (3) công nghệ khác (ML Python). Đừng split sớm — phải distributed transaction, eventual consistency.

CI/CD pipeline điển hình?

A: PR → lint + typecheck + test → build → deploy preview. Merge main → migration → deploy prod → smoke test → rollback nếu fail. Cache deps + artifact. Secret qua env.

▌Database

Index khi nào hại?

A: Mỗi index = write update index → chậm INSERT/UPDATE. Low-cardinality (boolean) — full scan rẻ hơn. Composite sai thứ tự (range trước equality) → miss. Đo EXPLAIN ANALYZE.

Breaking migration deploy thế nào?

A: Expand-contract. (1) Add column nullable. (2) Code dual-write. (3) Backfill. (4) Switch read sang mới. (5) Drop cột cũ deploy sau. KHÔNG drop trong cùng deploy với code change.

Transaction isolation level?

A: Read Uncommitted, Read Committed (default Postgres), Repeatable Read, Serializable. Cao = ít concurrent. 99% case Read Committed đủ.

▌Behavioral / STAR Hooks

Kể về 1 lần fix bug khó nhất

Framework: Situation (production bug, user impact) → Task (mình trực) → Action (reproduce, hypothesis, tool, root cause) → Result (số/metric, lesson). Pick bug có depth (race, leak, N+1, stampede) — không pick "typo".

Lần bất đồng với teammate

A: Tránh "tôi đúng họ sai". Show: lắng nghe → data → compromise hoặc spike thử cả 2. Result: giải pháp tốt hơn cả ban đầu, hoặc nhường vì lý do hợp lý.

Vì sao bạn ứng tuyển Base.vn?

Talking points: Product impact (Base phục vụ hàng ngàn DN VN). Stack overlap (Next.js + NestJS + Postgres). Multi-tenant SaaS — bài toán hay. Sản phẩm thực không phải outsource. Muốn build domain HR/Work. Cá nhân hóa — đề cập 1-2 sản phẩm cụ thể.

← Phase 2 Next: Backend →
🎯 TOP 28 DRILL

30-second answer drill

🎯 Top 28 Interview Q · Drill 30s each

BE Async (1-10) · FE/React (11-20) · BE Deep (21-28)

  1. 1. "Node single-thread sao concurrent?" → Event loop + libuv I/O thread pool
  2. 2. "Promise.all vs allSettled?" → all fail-fast; allSettled always wait
  3. 3. "POST /pay click 2 lần?" → Idempotency-Key + INSERT ON CONFLICT
  4. 4. "balance -= 100 race condition?" → Atomic UPDATE / FOR UPDATE / version
  5. 5. "CPU-bound Node không block?" → Worker threads (sharp, crypto, big JSON)
  6. 6. "10GB CSV upload?" → Streams + pipeline + backpressure
  7. 7. "useEffect race?" → AbortController trong cleanup
  8. 8. "setCount trong setInterval không update?" → Stale closure → setCount(prev => prev + 1)
  9. 9. "Search input không spam API?" → Debouncing 300-500ms
  10. 10. "TanStack optimistic update?" → cancel → snapshot → setQueryData → onError rollback / onSettled invalidate
  11. 11. "2 rules của hooks?" → Top level only · Inside component/hook only
  12. 12. "useMemo default dùng không?" → KHÔNG. 3 cases: expensive calc, identity matter cho memo'd child, avoid useEffect re-run
  13. 13. "Controlled vs Uncontrolled?" → React state vs DOM holds value. RHF = hybrid.
  14. 14. "Form 100 fields chậm fix sao?" → React Hook Form (uncontrolled) + Zod + tabs/stepper
  15. 15. "Password realtime validate?" → Zod .refine chain + RHF mode 'onTouched' + useWatch sub-component checklist
  16. 16. "RHF vs TanStack Form?" → RHF mature ecosystem. TanStack Form modern TS + framework-agnostic + first-class async
  17. 17. "isPending vs isFetching?" → isPending: no cached data. isFetching: actively fetching (including background)
  18. 18. "staleTime vs gcTime?" → staleTime: fresh duration. gcTime: cache retention after unmount.
  19. 19. "Query meta để làm gì?" → Metadata sidecar (KHÔNG ảnh hưởng cache). Global handlers đọc → custom error message, invalidation by tag, analytics
  20. 20. "AbortController vs cleanup flag?" → AbortController CANCEL request thật. Flag chỉ skip update.
  21. 21. 🆕 "PUT vs PATCH?" → PUT replace toàn bộ resource. PATCH update partial fields. PUT idempotent theo spec.
  22. 22. 🆕 "201 vs 200 cho POST?" → 201 Created khi tạo resource mới, kèm Location header. 200 chỉ cho read/update có body trả về.
  23. 23. 🆕 "401 vs 403?" → 401 chưa login / token invalid. 403 đã login nhưng không có quyền (RBAC fail).
  24. 24. 🆕 "Tại sao 2 token (access + refresh)?" → Access short-lived (15min) limit blast radius khi leak. Refresh long-lived để renew không bắt re-login. Rotate refresh mỗi lần dùng để detect reuse.
  25. 25. 🆕 "JWT lưu ở đâu?" → Standard 2026: Access in-memory, Refresh trong cookie httpOnly + Secure + SameSite=Strict. localStorage dễ XSS.
  26. 26. 🆕 "Phát hiện N+1 trong Prisma?" → Bật log: ['query'], fix bằng include/select. GraphQL thì DataLoader batch.
  27. 27. 🆕 "Khi nào Interactive transaction?" → Khi op sau cần kết quả op trước (vd post.authorId = user.id mới tạo). Batch array khi op độc lập.
  28. 28. 🆕 "Multi-tenancy default pattern?" → Shared schema + tenant_id column. Enforce qua Prisma middleware hoặc Postgres RLS. Enterprise tier dùng DB-per-tenant.