Structured Problem Solving and Decomposition Questions
Methodical problem solving for open-ended and ambiguous situations once the problem is defined: decomposing a goal or problem into mutually exclusive, collectively exhaustive parts (issue trees, metric trees and driver breakdowns, work breakdown into subproblems and vertical slices), forming and prioritizing hypotheses (hypothesis trees and funnels, including laying out candidate explanations for a metric drop or model degradation and the cheapest test for each branch), choosing an analytical approach, and reasoning to a recommendation. Also covers turning a vague mandate into measurable, testable subproblems with owners, breaking a large initiative into workstreams, mapping dependencies, sequencing the work, deciding the first deliverable and what to defer, structuring plans that mix research, analytics and experiments, and talking through real examples of cutting a messy problem into parts. Covers explaining and adapting structured problem-solving methods across contexts, choosing and switching methods, and coaching others to structure ambiguity. Excludes turning a vague request into a scoped problem statement, named-framework business cases, root-cause techniques for failures and metric movements (running the diagnosis itself), prioritization scoring and trade-off decisions, deciding how to act under incomplete information, market sizing and estimation, and framing machine-learning problems, which are covered elsewhere.
Tell me about a time you broke a messy problem into parts to find what was wrong. How did you decide the split, which part you tested first, and what did the structure help you avoid?
Sample Answer
Direct answer
Pick a story where the problem really was messy (many possible causes, no obvious owner), where you chose an explicit way of splitting it, and where the split saved you from a specific wasted effort. A strong answer says why that split (what made the parts independent), why you tested one part first (it ruled out the most possibilities for the least work), and what the structure stopped you from doing.
Structured elaboration
Use STAR (Situation, Task, Action, Result) and weight the Action section:
- Situation and Task: two sentences. What looked wrong, who noticed, why it mattered.
- Action, the part interviewers score: (1) the way you split, along a dimension such as stages of a data flow, and why that dimension; (2) the first part tested and why (cheapest check that cuts the search space in half); (3) what each result told you; (4) how you confirmed the cause before fixing.
- Result: what was fixed, what you added so it would not recur, and honestly what you would do differently.
- What the structure helped avoid: name at least one concrete trap, such as chasing the most visible suspect for days, blaming another team's data, or changing two things at once.
Worked example
Example story to adapt to your own facts (qualitative on purpose, meaning described in words rather than with measured figures; use your real numbers only if you can back them up).
Situation. A weekly sales report from our analytics tables was off by a few percent against the finance ledger. Finance distrusted the dashboard and the team suspected a faulty query.
Task. Find where the numbers diverged, without a week of guesswork.
Action. I split the path the data takes into stages: source system, extraction, staging table, transformation, final report table, dashboard. Rather than start at the dashboard (the most visible suspect), I compared row counts and totals at the middle, the staging table. They matched the source, so extraction and staging were cleared in one check and the problem lay in the second half. A second comparison after the transformation step showed the gap appeared there. Reading that step, an inner join (keeps only rows that match in both tables) to a currency-rate table dropped orders in a newly added currency with no rate row. I confirmed it by counting orders per currency before and after the join, then changed one thing only: a left join (keeps every order and fills missing rate matches with a blank) with a visible default flag.
Result. The report reconciled with finance. I added a row-count comparison between stages that alerts on mismatch. Looking back, I would have added that reconciliation when the pipeline was built.
What the structure avoided. Days of rewriting dashboard queries that were correct, an argument with finance about whose number was right, and bundling several changes so we would not know which one fixed it.
Trade-offs and pitfalls
- A story that is just "I investigated until I found it" shows no decomposition.
- Splitting by whatever is convenient (by person, by file) rather than by something that makes the parts independent is weak.
- Claiming exact impact figures you cannot support is worse than a clear qualitative result.
- Saying you would change nothing sounds like low self-awareness.
- Be ready for a different-domain version: the same move works for a slow service, an inconsistent survey result or a failing model.
Nightly pipelines deliver on time 85% of the time and the goal is 99% in three months. How would you structure the work: what to learn first, what subproblems to split off, and how you would explain the plan to leadership in one page?
Sample Answer
Direct answer
Treat "85% to 99%" as a measurement problem first and an engineering problem second. Spend the first week pinning down what "on time" means and why the late runs were late, then split the work along the causes that account for the most late runs, and give leadership a one-page plan with a baseline, a few workstreams, monthly targets and the decisions you need from them.
Structured elaboration
What to learn first (week 1)
- The definition. A pipeline is a scheduled job that moves and transforms data. "On time" needs a deadline (say 06:00), a measurement point (job finished, or data actually visible to consumers) and a scope (all pipelines, or only the ones people depend on). Count in one unit: a pipeline-night is one pipeline's run on one night.
- Who is hurt by lateness. Tier the pipelines. One feeding a 07:00 executive dashboard matters more than an archive job. The 99% may only need to hold for the top tier, which is a question to settle with leadership early.
- A cause log. For every late pipeline-night in the last several weeks, record the first thing that went wrong. Rule: each late run goes in exactly one bucket, so the buckets cannot overlap.
Subproblems to split off. The split below is MECE (mutually exclusive: no run in two buckets; collectively exhaustive: every late run lands somewhere), because the first-cause rule decides placement in time order.
| Subproblem | What it means | Typical levers |
|---|---|---|
| Started late | Upstream data or a dependency was not ready at start time | Agreed delivery times with upstream owners, sensors (checks that wait for the upstream data to appear and then start the job, instead of running at a fixed clock time), fallback to last good data |
| Failed | The run errored and recovery took too long | Automatic retries, safe reruns (idempotent: running twice gives the same result), alert routing to on-call (the engineer currently responsible for responding to pages) |
| Ran too long | Started on time but overran the window | Profile the slowest stage (measure where the time goes), fix skew (one worker getting far more data than the others, so everything waits for it), resize resources (give the job more compute), reorder jobs on the critical path (the longest chain of jobs that depend on each other, which sets the finish time) |
Worked example
All numbers are illustrative. Take 20 pipelines over 30 nights: 600 pipeline-nights. At 85% on time, 510 are on time and 90 are late. At 99%, at most 6 may be late, so about 84 of the 90 late runs (roughly 93%) must stop happening.
Cause log: started late 45 (upstream late 36, dependency chain with no slack 9 (job B waits for job A with no spare time between them, so any delay in A passes straight through)), failed 27, ran too long 18. The total is 90. So half the problem (45 of 90) is upstream timing and 30 percent (27 of 90) is failures. That ordering decides the plan: fixing run time first would attack only 20% of the lateness.
One run traced through the rule: a pipeline due at 06:00 gets its upstream data at 05:30 instead of 04:00, so it starts late, and it then also fails on a timeout. It is logged once, under started late, because that was the first thing that went wrong; the failure goes in a notes column. Counting it in both buckets would make the buckets sum to more than the 90 late runs.
Monthly targets: 91% means at most 54 late runs, 96% at most 24, 99% at most 6.
The one page for leadership (excerpt):
- Goal: tier-1 pipelines on time 99% of nights by month 3, measured as data visible by 06:00. Baseline today: 85% across all 20 pipelines (the tier-1 baseline comes from cutting the same cause log by tier, and the 99% applies to that tier-1 slice).
- Diagnosis: 90 late runs in 30 nights: 50% started late, 30% failed, 20% ran long.
- Workstreams: (1) upstream delivery agreements and fallback data, (2) failure recovery and alerting, (3) runtime on the critical path.
- Measure: weekly on-time rate per tier, plus late runs by cause.
- Milestones: 91% month 1, 96% month 2, 99% month 3.
- Asks and risks: a named owner on each upstream team; if upstream will not commit, we deliver stale-marked data on time instead of fresh data late.
The same one-page shape for a latency goal such as cutting data latency by 50% in six months. Define latency as source event to queryable data, measured at the 95th percentile (sort the runs from fastest to slowest; 95 of every 100 finish at or under this value, so it shows the slow tail rather than the typical run). Break it by stage and give each a budget. Illustrative: ingest 15, transform 30, load 10, refresh 5 minutes (60 total) becomes 8, 14, 5, 3 (30 total). Caveat: the 95th percentile of the total is not the sum of the stage 95th percentiles. With independent, light-tailed stages the sum usually overstates it, because the slowest run in one stage is rarely the slowest in every stage; with heavy-tailed stages (a few very long runs) it can understate it, so neither direction is guaranteed. Treat the stage budgets as targets and measure the end-to-end 95th percentile directly. The page then lists goal, one component per stage, a measure per stage and checkpoints roughly every month.
Trade-offs and pitfalls
- A single average hides the tail: report on-time rate per tier, not one blended number.
- Do not promise 99% before the cause log exists. After week 1, state the plan with real data.
- Upstream lateness cannot be fixed by your team alone, so the plan must contain a fallback you control.
- Fixing the loudest incident instead of the largest bucket is the common wrong turn.
- If two buckets turn out to share one cause (for example a shared cluster), say so on the page and treat it as one workstream.
Take a goal like 'onboarding completion dropped 30%' or 'migrate our monolith while cutting cost 20%'. Show me how you break it into smaller subproblems, how you decide the split, and how you know when to stop splitting.
Sample Answer
Direct answer
First I turn the goal into a precisely defined number. Then I split it using a rule that guarantees the pieces do not overlap and cover everything, and I pick the splitting dimension that separates owners and actions. I stop splitting when each leaf is testable, owned, measurable and decision-relevant.
Worked decomposition: "onboarding completion dropped 30%" (illustrative numbers; the monolith goal is worked through with numbers after the table of other goals)
- Define the metric. Completion = users who finish setup within 7 days of sign-up, divided by users who start. Check what "30%" means. A relative drop from 60% to 42% is 30% relative (18 percentage points); a drop of 30 points is a different problem.
- First split: by funnel stage. Stages are sequential, so every user stops in exactly one place (mutually exclusive) and a user who finished passed them all (exhaustive). A simplified two-stage funnel:
| Stage | Before | After |
|---|---|---|
| 1. Verify email | 75% | 75% |
| 2. Connect first data source | 80% | 56% |
| Completion (stage 1 x stage 2) | 60% | 42% |
Check: 0.75 x 0.80 = 0.60 and 0.75 x 0.56 = 0.42. Stage 2 fell from 0.80 to 0.56, which is 30% relative, so it holds the whole drop. A real funnel has more stages.
3. Second split inside stage 2: by what the user did. (a) never reached the connect screen, (b) reached it but never attempted, (c) attempted and failed. Each user is in exactly one state. The three states cover the stage-2 users who did not finish. Users who connected successfully are a fourth state, (d), kept in the split so it stays exhaustive and the sum test passes: with illustrative counts per 1,000 users who verified their email, before the drop 800 are in (d); after the drop 560 are in (d), and the 240 extra non-completers are spread across (a), (b) and (c). Each leaf has a metric from event logs, an owner (navigation team, product design, integrations engineering) and a test (count users in the state, before versus after). "Funnel" here means the ordered steps users pass through from sign-up to finished setup, and event logs are the recorded actions (screen viewed, button clicked) that let you count users at each step.
How I decide the split
I choose the dimension where (1) branches imply different actions, (2) branches map to different owners, (3) the data already exists, and (4) the split can be checked cheaply. A split by device or customer segment is useful too, but as a second-level cut, because it does not tell a team what to fix.
The stopping rule
A leaf is done when it is:
- Testable: one analysis or small experiment answers it in days, not weeks.
- Owned: one person or team can act on it.
- Measurable: it has a metric, a baseline and a target.
- Decision-relevant: a yes or no would change what we do.
Too shallow: a leaf needs a multi-week project or has two owners. Too deep: leaves nobody owns, or whose answer would not change the plan.
The same method on other goals
| Goal | Split rule | Leaves that pass the stopping rule |
|---|---|---|
| Migrate a monolith (one large deployable application) and cut cost 20% | First fix the baseline: 20% of which bill, and are one-off migration costs included? Then split by module along clear boundaries, and cost into run cost versus migration cost | Milestone 1: cost-per-module table. Milestone 2: move one low-risk module behind an interface (a stable boundary, so the rest of the application calls it the same way before and after the move) and measure its before/after cost. Each deliverable has an owner and a number |
| Reliability work (SRE, site reliability engineering) | Split by user journey, each piece tied to a service-level objective (SLO), a target like "99.9% of checkout requests succeed over 30 days" | "Checkout survives the loss of one zone" (a zone is a separate data-centre area within a cloud region), proven by a failover drill (deliberately switching to the backup) in staging (a test copy of the production system) |
| Raise engagement through recommendations (machine learning, ML) | Split along the pipeline: candidates retrieved (the shortlist the system pulls from the catalogue), ranking (ordering that shortlist), presentation (how it is shown), measurement | "Is a relevant item in the top 50 candidates?" is testable offline with logged clicks (recorded past clicks, treated as evidence of what was relevant) |
| User registration feature | Split by component: form validation, account storage, email verification, session creation, abuse protection | Each component has its own acceptance test (a check that it does what was agreed) and can be built and checked alone |
The monolith goal with numbers (illustrative)
Suppose the yearly bill is 1,200k and "cut cost 20%" means a saving of 240k a year, run cost only, with one-off migration cost reported separately. First split, by cost type, is run cost 1,200k plus one-off migration cost (tracked, not counted against the 20%). Second split, run cost by module: checkout 400k, search 300k, reports 200k, admin 100k, shared infrastructure 200k (400 + 300 + 200 + 100 + 200 = 1,200). Each module is a different team's code and bill, so each has an owner. Stopping check on the leaf "reports module, 200k": testable (move it behind an interface and compare its bill before and after, in weeks), owned (the reports team), measurable (baseline 200k, target for example 140k, a 60k saving, which is a quarter of the 240k goal), decision-relevant (if the saving is small, the next module is chosen instead). Shared infrastructure fails the check as a single leaf because no one team owns it, so it is split further by the module that consumes it.
Pitfalls
- Splitting by whatever is easiest to draw, which gives branches nobody can act on.
- Mixing two dimensions at one level (stage and device), which breaks mutual exclusivity.
- Splitting until the tree looks impressive instead of until leaves are testable.
That is every published Structured Problem Solving and Decomposition question for Site Reliability Engineer (SRE) so far. Browse the other topics in this category, or practice this one interactively.