cswork / libraryOpen practice workspace

Interview guides · Expand Energy

Expand Energy Data Scientist Interview Questions & Guide 2026

Timed data scientist practice for Expand Energy: short SQL and probability sets run end to end, then scored against a rubric.

The 60-second brief

The role of Data Scientist at Expand Energy is critical in shaping the future of energy trading and corporate development. As a Data Scientist, you will leverage advanced analytics and machine learning to optimize trading strategies, enhance resource allocation, and influence decision-making processes that drive business success. Your insights will not only aid in maximizing profitability but also play a pivotal role in the company's mission to innovate within the energy sector.

Product-sense cases reward reasoning from a mechanism to a testable prediction. Reciting every metric you can name reads as pattern matching; naming the single quantity that would move if your explanation were true reads as thinking.

Focus areas

  • Evaluate forecasts at the lag ordering actually uses
  • Price a service-level change in working capital
  • Size safety stock under variable lead times

Overview

You will be part of dynamic teams working on various projects, such as predictive modeling for market trends, optimizing energy distribution, and developing data-driven strategies to meet regulatory compliance. This role is appealing due to its complexity and the high impact it has on both internal stakeholders and external partners. Expect to engage with vast datasets, collaborate with cross-functional teams, and contribute to projects that push the boundaries of energy technology.

The Expand Energy interview process

Expand Energy candidates report 5 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.

Initial Screening

Most candidates lose this call inside the first two minutes, during the walkthrough of their own background. The account runs chronologically, sits at the level of tools and titles, and never arrives at a decision anyone could have disagreed with. Anchor on a problem instead of a timeline: what the team could not answer, what you did about it, what happened next. Ninety seconds is enough, and stopping on time leaves room for the half of the call that belongs to you. What you ask about how work gets prioritised signals your level more reliably than the walkthrough does.

What to demonstrate

  • Whether your background summary has a shape (problem, decision, consequence) or is a chronological list of tools and employers
  • Whether you can account for gaps, short stints and the reason you are looking, unprompted and without hedging
  • The substance of the questions you ask back, which an experienced screener reads as a level signal

How to prepare

  • Time your opening walkthrough against a clock. If it runs past two minutes, compress the earliest role into a single clause and spend the recovered time on the most recent one
  • Write one honest sentence for every gap or short stint visible on your resume and offer it before being asked about it
  • Prepare questions about how work arrives and gets prioritised: who writes the request, how often priorities change, and what happens to an analysis after it is delivered

Technical Assessments

A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.

What to demonstrate

  • Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
  • Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
  • Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.

How to prepare

  • Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
  • Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
  • If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows

Behavioral Interviews

Most of the weight in this round sits on the disagreement questions. Data work routinely produces an answer someone senior did not want, and the interviewer is trying to learn what you do in that hour. Both failure modes are common: folding as soon as a director pushes back, and treating the pushback as ignorance to be corrected with a better chart. A strong answer usually contains a specific thing the other person knew that you did not, and describes how you found out whether it changed the conclusion.

What to demonstrate

  • Whether you can state the other side's argument accurately before you explain why you disagreed
  • What you treated as evidence during the disagreement, such as a rerun under their assumption or a holdout check, rather than persuasion technique
  • Whether you distinguish being overruled from being wrong, and can give an example of each

How to prepare

  • Write out one disagreement where you turned out to be wrong, and say what in the data misled you. Candidates prepare the story where they were right, and the follow-up asks for the other one.
  • For your main disagreement story, be ready to say what result would have made you drop your position. If no such result exists, you were not arguing from the data.
  • Practise stating the opposing position out loud in one sentence the stakeholder would accept, then continue the story.

Case Studies

Underneath the business framing, this round is usually asking whether you can turn a fuzzy goal into a quantity that could be computed from data such a business would plausibly hold. That means a metric with a stated numerator, denominator, eligibility rule and time window, plus an honest account of the conditions under which it would mislead you. Answers come apart when a candidate names a familiar metric and never defines it, because every follow-up then lands on an ambiguity that was left open and the candidate has to invent the definition under pressure.

What to demonstrate

  • Whether a named metric arrives with its denominator, eligibility rule and window attached rather than assumed
  • Whether the measure follows from the mechanism you proposed, or is a recognisable metric retrofitted to it afterwards
  • Whether you name a guardrail that would reveal the gain came from somewhere you did not want it to come from
  • Whether you can say what data the plan requires and what you would settle for if that logging were never implemented

How to prepare

  • Take five metrics you reach for by reflex and write each as one sentence containing numerator, denominator, eligibility rule and time window. The ones you cannot finish are the ones that will fail under follow-up.
  • For a product you use daily, write the measurement plan you would propose for a change to it: primary metric, one guardrail, the unit of analysis, and the table the numbers would come from.
  • Practise the substitution question. For three metrics you like, write what you would measure instead if the event you depend on were not being logged.

Final Interviews

A loop is not scored one interview at a time. The people you meet compare notes afterwards, usually in a meeting you are not in, and the outcome turns on what each of them can say about you when asked. That rewards something other than survival: every room needs one specific thing worth repeating, and none of them can contradict another. The common way to lose is to tell the same project four times with different numbers in it, or to be uniformly fine in a way that leaves nobody with anything to argue for.

What to demonstrate

  • Whether your account of a project survives being told twice, with the same scale, the same metric definition and the same numbers each time
  • Whether each interviewer leaves with one concrete claim they could make on your behalf later, rather than an absence of complaints
  • Whether a question you already answered in an earlier room gets the same answer at the same depth, without visible impatience

How to prepare

  • Write a one-page fact sheet for your two or three main projects that fixes the numbers you will quote: rows of data, the metric as a single sentence, the effect you measured and how long the work took. Say them aloud from the sheet until they come out identical every time
  • For each kind of room you expect, decide the one sentence you want that interviewer repeating in a debrief, then check during the mock that you said it outright instead of implying it
  • Rehearse answering the same project question twice in one sitting, the second time as though you had not just answered it, because the thing that needs fixing is the flatness that creeps into a repeated story

Where candidates lose points

Computing average inventory from period-end snapshots

Shipments cluster before period close, so the month-end on-hand position is systematically the lowest point of the month; turns computed against it are biased high and days of supply biased low, frequently by ten to twenty percent, and the bias grows precisely when close-period push is strongest. The same shape of error appears when a daily snapshot is joined to shipment events on date equality: a SKU with several legs on one day fans the snapshot out and multiplies the valued inventory. Average across every daily snapshot in the window for the denominator, and join snapshots to events with an explicit as-of condition and a row-count check at each grain before aggregating.

Treating shipped units as demand

Shipments are censored at available inventory: on a stockout day the recorded quantity is a supply ceiling, not customer intent, and orders that were never placed because the item showed as unavailable leave no row at all. A forecast fitted on that history learns the constraint, under-forecasts the fast movers that stock out most often, and produces the replenishment that causes the next stockout, so the error compounds in one direction rather than averaging out. The fix is to model demand_qty rather than shipped_qty, flag stockout days with stockout_flag and treat them as censored (fit with a censored likelihood, or estimate unconstrained demand from uncensored periods and comparable locations), and to report how much of the history was censored alongside any accuracy number.

Reporting a p-value with no effect size or interval

Give the estimated difference with a confidence interval in the units the business cares about, then say whether that whole interval is worth acting on. A p-value only addresses whether you can rule out exactly zero; it says nothing about magnitude.

Interpreting a change before checking data quality and logging

Spend the first pass on row volume by day, null rates, duplicate keys, and whether the step change lands on a release or tracking-migration date. A discontinuity that coincides with a deploy is an instrumentation hypothesis before it is a behavioural one.

Questions & practice

Write a function to calculate the correlation coefficient between two datasets.

Medium · statistics and probability

Approach

  1. Translate the result into the decision it informs, in one plain sentence.
  2. Write down the assumption the method needs before you use the method.
  3. Sanity-check the answer against a simple bound or a simulated case.

Follow-up

  • Which assumption here is most likely to be violated in practice?
  • How would you explain this result to someone who does not know statistics?

Describe the time complexity of common sorting algorithms.

Medium · machine learning and modelling

Approach

  1. Set a baseline first, so any model has something honest to beat.
  2. Check what information would not exist at prediction time, and exclude it.
  3. Frame the prediction: the label, the moment of prediction, and the action it triggers.

Follow-up

  • Where could label leakage enter this setup?
  • What would you monitor after launch to know the model is still valid?

Simulate service levels under a variable inbound lead time

Medium · safety stock · monte carlo · service level

Daily demand for one SKU at one node is Poisson with mean 40. Replenishment lead time is 7 days with probability 0.7, 10 days with 0.2, and 14 days with 0.1, drawn independently per order. The policy is continuous review: order Q = 400 whenever the inventory position drops to the reorder point. Size safety stock two ways for a nominal 95 percent target, once as z times sigma_D times sqrt(mean lead time) and once with the variable-lead-time term. Simulate both and report achieved cycle service level and achieved unit fill rate.

Approach

  1. Compute both safety stock numbers analytically before simulating, so the simulation is a check on arithmetic you already understand rather than the source of the answer.
  2. Track inventory position (on hand plus on order) for the reorder trigger and on hand separately for the stockout test. Triggering off on hand alone re-orders while stock is already in transit and silently changes the policy you are measuring.
  3. Define the two outcomes precisely and separately: cycle service level is the fraction of replenishment cycles containing at least one unit of unmet demand, while fill rate is total units shipped from stock over total units demanded. They answer different questions and z targets only the first.
  4. Before running anything, bound the achievable service level by hand from the lead-time mixture. Each lead-time branch is a separate Poisson demand, so cycle service level is the probability-weighted sum of P(Poisson(40 x L) <= reorder point) across the three branches, and a reorder point that cannot cover the 14-day branch caps the policy at 0.9 no matter how the simulation is tuned.
  5. Run enough cycles that Monte Carlo error is small against the gap you are trying to see. The standard error of a service level is sqrt(p*(1-p)/n_cycles), about 0.005 at p = 0.7 with 10,000 cycles, so the 20-point gap between the two policies is unambiguous and a 1-point one is not.
  6. Let unmet demand be lost rather than backordered, state that choice, and note that switching to full backordering raises measured fill rate for the same policy.

Worked solution (35 min)

  1. Compute mean lead time 8.3 days, variance of lead time 5.01, sigma_D = sqrt(40) = 6.32, and mean demand 40 per day.
  2. Naive safety stock: 1.645 * 6.32 * sqrt(8.3) = 30 units, giving a reorder point of 332 + 30 = 362. Correct safety stock: 1.645 * sqrt(8.3 * 40 + 40^2 * 5.01) = 1.645 * 91.4 = 150 units, giving a reorder point of 482.
  3. Write one simulation loop parameterised by safety stock: draw daily Poisson demand, decrement on hand, record shortfall, trigger an order of 400 when position hits the reorder point, and schedule the receipt after a sampled lead time.
  4. Run 10,000 cycles per policy with a burn-in of at least two lead times discarded so the starting position does not flatter the first cycles.
  5. Report achieved cycle service level, achieved fill rate and the average on-hand position for each of the two safety stock settings.

Expected result: Naive safety stock is 30 units and the variable-lead-time figure is 150 units, a factor of five. At Q = 400 with lost sales, the naive policy achieves a cycle service level of about 0.70 and the correct policy about 0.90, so the naive policy misses the nominal 0.95 by roughly 25 points and the correct one by 5. The naive ceiling is arithmetic, not simulation noise: with a reorder point of 362 the 7-day branch is essentially always covered, the 10-day branch survives with probability P(Poisson(400) <= 362) = 0.029, and the 14-day branch never does, so cycle service level cannot exceed 0.7 + 0.20.029 + 0.10 = 0.706, and reorder-point undershoot of about 20 units under daily demand arrivals pulls it to roughly 0.70. The correct policy tops out near 0.90 for the same structural reason: a reorder point of 482 covers the 10-day branch almost completely (P = 0.99997) but not the 14-day one (P = 0.0004), so that 0.1 of probability mass is near-pure loss. Fill rate is higher than cycle service level under both, about 0.92 against 0.70 and about 0.98 against 0.90, because expected units short per cycle (roughly 33 and 10) are small against Q = 400.

Verify it yourself

  • Set the lead time to a constant 8.3 days and confirm the two formulas return an identical safety stock, since the lead-time variance term vanishes.
  • Compare the naive policy's simulated cycle service level against its analytic ceiling, 0.7 + 0.2P(Poisson(400) <= 362) + 0.1P(Poisson(560) <= 362) = 0.706 before undershoot. A simulated figure above that is a bug, usually triggering off on hand instead of inventory position, and three seeds should land a little below it and agree within about one point, consistent with a standard error of about 0.005 at 10,000 cycles.
  • Confirm fill rate exceeds cycle service level at Q = 400 under both policies, and treat that ordering as a consequence of Q rather than a law: expected units short per cycle depends on the reorder point and the lead-time demand distribution, not on Q, so holding the reorder point fixed and halving Q leaves cycle service level roughly unchanged while fill rate falls by about the same shortfall over a smaller denominator.
  • Confirm simulated demand over the lead time has mean near 332 units and standard deviation near 91.4, which is exactly the quantity the correct formula multiplies by z.

Follow-up

  • With Q = 100 against lead-time demand of 332 units, three or four orders are open at once. What happens to the meaning of a replenishment cycle, and to each of the two service measures?
  • Lead time and demand are correlated because the supplier is capacity constrained in peak weeks. What does that do to the formula you used?
  • How would you convert the extra 120 units of safety stock into an annual cost the business can weigh against the service gain?

How would you optimize a slow-running query in a database?

Medium · sql and data manipulation

Approach

  1. State the window function and its partition and ordering out loud before writing it.
  2. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
  3. Check whether any join is one-to-many before aggregating, or the sums inflate.

Follow-up

  • How does the query change if the join becomes one-to-many?
  • What breaks if events arrive late or out of order?

Bullwhip ratio by echelon from daily pipeline deltas

Hard · window functions · bullwhip · variance ratio

fct_inventory_daily gives on_order_qty (ordered, not yet shipped) and in_transit_qty (shipped, not yet received) per sku x location x date; dim_location gives echelon and parent_location_id. There is no replenishment-order table, so derive placements: a new order raises on_order, a shipment moves quantity from on_order to in_transit, and a receipt lowers in_transit, so placed_qty on a date is the positive part of the day-over-day change in (on_order_qty + in_transit_qty). Compute weekly placements per node and the bullwhip ratio against the demand that node received, reported per echelon. State what the derivation misses.

Approach

  1. Per sku-location, take LAG(on_order_qty + in_transit_qty) OVER (PARTITION BY sku_id, location_id ORDER BY inventory_date) and set placed_qty = GREATEST(pipeline - lag_pipeline, 0). The first date in each partition has no lag and must be dropped, not read as a placement equal to the whole standing pipeline.
  2. Name the blind spots before anyone else does: an order placed and received inside one day nets to zero, a cancellation is indistinguishable from a receipt, and minimum order quantities plus lot-size multiples make placements lumpy by construction rather than by anyone's behaviour.
  3. Define received demand by echelon. At the lowest echelon it is demand_qty in the same table. At a parent node it is the sum of its children's placed_qty joined through parent_location_id, not the parent's own demand_qty column, which is close to empty for a pure replenishment node.
  4. Aggregate both series to weekly buckets before computing dispersion, because day-of-week ordering patterns otherwise dominate the variance, and require a minimum number of weeks before quoting any ratio.
  5. Compute CV = stddev_samp / NULLIF(avg, 0) on each weekly series and report the ratio of squared CVs, stating that convention explicitly: a raw variance ratio is not level-free and is not comparable across nodes of different size.
  6. Read the output by echelon and locate where the ratio first crosses one going upstream. That is the node whose ordering rule amplifies, and it is usually not the node where the schedule instability is being felt.

Worked solution (45 min)

  1. CTE pipeline: select sku_id, location_id, inventory_date, on_order_qty + in_transit_qty AS pipe, and LAG(pipe) over the partition; drop rows where the lag is NULL and count them.
  2. CTE placements: placed_qty = GREATEST(pipe - lag_pipe, 0), aggregated to sku-location-week.
  3. CTE received: weekly demand_qty per node for the lowest echelon, and for higher echelons the weekly sum of children's placed_qty joined on parent_location_id.
  4. Join the two weekly series per node, require a minimum week count, and compute stddev_samp and avg on each side.
  5. Emit echelon, node, weeks_observed, cv_orders, cv_demand, bullwhip = (cv_orders / cv_demand) ^ 2, and the dropped first-date row count.

Expected result: One row per node with its echelon, weeks_observed, cv_orders, cv_demand and bullwhip as the squared CV ratio, plus an echelon-level rollup and the count of partition-start rows excluded for having no lag value.

Verify it yourself

  • Total placed_qty over a long window is close to the total of receipts implied by falls in in_transit_qty. A large shortfall means same-day place-and-receive is common and the derivation is understating placements.
  • Nodes at echelon 1 or 2 with no children under parent_location_id are excluded explicitly rather than silently producing a NULL or zero demand denominator.
  • Recomputing the CVs on daily instead of weekly buckets changes the ratio. An identical ratio means the weekly aggregation never took effect.
  • placed_qty is never negative, and its maximum is bounded by the largest single-day pipeline increase in the raw data.

Follow-up

  • A node shows a ratio near 3. Name three ordering rules that produce that and say how you would tell them apart using only these tables.
  • Why might a plant's schedule instability be untouchable from inside the plant, and what would you change instead?
  • What would you want logged so that placements no longer have to be inferred from pipeline deltas, and what is the smallest such change?

Given a dataset of energy consumption over the past year, how would you approach forecasting future consumption?

Medium · product sense and metrics

Approach

  1. Decompose the metric into the rates that drive it, and say which one you would check first.
  2. Name one primary metric, then the guardrail that stops it being gamed.
  3. Fix the population and the time window before naming any metric.

Follow-up

  • Which segment would you cut first, and what would that rule out?
  • What would you do if the primary metric and the guardrail moved in opposite directions?

How do you prioritize tasks when working on multiple projects?

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. Name one primary metric, then the guardrail that stops it being gamed.
  3. State what result would change your recommendation, so the answer is falsifiable.

Follow-up

  • What would you do if the primary metric and the guardrail moved in opposite directions?
  • Which segment would you cut first, and what would that rule out?

Walk us through your thought process for a recent data-driven decision you made.

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. Fix the population and the time window before naming any metric.
  3. Name one primary metric, then the guardrail that stops it being gamed.

Follow-up

  • What would you do if the primary metric and the guardrail moved in opposite directions?
  • Which segment would you cut first, and what would that rule out?

Present a solution for reducing operational costs through data analysis.

Medium · product sense and metrics

Approach

  1. Fix the population and the time window before naming any metric.
  2. Restate the decision this analysis has to support, and who acts on the answer.
  3. Decompose the metric into the rates that drive it, and say which one you would check first.

Follow-up

  • How would you detect that the metric is being gamed rather than genuinely improving?
  • Which segment would you cut first, and what would that rule out?

How would you design an experiment to test the effectiveness of a new trading strategy?

Medium · a/b testing and experimentation

Approach

  1. State the primary metric and the minimum effect worth shipping, then size the test.
  2. Decide the analysis before seeing data, including how long it runs and when you look.
  3. Say whether units interfere with each other, and switch design if they do.

Follow-up

  • What would you do if you could not randomise at all?
  • What would you conclude if the result is positive but the test is underpowered?

Can you discuss a project where you applied data science techniques to solve a business problem?

Medium

Approach

  1. Work from the decision backwards to the evidence you would need.
  2. State your assumptions explicitly before working the problem.
  3. Clarify what is being asked and what a complete answer would contain.

Follow-up

  • How would you know your answer was wrong?
  • What assumption would you test first?

Cut variance on a safety-stock test with CUPED and strata

Medium · cuped · stratification · variance reduction · ratio metrics

You are testing a new safety-stock formula on 300 SKU-location cells inside one region, randomised 150/150. The outcome is eight-week unit fill rate per cell from fct_order_line; you also have 26 weeks of pre-period fill rate per cell, and each cell carries abc_class and xyz_class in dim_sku. The cell-level correlation between pre-period and post-period fill rate is 0.7. Show the CUPED adjustment, state exactly what it does to the standard error, and say which cells it will fail on and why.

Approach

  1. Define the adjusted outcome: Y* = Y - theta * (X - Xbar), where X is the pre-period cell fill rate and theta = Cov(Y, X) / Var(X). Because randomisation makes X independent of assignment, the treatment effect estimate is unbiased for any theta; theta only controls how much variance is removed.
  2. Quantify the win rather than asserting it: Var(Y*) = Var(Y) * (1 - rho^2) = 0.51 * Var(Y), so the standard error falls by a factor of sqrt(0.51) = 0.71, the MDE falls 29%, and the same precision would otherwise have needed 51% of the cells.
  3. Estimate theta pooled across both arms on the observed data. Fitting it per arm re-introduces a treatment-dependent term into the adjustment; the O(1/n) bias from estimating theta at all is negligible at 300 cells but should be named rather than ignored.
  4. Stratify the randomisation itself on abc_class by xyz_class and fit with stratum fixed effects. Strata remove between-class variance that a single pre-period covariate does not, and XYZ class is precisely the axis along which demand variability, and therefore fill-rate variance, differs.
  5. Name where it fails. Fill rate is a ratio whose denominator is random and small for C and Z cells, so the pre-period value is a noisy estimate of the cell's true rate, rho collapses and the adjustment buys little; a cell with zero pre-period demand has no covariate at all. Handle the ratio by adjusting numerator and denominator and applying the delta method for the variance, never by averaging cell-level ratios.

Worked solution (30 min)

  1. Build a cell-level table: 26-week pre-period fill rate X, 8-week post-period fill rate Y, arm, abc_class, xyz_class, and pre-period ordered_qty as a weight.
  2. Regress Y on X pooled across arms to obtain theta, then compute Y* = Y - theta * (X - Xbar).
  3. Estimate the effect by regressing Y* on treatment with abc by xyz stratum fixed effects and heteroskedasticity-robust standard errors.
  4. Compare the adjusted and unadjusted standard errors; the ratio should sit near sqrt(1 - 0.49) = 0.71.
  5. Split by xyz_class and report rho within each; expect a materially lower correlation and a much smaller reduction on Z cells.

Expected result: theta = Cov(Y, X) / Var(X). At rho = 0.7 the adjusted variance is 51% of the unadjusted, the standard error falls 29%, and the MDE falls by the same 29%. Unbiasedness does not depend on theta being right; only the size of the reduction does. The adjustment buys almost nothing on low-volume C and Z cells whose pre-period rate is itself noisy.

Verify it yourself

  • An A/A replay on the pre-period must give a CUPED effect estimate centred on zero; if it does not, the covariate is contaminated by post-assignment data.
  • The empirical ratio Var(Y*) / Var(Y) should land near 1 - rho^2, which is 0.51 here.
  • The adjusted and unadjusted point estimates should agree within roughly one unadjusted standard error; a larger move means theta is absorbing a real imbalance rather than noise, and the randomisation deserves a second look.

Follow-up

  • The policy change alters ordered_qty through substitution behaviour. What does a treatment-affected denominator do to a ratio metric, and does CUPED still help?
  • Three cells carry 40% of regional volume. What does that do to your variance, and which estimand should you actually report?

Plant schedule instability generated two echelons downstream

Hard · bullwhip · echelon attribution · variance

A plant reports that the replenishment orders it receives swing far more than end-customer demand, and asks for a larger finished-goods buffer. You have fct_order_line for customer demand at store and forward-stock nodes, fct_inventory_daily (on_order_qty, demand_qty per sku-location-date), dim_location (echelon, parent_location_id) and dim_sku (units_per_case, cases_per_pallet). Measure amplification at each echelon, identify the node whose ordering rule generates it, and price the buffer request against fixing that rule. Deliverable: a per-echelon amplification table and a recommendation.

Approach

  1. Build two series per node at a fixed weekly bucket per SKU: the quantity the node ordered from its parent_location_id, and the demand it received from its children or from customers. Both series must cover the same SKU, the same weeks and the same node set, or the ratio between them means nothing.
  2. Compute amplification per node as Var(orders placed) / Var(demand received), and report the squared coefficient-of-variation form alongside it. Mean volumes differ by an order of magnitude between echelons, so a raw variance ratio is not comparable across nodes of different size while the CV-squared ratio is scale-free.
  3. Read the table echelon by echelon and find where the ratio steps up. The generating node is where it first exceeds one by a wide margin, not the node that feels the pain: amplification observed at the plant is the product of every ratio below it along that chain.
  4. Name the mechanism at that node rather than asserting bullwhip generically. Minimum order quantity and lot-size multiple, the review period, batching up to a full truckload, and forecast-driven ordering that reacts to its own safety stock recalculation each leave a distinct signature in the order-size histogram.
  5. Price both options rather than choosing one. The buffer request converts to units, then to cost at standard_cost_cents and to carrying cost at the applicable cost of capital. The rule change converts to more frequent, smaller replenishment and therefore more freight per unit. Present the trade with both numbers attached.

Follow-up

  • Orders cluster on exact truckload multiples. Would you break the batching rule, and what does that cost in freight per unit?
  • How would you test an ordering-rule change when there are twelve nodes, they draw on the same stock and the same outbound loads, and one replenishment cycle is three weeks?
  • Part of the plant's variance is its own production batching. How do you separate inbound amplification from what the plant creates for itself?

Suggested practice checklist

Instead of guessing where the week should go, day one measures it under a fixed rubric and allocates the remaining hours in proportion to the gaps. The method is deliberately rigid: the allocation is written down before any studying starts and is not renegotiated when a topic turns out to be unpleasant.

Day 1 — Diagnostic, scored before you study anything

  • Sit a 100-minute timed diagnostic in four blocks: 30 minutes of SQL across three prompts, 25 minutes of short-answer statistics, 25 minutes on one modelling or case prompt, and 20 minutes delivering one behavioural story aloud.
  • Score each block from 0 to 3 on a fixed rubric where 3 is correct and fluent, 2 is correct but slow or prompted, 1 is partially correct, and 0 is stuck, grading the output rather than how the attempt felt.
  • Allocate the hours for days two to five roughly in proportion to 3 minus the score in each block, write the allocation down, and commit to not revising it midweek.

Deliverable: A scored rubric and a fixed hour allocation for the rest of the week.

Day 2 — Largest gap: find the boundary rather than the subject

  • Break the weakest area into five named sub-skills (for query work: grain control, window frames, date arithmetic, set logic with NULLs, and reading a query plan) and rate each one, so the rest of the week targets a sub-skill instead of a subject.
  • Solve three problems chosen to sit just above where the rating drops off, and for each write the first move you failed to make.
  • Re-solve one of them from memory four hours later, on paper, with nothing open.

Deliverable: A five-item sub-skill map with the two blocking sub-skills circled.

Day 3 — Largest gap: drill the blocking sub-skill

  • Do eight short repetitions of the same shape rather than eight different problems, so what you practise is the pattern and not the puzzle.
  • Write the rule you now hold in one sentence, then test it against a case built to break it: a ranking function over a column with ties, or a two-sample test on observations that are obviously dependent.
  • Have someone else read your one-sentence rule and find the precondition you left out.

Deliverable: One rule statement with its preconditions attached and one counterexample that would have caught the incomplete version.

Day 4 — Second gap, plus maintenance on your strongest area

  • Run the same sub-skill map and boundary protocol on the second-largest gap, compressed into half the day.
  • Spend 25 timed minutes on your strongest area to stop it decaying, choosing the hardest problem you can still finish rather than an easy warm-up.
  • Compare how the two areas fail: whether you lose time on recall, on setup, or on arithmetic, because the fix differs for each.

Deliverable: A second sub-skill map plus a one-line diagnosis of how each area fails you.

Day 5 — The gap that is not a skill

  • Record yourself answering one technical and one behavioural prompt, then count two things in the playback: how many seconds before your first clarifying question, and how many sentences you started without knowing where they ended.
  • Rewrite your three most-used stock phrases into shorter versions, and practise saying "I do not know, here is how I would find out" without softening it into a guess.
  • Deliver one answer again with a hard 90-second limit to force structure before detail.

Deliverable: Two recordings with a counted improvement in time-to-first-question.

Day 6 — Retest under day-one conditions

  • Sit the same 100-minute diagnostic structure with new prompts of comparable difficulty and score it on the identical rubric.
  • Compare block by block, and for any block that did not move, change the method rather than adding hours: a block stuck at 1 usually means the practice was too varied, not too short.
  • Write which single block you would still lose the offer on.

Deliverable: A second scored rubric placed next to the first, with one named remaining risk.

Day 7 — Full loop under interview conditions

  • Run a 60-minute mock covering the two blocks that moved least, with an interviewer instructed to interrupt and change direction.
  • Write your recovery script for the moment you go blank: restate the question, state your assumption, name the first thing you would check.
  • Reduce the week to the rule statements you wrote, each with its preconditions attached, then say every one of them out loud without reading it and cut any you cannot state in a single sentence, since a rule you have to reconstruct mid-answer will not survive being interrupted.

Deliverable: A one-page card holding the recovery script and only the rules you could state from memory.

Bring numbers, including the ones you are unsure of

An answer without a quantity is hard to interrogate, so interviewers keep probing until they find one. Come with the baseline, the change, the window it was measured over, and how confident you were. If the effect never got measured, say so and say what you would have measured. Fabricated precision is worse than an honest gap.

What values do you believe are essential for a successful team dynamic?

Medium · behavioural and stakeholder questions

Approach

  1. Name the disagreement or constraint, and how you resolved it with evidence.
  2. Close with what you would do differently, concretely.
  3. Quantify the outcome, including what you would not claim credit for.

Follow-up

  • What would you do differently if you ran that project again?
  • How did you know the outcome was caused by your change?

Disagree with a planning manager about a safety stock cut

Medium · disagreeing with data · censoring · forecast evaluation

A planning product manager proposes cutting safety stock 30 percent on every C and Z class sku-location cell, citing a MAPE improvement from 41 to 28 percent over two quarters. Checking the query, you find MAPE is computed over fct_inventory_daily rows where the actual is greater than zero, and the actual used is shipped_qty rather than demand_qty; stockout_flag is true on 14 percent of the rows that were kept. You have fifteen minutes in his planning review. Make the disagreement, and propose what you would do instead of the flat cut.

Approach

  1. Lead with the decision at risk, not the metric error: a 30 percent cut on intermittent items is the cheapest way to convert a measurement artefact into stockouts eight weeks later, by which time nobody will connect the two.
  2. Name the two defects precisely. Dropping zero-actual rows is not a rounding choice, it removes most of the history for a C-class item at a forward-stocking location and it removes the rows where over-forecasting is penalised, so the surviving MAPE is biased toward whichever series stocked out. Using shipped_qty as the actual scores the forecast against a supply ceiling, so a series looks more accurate the more often it ran out.
  3. Offer the replacement metric in the same breath: WMAPE, sum of absolute errors over sum of actuals against demand_qty, computed at the sku-location-week grain the ordering decision uses and at the lag it uses, reported next to signed bias so a persistently short series cannot hide inside an accuracy number.
  4. Propose the smaller action that is defensible now: recompute on the corrected basis, rank cells by bias rather than accuracy, and cut cover only where the corrected series is unbiased or over-forecasting, in a staged rollout with a service guardrail.
  5. Give him the win he actually wants: if the corrected numbers still support cuts on a subset, say so in advance, so the disagreement is about evidence rather than about territory.

Follow-up

  • He says demand_qty is itself incomplete because customers stop ordering what shows out of stock. Is he right, and what do you do about it?
  • Which items would you leave alone regardless of what the corrected metric says?

Quantify your own impact on a safety stock change honestly

Hard · impact measurement · confounding · difference in differences

In March you re-sized safety stock at twelve regional DCs using the variable lead time formula. Unit fill rate at those nodes rose from 94.1 to 96.5 percent by June. In the same window a supplier that had been running 71 percent inbound on-time recovered to 93 percent, and Q2 volume is seasonally about 8 percent below Q1. Your manager asks for one sentence on impact for a performance review. Write the claim you are willing to defend under challenge, and explain how you bounded the portion attributable to your change.

Approach

  1. Refuse the naive claim first: the 2.4 point gross movement contains at least three generating processes, and attributing all of it is the sort of claim that collapses the moment someone plots the supplier's on-time series next to it.
  2. Build a comparison group from nodes that did not get the change, check that their pre-period fill rate moved in parallel with the treated nodes for at least two quarters before March, and estimate the difference in differences with variance clustered at the node, since twelve treated clusters is the effective sample size regardless of how many node-weeks there are.
  3. Strip the confounders you can measure directly rather than trusting the design alone: restrict to sku-location cells sourced from other suppliers to remove the recovery, and hold the sku mix fixed across periods so the seasonal volume drop does not enter through mix.
  4. Sanity-check the mechanism, not just the coefficient: if your change worked, the improvement should concentrate in cells whose reorder point rose and in short_reason_code = 'no_stock' lines, and should be absent where the policy did not move. If the gain is spread evenly, something else caused it.
  5. State the result as an interval with the confounders named, and state the cost side too: extra units held at the applicable cost of capital, so the claim is a net one rather than a service headline.
  6. Write the sentence so that it survives someone else re-running it, which usually means a smaller number than the gross movement and a named method.

Follow-up

  • The comparison nodes are not parallel in the pre-period. What do you do next?
  • Your bounded estimate is roughly half the gross movement. How do you present that to a manager who already told his boss the larger number?