cswork / libraryOpen practice workspace

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 areaQuestion to clarifyWork to bring
CodingWhich language and implementation format?Correct baseline, tests and a follow-up
DesignObject model, distributed system or integration?State ownership and failure trace
Role depthWhich runtime and operating constraints?Relevant fundamentals and measured project evidence
Project discussionWhat experience should you explain?Personal decision, alternatives and outcome
MotivationWhy 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}
StepLocal or server conditionExpected outcome
Disconnected at 12Snapshot age 7; revision 10, epoch 7Stale display; draft only
Reconnect at 18Server revision 11, epoch 8Reject old command a
Review current statePerson approves replacement bNew ID, current epoch and revision
Accept b at 20Valid before expiry 30Server revision 12; one applied record
Response is lostClient does not know the resultRetry identical b or query its receipt
Retry b at 31Record was already committedReturn 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.

FailureDesign decisionObservable evidence
Old snapshotShow age and draft/commit distinctionLast observation and sync times
Authority changeReject new writes from old epochRejection reason and current generation
Lost acknowledgementQuery or replay identical IDDurable receipt and original revision
Concurrent record updateReject stale expected revisionConflict and refreshed record
Unknown result after outageKeep pending until reconciledPending 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

DayPracticeOutput
1Read the role and confirm roundsSkills map and tool rules
2Solve heap/graph reachabilityTests for cycles, roots and missing IDs
3Add a stateful follow-upRefactor with explicit ownership
4Trace the inspection outageStale-view and reconnect table
5Inject expiry, revocation and lost responseRejection and receipt results
6Rehearse a real project and motivationDecisions, trade-offs and evidence
7Run a mock with changed constraintsSpecific 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.