Free · No login required to browse

Ace your next technical interview.

162 real interview questions across 32 companies and 17 roles, each with an expert answer and a plain-English explanation.

162
Questions
32
Companies
17
Roles
27
Topics
~6
Avg. min read
01 — Inside an answer

Every question, answered seven ways.

One real question from the database, shown exactly as it appears on its own page.

Q-084 Microsoft Backend Developer ~5 min read

How do you design an idempotent API endpoint, and why does it matter for payment retries?

An idempotent endpoint produces the same result no matter how many times the same request is sent, so a client that times out and retries never causes a duplicate side effect, like charging a customer's card twice for one purchase. The standard pattern is an idempotency key: the client generates a unique token per logical operation (not per HTTP attempt) and sends it in a header, and the server stores the outcome of the first request against that key so any retry with the same key just returns the original result instead of re-executing the operation.

Why retries are unavoidable

Networks fail in ways that leave the client unable to tell whether the server actually processed the request or not, the request could have succeeded and the response got lost. Since the client can't distinguish these cases, it has to retry to be safe, which means the server has to be the one guaranteeing safety, not the client.

Best practice

Store the idempotency key, the request's result, and its status in a fast, durable store (a database row or Redis with an appropriate TTL) keyed by that token, before returning a response. On a retried request, look up the key first, if found, return the stored result immediately without touching the underlying business logic (like charging a card) again.

Edge case interviewers probe for

What happens if a retry arrives while the first request is still in-flight (not yet finished)? A naive check-then-act lookup lets both requests slip through and double-execute; the fix is to atomically claim the key first (an insert with a uniqueness constraint, or a Redis SETNX) so the second request sees it's already claimed and waits for or returns the first request's eventual result instead of racing it.

Common mistake

Making the endpoint's business logic itself naturally idempotent (like a database update, which is; running it twice sets the same final value) is not the same thing as making the whole HTTP operation idempotent, non-idempotent operations like "charge $50" or "send one email" need this explicit key-based pattern since re-running them isn't naturally safe.

What the interviewer is checking

Whether you think about distributed systems in terms of failure modes (timeouts, retries, partial failures) rather than assuming the happy path, and whether you know a concrete, standard mechanism (idempotency keys) rather than a vague "we'd handle duplicates somehow."

Imagine mailing a check, not hearing back for weeks, and not knowing if it got lost or if it arrived and the reply is just slow. If you mail a second check "just in case," you risk paying twice if the first one actually arrived. An idempotency key is like writing the same reference number on both checks: the bank sees the second check has the same reference number as one it already cashed, so it simply ignores the duplicate instead of cashing it again.

That's exactly what happens when an app's network request times out. The app doesn't know if the payment went through, so it wants to safely retry. By sending the same unique "reference number" (the idempotency key) with the retry, the server can recognize it already handled this exact request and just resend the original result, instead of charging the customer a second time.

Interviewers often continue with:

  • How long should an idempotency key be valid for?
  • How would you handle a retry arriving while the original request is still processing?
  • Is GET naturally idempotent, and why doesn't it need this pattern?
charge.py
# Atomically claim the key before doing anything, so concurrent retries can't both slip through
def charge(idempotency_key, amount, customer_id):
    existing = db.execute(
        "INSERT INTO idempotency_keys (key, status) VALUES (%s, 'processing') "
        "ON CONFLICT (key) DO NOTHING RETURNING key",
        [idempotency_key],
    )
    if existing is None:
        # Key already exists: another request owns it, return its stored result
        return db.fetch_result(idempotency_key)

    result = payment_gateway.charge(amount, customer_id)
    db.execute(
        "UPDATE idempotency_keys SET status='done', result=%s WHERE key=%s",
        [result, idempotency_key],
    )
    return result
Read the full answer →
Expert Answer ELI5 Interview Tips Practical Example Code Example Diagram Key Takeaways
04 — Study tips

What actually moves the needle.

Preparation habits pulled from candidates who went through the process more than once.

01

Study the pattern, not the problem

Two Sum and Subarray Sum look different until you notice they're both solved with the same hash map trick. Learn the pattern once, recognize it everywhere.

02

Say your answer out loud

Silent practice hides the moments where your reasoning has a gap. Reading aloud finds them before the interview does.

03

Time-box every rep

Twenty-five minutes per question, no exceptions. Interviewers won't give you the extra ten either.

04

Revisit what you got wrong

A missed question you review twice sticks. One you skip past tends to show up again in a different interview.

Open a question. Read it out loud.

All 162 questions are one click away.

Start learning