A strong answer
A strong candidate frames How would you build a move-only task that runs exactly once? around the exact memory layout, compiler semantics, and hardware execution model covered in Project: A Movable Task Type. They want an id plus erased callable with deleted copies, moves that clear the source, and a validity guard before each run.
Producers create work with captured state: a lambda holding a filename, a bound method holding a connection index, a small counter holding a range. The queue must accept all of them in one container and deliver each to a single worker. Storing concrete lambda types fails because each lambda has a distinct type. Copying callables duplicates effects and breaks uniqueness. The trace above shows the target behavior with two slots, where ownership passes from the first to the second and only the second may run.
A move only task pairs an identifier with an erased callable, forbids copies, and permits moves. Producers build it, the queue stores it, workers take it by move and invoke it. Validity checks prevent execution of emptied sources.
In a production interview, always connect the specification rule to its concrete runtime consequence: state what lives on the stack versus the heap or static storage segment, how the compiler or operating system validates alignments, lifetimes, and error codes, and what happens under adversarial or boundary inputs (such as zero-length buffers, integer overflow, concurrent mutation, or partial I/O). Backing your explanation with a small trace of register/memory state transitions immediately separates senior systems engineers from candidates who only memorized syntax.
What the interviewer is listening for
- Mastery of core invariant: Build a move-only task holding an id plus an erased callable.
- Mastery of core invariant: Transfer tasks through a queue without copying.
- Mastery of core invariant: Explain why single ownership prevents double execution.
- Hardware and ABI awareness: Explaining how sizes, alignments, calling conventions, or kernel boundaries behave on real 64-bit targets rather than relying on implementation-defined assumptions.
- Defensive engineering: Naming the exact compiler flags (
-Wall -Wextra -Werror), static analyzers, or runtime sanitizers (-fsanitize=address,undefined,thread) that verify correctness in CI.
Common mistakes
- Explaining only surface syntax without tracing the underlying memory addresses, ownership lifetime, or kernel/user-space state transitions.
- Assuming undefined behavior (such as signed overflow, uninitialized reads, strict-aliasing violations, or dangling pointers) will "just work" because it passed an unoptimized
-O0debug build. - Ignoring return codes, partial reads/writes, alignment padding, or cleanup paths when an allocation or syscall fails midway through a function.