Production Python for Data Engineers

Final Interview Preparation — System Design Questions

About this document

Three system design questions. No answers here — that's deliberate. Model answers exist in a separate document, interview-model-answers.md, and you should not open it before genuinely attempting all three questions yourself, out loud, the way you would in a real interview.

Each question asks for a complete data pipeline system design — the same scope and depth as the capstone you just finished, in a different domain, with a different core challenge you haven't had to solve yet. Your own capstone is, itself, a fourth example of exactly this kind of question — use it as a reference point for depth and structure, not as a template to copy into a different domain.


How to approach any question like this

Before the three questions, a shared framework — the same shape a strong candidate uses regardless of which specific system they're asked to design. Use this structure for all three.

  1. Clarify the requirements before designing anything. What's the actual scale — records per day, or per second? What does "correct" mean for this specific system, precisely? What happens if this is wrong — a minor inconvenience, or real financial or compliance exposure? A senior candidate asks these before sketching a single box.

  2. Identify the hardest constraint first. Every one of these three questions has one requirement that's genuinely difficult to satisfy, and the rest of the design mostly follows from getting that one thing right. Find it early — don't discover it halfway through your answer.

  3. Sketch the high-level architecture before the details. What are the major components, and how does data move between them? Get this right at a coarse level before arguing about specific tools or syntax.

  4. Walk through failure, not just the happy path. For each major component, ask: what happens when this fails, or receives bad input, or falls behind? A design that only works when everything goes right isn't a real design.

  5. Name the tradeoffs you're making, explicitly. Almost no decision in a system like this is free. A strong answer says what you're giving up, not just what you're gaining.

  6. Connect it back to what you actually know. Every one of these questions can be answered using exactly the disciplines your capstone already forced you to build — idempotency, classified retries, structured observability, safe configuration, bounded concurrency. You're not learning new concepts here. You're proving you can apply the same ones to an unfamiliar shape.


Question 1: Multi-Bank Payment Reconciliation

The scenario:

You're designing a system for a fintech company that receives daily settlement files from several partner banks. Each bank sends its file in a slightly different format. Your system needs to determine, for every transaction, whether it's present and matching on both sides — the bank's file and the company's own internal transaction records — and produce a reliable report of any mismatches for a finance team to review. This system has real regulatory and audit requirements: every reconciliation decision needs to be traceable, after the fact, to exactly why it was made.

Design a complete system for this.

What's expected in a strong answer:

  • A clear plan for handling multiple, differently-shaped input sources
  • An explicit definition of what "matched," "mismatched," and "missing" actually mean, and how the system determines each
  • A real answer to the audit/traceability requirement — not just "we'll log it"
  • The same core disciplines your capstone required — idempotency, resilience, observability — applied here, and explained specifically in this system's terms, not just asserted

How to start thinking about this:

Ask yourself first: what's actually being compared here? Unlike your capstone, which validated one stream of records against a schema, this system is comparing two independent sources of truth against each other. What are the possible outcomes of that comparison, and how many are there really? Start there before thinking about file formats or scale at all.


Question 2: Real-Time Clickstream Analytics

The scenario:

You're designing a system for a media streaming platform that needs to ingest clickstream and watch-events from millions of client devices, and produce rolling engagement metrics — like concurrent viewers per title — with a freshness requirement of under five minutes. Events can arrive out of order, sometimes significantly delayed, due to real client-side network conditions. The analytics team also needs the ability to reprocess historical data when their aggregation logic changes, without re-ingesting everything from the original source again.

Design a complete system for this.

What's expected in a strong answer:

  • A real answer for what happens to an aggregate metric when an event for an already-"closed" time window arrives late — this is the hardest part of this question, and an answer that ignores it isn't complete
  • A genuine distinction between "near-real-time" and "batch" in your design, and why each piece of the system is one or the other
  • A real answer to the reprocessing requirement — what makes reprocessing possible here, architecturally, not just "we'll run it again"
  • The same disciplines as always, applied to a system that's under much higher throughput and much tighter latency requirements than your capstone

How to start thinking about this:

Ask yourself: what does "correct" mean for a rolling metric, when the data feeding it can still change after you've already reported a number? Your capstone never had to answer this — every record it saw was, once fetched, a fixed fact. Here, "how many people are watching right now" is a number that can be revised. Start by deciding how your system will handle that reality, before designing anything else.


Question 3: Multi-Tenant Usage Metering for Billing

The scenario:

You're designing a system for a B2B SaaS platform that needs to meter every customer's API usage, across hundreds of tenants, and aggregate it into monthly billing line items. The business requirement is absolute: a bug in this system must never result in a customer being double-billed or silently under-billed. Customers occasionally dispute a specific charge, which requires the team to precisely reprocess one narrow historical window for one specific tenant — without touching anyone else's already-finalized billing data.

Design a complete system for this.

What's expected in a strong answer:

  • A real answer for tenant isolation — what happens if one tenant sends dramatically more usage events than every other tenant combined?
  • A precise mechanism for the "reprocess one tenant, one window" requirement — not "we'll rerun the whole pipeline carefully"
  • An explicit answer for what "never double-billed" actually requires, mechanically, not just as a stated goal
  • The same disciplines as always, with idempotency specifically reasoned about at the level of "one tenant, one billing period," not just "the whole system"

How to start thinking about this:

Ask yourself: what's the actual unit of correctness here? It's not "the whole system was correct today" — it's "this one tenant's bill, for this one month, is exactly right." Once you've defined the unit that has to be correct, precisely, the reprocessing requirement becomes a lot easier to reason about. Start there, before thinking about ingestion volume or tenant isolation.