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). 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.
01Lậ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.
02Bạ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.
03Con trỏ và tham chiếu (reference) trong C++ khác nhau thế nào?C/C++ & Embedded · Junior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Con trỏ là biến chứa địa chỉ, có thể
nullptrvà trỏ sang đối tượng khác. Tham chiếu là tên gọi khác của một đối tượng đã tồn tại, phải khởi tạo ngay và không gán lại được.int x = 1, y = 2; int* p = &x; p = &y; // đổi đối tượng được trỏ int& r = x; r = y; // gán giá trị y cho x- Truyền tham số: dùng
const T&cho đối tượng lớn chỉ đọc,T&khi cần sửa, con trỏ khi tham số có thể vắng mặt. - Có con trỏ tới con trỏ và phép toán số học trên con trỏ; tham chiếu thì không.
Hay sai: trả về tham chiếu hoặc con trỏ tới biến cục bộ. Biến bị huỷ khi hàm kết thúc và dùng nó là undefined behavior.
- Truyền tham số: dùng
04Stack và heap khác nhau thế nào? Memory leak và dangling pointer là gì?C/C++ & Embedded · Junior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Stack chứa biến cục bộ, cấp phát và giải phóng tự động theo phạm vi hàm, rất nhanh nhưng kích thước nhỏ. Heap cấp phát động (
new/malloc), sống đến khi giải phóng thủ công, linh hoạt nhưng chậm hơn và dễ phân mảnh.- Memory leak: cấp phát trên heap mà không giải phóng, bộ nhớ tăng dần. Trên thiết bị nhúng chạy lâu ngày đây là lỗi chết người.
- Dangling pointer: con trỏ vẫn giữ địa chỉ của vùng nhớ đã giải phóng hoặc biến đã hết phạm vi.
- Double free: giải phóng một vùng hai lần.
Phòng tránh: dùng RAII và smart pointer trong C++, đặt con trỏ về
NULLsaufreetrong C, kiểm tra bằng AddressSanitizer hoặc Valgrind.Người phỏng vấn muốn nghe (nhúng): nhiều hệ thống hạn chế hoặc cấm cấp phát động sau khi khởi động, dùng memory pool hoặc mảng tĩnh.
05Từ khoá volatile dùng để làm gì trong lập trình nhúng?C/C++ & Embedded · Junior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →volatilebáo cho compiler rằng giá trị biến có thể thay đổi ngoài luồng code hiện tại, nên mỗi lần truy cập phải đọc hoặc ghi thật vào bộ nhớ, không được tối ưu bỏ hay cache vào thanh ghi.Dùng cho:
- Thanh ghi phần cứng ánh xạ bộ nhớ (memory-mapped register).
- Biến chia sẻ giữa ISR (hàm phục vụ ngắt) và vòng lặp chính.
volatile bool data_ready = false; void UART_IRQHandler(void) { data_ready = true; } while (!data_ready) { } // không có volatile có thể thành lặp vô hạnHay sai: nghĩ
volatileđảm bảo thread-safe hoặc atomic. Nó không chống race condition và không tạo memory barrier giữa các core; cần atomic, tắt ngắt hoặc mutex.06Giải thích 4 tính chất OOP và virtual function / vtable trong C++.C/C++ & Embedded · Junior
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Bốn tính chất: đóng gói (ẩn dữ liệu sau interface), kế thừa, đa hình (gọi cùng interface, hành vi theo kiểu thật) và trừu tượng (chỉ lộ cái cần thiết).
Đa hình lúc chạy trong C++ dùng
virtual: mỗi class có hàm ảo có một bảng vtable chứa địa chỉ hàm, mỗi object giữ một con trỏ vptr tới bảng đó. Gọi qua con trỏ hoặc tham chiếu lớp cha sẽ tra vtable để gọi hàm của lớp con.struct Sensor { virtual ~Sensor() = default; virtual int read() = 0; }; struct TempSensor : Sensor { int read() override { return 25; } };Hay sai: quên destructor ảo ở lớp cha, khi
deletequa con trỏ lớp cha sẽ không gọi destructor lớp con. Trên nhúng cũng nên nhắc chi phí: thêm vptr cho mỗi object và một lần gọi gián tiếp.07RAII là gì? So sánh unique_ptr, shared_ptr và weak_ptr.C/C++ & Embedded
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →RAII (Resource Acquisition Is Initialization): gắn tài nguyên vào vòng đời một object; constructor lấy tài nguyên, destructor tự giải phóng. Nhờ vậy không rò rỉ kể cả khi có exception hoặc return sớm.
unique_ptr: sở hữu duy nhất, chỉ move được, không tốn thêm chi phí so với con trỏ thường. Nên là lựa chọn mặc định.shared_ptr: sở hữu chung bằng bộ đếm tham chiếu (cập nhật atomic), giải phóng khi bộ đếm về 0.weak_ptr: quan sát mộtshared_ptrmà không tăng bộ đếm, dùng phá vòng tham chiếu (vd. con trỏ ngược từ con về cha).
auto dev = std::make_unique<Device>("/dev/i2c-1");Hay sai: dùng
shared_ptrkhắp nơi "cho an toàn", làm mờ quyền sở hữu và tốn chi phí atomic.08Move semantics và rvalue reference giải quyết vấn đề gì? Rule of 3/5/0 là gì?C/C++ & Embedded
Gợi ý trả lời
Ôn thêm câu hỏi C/C++ & Embedded →Move semantics cho phép chuyển tài nguyên (buffer, handle) từ một object tạm hoặc sắp bị bỏ đi sang object khác thay vì sao chép sâu. Rvalue reference
T&&nhận các object như vậy;std::movechỉ là phép ép kiểu để cho phép move.std::vector<int> a(1'000'000); std::vector<int> b = std::move(a); // chuyển con trỏ, không chép 1 triệu phần tử- Rule of 3: nếu tự viết destructor, copy constructor hoặc copy assignment thì gần như phải viết đủ cả ba.
- Rule of 5: thêm move constructor và move assignment.
- Rule of 0: tốt nhất là không tự viết hàm nào, để các thành viên RAII (
vector,unique_ptr) lo.
Hay sai: dùng lại object sau khi đã move. Object vẫn hợp lệ nhưng ở trạng thái không xác định.
09Where do you see yourself in three to five years?Phỏng vấn tiếng Anh
Gợi ý trả lời
Ôn thêm câu hỏi Phỏng vấn tiếng Anh →"In three to five years, I see myself as a senior engineer who can design and own a major part of the system. I'd also like to mentor junior developers, because I enjoyed doing that in my current team. To get there, I'm studying system design and taking on more responsibility in technical discussions. I hope to grow in that direction with a company like yours."
Mẹo: dùng "I see myself…", "I'd like to…", "I hope to…". Mục tiêu nên thực tế và liên quan tới công việc đang ứng tuyển. Người Việt hay nói "I want to become a leader" quá chung chung; nên nói rõ leader làm việc gì.
10Bạn phản ứng thế nào khi nhận góp ý tiêu cực về công việc của mình?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á →Cho thấy bạn tách góp ý khỏi cảm xúc cá nhân và biến nó thành hành động.
- Lắng nghe hết, hỏi lại để hiểu ví dụ cụ thể và kỳ vọng.
- Cảm ơn, kể cả khi chưa đồng ý hoàn toàn; nếu có góc nhìn khác, trao đổi bằng thông tin, không phòng thủ.
- Lên kế hoạch cải thiện và chủ động xin phản hồi lại sau một thời gian.
Câu mẫu: "Có lần lead góp ý code review của em quá dài, khó review. Lúc đầu em hơi chột dạ, nhưng em hỏi anh muốn chia thế nào cho dễ. Từ đó em tách pull request nhỏ theo từng thay đổi, thời gian review của team giảm hẳn và em cũng ít bị yêu cầu sửa lại hơn."
Hay sai: nói "em luôn vui vẻ đón nhận mọi góp ý" mà không có ví dụ.
Bạn đã phỏng vấn ở Hella 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