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/C++ & Embedded, Python, 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.
01Viết hàm phục vụ ngắt (ISR) cần lưu ý những gì?C/C++ & Embedded
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →ISR phải ngắn và nhanh: ghi nhận sự kiện, lấy dữ liệu tối thiểu, rồi để phần xử lý nặng cho task hoặc vòng lặp chính.
- Không gọi hàm có thể block (delay, chờ mutex), không
printf, tránh cấp phát động. - Biến dùng chung với code chính khai báo
volatilevà truy cập atomic, hoặc tắt ngắt ngắn khi đọc dữ liệu nhiều byte. - Xoá cờ ngắt đúng cách để không bị gọi lại liên tục.
- Với RTOS, chỉ dùng API dành cho ngắt (vd. hàm có hậu tố
FromISRtrong FreeRTOS) để báo task qua semaphore, queue hoặc task notification. - Dùng ring buffer cho dữ liệu đến liên tục như UART.
Người phỏng vấn muốn nghe: bạn biết về độ ưu tiên ngắt, ngắt lồng nhau, và cách đo thời gian chạy ISR bằng cách bật tắt một chân GPIO rồi xem trên oscilloscope.
- Không gọi hàm có thể block (delay, chờ mutex), không
02RTOS khác vòng lặp super-loop thế nào? Mutex khác semaphore ra sao?C/C++ & Embedded
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Super-loop chạy tuần tự các việc trong một vòng
while(1), đơn giản nhưng một việc chậm sẽ làm trễ mọi việc khác. RTOS có scheduler preemptive theo độ ưu tiên, giúp các việc cần thời gian thực được đáp ứng đúng hạn.- Mutex: khoá loại trừ cho tài nguyên dùng chung, có khái niệm sở hữu (ai khoá thì người đó mở) và thường có priority inheritance để giảm đảo ưu tiên.
- Binary semaphore: dùng để báo hiệu giữa ISR và task hoặc giữa các task, không có sở hữu.
- Counting semaphore: quản lý N tài nguyên giống nhau.
Hay sai: dùng semaphore thay mutex để bảo vệ tài nguyên, gặp priority inversion: task ưu tiên cao chờ task thấp đang giữ khoá, trong khi task trung bình chiếm CPU.
Người phỏng vấn muốn nghe: bạn biết đặt độ ưu tiên task và kích thước stack hợp lý, và từng phát hiện stack overflow.
03Undefined behavior trong C/C++ là gì? Cho ví dụ và cách phát hiện.C/C++ & Embedded · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Undefined behavior (UB) là những thao tác mà chuẩn ngôn ngữ không quy định kết quả. Compiler được phép giả định UB không bao giờ xảy ra và tối ưu theo giả định đó, nên lỗi có thể chỉ lộ ra ở bản build
-O2hoặc trên một compiler khác.Ví dụ hay gặp:
- Tràn số nguyên có dấu (tràn số không dấu thì được định nghĩa là quay vòng).
- Truy cập mảng ngoài phạm vi, dereference con trỏ null hoặc dangling.
- Đọc biến chưa khởi tạo, data race giữa các thread.
- Vi phạm strict aliasing, vd. ép
float*sangint*rồi đọc (nên dùngmemcpyhoặcstd::bit_casttừ C++20).
Phát hiện: bật cảnh báo
-Wall -Wextra, chạy test với-fsanitize=address,undefined, dùng static analysis (clang-tidy, cppcheck, MISRA checker).Người phỏng vấn muốn nghe: "chạy đúng trên máy tôi" không chứng minh code không có UB.
04Context manager (
with) là gì? Làm sao tự viết một context manager?PythonGợi ý trả lời
Ôn thêm câu hỏi Python →Context manager đảm bảo việc "mở" và "dọn dẹp" luôn đi cùng nhau, kể cả khi có exception: đóng file, trả connection, nhả lock, rollback transaction.
Cách nhanh nhất là dùng
contextlib.contextmanager:from contextlib import contextmanager @contextmanager def db_transaction(conn): try: yield conn conn.commit() except Exception: conn.rollback() raise- Cách đầy đủ: viết class có
__enter__và__exit__(self, exc_type, exc, tb). Nếu__exit__trả vềTruethì exception bị nuốt. - Bản async:
async with,__aenter__/__aexit__hoặcasynccontextmanager.
Hay sai: quên
raiselại exception trong khốiexcept, khiến lỗi bị che mất và code phía sau tưởng mọi thứ đã thành công.- Cách đầy đủ: viết class có
05Giải thích event loop của asyncio. Trong FastAPI, khi nào viết
async defvà khi nào viếtdef?Python · SeniorGợi ý trả lời
Ôn thêm câu hỏi Python →asyncio chạy nhiều coroutine trên một thread. Khi coroutine gặp
awaitmột thao tác I/O, nó nhường quyền cho event loop chạy coroutine khác. Đây là đa nhiệm hợp tác: coroutine nào khôngawaitthì chiếm luôn cả loop.Trong FastAPI:
async defkhi mọi thứ bên trong đều async (httpx.AsyncClient, driver DB async).defkhi dùng thư viện blocking (requests, ORM đồng bộ). FastAPI sẽ chạy hàm này trong threadpool, nên không chặn loop.- Gọi song song:
await asyncio.gather(fetch_a(), fetch_b()).
Hay sai: viết
async defrồi gọirequests.get()hoặctime.sleep()bên trong. Cả server đứng hình trong lúc chờ. Nếu buộc phải gọi code blocking, dùngawait asyncio.to_thread(func).Người phỏng vấn muốn nghe: async tăng khả năng xử lý đồng thời cho I/O, không làm code CPU nhanh hơn.
06Ứ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
07Thiế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.
08Lậ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.
09Bạn thiết kế firmware thế nào để dễ test, dễ port sang vi điều khiển khác và áp dụng SOLID?C/C++ & Embedded · Senior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Tách phần phụ thuộc phần cứng ra sau một lớp trừu tượng, để logic nghiệp vụ chạy và test được trên máy tính.
- Phân lớp: driver thanh ghi / HAL → BSP → service (giao thức, lưu trữ) → application.
- Dependency inversion: application phụ thuộc interface (
structchứa con trỏ hàm trong C, abstract class hoặc template trong C++), không gọi thẳng thanh ghi. - Single responsibility: mỗi module một việc, như đọc cảm biến, lọc tín hiệu, gửi dữ liệu.
- Unit test trên host với Unity, CppUTest hoặc GoogleTest bằng driver giả; test trên phần cứng (HIL) cho phần còn lại.
- Máy trạng thái (state machine) rõ ràng cho logic phức tạp.
- CI build nhiều target, chạy static analysis và kiểm tra theo chuẩn code (vd. MISRA).
Người phỏng vấn muốn nghe: bạn cân đối được giữa trừu tượng hoá và giới hạn RAM, flash, thời gian thực.
10Kể về một thất bại hoặc sai lầm của bạn và bài học rút ra.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 sai lầm thật, có hậu quả vừa phải, nhận trách nhiệm rõ ràng, và nhấn mạnh việc bạn đã thay đổi sau đó.
Cấu trúc: chuyện gì xảy ra, phần lỗi của bạn, bạn khắc phục ngay thế nào, bài học và thay đổi lâu dài.
Câu mẫu: "Có lần em deploy một thay đổi cấu hình lên production vào chiều thứ Sáu mà không kiểm tra kỹ trên staging, làm một tính năng lỗi khoảng một giờ. Em báo ngay cho lead, rollback và viết báo cáo sự cố. Sau đó em đề xuất checklist trước deploy và quy ước hạn chế deploy cuối tuần; team áp dụng tới giờ."
Hay sai: kể một "thất bại" thực ra là khoe, đổ lỗi cho người khác, hoặc nói mình chưa từng thất bại.
Bạn đã phỏng vấn ở Greystone Data Systems 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