Representative practice prompts
Five Waymo frontend interview practice questions
For each prompt, clarify the contract, explain ownership and trade-offs, implement or diagram the smallest credible slice, and test the failure cases. Each prompt links to the public report it is modelled on and to a runnable practice page.
Prompt 1
Filter a tree by substring and render it indented
Given an n-ary tree of named nodes and a search term, drop every node whose name contains the term together with its subtree, then render what remains so the hierarchy stays readable.
Practice version modelled on a reported round: Public report: Waymo senior frontend engineer loop, May 2026
What this measures
Recursion or explicit stacks, pruning at visit time, order and indentation contracts, immutability, and whether you ask about case sensitivity and the empty term before coding.
Clarify first
- Confirm match semantics: substring or exact, case-sensitive or not, and what an empty term should do.
- Confirm whether a matching root removes everything and whether ancestors of a surviving node must stay visible.
Strong answer should cover
- Walk the tree depth-first and decide at each node whether it survives; skip the subtree of a pruned node instead of filtering afterwards.
- Carry depth with each node so indentation or nesting is derived during the walk.
- Keep sibling order and never mutate the input tree.
- Rendering as UI: map the same walk to nested list elements and keep expand and collapse state outside the traversal.
- Test a matching root, an empty term, case sensitivity, deep nesting and a node without children.
Common miss: Filtering children after rendering, which keeps the grandchildren of a pruned node alive, or letting an empty term prune the whole tree because every string includes the empty string.
Practice the tree filter with tests Prompt 2
Fix an Angular screen from three user bug reports
You receive an Angular app and three short reports from people who use it. Reproduce each report, find the root cause, fix all three, and explain what you changed without breaking the existing behaviour.
Practice version modelled on a reported round: Public report: Waymo senior frontend engineer loop, May 2026
What this measures
Reading unfamiliar component and template code, turning a report into a reproduction, derived-state and event-binding reasoning, and communicating a root cause rather than a symptom patch.
Clarify first
- Ask which report is most urgent and whether the fix may change the template structure or only the component logic.
- Ask how the screen is tested so your fix can be verified the same way.
Strong answer should cover
- Reproduce before editing: trigger each report in the running app and name the state that is wrong.
- Look for derived state computed from a previous result instead of from the source, and for flags that are set but never reset.
- Check for duplicate handlers, such as a submit button inside a form that also listens for submit.
- Fix the cause, keep test ids and public behaviour, and say what each change does.
Common miss: Patching the symptom, for example resetting a flag in the click handler, while the derived-state bug that caused it stays in place.
Debug the fleet status board (Premium) Prompt 3
Implement a Promise contract in TypeScript
The report says a pure TypeScript Promise problem was asked and does not say which. Prepare the family: build a deferred promise, implement Promise.all with ordering and fail-fast semantics, and add cancellation or timeouts without breaking Promise rules.
Practice version modelled on a reported round: Public report: Waymo senior frontend engineer loop, May 2026
What this measures
Microtask timing, settlement rules, typed generics, error propagation, and whether you can explain adoption of a thenable and first-settlement-wins behaviour.
Clarify first
- Confirm whether native Promise may be used inside the implementation or whether the exercise is about the state machine itself.
- Confirm the expected behaviour on an empty input and on the first rejection.
Strong answer should cover
- Keep settlement in one place so only the first resolve or reject wins and later calls are ignored.
- Preserve input order in Promise.all results while letting work run concurrently.
- Type the public contract with generics and let callbacks run on a later microtask.
- State which follow-ups you would add: timeout, cancellation through AbortSignal, and settled-count reporting.
Common miss: Resolving with an array that fills in completion order, or letting a second resolve call overwrite an already settled value.
Practice the deferred promise drill Prompt 4
Design the frontend of an AI chat application
Design the composer, the streaming reply and the conversation state for an AI chat product: one active reply at a time, Send that becomes Stop, retries that never duplicate a turn, and stale stream events that cannot touch the new turn.
Practice version modelled on a reported round: Public report: Waymo senior frontend engineer loop, May 2026
What this measures
State ownership across input, drafts, uploads and the active turn; stream and command identity; cancellation and recovery; and accessibility of streamed text.
Clarify first
- Confirm the transport (SSE, WebSocket or a fetch stream) and whether the server can resume a stream by sequence number.
- Confirm what Stop must guarantee: a server-side stop or only a local abort with partial text kept.
Strong answer should cover
- Give every send and every stream a stable identity and reject events that do not match the active turn.
- Separate persisted draft, transient composition and attachment readiness so Enter during IME composition cannot send.
- Batch rendered tokens and keep the scroll pinned to the bottom until the reader scrolls up.
- Define recovery: resume by sequence or snapshot, retry with the same request id, and show a truthful status at every step.
Common miss: Treating a local abort as a confirmed server Stop, so a late chunk from the old stream mutates the new reply.
Work through the AI chat composer case Prompt 5
Build an autocomplete search bar with debounce
Build a search box that suggests results as the user types, waits for a pause before requesting, ignores stale responses, and stays usable from the keyboard.
Practice version modelled on a reported round: Public report: Waymo senior frontend engineer loop, May 2026
What this measures
Timing control, request ownership and cancellation, keyboard and listbox semantics, and truthful loading, empty and error states.
Clarify first
- Confirm the debounce interval, the minimum query length, the result limit and the selection behaviour.
- Confirm whether earlier requests can be aborted or only ignored.
Strong answer should cover
- Separate input value, active query, request identity, results and visible status.
- Debounce starts; use an abort controller or a latest-request guard so an older response cannot overwrite a newer query.
- Expose combobox and listbox semantics and keep focus in the input while arrowing through results.
- Test out-of-order responses, rapid deletion to an empty query, a failed request and retry.
Common miss: Treating debounce as the race-condition fix while an older response or a finally block still overwrites the current query.
Practice the React autocomplete starter