cswork / libraryOpen practice workspace

Interview guides · Axle Energy

Axle Energy Data Scientist Interview Questions & Guide 2026

Axle Energy data scientist prep on data pitfalls: selection bias, target leakage, and checking an outlier's provenance before you drop it.

The 60-second brief

As a Data Scientist at Axle Energy, you are at the intersection of energy transition and advanced data modeling. The company operates in a high-stakes, rapidly evolving environment, building the software layer that connects distributed energy resources—like electric vehicles and home batteries—to the power grid. Your work directly influences how the company optimizes energy consumption, stabilizes the grid, and drives sustainable value for both users and the business.

SQL is seldom the hardest round and is often the one that eliminates people. The working bar is usually window functions, correct deduplication, and joins that do not silently fan out rows, rather than obscure syntax.

Focus areas

  • Join daily snapshots to shipment events safely
  • Evaluate forecasts at the lag ordering actually uses
  • Size safety stock under variable lead times

Overview

This role is highly product-focused and load-bearing. You will not just be running models; you will be designing the metrics that define success for new energy products and diagnosing complex behavioral patterns in consumer energy usage. Because Axle Energy operates as a fast-paced startup, you will have significant autonomy to shape the data strategy, from conducting rigorous A/B tests to building robust simulators that predict how users interact with energy-smart technology.

You will work closely with engineering, product, and operations teams to bridge the gap between raw data and actionable business strategy. Success in this role requires a blend of technical precision—specifically in statistical modeling and SQL—and a strong product-sense to ensure your analytical outputs drive real-world impact.

The Axle Energy interview process

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

Initial Screening

Data Scientist covers at least four different jobs: experimentation, product analytics, causal work on observational data, and applied modelling that ships into a system. A screening call is the cheapest place to find out which of them is being hired for, and doing that diagnosis openly reads as senior rather than fussy. Ask what the last few pieces of work on the team actually were, and roughly how a week splits between querying, modelling and stakeholder time. Then say which parts of that you have done and which you have not. Claiming the whole range is the fastest way to be caught one round later.

What to demonstrate

  • Whether you can distinguish the flavours of the role and locate your own experience inside one of them honestly
  • Whether you name what you have not done instead of stretching to cover every line of the posting
  • Whether your hard constraints (notice period, location, work authorisation, level) surface now rather than at offer stage

How to prepare

  • Map the last two years of your time into rough percentages across query writing, experiment design, modelling and stakeholder work, so a question about scope has a real answer
  • Mark every responsibility in the posting as done, adjacent or new, and prepare one sentence for each adjacent item naming the closest thing you have actually built
  • Decide which logistics are non-negotiable before the call so you can state them in one sentence rather than negotiating live

Technical Assessment

Much of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.

What to demonstrate

  • Whether the query you write matches the plan you just described
  • What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
  • Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly

How to prepare

  • Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
  • Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
  • Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock

Technical Review

Before anything else, this round is a reading test. You are given a small schema and a question phrased in business language, and most of the difficulty sits in the gap between them. Who counts as an active user, does a refunded order still count as an order, is that date column an event time or a load time. Weak answers start typing immediately and compute something precise about the wrong population. Strong ones pin the definition in one sentence, name the column that encodes it, then write the query. On a timed assessment with nobody to tell, write the definition in a comment anyway.

What to demonstrate

  • Whether an ambiguous term becomes a specific column and filter before any computation happens
  • Whether you read the schema for keys and cardinality rather than only for column names
  • Whether the result answers the question at the grain it was asked at, per user or per session or per day

How to prepare

  • Take three metrics you already use and write down the exact filter and exact grain behind each, then practise stating one of them in a single sentence out loud
  • On a schema you have never seen, spend the first minute writing what one row of each table means and which key it is unique on, then predict which joins can duplicate rows
  • Rehearse a version where the definition changes halfway through, and edit the query you have instead of starting over

Meet the Team

Rounds outside the standard loop often open with something deliberately under-specified: a loose business problem, an open question about a product area, a dataset described in one sentence. The common failure is surveying, listing six plausible approaches and committing to none of them. The thing that separates a strong answer is scoping out loud. State what you are treating as the goal, name the metric you would move, say what you are choosing not to do and why, then take one path through to an actual answer. An interviewer can follow you down a narrow path. Nobody can grade a menu.

What to demonstrate

  • Whether you turn an ambiguous prompt into a stated question with a measurable outcome before doing any work
  • The judgement visible in what you cut, and whether you say why you cut it rather than silently dropping it
  • Whether you land on a concrete recommendation with its caveat attached, rather than an unranked set of options

How to prepare

  • Take three vague prompts, such as 'is this feature working', 'why did retention drop', and 'should we expand into a new segment'. For each, write one sentence of goal, one primary metric with its window, and two things you are explicitly not doing.
  • Practise giving the recommendation first and the reasoning second, in five minutes. Loosely defined rounds are usually time-boxed, and an answer that arrives last often does not arrive.
  • Keep a running assumption list as you talk, on paper or in the shared doc, so the interviewer can challenge one assumption instead of your whole answer.

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.

Sizing safety stock as z times sigma_D times the square root of lead time

That form assumes lead time is deterministic. When lead time itself varies, the standard deviation of demand over lead time is sqrt(L_bar * sigma_D^2 + D_bar^2 * sigma_L^2), and the second term dominates whenever supply is unreliable, so the familiar formula can understate the requirement severalfold for a long, variable inbound lane. Two further preconditions are routinely forgotten: demand is assumed independent across periods, which promotions and order batching break, and z maps to cycle service level (the probability of no stockout in a replenishment cycle), not to fill rate, which additionally depends on order quantity through the unit normal loss function. Quoting a z-derived number as a fill rate overstates achieved service, and the gap widens as order quantity shrinks.

Over-explaining the method and under-explaining the implication

Lead with the answer and what you would do about it, then give the approach when asked. Roughly one sentence of method per three of implication is the right ratio for a stakeholder-facing answer; the interviewer already knows what a regression is.

Answering a product-sense question with a list of features

Answer with a decision and the measurement that would settle it: the hypothesis, the primary metric, the guardrails, and the result that would make you not ship. A feature brainstorm cannot be wrong, which is exactly why it earns no points.

Questions & practice

Explain the difference between correlation and causation in the context of energy usage patterns.

Medium · statistics and probability

Approach

  1. Say what the estimate is of, and over what population it generalises.
  2. Sanity-check the answer against a simple bound or a simulated case.
  3. Quantify uncertainty explicitly rather than reporting a point estimate alone.

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?

Reconstruct replenishment cycles from a daily inventory series

Medium · event sessionisation · state reconstruction · lead time

For one sku-location you have a daily series: inventory_date, on_hand_qty, in_transit_qty, on_order_qty, allocated_qty, shipped_qty, demand_qty, reorder_point_qty, stockout_flag. There is no purchase-order table. Infer the replenishment cycles: a cycle opens on the first day inventory position falls to or below reorder_point_qty, and closes on the first subsequent receipt. Receipts must be inferred from the series itself. Return one row per cycle with trigger date, receipt date, inferred lead time in days, demand during the cycle and stockout days, then report mean and standard deviation of the inferred lead time.

Approach

  1. Derive the receipt signal from the stock balance rather than looking for a column that does not exist: on_hand today equals on_hand yesterday plus receipts minus units shipped, so implied_receipt = on_hand_qty.diff() + shipped_qty, and a positive value means goods arrived.
  2. State what else can make that quantity positive: a cycle-count adjustment, a customer return, or a scrap reversal. Corroborate each candidate receipt with a matching fall in in_transit_qty on the same or adjacent day, and discard the ones with no corroboration.
  3. Debounce arrivals. A load split across two dock shifts produces positive implied receipts on consecutive days; collapse runs of receipt days separated by less than a chosen gap into a single arrival and make the gap an explicit parameter.
  4. Compute inventory position as on_hand + in_transit + on_order - allocated, not on hand alone, or every day after a trigger looks like another trigger and the cycle count explodes.
  5. Walk the series once with an explicit state variable (awaiting-trigger, awaiting-receipt) rather than trying to vectorise the pairing. The state machine is what makes cycles non-overlapping, and it is what a reviewer can check line by line. Be clear that cycles defined this way do not tile the calendar: the stretch from a receipt until the position next falls to the reorder point sits inside no cycle.

Follow-up

  • Two orders are open at once because the trigger fired again before the first arrived. How does your state machine change?
  • The policy quotes lead time in working days. What do you need from dim_location to convert, and where does the timezone matter?
  • You now have mean and standard deviation of lead time. Write the safety stock this implies and say which assumption you are least comfortable with.

Audit a daily inventory snapshot for silent corruption

Easy · data quality · invariants · completeness

You receive fct_inventory_daily with inventory_date, sku_id, location_id, on_hand_qty, allocated_qty, blocked_qty, available_qty, in_transit_qty, demand_qty, shipped_qty, stockout_flag and standard_cost_cents. The table is supposed to carry one row per active sku-location per date, including days with no movement. Write a check suite that returns one row per named check with the number of sku-location-days affected, the share of the scope, and the on-hand value at standard cost sitting behind the failures. Do not repair anything; the deliverable is the evidence.

Approach

  1. Start with the arithmetic identity the table declares: available_qty must equal on_hand_qty minus allocated_qty minus blocked_qty. Report exact row counts rather than a boolean, because a handful of violations is a feed bug and a uniform offset is a definition change upstream.
  2. Check sign constraints separately from the identity. Negative on_hand_qty usually means receipts posted out of order, while negative available_qty is legitimate at some sites when allocation is allowed to over-commit, so flag it and ask rather than assuming corruption.
  3. Check calendar completeness per sku-location by comparing the observed row count against the number of dates between that pair's first and last appearance. Count the missing dates without reindexing the frame, because filling them with zeros converts a feed gap into a plausible run of zero-demand days.
  4. Check stockout_flag in one direction only: available_qty of 0 at the cut-off with stockout_flag false is a contradiction, while flag true with positive available_qty is not, since the flag records an intraday touch of zero that a late receipt can recover.
  5. Weight every failure by on_hand_qty times standard_cost_cents so the summary orders checks by money at risk rather than by row count, and state the scope denominator on each row.

Worked solution (20 min)

  1. Define the scope explicitly as the distinct sku-location pairs and the date range under audit, and store the scope row count for use as every check's denominator.
  2. Evaluate the identity, sign and stockout-flag checks as boolean masks over the frame and record the count and affected value for each.
  3. For completeness, group by sku_id and location_id, take min and max inventory_date and the row count, and compare the count to the number of calendar days spanned.
  4. Assemble one output row per check with check_name, failing_rows, share_of_scope and failing_on_hand_value_cents, sorted by value descending.
  5. Spot-print five failing rows per check so the output is actionable rather than a set of counts.

Expected result: A small DataFrame with one row per check. Shares are between 0 and 1 against a stated scope denominator, and the value column is computed as on_hand_qty times standard_cost_cents on failing rows only.

Verify it yourself

  • Inject a known defect into a copy (flip one available_qty by +1) and confirm the identity check count rises by exactly one.
  • Confirm the completeness check reports zero missing dates for a sku-location pair you verify by hand against a printed date list.
  • Confirm the sum of on-hand value over all rows exceeds the value reported on any single check, and that no check's share exceeds 1.0.
  • Confirm no check silently drops nulls: count nulls per column first, since a comparison against null returns false and hides the row.

Follow-up

  • Someone proposes asserting shipped_qty is at most demand_qty on the same row. Why does that fire on thousands of healthy rows?
  • Half the missing dates fall on Sundays at one set of nodes. What is the most likely explanation and does it change the severity?
  • Which of these checks would you run as a blocking gate before a nightly planning job, and which as a monitored report?

Given a table of user interactions, how would you join and aggregate data to find the average time between two specific events?

Medium · sql and data manipulation

Approach

  1. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
  2. Say which table is the grain you start from, and join outward from it.
  3. Compute rates by summing numerator and denominator separately, never by averaging rates.

Follow-up

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

Write a query using SQL window functions to calculate the running total of energy consumption per user over a 30-day period.

Medium · sql and data manipulation

Approach

  1. Say which table is the grain you start from, and join outward from it.
  2. Check whether any join is one-to-many before aggregating, or the sums inflate.
  3. State the window function and its partition and ordering out loud before writing it.

Follow-up

  • How would you verify this result without re-running the same query?
  • How does the query change if the join becomes one-to-many?

How would you identify the top 5% of energy-consuming devices in our database using a subquery or CTE?

Medium · sql and data manipulation

Approach

  1. Compute rates by summing numerator and denominator separately, never by averaging rates.
  2. Say which table is the grain you start from, and join outward from it.
  3. State the window function and its partition and ordering out loud before writing it.

Follow-up

  • How does the query change if the join becomes one-to-many?
  • How would you verify this result without re-running the same query?

As-of inventory position behind each short-shipped line

Medium · as-of join · window functions · lateral join

For every fct_order_line with line_status in ('shipped_short','backordered','cancelled_no_supply') and requested_ship_date in the last quarter, attach the inventory state that governed it: the fct_inventory_daily row for the same sku_id and ship_from_location_id with the greatest inventory_date strictly before requested_ship_date. Snapshots are taken at the location-local end of day. Return the line, ordered_qty, shipped_qty, and that snapshot's available_qty, blocked_qty, on_order_qty and in_transit_qty, plus the snapshot's age in days. Lines with no prior snapshot must appear with NULLs rather than disappearing from the result.

Approach

  1. Recognise the join is an inequality, not an equality. The snapshot is an end-of-day state, so the position that governed allocation is the last close strictly before the requested ship date, and the same-date row reflects the outcome rather than the cause.
  2. Implement it with LEFT JOIN LATERAL (SELECT ... WHERE sku_id and location_id match AND inventory_date < requested_ship_date ORDER BY inventory_date DESC LIMIT 1) ON TRUE, or equivalently ROW_NUMBER() OVER (PARTITION BY order_line_id ORDER BY inventory_date DESC) = 1 over a bounded candidate set.
  3. Bound the lateral with a floor such as inventory_date >= requested_ship_date - 14 so the scan does not walk the whole history for each line, and let that floor produce NULLs rather than silently dropping the line.
  4. Keep the join LEFT. Lines at a node with no prior snapshot are a data-quality finding worth counting, and an INNER join converts them into an invisible bias toward nodes with clean snapshot coverage.
  5. Check the row count before and after the join: the output must have exactly one row per order_line_id, and any excess means the as-of match is returning more than one candidate.

Worked solution (30 min)

  1. Filter fct_order_line to the three statuses and the quarter, and record the row count as the target.
  2. Attach LEFT JOIN LATERAL over fct_inventory_daily with the strict inequality, the fourteen-day floor, ORDER BY inventory_date DESC and LIMIT 1.
  3. Project the four quantity columns plus snapshot_age_days = requested_ship_date - inventory_date.
  4. Compare the result row count with the target; investigate any difference before aggregating anything.
  5. Count and group the NULL-snapshot rows by ship_from_location_id to see whether the gap is a node or a SKU launch artefact.

Expected result: Exactly one row per qualifying order_line_id, with snapshot columns drawn from the greatest inventory_date strictly less than requested_ship_date, snapshot_age_days at least 1, and NULL snapshot columns where no prior row exists inside the floor.

Verify it yourself

  • COUNT() of the result equals COUNT() of the filtered order-line set. Any excess is fan-out from a non-unique as-of match.
  • MAX(inventory_date) per line is strictly less than that line's requested_ship_date, with no equality cases.
  • The count of NULL-snapshot rows is small and attributable to specific nodes or newly launched SKUs rather than spread evenly.

Follow-up

  • Split the output by short_reason_code. Which codes should show available_qty at or near zero, and what does it mean when 'no_stock' lines show healthy availability?
  • blocked_qty is large on many of these lines. Is that a planning problem, and who owns it?
  • How would you extend this to the position at the moment of allocation rather than the previous close, and what would you need that the daily snapshot does not give you?

How do you balance the trade-off between user convenience and energy efficiency in our product design?

Medium · product sense and metrics

Approach

  1. State what result would change your recommendation, so the answer is falsifiable.
  2. Decompose the metric into the rates that drive it, and say which one you would check first.
  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?

If the primary metric for our energy-saving app drops by 10% overnight, how would you go about diagnosing the root cause?

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. State what result would change your recommendation, so the answer is falsifiable.
  3. Restate the decision this analysis has to support, and who acts on the answer.

Follow-up

  • How would you detect that the metric is being gamed rather than genuinely improving?
  • What would you do if the primary metric and the guardrail moved in opposite directions?

How would you design a metric to measure the "success" of a new smart-charging feature for EV drivers?

Medium · product sense and metrics

Approach

  1. Name one primary metric, then the guardrail that stops it being gamed.
  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

  • 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?

If we launch a new feature to only 5% of our users, how do you ensure the sample is representative to avoid bias?

Medium · a/b testing and experimentation

Approach

  1. Say whether units interfere with each other, and switch design if they do.
  2. State the primary metric and the minimum effect worth shipping, then size the test.
  3. Name the guardrails that would stop a launch even on a positive primary result.

Follow-up

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

How do you determine if the results of an A/B test have reached statistical significance?

Medium · a/b testing and experimentation

Approach

  1. Name the guardrails that would stop a launch even on a positive primary result.
  2. State the primary metric and the minimum effect worth shipping, then size the test.
  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?

A planner scorecard that aggregation cannot flatter

Hard · wmape · gameable metrics · forecast bias

Demand planners will be scored on forecast accuracy. fct_inventory_daily carries demand_qty, forecast_qty_lag7, forecast_qty_lag28 and stockout_flag at sku by location by date, with NULL forecasts before a series existed. Specify the scorecard: error metric, grain, lag, exclusion policy and guardrail. Then show the three ways a planner raises the headline without forecasting better, and state which single number you would prefer to accuracy if you could publish only one.

Approach

  1. Fix the grain and lag to the decision. The ordering policy consumes a forecast at one horizon for one sku-location-week cell, so the score is computed there; a number quoted at any other grain is not the number the policy used and cannot be compared to it.
  2. Choose WMAPE, sum of absolute errors over sum of actuals, or a pinball loss at the service quantile the policy targets. Rule out MAPE explicitly: it is undefined at zero actuals, which is most days for a C item at a forward-stocking location, and it is asymmetric where it is defined, so optimising it drives systematic under-forecasting.
  3. Show why aggregation flatters, and show it as arithmetic rather than opinion. The absolute value of a sum is at most the sum of absolute values, so errors cancelling across SKUs, locations or weeks make aggregated WMAPE weakly lower than the disaggregated figure on the same denominator, with no forecasting improvement involved.
  4. Name the other two routes: scoring at a shorter lag than ordering actually uses, and exclusion drift, where NULL-forecast rows, zero-demand cells or stockout days are dropped without publishing the excluded count, quietly removing the hardest cells from the sample.
  5. Set the guardrail on signed bias, weighted mean percentage error over the same window and cells, reported per ABC/XYZ cell. A series can be inaccurate but unbiased, or accurate on average and persistently short, and only the second wrecks inventory in one direction.
  6. Answer the last question directly: prefer the outcome that accuracy is a means to, achieved fill rate at a given inventory at cost per cell, because that is what the business buys, and accuracy that does not move it is not worth paying for.

Worked solution (40 min)

  1. Build the scored panel at sku by location by week, summing demand_qty and taking the forecast at the lag the ordering policy uses, excluding NULL-forecast cells and counting every exclusion.
  2. Compute WMAPE and signed WMPE per planner per ABC/XYZ cell by re-summing numerator and denominator, never by averaging cell ratios.
  3. Recompute the same WMAPE at region and at month to demonstrate the mechanical improvement, and record the difference as the aggregation premium.
  4. Recompute with and without stockout days and with and without zero-demand cells, recording each shift as the exclusion premium.
  5. Publish WMAPE, WMPE, the excluded-row count and the paired inventory-and-service outcome, with grain and lag printed on the page rather than held in a footnote.

Expected result: A scorecard pinned to sku by location by week at the ordering lag, using WMAPE with signed bias beside it and per-ABC/XYZ reporting so the tail cannot be abandoned; three gaming routes each sized on the real data as an aggregation premium, a lag premium and an exclusion premium; and a stated preference for achieved fill rate at a given inventory at cost as the single number, with forecast accuracy kept as a diagnostic rather than as the target.

Verify it yourself

  • Aggregated WMAPE is less than or equal to disaggregated WMAPE on the same rows in every roll-up tested; a case where it is higher means the two were computed over different denominators.
  • On one panel, the absolute value of WMPE is at most WMAPE; a violation means the two used different exclusions.
  • Excluded rows plus scored rows equal the full panel; if they do not, rows are being dropped somewhere other than the stated policy.

Follow-up

  • Two planners have identical WMAPE and opposite bias. Which one is doing more damage, and to what?
  • The scorecard is per planner but forecasts are hierarchical and reconciled. Whose number is the reconciled one, and who gets charged for the reconciliation loss?

Unit fill rate fell four points in one region

Easy · fill rate · segment cuts · mix shift

Weekly unit fill rate for one region fell from 96.1 percent to 92.0 percent over four weeks and has not recovered. Network fill rate is flat. You have fct_order_line (ordered_qty, shipped_qty, requested_ship_date, ship_from_location_id, sku_id, line_status, short_reason_code), dim_location (location_type, region_code, echelon) and dim_sku (abc_class, xyz_class, lifecycle_status). Produce the first four query cuts, say what each one rules in or out, and name the single most likely cause together with the evidence that would confirm it. Thirty minutes, SQL plus a short written argument.

Approach

  1. Rebuild the metric by summing shipped_qty and ordered_qty to region level and dividing once, rather than averaging per-SKU-location rates. An unweighted mean of cell rates moves with portfolio mix on its own, so if the drop does not survive re-summing there is nothing physical to diagnose.
  2. Cut by ship_from_location_id first. If one node carries the whole drop the mix of demand across nodes is not the story and the problem is local; if every node fell a little, the cause sits upstream in supply or forecast rather than in any warehouse.
  3. Decompose the region change over abc_class by xyz_class cells into within-cell, mix and interaction terms: delta R = SUM(w0 * (r1 - r0)) + SUM(r0 * (w1 - w0)) + SUM((w1 - w0) * (r1 - r0)), where w is a cell's share of the denominator and r is its rate. A dominant mix term means demand moved toward hard-to-serve intermittent items and no cell actually got worse.
  4. Group the lost units (ordered_qty minus shipped_qty) by short_reason_code. 'no_stock' points at planning, 'pick_shortage' and 'damage_on_pick' mean the stock was physically present and execution lost it, 'allocation_rule' means the units existed and were promised to someone else, and 'credit_hold' is not a supply chain failure at all.
  5. Only then cross the weekly series against the promotion calendar, against SKUs with lifecycle_status = 'pre_launch' cutting in, and against accounts placing their first order in the window. A step change starting in the same week as a promotion or a new-item onboarding is a demand-side event, not a degradation.

Follow-up

  • Fill rate is flat nationally but down in this region. What does that tell you about where the stock went, and how would you test it?
  • Most of the failed units carry short_reason_code = 'no_stock', yet on_hand_qty at the node stayed above reorder_point_qty all month. How is that possible?
  • Would you publish this rate weighted by units or by revenue, and which team gets a different answer from each?

Suggested practice checklist

Four days spend equal time on query work, statistics, modelling and product judgement at deliberately shallow depth, which produces a scored map of where you actually stand. The last three days spend everything on the two areas the role weights most, and close by re-running day one to measure movement.

Day 1 — Breadth pass: query fluency

  • Solve six prompts spanning aggregation, joins, window functions and date arithmetic in 60 minutes total, stopping at 10 minutes each whether or not it works, and mark every prompt as solved, solved slowly, or stuck.
  • For each unsolved prompt write the single blocking sentence (I lost the grain, I did not know the frame clause, I could not express the date boundary) instead of reading the solution.
  • Translate one pandas transformation you know well into SQL and one SQL query into pandas, checking that both return the same row count and the same totals.

Deliverable: A scored six-row table, one line per prompt, saved for the day-seven re-run.

Day 2 — Breadth pass: statistics and inference

  • Answer ten short questions in writing with nothing open: what a p-value is conditional on, what a 95 percent interval covers across repeated samples, when a paired test is the right one, what the bootstrap estimates, why multiple comparisons inflate false positives, how controlling the family-wise error rate differs from controlling the false discovery rate, what power depends on, what a missed real effect costs a product, the three situations where the central limit theorem does not rescue you (small n, very heavy tails, dependent observations), and what a standard error is the standard deviation of.
  • Grade yourself against a reference and count only the answers that were exactly right, not the ones that were nearly right.
  • Rewrite the two weakest answers the following morning from memory in full sentences.

Deliverable: Ten graded answers with an honest count of exact hits.

Day 3 — Breadth pass: modelling

  • Take one tabular dataset end to end in 90 minutes: a leakage-safe split, a baseline that is not a model (majority class or historical mean), one regularized linear model, one gradient-boosted tree, and a single evaluation metric chosen before you look at any result.
  • Write why that metric fits the cost structure: precision at a fixed recall for alerting, calibration for anything feeding a price or a threshold, ranking metrics for retrieval, and note that area under the ROC curve is insensitive to class balance in a way that can flatter a rare-positive problem.
  • Name the leak you were most likely to introduce (an encoding fit on all rows before splitting, or a feature computed after the label's timestamp) and write the check that would have caught it.

Deliverable: A notebook whose first cell states the metric and the baseline, plus two lines on what beat what and by how much.

Day 4 — Breadth pass: product judgement

  • Answer three case prompts aloud at 15 minutes each, timing how long passes before you state a success metric.
  • For one case write the first segmentation you would run and the row counts you expect per segment, so that a tiny segment cannot quietly drive the conclusion.
  • Take a metric definition you did not write, from a public dashboard, a textbook, or documentation you already have open, and list every place two analysts implementing it would diverge: which rows the denominator admits, whether the unit is an account or a person, what the time window is anchored to, and what happens to data that arrives late. Then write the one question that would close the largest of those gaps.

Deliverable: Three recorded case answers plus an ambiguity list for a metric someone else defined, ending in the single question you would ask about it.

Day 5 — Depth, first area

  • Rank the four areas by how many bullet points in the role description each one covers, pick the top one, and spend the entire day inside it.
  • Work the six hardest problems you can find in that area and for each write the generalizable move you should have reached for first, rather than the answer.
  • Re-solve the two you failed the same evening with notes closed.

Deliverable: Six generalizable moves written as instructions to yourself, not as solutions.

Day 6 — Depth, second area, and the seam between them

  • Repeat the depth protocol on the second-ranked area with the same six-problem structure.
  • Construct one problem that requires both areas at once, for example a metric redefinition whose effect you must validate with a test whose readout you then have to query.
  • Solve your own combined problem end to end and note where the handoff between the two areas cost you time.

Deliverable: One combined problem, solved end to end, with the handoff failure written down.

Day 7 — Integration and re-measurement

  • Re-run the six prompts from day one under the same clock and compare both correctness and time.
  • Run a 60-minute mixed mock that moves between areas without warning, since switching cost is what breadth passes do not train.
  • Write the two areas you would still fail on, and the sentence you will use in the interview when you hit one of them.

Deliverable: A before-and-after score table plus a written plan for the two remaining gaps.

Ownership when the result is inconvenient

Sometimes the honest read is that the initiative did not work, and the person who commissioned the analysis was hoping otherwise. Interviewers want to know whether you softened it. Prepare the case where you delivered an unwelcome result, how you presented the uncertainty without hiding behind it, and what the team did next.

Talk about one specific project you are most proud of and your role in its success.

Medium · behavioural and stakeholder questions

Approach

  1. Close with what you would do differently, concretely.
  2. State the situation in two sentences and spend the rest on your reasoning.
  3. Quantify the outcome, including what you would not claim credit for.

Follow-up

  • How did you know the outcome was caused by your change?
  • What did you decide not to do, and why?

Prioritise transport, plant and commercial in one week

Medium · prioritisation · stakeholder management · decision value

Three requests land in the same week. Transport wants landed cost per delivered unit split by lane and mode from fct_shipment_leg for a carrier bid that closes in nine days. A plant manager wants OEE on two work centres decomposed into availability, performance and quality from fct_production_run for a capital request due next month. Commercial wants a fill-rate root cause from fct_order_line for an account review on Thursday. You are the only data scientist and have about four working days. Give your order, the rule that produced it, and what you say to the two who wait.

Approach

  1. Rank by the decision each request feeds and by whether your input can still change it, not by seniority or by who asked loudest: a bid closing in nine days is a live decision with a large irreversible spend attached, a capital request due next month has slack, and an account review has a fixed date but a smaller reversible decision.
  2. Check reversibility and blast radius: carrier rates lock for a contract period across every lane, so an error or an absence there is expensive for a year, while the fill-rate story can be revised next week.
  3. Look for the cheap partial that unblocks someone else: the fill-rate cut by node, by short_reason_code and by week is a few hours of work and covers most of what commercial needs on Thursday, so it does not have to wait behind the bid.
  4. Sequence with explicit time boxes: the commercial cut first because it is short and date-locked, the lane and mode cost analysis next with the allocation basis for multi-stop loads stated up front, and the OEE decomposition scheduled into the following week with a date the plant manager can hold you to.
  5. Tell the plant manager directly and early, with a date rather than a maybe, and say what you need from him in the meantime so the delay produces something.
  6. Escalate the trade-off rather than absorbing it silently: your manager should know a capital request slipped a week, because that is a business choice and not yours alone to make.

Follow-up

  • The plant manager escalates and his director asks you to reorder. What do you do?
  • Which of the three would you push back on entirely, and what would you offer instead?

Defend a finding that the expedite program bought nothing

Medium · defending findings · counterfactual reasoning · landed cost

Over two quarters, expedite_premium_cents on outbound legs in fct_shipment_leg rose from 0.4 to 1.3 percent of landed cost, while perfect order rate moved from 91.2 to 91.5 percent, inside the week-to-week spread. The transport lead who sponsored the expedite program disputes the finding in a review in front of his director, arguing that your window contains a port disruption that would have made service worse without the spend. Present the finding, say what you concede on the spot, say what you hold, and name the evidence that would change your conclusion.

Approach

  1. Restate his objection in its strongest form before answering it, because a counterfactual worsening is a legitimate argument and treating it as an excuse ends the conversation.
  2. Separate what you measured from what you claimed: the data show no detectable service gain, not that expedite has no effect, and the difference is the entire argument.
  3. Test his hypothesis with the data you already have rather than defending in the abstract: split legs by exception_code = 'customs_hold' and by lane, and compare expedited against non-expedited legs on the same lanes in the same weeks, since if expedite were holding the line the expedited lanes should show a service gap over comparable non-expedited ones.
  4. Concede what is true: without a holdout you cannot rule out a protective effect, and the pre-period is contaminated by the disruption, so the honest statement is an upper bound on the gain rather than a zero.
  5. Hold the part that survives: the spend is real, it is concentrated in a small set of lanes, and nobody set a decision rule for when a leg gets expedited, which is a controllable problem independent of the counterfactual.
  6. Name the next measurement: a lane-level staggered switch-off with a stated burn-in, and say what it would cost and how long it would take.

Follow-up

  • He offers to run the switch-off only on his two best lanes. Why is that a problem, and what do you counter with?
  • His director asks you for a yes or no on cutting the budget today. What do you say?