Interview guides · voize
voize Software Engineer Interview Questions & Guide 2026
Testing practice for voize software engineer candidates: the boundaries worth covering, and why flakiness is a real defect.
The 60-second brief
voize builds an AI companion for nurses, beginning with documentation workflows.
This guide focuses on fullstack preparation: versioned edits, reliable requests and interfaces that make record state clear.
Design a reliable save flow, resolve competing edits, and keep the interface clear when requests fail.
Focus areas
- Versioned edits
- Request reliability
- Clear interfaces
Overview
“Saved” is a promise the interface must be able to keep. For a documentation product, a successful button animation is not enough. Practise explaining which record was saved, under which version and what the user sees if the request times out. That turns an ordinary CRUD exercise into a useful fullstack discussion.
Connect your preparation to the work. voize’s Senior Fullstack posting names React/TypeScript, Kotlin services and tooling for annotation and model evaluation. The careers page describes its focus on nursing workflows. Use the exercises below to practise versioned data, clear interfaces and reliable updates.
Choose the right role boundary. This guide targets general fullstack reasoning. A mobile role may put more emphasis on device lifecycle and Kotlin; a backend role may prioritize storage and concurrency. Do not treat a single senior posting as a requirement list for every opening. Use your exact role description to decide which exercises deserve the deepest rehearsal.
Practise with synthetic records. Use invented note IDs, versions and text. Define when an edit becomes server-confirmed and how a person can recover unsaved work. Connect implementation to the user’s next action. If a save conflicts, what should the person do next? If the network disappears, which work remains available? State that behavior before selecting a database or frontend library. Then test a slow response, two open tabs and a repeated click.
What to prepare
Follow one edit from the interface to storage and back. Define the saved state, add a competing writer, then make recovery understandable to the user.
Define what saved means
Start with one edit and one explicit promise to the user. Separate locally entered text from server-confirmed text. Decide whether leaving the page discards work, preserves it locally or blocks navigation. This is a design exercise; the best answer depends on the stated constraints.
What to demonstrate
- Product reasoning: Give each visible state an actionable meaning.
- Boundaries: Identify the record version to which a response belongs.
How to prepare
- Sketch editing, saving, saved and conflict states before writing a component.
- Describe what remains visible when a request fails after the server has committed.
Protect concurrent updates
Now add a second editor. Both read version three, but only one can replace it without seeing the other change. Choose an explicit conflict rule. A last-write-wins policy may be simple, yet it can silently erase a valid edit.
What to demonstrate
- Concurrency: Make version comparison and update atomic.
- API design: Distinguish a conflict from an authentication failure or a temporary network error.
How to prepare
- Write a conditional update and explain the meaning of zero affected rows.
- Attempt the revision-selection SQL and retry-deduplication exercises. Test two edits based on the same version.
Make failure understandable
Finish by describing the interface after a late response or conflict. Keep the person’s unsaved text available while showing enough context to resolve the problem. Error handling is incomplete if the user can only retry blindly and risk repeating the same mistake.
What to demonstrate
- Clarity: Offer a next action without claiming success prematurely.
- Debugging: Trace the request identity and version without recording sensitive text in logs.
How to prepare
- Prepare a collaboration story where feedback changed the behavior you shipped.
- Reproduce two requests completing in reverse order, then explain why the older result must not replace the newer state.
Where candidates lose points
Showing saved before confirmation
Separate optimistic display from durable success. Give pending work its own state. If the request times out, recover by its identity before assuming either failure or success.
Overwriting a newer edit
Require an expected version. Perform the check and update together. A client-side comparison followed by an unconditional write still has a race.
Using record text as diagnostic context
Log identifiers and state transitions. For this exercise, synthetic data is enough to reproduce the bug. Build debugging around request IDs, versions and error classes rather than sensitive text.
Retrying every failure
Classify the response. A version conflict requires a decision, while a transient transport failure may justify retrying the same operation. A new operation identity can turn a retry into a duplicate.
Questions & practice
Keep the highest revision for each note
Medium · Maps · Versioning
Given (note_id, revision, text) records, return one record per ID sorted by ID. Keep the highest revision; reject equal revisions with different text.
Approach
- Use a dictionary keyed by note ID. Compare each new revision to the stored one.
- Do not silently choose between conflicting copies of the same revision.
Worked solution (35 min)
- Track the highest revision per ID. A lower revision arriving later does not replace it.
- Reject conflicting content at any repeated (ID, revision), including older revisions. Return a sorted list so results do not depend on arrival order. The reference uses O(n) space and O(n + u log u) expected time.
def latest_notes(records):
seen, latest = {}, {}
for note_id, revision, text in records:
key = (note_id, revision)
if key in seen and seen[key] != text:
raise ValueError("conflicting revision")
seen[key] = text
if note_id not in latest or revision > latest[note_id][1]:
latest[note_id] = (note_id, revision, text)
return [latest[key] for key in sorted(latest)]
Expected result: For A version 1, B version 1 and A version 2, return A version 2 and B version 1.
Verify it yourself
- Test late old revisions and identical repeated records.
- Reject conflicting copies of an old revision even after a newer revision arrived.
Follow-up
- How would you return conflicts for review instead of raising an error?
Ignore a repeated operation ID
Easy · Idempotency · Validation
Given operation IDs, return each ID once in first-seen order. Explain what additional data is needed if one ID arrives with two different payloads.
Approach
- Use a set and ordered output for the basic contract.
- A real request ledger should bind the ID to a payload identity and result; reject an inconsistent reuse.
Follow-up
- Which boundary should define the lifetime of a deduplication key?
Count recent save acknowledgements
Medium · Queues · Metrics
Count acknowledgements in (now − 10, now]. Each event has weight one and timestamps arrive in order. The clock may move without any new event.
Approach
- Keep active timestamps in a deque and expire the lower boundary.
- This measures acknowledgements, not unique saved records. Repeated acknowledgements need a different deduplication rule.
Follow-up
- What would you change to count distinct note IDs instead?
Select the newest note revision
Medium · Window functions · Data grain
From revisions(note_id, version, text), select the highest version per note. The pair note_id and version is unique.
Approach
- Rank each note’s rows by version descending.
- Keep record identity in the partition; grouping by text would merge unrelated notes.
Worked solution (35 min)
- Rank revisions per note. Select the highest version rather than whichever row was inserted last.
- The unique key removes ties. If imported data violates it, fix the data contract rather than making an arbitrary selection.
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY note_id ORDER BY version DESC) AS rn
FROM revisions
)
SELECT note_id, version, text FROM ranked WHERE rn = 1;
Expected result: Note A selects version 2 even if version 1 was inserted later.
Verify it yourself
- Test multiple note IDs with the same text.
- Test a single-row note and an empty table.
Follow-up
- What constraint prevents ambiguous equal-version rows?
Find operations awaiting acknowledgement
Medium · Anti joins · Reconciliation
Given operations(op_id) and acknowledgements(op_id), find operations with no acknowledgement. IDs in operations are unique; acknowledgements may repeat.
Approach
- Use NOT EXISTS so duplicate acknowledgements cannot multiply rows.
- Do not interpret absence as proof the remote system did not commit; reconciliation may still be needed.
Follow-up
- How would you distinguish a delayed acknowledgement from a permanently failed operation?
Design a version-aware save API
Medium · Concurrency · API contracts
Design an API that accepts note ID, expected version, operation ID and replacement text. Support retries and competing edits without silently losing work.
Approach
- Authenticate and authorize access before exposing record details.
- Bind the operation ID to the request and compare the expected version within the write transaction.
- Return a stable result for a repeated identical operation; return a conflict for an outdated version.
Worked solution (35 min)
- Begin with an authorized request and a stable operation ID. Check whether that exact operation already has a result.
- Within a transaction, compare the expected version and write the new revision plus the operation result. A competing write makes the comparison fail.
- Return the recorded result on an identical retry. Preserve the user’s text when a different operation conflicts.
Expected result: Two writers based on version 3 cannot both overwrite it successfully.
Verify it yourself
- Replay a successful operation after a simulated timeout.
- Send the same operation ID with different text and reject the mismatch.
Follow-up
- What should the interface preserve while a user resolves a conflict?
Design an annotation review queue
Medium · Workflow · Audit history
Design a small internal review tool with assignments, revisions and an audit history. Two reviewers may open the same item. They must see who changed what without losing their own work.
Approach
- Separate assignment state from content revision.
- Use conditional updates for decisions and append attributable history.
- Provide a recovery path for abandoned assignments; do not confuse reassignment with deleting earlier work.
Follow-up
- Can a reviewer submit a decision against a revision they have never seen?
An old response replaces newer text
Medium · Async state · Frontend correctness
The user opens note A, then note B. A’s slower response arrives last and replaces B’s text. Trace the bug and explain two layers of protection.
Approach
- Associate each response with the current request generation and note ID. Ignore mismatches.
- Cancel obsolete requests where supported, but retain the identity check because cancellation can race with completion.
Worked solution (35 min)
- Start requests A and B, then resolve B before A in a controlled test.
- Before updating state, compare the response’s note ID and request generation with the current view.
- Use cancellation to reduce wasted work, while keeping the identity check as the correctness boundary.
Expected result: B stays visible after the older A response arrives.
Verify it yourself
- Test switching away and back to the same note with a new generation.
- Test an obsolete failure response so it cannot replace the current view with an error.
Follow-up
- Why does a loading boolean alone fail to distinguish the two requests?
Suggested practice checklist
A suggested week of practice, with one concrete outcome per session. Adjust the order and pace to your experience and interview date.
Day 1 — Map your evidence
- Read your exact opening and match two responsibilities to real project examples.
Deliverable: A role-to-project map
Day 2 — Test the coding contract
- Attempt the first coding problem. Add boundary cases before reading the solution.
Deliverable: A tested function
Day 3 — Query 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
Day 4 — Trace the unhappy path
- Switch the scenario diagram and explain which state is safe to show to a reader.
Deliverable: A recovery sketch
Day 5 — Reproduce the race
- Explain the debugging example with two competing operations. Identify the atomic or identity check.
Deliverable: A reproducible timeline
Day 6 — Prepare your stories
- Choose two behavioral prompts. Use real decisions, evidence and limitations instead of memorized scripts.
Deliverable: Two concise story outlines
Day 7 — Rehearse 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
Explain the decisions behind your work
Use a real project. Explain your responsibility, the decision you made, the evidence you used and what you would change.
- Choose examples you can discuss without sharing confidential customer data.
Turn feedback into a better workflow
Medium · Communication · Ownership
Describe a feature whose behavior changed after a user or teammate review.
Approach
- Be specific: Explain the original assumption, the evidence that challenged it and the concrete change you shipped.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- How did you check whether the new behavior helped?
Negotiate a smaller reliable release
Medium · Communication · Ownership
Describe a time you narrowed a feature to preserve correctness under a deadline.
Approach
- Be specific: Name what remained usable, what was postponed and who agreed to the tradeoff.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- What signal would have made you delay the whole release?
Explain a confusing customer incident
Medium · Communication · Ownership
Describe a bug that was hard for a user to report precisely.
Approach
- Be specific: Turn the symptom into a timeline and reproducible state without blaming the person reporting it.
- Own your part: Distinguish your decision from the team’s work. Use a real result and state any remaining limitation.
Follow-up
- How did you make a similar incident easier to diagnose?