10 câu hỏi có thể gặp khi phỏng vấn
Chọn theo kỹ năng và cấp của tin (JavaScript & TypeScript, Java, C# & .NET). Gợi ý trả lời do Drama Công Ty biên soạn để bạn ôn nhanh, không phải đề của công ty.
01Dùng generics và type narrowing trong TypeScript thế nào? Cho ví dụ discriminated union.JavaScript & TypeScript · Senior
Gợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →Generics giúp viết hàm và kiểu dùng lại được mà vẫn giữ thông tin kiểu, thay vì rơi về
any.type Result<T> = | { ok: true; data: T } | { ok: false; error: string }; function show(r: Result<User>) { if (r.ok) return r.data.name; // TS biết có data return r.error; }- Field chung (
ok,type,status) giúp TypeScript thu hẹp kiểu trongif/switch. Đây là cách mô hình hoá trạng thái không thể sai: không có chuyện vừa códatavừa cóerror. - Ràng buộc generic:
<T extends { id: string }>. - Utility types hay dùng:
Partial,Pick,Omit,Record,ReturnType,Awaited. - Type guard tự viết:
function isUser(x: unknown): x is User.
Người phỏng vấn muốn nghe: bạn dùng kiểu để làm trạng thái sai không biểu diễn được, chứ không chỉ để chú thích.
- Field chung (
02Một trang web dùng càng lâu càng chậm và tốn RAM. Bạn tìm memory leak ở frontend thế nào?JavaScript & TypeScript · Senior
Gợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →Memory leak ở frontend thường do thứ gì đó vẫn giữ tham chiếu đến object đáng lẽ đã bỏ đi, nhất là trong SPA vì trang không bao giờ tải lại.
Nguyên nhân hay gặp:
addEventListenertrênwindow/documentmà không gỡ khi component bị huỷ.setInterval, subscription (WebSocket, store) không huỷ.- DOM đã bị gỡ khỏi trang nhưng vẫn được biến JS giữ lại (detached DOM).
- Cache hoặc mảng toàn cục chỉ tăng không giảm.
Cách điều tra với Chrome DevTools:
- Tab Memory: chụp heap snapshot, thực hiện thao tác vài lần, chụp lại, so sánh phần tăng thêm.
- Lọc "Detached" để tìm DOM bị giữ, xem chuỗi retainers để biết ai đang giữ.
- Tab Performance bật Memory để xem heap có giảm sau GC không.
Người phỏng vấn muốn nghe: mỗi tài nguyên đăng ký đều có chỗ huỷ tương ứng (cleanup của effect,
ngOnDestroy,onUnmounted,AbortController).03Core Web Vitals gồm những chỉ số nào? Bạn cải thiện hiệu năng tải trang ra sao?JavaScript & TypeScript · Senior
Gợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →Ba chỉ số chính đo trải nghiệm thật của người dùng:
- LCP (Largest Contentful Paint): thời gian hiện phần tử lớn nhất. Cải thiện: tối ưu ảnh (định dạng hiện đại, đúng kích thước, ưu tiên tải ảnh hero), giảm thời gian phản hồi server, cache/CDN, render phía server.
- INP (Interaction to Next Paint, thay FID từ 2024): độ trễ khi tương tác. Cải thiện: chia nhỏ tác vụ JS dài, giảm JS chạy trên main thread, tránh render lại quá nhiều.
- CLS (Cumulative Layout Shift): độ xô lệch bố cục. Cải thiện: khai báo kích thước cho ảnh, video, quảng cáo; tránh chèn nội dung đẩy trang xuống; xử lý font.
Ngoài ra: code splitting và lazy load theo route, bỏ thư viện nặng không cần, nén và cache tài nguyên tĩnh.
Người phỏng vấn muốn nghe: bạn đo bằng dữ liệu người dùng thật (field data) lẫn Lighthouse, và biết điểm Lighthouse không phải là mục tiêu cuối.
04So sánh
synchronized,volatile,ReentrantLockvàConcurrentHashMap. Bạn tránh race condition thế nào?Java · SeniorGợi ý trả lời
Ôn thêm câu hỏi Java →Race condition xảy ra khi nhiều thread đọc-sửa-ghi cùng dữ liệu mà không đồng bộ. Mỗi công cụ giải quyết một phần:
volatile: đảm bảo visibility (thread khác thấy giá trị mới nhất), nhưng không làmcount++thành atomic.synchronized: vừa loại trừ lẫn nhau vừa đảm bảo visibility (quan hệ happens-before).ReentrantLock: nhưsynchronizednhưng cótryLockvới timeout, lock có thể ngắt, nhiềuCondition.AtomicInteger/LongAdder: đếm không cần lock.ConcurrentHashMap: thread-safe với độ tranh chấp thấp. Dùngcompute/merge/putIfAbsentcho thao tác kép, đừnggetrồiput.
Hay sai: dùng
Collections.synchronizedMaprồi duyệt map mà không lock, hoặc kiểm traif (!map.containsKey(k)) map.put(k, v)trên map đồng thời: hai bước riêng lẻ vẫn bị chen ngang. Cách tốt nhất vẫn là giảm state dùng chung (object bất biến, mỗi thread một bản).05Một service Spring Boot trên production đột nhiên chậm, CPU cao hoặc bị OOM. Bạn điều tra thế nào?Java · Senior
Gợi ý trả lời
Ôn thêm câu hỏi Java →Đi từ số liệu đến bằng chứng, đừng đoán rồi sửa.
- Xem metrics (Actuator, Micrometer): latency, số request, heap, GC pause, connection pool đang chờ, thời gian gọi DB và API ngoài.
- CPU cao: lấy thread dump vài lần cách nhau vài giây (
jcmd <pid> Thread.printhoặcjstack), tìm thread luôn RUNNABLE ở cùng chỗ. Có thể là vòng lặp, regex xấu, hoặc GC chạy liên tục. - Chậm mà CPU thấp: thread đang chờ: hết connection DB, lock, gọi API ngoài không có timeout.
- OOM hoặc heap tăng dần: bật
-XX:+HeapDumpOnOutOfMemoryError, mở heap dump bằng Eclipse MAT, xem ai giữ nhiều bộ nhớ nhất. - Java Flight Recorder (
jcmd <pid> JFR.start) cho profile chi phí thấp, dùng được trên production.
Người phỏng vấn muốn nghe: có quy trình rõ ràng, biết cả cách giảm thiệt hại tạm thời (rollback, scale) trước khi tìm nguyên nhân gốc.
06Bạn tối ưu hiệu năng một Web API .NET chịu tải cao thế nào?C# & .NET · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →Bắt đầu bằng đo đạc (load test, APM, profiler), sau đó xử lý các điểm nghẽn phổ biến theo thứ tự tác động.
- I/O: async xuyên suốt, không sync-over-async; dùng connection pool đúng cách.
- Database: projection,
AsNoTracking, index đúng, tránh N+1; với bulk update dùngExecuteUpdateAsync. - Cache:
IMemoryCache, distributed cache (Redis),HybridCachetừ .NET 9, output caching cho response công khai. - Cấp phát bộ nhớ: giảm object tạm trong hot path, dùng
Span<T>,ArrayPool,System.Text.Jsonvới source generator. - Hạ tầng: response compression, rate limiting middleware, scale ngang khi stateless.
Luôn so sánh số liệu trước và sau (p95 latency, throughput, CPU, GC). Micro-optimize nên đo bằng BenchmarkDotNet.
Hay sai: tối ưu code C# trong khi 90% thời gian nằm ở query DB.
07Frontend cần chú ý gì về bảo mật: XSS, CSRF, CORS? Nên lưu access token ở đâu?JavaScript & TypeScript · Senior
Gợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →- XSS: kẻ tấn công chèn script chạy trên trang của bạn. Phòng: framework tự escape khi render; tránh
innerHTML,v-html,dangerouslySetInnerHTMLvới dữ liệu người dùng (nếu bắt buộc thì sanitize); cấu hình Content-Security-Policy. - CSRF: trang lạ khiến trình duyệt gửi request kèm cookie của người dùng. Phòng: cookie
SameSite=LaxhoặcStrict, CSRF token, kiểm traOrigin. - CORS: là cơ chế trình duyệt nới lỏng same-origin policy, do server cấu hình. Nó không phải lớp bảo vệ API khỏi người gọi ngoài trình duyệt.
Lưu token:
localStoragetiện nhưng script XSS nào cũng đọc được.- Cookie
HttpOnly+Secure+SameSitethì JS không đọc được, nhưng phải tính đến CSRF.
Người phỏng vấn muốn nghe: không có chỗ lưu nào an toàn tuyệt đối; chặn XSS mới là việc quan trọng nhất, vì có XSS thì mọi cách lưu đều bị lợi dụng.
- XSS: kẻ tấn công chèn script chạy trên trang của bạn. Phòng: framework tự escape khi render; tránh
08Phân biệt
var,letvàconst. Hoisting và temporal dead zone là gì?JavaScript & TypeScript · JuniorGợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →varcó phạm vi hàm, cònlet/constcó phạm vi block ({}).constkhông cho gán lại biến, nhưng object hay array bên trong vẫn sửa được.- Hoisting: khai báo được "kéo" lên đầu phạm vi.
varđược khởi tạo sẵn làundefined, nên dùng trước khi khai báo không báo lỗi. let/constcũng được hoist nhưng chưa khởi tạo. Truy cập trước dòng khai báo némReferenceError; khoảng đó gọi là temporal dead zone.- Function declaration được hoist cả phần thân, nên gọi được trước khi định nghĩa.
console.log(a); // undefined console.log(b); // ReferenceError var a = 1; let b = 2;Người phỏng vấn muốn nghe: mặc định dùng
const, cần gán lại mới dùnglet, và gần như không dùngvartrong code mới.- Hoisting: khai báo được "kéo" lên đầu phạm vi.
09
==và===khác nhau thế nào? Những giá trị nào là falsy?JavaScript & TypeScript · JuniorGợi ý trả lời
Ôn thêm câu hỏi JavaScript & TypeScript →===so sánh cả kiểu lẫn giá trị.==ép kiểu trước khi so, nên cho ra kết quả khó đoán:"0" == 0làtrue,[] == falsecũngtrue.- Các giá trị falsy:
false,0,-0,0n,"",null,undefined,NaN. Mọi thứ khác là truthy, kể cả[],{}và"0". NaN === NaNlàfalse; dùngNumber.isNaN(x).- Ngoại lệ hay được chấp nhận:
x == nullđể bắt cảnulllẫnundefined.
Hay sai: viết
const page = input || 1. Khi người dùng nhập0, giá trị bị thay bằng1. Dùng nullish coalescinginput ?? 1để chỉ thay khi lànullhoặcundefined.- Các giá trị falsy:
10Điểm yếu của bạn là gì?Câu hỏi hành vi & văn hoá
Gợi ý trả lời
Ôn thêm câu hỏi Câu hỏi hành vi & văn hoá →Chọn điểm yếu thật, không chí mạng với vị trí, và cho thấy bạn đang cải thiện.
Cấu trúc: điểm yếu, ảnh hưởng đã gặp, việc bạn đang làm để khắc phục, tiến bộ đến nay.
Câu mẫu: "Trước đây em hay ngại hỏi khi bị kẹt, tự loay hoay quá lâu, có lần làm trễ task. Giờ em tự đặt giới hạn: kẹt quá một hai giờ mà không có hướng thì em hỏi đồng đội, kèm những gì đã thử. Từ khi làm vậy em xong việc đúng hạn hơn và học được nhanh hơn từ người khác."
Ví dụ khác có thể dùng: chưa quen nói trước đám đông, tiếng Anh nói chưa trôi chảy, hay ôm việc.
Hay sai: "Điểm yếu của em là quá cầu toàn" (nghe như né câu hỏi), hoặc nêu điểm yếu là kỹ năng cốt lõi của vị trí.
Bạn đã phỏng vấn ở ISV Vietnam?
Kể lại các vòng và câu hỏi đã gặp (ẩn danh) để người sau ôn đúng trọng tâm.
Chia sẻ kinh nghiệm phỏng vấn