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 (C# & .NET, C/C++ & Embedded, AI / Machine Learning). 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.
01Ứng dụng ASP.NET Core bị memory leak hoặc CPU cao trên production. Bạn điều tra thế nào?C# & .NET · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →Thu thập số liệu trước, đoán sau: xem metrics, chụp dump hoặc trace, rồi phân tích.
- Theo dõi bằng
dotnet-counters: heap size, số lần GC từng gen, thread pool queue length, exception rate. - Leak bộ nhớ: chụp hai lần
dotnet-gcdumphoặcdotnet-dumpcách nhau một khoảng, so sánh loại object tăng và tìm ai đang giữ tham chiếu. - CPU cao hoặc treo:
dotnet-traceđể xem hot path; thread pool queue tăng thường do sync-over-async.
Nguyên nhân hay gặp: event handler không gỡ đăng ký, cache static không giới hạn kích thước, giữ
DbContextquá lâu, regex hoặc serialize lặp lại trong vòng lặp nóng.Người phỏng vấn muốn nghe: một ca thực tế bạn từng xử lý, công cụ đã dùng và kết quả trước/sau.
- Theo dõi bằng
02Xử lý concurrency khi nhiều request cùng cập nhật một bản ghi trong EF Core thế nào?C# & .NET · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →Hai hướng chính: optimistic concurrency (phát hiện xung đột khi lưu) và pessimistic (khoá trước khi sửa).
Optimistic với EF Core: đánh dấu một cột làm concurrency token, EF thêm điều kiện so sánh vào
UPDATEvà némDbUpdateConcurrencyExceptionnếu không có dòng nào bị cập nhật.public class Product { public int Stock { get; set; } [Timestamp] public byte[] RowVersion { get; set; } = []; }- Bắt exception, tải lại dữ liệu, rồi retry hoặc báo người dùng.
- PostgreSQL thường dùng cột hệ thống
xminlàm token. - Trường hợp đơn giản như trừ tồn kho có thể dùng một câu
ExecuteUpdateAsyncatomic kèm điều kiệnStock >= qty.
Người phỏng vấn muốn nghe: bạn cân nhắc mức độ tranh chấp: thấp thì optimistic, cao và nghiệp vụ quan trọng thì khoá hoặc đưa vào hàng đợi.
03Bạ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.
04Thiết bị nhúng thỉnh thoảng bị treo hoặc reset ngoài hiện trường. Bạn debug thế nào?C/C++ & Embedded · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Cần thu thập dấu vết từ thiết bị trước, sau đó tái hiện trong phòng lab.
- Lưu nguyên nhân reset: đọc thanh ghi reset cause (watchdog, brown-out, hard fault) khi khởi động và ghi vào flash hoặc gửi log lên.
- Hard fault handler: lưu các thanh ghi PC, LR và stack frame để biết lệnh gây lỗi, sau đó tra file
.maphoặcaddr2line. - Stack overflow: bật kiểm tra stack của RTOS, tô mẫu (stack painting) để đo mức dùng tối đa.
- Watchdog: chỉ "đá" watchdog khi mọi task quan trọng còn sống, không đá trong ISR timer.
- Kiểm tra phần cứng: nguồn sụt áp, nhiễu, nhiệt độ.
Trong lab dùng JTAG/SWD với GDB, logic analyzer và chạy stress test dài.
Người phỏng vấn muốn nghe: một ca thật bạn đã xử lý, cách khoanh vùng và cách chứng minh đã sửa đúng.
05Lập trình đa luồng trong C++ hiện đại: std::atomic, mutex và memory order dùng khi nào?C/C++ & Embedded · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Dữ liệu chia sẻ giữa các thread mà có ít nhất một thread ghi thì phải đồng bộ, nếu không là data race (undefined behavior).
std::mutexvớistd::lock_guardhoặcstd::scoped_lock(khoá nhiều mutex không deadlock): dùng cho vùng găng có nhiều biến hoặc logic phức tạp.std::atomic<T>: cho biến đơn lẻ như cờ, bộ đếm, không cần khoá.- Memory order: mặc định
seq_cstan toàn nhất.acquire/releasedùng cho mẫu producer/consumer;relaxedchỉ cho bộ đếm thống kê không cần thứ tự. - C++20 bổ sung
std::jthread(tự join, có stop token),std::latch,std::barrier,std::counting_semaphore.
std::atomic<int> hits{0}; hits.fetch_add(1, std::memory_order_relaxed);Hay sai: dùng memory order yếu khi chưa thật hiểu, hoặc lock-free hoá sớm khi mutex đã đủ nhanh. Kiểm tra bằng ThreadSanitizer.
06Chatbot RAG trả lời sai dù tài liệu có thông tin đúng. Bạn debug thế nào?AI / Machine Learning · Senior
Gợi ý trả lời
Ôn thêm câu hỏi AI / Machine Learning →Tách lỗi theo từng khâu của pipeline, kiểm tra từ dưới lên.
- Dữ liệu: tài liệu đã được nạp chưa, trích xuất từ PDF/bảng có bị vỡ không, có phiên bản cũ mâu thuẫn không.
- Chunking: thông tin cần thiết có bị cắt đôi giữa hai chunk không.
- Truy xuất: log các chunk lấy về cho câu hỏi đó; đúng chunk có nằm trong top-k không. Thử hybrid search, rerank, viết lại câu hỏi.
- Sinh: chunk đúng đã có trong prompt mà vẫn sai thì xem prompt, thứ tự đặt ngữ cảnh, quá nhiều ngữ cảnh nhiễu.
- Thêm ca này vào bộ eval để tránh tái diễn.
Người phỏng vấn muốn nghe: có tracing để xem từng bước, không đoán mò.
07Bạn tổ chức một dự án .NET lớn thế nào? Clean Architecture có luôn cần thiết?C# & .NET · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →Mục tiêu là tách nghiệp vụ khỏi chi tiết hạ tầng để dễ test và dễ thay đổi; mức độ tách nên tương xứng với độ phức tạp của dự án.
Clean Architecture điển hình có các project: Domain (entity, rule), Application (use case, interface), Infrastructure (EF Core, gửi mail, gọi API ngoài), Api (controller hoặc minimal API). Phụ thuộc chỉ hướng vào trong.
- Dịch vụ CRUD nhỏ thì cách tổ chức theo vertical slice (mỗi tính năng một thư mục) thường gọn hơn và ít boilerplate.
- Tránh bọc thêm repository chung chung lên EF Core nếu nó chỉ chuyển tiếp lời gọi.
- MediatR hay CQRS là công cụ, không phải yêu cầu bắt buộc.
Người phỏng vấn muốn nghe: bạn hiểu trade-off giữa số lớp trừu tượng và tốc độ phát triển, và nêu được lý do cho lựa chọn trong dự án gần nhất.
08Dependency Injection trong ASP.NET Core: phân biệt Transient, Scoped và Singleton.C# & .NET
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →ASP.NET Core có DI container sẵn; lifetime quyết định khi nào tạo instance mới.
- Transient: mỗi lần resolve tạo mới. Hợp với service nhẹ, không trạng thái.
- Scoped: một instance cho mỗi request (mỗi scope).
DbContextmặc định là scoped. - Singleton: một instance cho cả vòng đời ứng dụng. Phải thread-safe.
builder.Services.AddScoped<IOrderService, OrderService>(); builder.Services.AddSingleton<IClock, SystemClock>();Hay sai: inject service scoped (như
DbContext) vào singleton, gọi là captive dependency: DbContext bị giữ mãi và dùng chung giữa nhiều thread. Môi trường Development sẽ báo lỗi khi validate scope. Nếu singleton cần dữ liệu scoped, hãy injectIServiceScopeFactoryvà tự tạo scope.09Middleware trong ASP.NET Core là gì? Thứ tự đăng ký có quan trọng không?C# & .NET
Gợi ý trả lời
Ôn thêm câu hỏi C# & .NET →Middleware là các bước nối thành pipeline xử lý request: mỗi bước có thể xử lý, gọi bước kế tiếp, rồi xử lý tiếp response trên đường về. Thứ tự rất quan trọng vì request đi qua đúng theo thứ tự đăng ký.
app.UseExceptionHandler("/error"); app.UseHttpsRedirection(); app.UseRouting(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers();- Exception handler phải đứng đầu để bắt lỗi của mọi bước sau.
UseAuthenticationphải trướcUseAuthorization, nếu không user luôn là ẩn danh.- Middleware có thể "short-circuit", vd. trả cache hoặc 401 mà không gọi
next.
Người phỏng vấn muốn nghe: bạn từng viết middleware riêng, vd. gắn correlation id hoặc log thời gian xử lý, và phân biệt được middleware với filter của MVC.
10Bạn hãy giới thiệu ngắn về bản thân.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á →Đây là câu mở đầu gần như chắc chắn có. Dùng công thức Hiện tại – Quá khứ – Tương lai, gói trong khoảng 1–2 phút.
- Hiện tại: vị trí, số năm kinh nghiệm, mảng/công nghệ chính.
- Quá khứ: một hai dự án hoặc thành tích liên quan nhất tới vị trí đang tuyển.
- Tương lai: vì sao bạn quan tâm tới vị trí này.
Câu mẫu: "Em là backend developer, khoảng 3 năm kinh nghiệm, chủ yếu làm Java Spring cho hệ thống thanh toán. Ở dự án gần nhất em phụ trách module đối soát và tối ưu các truy vấn báo cáo chạy chậm. Em đang tìm môi trường làm sản phẩm lâu dài để đi sâu hơn về thiết kế hệ thống, nên rất quan tâm tới vị trí này."
Hay sai: kể từ quê quán, trường cấp ba, hoặc đọc lại nguyên CV.
Bạn đã phỏng vấn ở DTS Software 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