Articles · Anduril
Anduril Software Engineer Interview Guide 2026: Coding, Systems, and Mission Fit
Prepare for Anduril SWE interviews with progressive coding, a worked offline inspection system, reconnect recovery, tested authority checks and mission fit.
An offline-capable system is easy to draw and harder to define. When a connection returns, should an old queued instruction run, be rejected, or wait for a person to review it? A useful Anduril software engineer interview answer makes that decision explicit and follows it through the data model, code and recovery path.
This guide keeps the focus on progressive coding, systems judgment, project ownership and mission fit. It adds an original disconnected field-maintenance workflow with stale data, authority changes, receipts and reconnect reconciliation. The mock records inspections; it does not control a physical device or describe an Anduril product protocol.
Attempt a heap or graph question before reading its solution, then add references, cycles or a changed requirement and explain which invariant still holds.
Prepare from the specific role outward
Anduril engineering roles differ across applications, infrastructure, embedded software, networking and robotics. The current Vehicle Software, Communications posting mentions production C++ or Rust on Linux, telemetry, degraded links, lost-communications behavior and working with physical hardware. These responsibilities provide relevant preparation context; they do not publish a fixed interview question set.
The official early-careers page emphasizes project ownership, mentorship and real-world work. It is useful role context, but it should not replace your recruiter packet. The sources reviewed do not establish one universal SWE loop. Confirm whether your rounds assess algorithms, object-oriented design, distributed systems, debugging, language depth, project experience or team-specific knowledge.
| Preparation area | Question to clarify | Work to bring |
|---|---|---|
| Coding | Which language and implementation format? | Correct baseline, tests and a follow-up |
| Design | Object model, distributed system or integration? | State ownership and failure trace |
| Role depth | Which runtime and operating constraints? | Relevant fundamentals and measured project evidence |
| Project discussion | What experience should you explain? | Personal decision, alternatives and outcome |
| Motivation | Why this team and work? | Honest reason connected to a real choice |
Security, location and other eligibility requirements are posting-specific. Read the exact role rather than assuming that one communications job describes every SWE opening. Ask about permitted interview tools before using assistance.
Progressive coding: change the model before the code
The original guide's heap-reachability practice is useful because a small follow-up changes the problem. If stack roots reference A directly, a direct-reference scan can identify which objects lack a stack reference. Add heap references A→B and B→A, and the task becomes transitive reachability from roots. B is reachable despite lacking a direct stack reference; the cycle must not loop forever.
For a fictional heap {A,B,C} with root A and those two edges, a visited-set traversal reaches A and B, leaving C unreachable. Define dangling references, duplicate roots and missing IDs before implementation. This is a practice example, not a prediction that Anduril will ask it.
Use a steady rhythm: restate, model, implement, test, explain and extend. A visited set supports O(V+E) traversal when the graph is explicitly represented; include the graph and output in your memory accounting. If a follow-up changes object identity or adds concurrent mutation, revisit the snapshot contract instead of patching another conditional into the traversal.
For object-oriented design, name who owns mutable state. For C++ or Rust, explain lifetime and ownership where they affect correctness. For systems work, distinguish a reliable local operation from a guarantee that spans networks or devices.
Original mock: an inspection tablet loses connectivity
An authorized maintenance team uses a tablet to record that an asset inspection was reviewed. The server owns the asset record. The tablet can display cached information and save a draft while disconnected, but it cannot claim that the server accepted the inspection.
Use a fictional integer logical clock. At time 12, the tablet's snapshot was observed at time 5: its age is 7, exceeding the supplied freshness budget of 5. Display “stale, last observed at 5” and distinguish a locally saved draft from a committed record. These numbers are exercise constraints, not product performance claims.
The snapshot shows asset revision 10 and authority epoch 7. During disconnection, the server advances to revision 11 and epoch 8. An epoch represents the current authority generation in this mock; it is not a timestamp or a provider-defined token.
Queued command and reconnect decision
The old reviewed draft carries:
{"id":"a","epoch":7,"expected_revision":10,"expires_at":20,"op":"record_inspection","reviewed":true}
At reconnect time 18, the command has not expired, but its authority epoch is obsolete. Reject it. Do not rewrite its epoch or expected revision automatically: that would turn a review of old state into consent for new state.
Fetch the current record, show the conflict, and ask the authorized person to review a new proposal. The replacement uses a new immutable ID:
{"id":"b","epoch":8,"expected_revision":11,"expires_at":30,"op":"record_inspection","reviewed":true}
| Step | Local or server condition | Expected outcome |
|---|---|---|
| Disconnected at 12 | Snapshot age 7; revision 10, epoch 7 | Stale display; draft only |
| Reconnect at 18 | Server revision 11, epoch 8 | Reject old command a |
| Review current state | Person approves replacement b | New ID, current epoch and revision |
| Accept b at 20 | Valid before expiry 30 | Server revision 12; one applied record |
| Response is lost | Client does not know the result | Retry identical b or query its receipt |
| Retry b at 31 | Record was already committed | Return receipt revision 12; no second write |
Returning a receipt after expiry is a report of a past committed result. It does not authorize a fresh action. A new command arriving at exactly its expiry is rejected.
Code the authority, revision and receipt boundary
The server mock accepts one operation for one configured team/asset scope. authenticated_scope represents a trusted server-side authorization result; it must not come directly from a client JSON field. The reviewed boolean is a teaching stand-in for a verified approval workflow, not authentication or a cryptographic approval token.
class Rejected(ValueError):
pass
class InspectionServer:
"""Single-threaded maintenance-record mock; no physical device control."""
def __init__(self, scope, epoch=8, revision=11):
self.scope, self.epoch, self.revision = scope, epoch, revision
self.receipts, self.applied = {}, 0
def accept(self, command, now, authenticated_scope):
if authenticated_scope != self.scope:
raise Rejected("unauthorized scope")
if type(now) is not int or now < 0 or not isinstance(command, dict):
raise Rejected("invalid time or command")
key = command.get("id")
if not isinstance(key, str) or not key:
raise Rejected("nonempty command ID required")
fields = ("epoch", "expected_revision", "expires_at")
if any(type(command.get(k)) is not int or command[k] < 0 for k in fields):
raise Rejected("nonnegative integer fields required")
if command.get("op") != "record_inspection" or command.get("reviewed") is not True:
raise Rejected("only a human-reviewed inspection record is supported")
payload = tuple(command[k] for k in fields) + (command["op"], command["reviewed"])
if key in self.receipts:
prior_payload, prior_revision = self.receipts[key]
if payload != prior_payload:
raise Rejected("command ID reused with different content")
return prior_revision
if command["epoch"] != self.epoch:
raise Rejected("authority epoch changed")
if now >= command["expires_at"]:
raise Rejected("command expired")
if command["expected_revision"] != self.revision:
raise Rejected("stale asset revision")
self.revision += 1
self.applied += 1
self.receipts[key] = (payload, self.revision)
return self.revision
Command IDs are scoped by this server's team/asset context. The same ID with changed semantic fields is rejected. A matching receipt is checked before new-write epoch, expiry and revision checks because its effect already happened. Access to the receipt still requires the authenticated scope, and a revoked user's actual authentication should fail before this method is called.
The demonstration is single-threaded and in memory. A production service must commit the inspection update and receipt atomically, preserve receipts durably and define retention. Otherwise, a process crash between the two writes can allow a duplicate effect. Do not describe a Python dictionary as exactly-once delivery across a network.
The fixed-field validation and receipt lookup have expected O(1) cost per command; retained receipts use O(K) memory for K committed IDs. A bounded retention policy needs a separate guarantee about old retries. Deleting receipts merely to save memory can reintroduce duplication.
Tests and the changed-authority follow-up
The local suite passed 32 checks. It verified obsolete epochs, stale revisions, exact expiry, missing review, unauthorized scope, unchanged state after rejection, successful revision increments, duplicate receipts after expiry, conflicting ID reuse and separate server scopes. It also rejects unsupported operations and malformed integer fields.
Now advance the authority epoch from 8 to 9 after b committed. An authorized caller may retrieve b's existing receipt without a new write. A fresh command with epoch 8 is rejected. A newly reviewed command with epoch 9, expected revision 12 and a valid deadline can advance the maintenance record to revision 13.
That is the follow-up to explain aloud: “Old success remains an auditable fact. New authority governs new writes.” Authentication, approval verification, durable transactions, networking, real clocks and physical control are outside the code and were not tested.
For intervals within one process, Python's monotonic clock avoids wall-clock adjustments. Its reference point is undefined, so do not send its absolute value as a cross-machine expiry timestamp. Distributed deadlines need a defined authoritative clock and treatment of uncertainty. The example uses supplied logical times rather than implementing clock synchronization.
Design the reconnect and degraded modes
Separate three paths: cached reads, local drafts and authoritative commits. During an outage, the first two can continue within their stated limits. The interface should not display a locally queued draft as a completed server action.
On reconnect, refresh state, reconcile queued IDs with receipts, reject obsolete proposals, and present conflicts for review. Prioritize fresh acknowledgements and recovery status over old bulk telemetry. Bound queue size and retained draft age; when limits are reached, make the loss or rejected work explicit instead of silently dropping commands.
| Failure | Design decision | Observable evidence |
|---|---|---|
| Old snapshot | Show age and draft/commit distinction | Last observation and sync times |
| Authority change | Reject new writes from old epoch | Rejection reason and current generation |
| Lost acknowledgement | Query or replay identical ID | Durable receipt and original revision |
| Concurrent record update | Reject stale expected revision | Conflict and refreshed record |
| Unknown result after outage | Keep pending until reconciled | Pending age and recovery action |
Keep any physical actuation outside this maintenance-record example. A real device-control design needs a separately specified safety case, local interlocks and authorized operating boundaries. A cloud retry policy cannot establish those guarantees.
Useful operational signals include oldest unreconciled draft, last confirmed server state, stale-view age, expired proposals, authority conflicts and receipt lookup failures. A green network indicator proves connectivity, not agreement about the record.
Mission fit: connect a real choice to the work
Anduril is a defense technology company. A credible motivation answer should address the actual work and users, your personal reasons, the role's engineering constraints and any boundaries that matter to you. Do not borrow conviction or invent field experience.
Use this original fictional rehearsal answer to study structure, not as a personal claim: “In a maintenance-app project, I owned the reconnect state machine. I chose to label cached records stale and require review after a conflicting server revision, because a queued update should not look complete before it is accepted. The trade-off was an extra review step after outages. We tested lost acknowledgements and stale revisions before rollout. I want a role where those reliability decisions matter to the people using the system, and I would ask this team how it verifies behavior during disconnected operation.”
The first two sentences identify ownership and a technical decision. The next two expose a cost and verification method. The last connects the interest to a concrete team question. It contains no fabricated metric, heroic incident or claim to have deployed defense software.
For your own answer, replace every project detail with work you actually did. Explain the measurable result if you have one; if you do not, give the observed test or rollout evidence. Separate your code and decisions from other people's deployment, hardware or research contributions.
Seven days with concrete deliverables
| Day | Practice | Output |
|---|---|---|
| 1 | Read the role and confirm rounds | Skills map and tool rules |
| 2 | Solve heap/graph reachability | Tests for cycles, roots and missing IDs |
| 3 | Add a stateful follow-up | Refactor with explicit ownership |
| 4 | Trace the inspection outage | Stale-view and reconnect table |
| 5 | Inject expiry, revocation and lost response | Rejection and receipt results |
| 6 | Rehearse a real project and motivation | Decisions, trade-offs and evidence |
| 7 | Run a mock with changed constraints | Specific corrections to repeat |
Frequently asked questions
Is there one Anduril SWE interview loop?
The reviewed sources do not establish one universal sequence. Prepare for the role's language and systems requirements, and confirm the actual assessment format with recruiting.
What should continue while disconnected?
In this mock, cached reads and local drafts continue with visible freshness limits. Authoritative inspection records wait for reconnection, validation and review. Other applications need their own operating contract.
Why reject the old proposal instead of updating its epoch?
Changing authority or revision changes what was reviewed. Silently rewriting the queued proposal would bypass that decision. Refresh the record and create a newly reviewed command with a new ID.
Why return an expired command's receipt?
A matching receipt reports an already committed result and prevents a second write. A fresh expired command remains invalid; receipt access still requires authorization.
How should I discuss mission fit?
Give an honest reason for the work, connect it to an actual engineering choice and ask a specific team question. Clearly distinguish your contribution from the team's work and the fictional examples here.
Sources and scope
Reviewed October 8, 2026. The official role provides operating-context examples; the maintenance workflow, logical times, code and rehearsal answer are original practice material, not a product protocol or private hiring rubric.
- Anduril Early Careers — current public ownership and early-career context.
- Vehicle Software, Communications role — language, telemetry and degraded-link responsibilities for this specific posting.
- Python time.monotonic documentation — local interval timing and undefined absolute reference point.