A passing simulation means little if you cannot reproduce it. Start your preparation with a small experiment runner: accept a scenario, record its inputs, run a worker and explain the result. This gives you a concrete way to discuss coding, distributed systems and debugging without pretending to know the company’s internal infrastructure.
Connect your preparation to the work. Waabi’s Simulation Platform posting describes a platform that brings together autonomy software, actor models and sensor simulation. Use the exercises below to practise the engineering decisions around that work: clear input contracts, reliable execution and results you can trace.
Match the team before choosing depth. Simulation infrastructure, motion planning and research are different paths. This guide emphasizes general software engineering rather than mathematical proofs or model training. Take the exact opening you applied for and mark which responsibilities you can support with a project example. Spend additional time on the gaps that matter to that team.
Use a deliberately small model. Our practice runner processes named scenarios and stores one result per logical run. Retries are separate attempts. Record the scenario version, software version and seed beside each result. Then identify any other dependencies that could change the outcome.
Bring evidence to your explanations. Show a test that failed, the smaller input that reproduced it and the change that fixed it. Explain what the test covers and what you would investigate next.
Explore your preparation priorities
Choose a focus to see how to prepare.
Define a reproducible run
Correctness: Make repeated inputs and missing results distinguishable.
YOUR PREPARATION- Write a run manifest and identify every mutable dependency it references.
- Attempt the interval and duplicate-run prompts. Add an empty input and a repeated identifier to each test set.
Choose a focus, review the preparation steps, then try the linked practice question.
Define a reproducible run
editorialBegin with the smallest experiment you can explain from input to result. Give the scenario and software explicit versions. Separate a logical run from each attempt to execute it. Describe what you would record if a worker dies before reporting completion.
What to demonstrate
- Correctness: Make repeated inputs and missing results distinguishable.
- Communication: Explain which assumptions are required for a comparison to be meaningful.
How to prepare
- Write a run manifest and identify every mutable dependency it references.
- Attempt the interval and duplicate-run prompts. Add an empty input and a repeated identifier to each test set.
Trace execution and recovery
editorialNext, walk one job through a worker failure. Sketch who owns the job while it runs and what happens when that ownership expires. A second worker may start before the first stops, so the result store must reject stale completion attempts.
What to demonstrate
- Recovery: Protect the final result even when execution happens more than once.
- Tradeoffs: Separate faster retries from safe publication.
How to prepare
- Draw a lease timeline with a paused worker and a replacement worker.
- Explain how a token or version check prevents the old worker from overwriting the new result.
Explain a result you distrust
editorialFinish with a result that changed unexpectedly. Keep input and software versions visible while you narrow the failure. Start from a repeatable small case; adding more runs before understanding the comparison can make a misleading aggregate look more convincing.
What to demonstrate
- Debugging: Separate measurement errors from behavior changes.
- Judgment: Describe what would make you halt a comparison or investigate further.
How to prepare
- Prepare a real debugging story with the observation that changed your hypothesis.
- Compare results only after checking the matched scenario set, metric definition and missing-run policy.
PracHub editorial advice for the preparation topics above.
Follow the state, not just the happy path
Choose a scenario to trace what changes.
The current owner completes the job.
- 01QueueQueue.
- 02Run with tokenRun with token.
- 03Commit current tokenCommit current token.
Publish the artifact after checking ownership.
Switch between scenarios to trace worker ownership, retries and result publication.
Treating a seed as the whole experiment
Record the inputs that can change. A seed cannot identify a changed scenario, dependency or simulator build. Keep those versions beside the result and document which sources of nondeterminism remain.
Counting retries as fresh evidence
Count logical runs, not attempts. A worker failure should not give one scenario extra weight in a success-rate calculation. Decide which completed attempt represents the run.
Publishing a late worker result
Check ownership when committing. A lease expiring does not stop a paused process. Reject results with stale fencing tokens even if their computation finished successfully.
Comparing different scenario sets
Inspect the denominator. A higher pass rate may come from missing difficult cases. Report absent results separately and compare matched scenario IDs before drawing a conclusion.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Merge overlapping simulation windows
Given integer intervals [start, end), reject end <= start and merge intervals that overlap or touch. Return sorted, nonoverlapping windows without changing the input.
Approach
- Start simple: Sort a copy by start, then extend the final output window when the next start is at or before its end.
- Check boundaries: Touching intervals are merged by this contract, even though their half-open sets do not overlap.
Worked solution 35 min
- Sort a new list so the caller’s input is preserved. Validate each interval before extending the output.
- When a window touches or overlaps the final output window, replace its end with the larger end. Otherwise append a new window. Sorting dominates at O(n log n).
def merge_windows(intervals):
result = []
for start, end in sorted(intervals):
if end <= start:
raise ValueError("invalid interval")
if result and start <= result[-1][1]:
result[-1] = (result[-1][0], max(result[-1][1], end))
else:
result.append((start, end))
return result
Scroll sideways to view long lines.
Follow-up
- How would the answer change if touching windows had to remain separate?
Deduplicate run requests
Given request IDs in arrival order, return the first occurrence of each ID while preserving order. Assume IDs are nonempty strings; reject a blank ID.
Approach
- Use a set for membership and a list for output. State the O(n) expected time and O(u) additional space.
- A bounded cache needs an expiry policy; after expiry it no longer promises global deduplication.
Follow-up
- How would you support a stream that never ends?
Count recent completed jobs
Count completion events in (now − 10, now]. Events arrive in timestamp order and each contributes one. Advance the clock during idle periods too.
Which events still count?
The left boundary is excluded; the right boundary is included. Drag past an event to see it enter, then expire 10 seconds later.
See the event values
- At 0s: +1 — expired
- At 5s: +1 — in window
- At 10s: +1 — in window
- At 14s: +1 — not arrived
- At 19s: +1 — not arrived
Drag the clock to follow the example events. Each dot counts once inside (now − 10, now]; the lower boundary is excluded.
Approach
- Expire timestamps at or before the lower boundary. A deque gives amortized constant work per arrival.
- Treat the timestamps as arrival time; out-of-order event time needs a different contract.
Follow-up
- What happens to the result at 30 seconds with no recent events?
Validate a reproducible run manifest
Implement a parser for JSON run manifests containing run_id, schema_version, seed and scenario_ids. Reject unknown versions, blank identifiers, duplicate scenario IDs and booleans used as integer seeds. Return either a normalized record or field-level errors.
Approach
- Define required fields and accepted types before parsing; distinguish malformed JSON from a valid object with invalid fields.
- Check exact integer types because Python bool is an int subclass. Preserve scenario order and reject duplicates rather than silently changing the requested run.
- Test missing fields, empty scenarios, duplicate IDs and unsupported versions. Keep parsing independent of storage so tests are deterministic.
Follow-up
- How would you migrate version 1 without silently changing its meaning?
- Which dependencies beyond the random seed must be pinned for reproducibility?
Select the latest successful attempt
From attempts(run_id, attempt_no, status, score), return the highest numbered successful attempt per run. The pair run_id and attempt_no is unique.
Approach
- Filter successes before ranking within each run.
- Keep failed-only runs absent from this result, then report them separately rather than calling them passes.
Worked solution 35 min
- Filter successful attempts before applying ROW_NUMBER. Otherwise a newer failed attempt can hide an earlier valid success.
- Rank within the logical run, then select rank one. Keep attempt number in the output for traceability.
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY run_id ORDER BY attempt_no DESC) AS rn
FROM attempts WHERE status = 'success'
)
SELECT run_id, attempt_no, score FROM ranked WHERE rn = 1;Scroll sideways to view long lines.
Follow-up
- How would you expose runs with no successful attempt?
Find scenarios missing results
Given expected(scenario_id) and results(scenario_id, build_id), return expected IDs without a result for build B. Expected IDs are unique.
Approach
- Use NOT EXISTS with both the scenario match and target build condition.
- Test an ID present only in build A so it does not accidentally count as coverage for B.
Follow-up
- Should a failed run count as a missing result or a known failure?
Design a simulation job runner
Design a queue-backed runner with retries, worker crashes and one published result per logical run. Users need to inspect failures and rerun a versioned experiment.
Approach
- Separate run identity, attempt identity and worker ownership.
- Write results under an ownership check; store immutable artifacts before publishing their reference.
- Expose queue delay, attempt failures and completed logical runs as separate metrics.
Worked solution 35 min
- Store a durable run manifest. Allocate a fresh fencing token when a worker receives ownership.
- Write artifacts under an attempt-specific path. Commit the selected artifact only if the worker still holds the current token.
- After a timeout, retry execution with a new token. Keep incomplete artifacts invisible and clean them up later.
Follow-up
- What happens if artifact upload succeeds but the commit fails?
Compare two software builds fairly
Design a report comparing build A and build B on a named scenario set. Some runs fail to produce a result. Users must be able to trace every summary to its inputs.
Approach
- Version the scenario set and metric definition.
- Show matched coverage and missing runs before computing a change.
- Keep result references so a reader can inspect individual cases.
Follow-up
- How would you prevent selection of only favorable scenarios?
A paused worker overwrites a newer result
Worker A loses its lease. Worker B completes the same run. A resumes and overwrites B. Explain the race and fix the commit boundary.
Approach
- A timeout changes ownership, not process liveness.
- Attach a monotonically increasing token to each lease and reject commits from older tokens atomically.
Worked solution 35 min
- Reproduce the pause between computation and commit. Check which token each worker holds.
- Move the ownership condition into the atomic commit. A separate read followed by a write leaves another race.
- Retest with multiple pauses, including one immediately after the ownership check would previously have passed.
Follow-up
- Why is checking the lease only before the computation insufficient?
Investigate intermittent simulation job failures
A distributed simulation cluster intermittently stalls. Explain how you would distinguish queue saturation, worker crashes and failed result publication without rerunning every job.
Approach
- Correlate logical run ID, attempt ID and worker ownership across enqueue, start, heartbeat and commit events.
- Measure queue age separately from execution duration and artifact-upload duration. Compare failed attempts with successful attempts on the same software and input versions.
- Use a small reproducer and a falsifiable hypothesis; do not put high-cardinality run IDs in metric labels. Verify that a fix reduces the observed failure class.
Follow-up
- What evidence survives a worker crash?
- How would you detect a job that finished but never published its result?
A suggested week of practice, with one concrete outcome per session. Adjust the order and pace to your experience and interview date.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Map your evidence
- Read your exact opening and match two responsibilities to real project examples.
Deliverable: A role-to-project map
02Test the coding contract
- Attempt the first coding problem. Add boundary cases before reading the solution.
Deliverable: A tested function
Practice prompt ↗03Query the right record
- Run the SQL example and create a case where insertion order gives the wrong answer.
Deliverable: A small dataset and expected output
Practice prompt ↗04Trace the unhappy path
- Switch the scenario diagram and explain which state is safe to show to a reader.
Deliverable: A recovery sketch
Practice prompt ↗05Reproduce the race
- Explain the debugging example with two competing operations. Identify the atomic or identity check.
Deliverable: A reproducible timeline
Practice prompt ↗06Prepare your stories
- Choose two behavioral prompts. Use real decisions, evidence and limitations instead of memorized scripts.
Deliverable: Two concise story outlines
07Rehearse and revise
- Explain one solution aloud, test its weakest assumption and prepare questions about the actual role.
Deliverable: A review sheet for your next session
Expand any day for tasks and deliverables. Your progress is saved on this device.
Use a real project. Explain your responsibility, the decision you made, the evidence you used and what you would change.
Explain a hypothesis you disproved
Describe a debugging investigation in which evidence contradicted your first explanation.
Approach
- Be specific: Choose the smallest observation that changed your mind. Separate what you measured from what you inferred.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- What test would have disproved the replacement hypothesis?
Defend a reliability tradeoff
Describe a time you reduced scope to protect correctness or reproducibility.
Approach
- Be specific: Name the user impact, options rejected and follow-up that checked whether the choice worked.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- What would have justified choosing speed instead?
Hand off an unresolved failure
Explain how another engineer could continue your investigation without repeating it.
Approach
- Be specific: Provide the reproducer, known versions, attempted fixes and the next discriminating test.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- What detail did you initially omit that the next person needed?
- 01
Choose examples you can discuss without sharing confidential customer data.
Where should I start preparing?
Start with a small simulation runner you can explain end to end. Define its inputs, merge overlapping windows, then add retries and inspect what happens when a worker loses ownership.
What makes a strong project walkthrough?
Bring a concrete failure, the evidence that narrowed it down and the test that verified your fix. Explain how another engineer could reproduce the result using the same inputs and software version.
Do I have to use Python for these exercises?
The short Python examples make the contracts easy to test. Reimplement them in the language appropriate to your role, keeping the same inputs, expected outputs and edge cases.
How should I use the one-week checklist?
Treat each day as a practice session with a concrete deliverable. Repeat a session when you need more time, and use the final review to revisit the assumptions or edge cases you found hardest to explain.
What should I prioritize if time is short?
Start with the role description, one tested coding solution and one failure scenario you can explain end to end. Then prepare a real project story that shows how you made a decision under constraints.
Sources & methodology 5 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01Waabi — engineering role ↗
Role context. Practice questions, preparation priorities and diagrams are created by PracHub.
official · Accessed 2026-09-15 - 02Waabi — Careers ↗
Company and product context.
official · Accessed 2026-09-15 - 03PostgreSQL — Window functions ↗
Technical reference for the original SQL exercise.
official · Accessed 2026-09-15 - 04PracHub — Software Engineer practice ↗
Cross-company practice.
platform · Accessed 2026-09-15 - 05Dataford — Waabi Software Engineer preparation topics ↗
Third-party preparation topics. Adapted exercises include original PracHub constraints, approaches and follow-ups; this page does not verify current employer questions.
platform · Accessed 2026-09-15