Embedded Systems Interview Questions That Actually Show Up in the Loop
The BLS projects computer hardware engineer employment to grow 7 percent through 2034, faster than average, with a median wage of $155,020 in May 2024. That number includes embedded engineers at automotive suppliers, IoT device makers, and medical device companies – three sectors with notably different interview styles. The question list that circulates online is almost always too long and too shallow. Here’s a tighter set that actually shows up in loops at companies like Bosch, Texas Instruments, and Nordic Semiconductor.
What embedded interviews actually test
Most embedded role interviewers aren’t looking for someone who can recite the I2C spec from memory. They want to see how you reason about constraints – power budgets, stack size limits, interrupt latency windows. The candidates I’ve watched struggle aren’t weak on theory; they’re weak on explaining trade-offs under pressure. The 13 questions below are organized around that skill, not around getting every protocol detail right.
One honest caveat: this list skews toward bare-metal and RTOS roles. If you’re interviewing for a Linux-on-embedded role at a company running Yocto, you’ll see maybe 4 of these and more questions about device trees and BSPs. I don’t have good data on how often that tracks by industry – only that it varies more than any generic list suggests.
Memory and C fundamentals (the ones that trip people up)
1. Explain the difference between stack and heap in an embedded context
Stack is fast, deterministic, automatic – local variables live and die with function scope. Heap is flexible but slower, with non-deterministic allocation time. The follow-up is almost always “so why avoid malloc on a safety-critical system?” Good answers cover fragmentation and heap exhaustion. The best answers get specific: “we used a fixed-size memory pool allocator instead.”
2. What does volatile actually do, and when does omitting it cause bugs?
Volatile tells the compiler the variable can change outside normal program flow – don’t optimize away reads or writes. The subtle part is when forgetting it causes real bugs: a flag set in an ISR that the main loop never sees updated because the compiler cached it in a register. Hardware memory-mapped registers are the other canonical case. Being able to say “the compiler has no visibility into the interrupt context” is the answer interviewers want to hear.
3. What is memory alignment and what happens when it goes wrong?
A 4-byte integer is typically expected at an address divisible by 4. When it isn’t, some ARM Cortex-M cores trap with a HardFault. Others silently perform two memory reads and merge the result – which wastes cycles and breaks your timing budget. The compiler handles alignment for normal declarations, but it bites you when you cast pointers or overlay structs on raw buffers from a serial protocol parser.
4. Implement a circular buffer in C
Interviewers ask this one specifically to watch how you handle the edge cases – the buffer-full and buffer-empty states that look identical when head == tail. One clean approach uses a separate boolean flag:
typedef struct {
uint8_t buffer[BUF_SIZE];
uint16_t head;
uint16_t tail;
bool full;
} circ_buf_t;
bool cb_put(circ_buf_t *cb, uint8_t data) {
if (cb->full) return false;
cb->buffer[cb->head] = data;
cb->head = (cb->head + 1) % BUF_SIZE;
cb->full = (cb->head == cb->tail);
return true;
}
The discussion after the code matters as much as the code itself. Talk about thread-safety: if the ISR writes and the main loop reads, you need to disable interrupts briefly or use atomic types.
5. When do you use #define versus const?
#define is preprocessor text substitution – no type checking, no debug symbol. const is type-safe and visible in the debugger. For hardware register addresses, #define is conventional. For constant arrays or values you want visible in a debug session, const is better. Some compilers place const in flash automatically on Harvard architecture chips; others don’t.
Hardware and peripherals
6. Walk me through configuring a GPIO pin
On most Cortex-M devices you touch at minimum three registers: enable the clock to the GPIO peripheral, set the direction (input/output), and configure pull resistors. The trap answer is describing the HAL abstraction without knowing what’s underneath it. Interviewers want to know you’ve actually done this at register level.
7. What is PWM and how do you implement it in hardware?
PWM varies the duty cycle of a digital signal to control average power to a load – motor speed, LED brightness, servo position. A hardware timer generates the waveform; you set the period and compare register values. The question sometimes extends to dead-time insertion for complementary outputs in H-bridge motor drivers.
8. What is a watchdog timer?
A watchdog resets the system if software fails to “kick” it within a configured timeout. It’s the last line of defense against a hung task or deadlocked ISR. Better answers mention the windowed watchdog – where kicking too early also triggers a reset – which some safety standards require because it catches runaway fast-spinning loops as well as stalled ones.
9. Compare SPI and I2C: when does each win?
SPI is four-wire, full-duplex, fast, with no addressing overhead. I2C is two-wire, half-duplex, slower, but lets you run multiple sensors on one bus without extra chip-select lines. SPI wins for throughput – a high-speed ADC, a display controller. I2C wins when you want to conserve pins. Honestly, both are slow enough that the choice often comes down to what your sensor vendor supports.
RTOS and real-time behavior
10. What is priority inversion and how do you handle it?
Priority inversion is when a high-priority task waits on a resource held by a low-priority task, while a medium-priority task runs freely and starves the low-priority one. The Mars Pathfinder mission hit this in 1997; the spacecraft kept resetting. Priority inheritance – temporarily boosting the low-priority task’s priority – is the standard fix. FreeRTOS mutexes implement this; binary semaphores don’t.
11. What’s the difference between a semaphore and a mutex?
A mutex has ownership – only the task that takes it can release it. A semaphore doesn’t have that constraint; any task can post to it. Use mutexes to protect shared resources. Use semaphores for signaling between tasks or ISRs. Swapping them produces priority inversion bugs that are hard to catch in testing.
Interrupts
12. What are the rules for writing a good ISR?
- Keep it short. Set a flag or push to a queue, then do the real work in a task.
- Never call blocking functions – no printf, no malloc, no mutex waits with timeouts.
- Mark all shared variables as volatile.
- Clear the interrupt flag before returning (or before re-enabling interrupts on edge-sensitive controllers).
- Watch reentrant functions – C standard library functions like memcpy are not always reentrant.
13. How do you handle a race condition between an ISR and main-loop code?
Three approaches: disable the interrupt briefly while reading/writing (cheap, predictable for short critical sections); use atomic operations where the hardware supports them (Cortex-M has LDREX/STREX); or pass data through a thread-safe queue instead of sharing a variable. RTOS-based systems should prefer the queue approach – it makes data flow explicit.
What we see in LastRound AI mock interviews
Candidates practicing embedded systems questions through LastRound AI’s mock interview product consistently struggle on one specific pattern: the follow-up question. They answer “what is volatile?” correctly, then freeze when the interviewer asks “so show me a code path where omitting it produces a silent bug.” The AI copilot flags this gap after the mock session and queues a second attempt with a harder follow-up variant. That second pass is where the real learning happens.
How to actually prepare
The 2024 Stack Overflow Developer Survey found that C and C++ are used by 20.3% and 23% of all respondents respectively – and among people just learning to code, those numbers jump to 38% and 39%. That’s a bigger pipeline of embedded-adjacent developers than most people realize.
What the survey can’t tell you is how the interview varies by sector. Automotive roles (think Bosch, Continental, Aptiv) lean heavily on MISRA C, functional safety, and AUTOSAR. IoT startups care more about BLE integration and power budgets. Medical device companies add IEC 62304 questions to the mix. Knowing which flavor you’re targeting beats memorizing 30 generic questions.
For the system design rounds that show up in senior embedded loops, the system design interview guide covers the architectural thinking those questions are testing. And if your target company uses AI-driven screening before the technical rounds, this breakdown of AI screening interviews is worth a read first. For hybrid embedded/software roles, the software developer interview questions post covers the CS fundamentals overlap.
