Interview guides · Arcelormittal México
Arcelormittal México Data Scientist Interview Questions & Guide 2026
Arcelormittal México Data Scientist interview guide: reported rounds, practice questions with worked solutions and a 7-day prep plan.
The 60-second brief
At Arcelormittal México, a Data Scientist plays a pivotal role in transforming one of the world's most traditional and vital industries through advanced analytics. Operating at the intersection of heavy manufacturing, supply chain logistics, and industrial internet of things (IoT), you will leverage massive datasets to optimize complex steel production processes. Your models will directly influence operational efficiency, energy consumption, and product quality across massive manufacturing facilities like the Lázaro Cárdenas plant.
How much statistics you need depends on the flavour of the seat. Experiment-facing work wants you deep enough to notice that repeated looks at accumulating data inflate the false positive rate of a fixed-sample test; modelling-facing work wants estimation and honest uncertainty intervals.
Focus areas
- Size safety stock under variable lead times
- Price a service-level change in working capital
- Separate true demand from censored, stocked-out sales
Overview
The impact of this role is both tangible and immense. Unlike digital-only environments, the algorithms you develop here translate into physical outcomes—reducing carbon emissions, predicting equipment failures before they cause costly shutdowns, and optimizing the chemical composition of high-grade steel. You will work with highly complex, multi-dimensional sensor data, requiring a deep understanding of physical processes and robust statistical modeling.
This position is ideal for analytical minds who thrive on solving real-world, high-stakes problems. You will collaborate with metallurgists, process engineers, and business leaders to turn raw industrial data into strategic advantages. It is a challenging but highly rewarding environment where your data-driven insights directly shape the future of sustainable steel manufacturing.
The Arcelormittal México interview process
Arcelormittal México candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
Application Review
A screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.
What to demonstrate
- Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
- Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
- Whether timeline, location and compensation expectations make the rest of the loop worth scheduling
How to prepare
- Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
- Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
- Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
Technical Assessment
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
Panel Interview
Where a loop includes a partner from outside the data team, that conversation usually carries the same weight as the technical ones and gets the least preparation. The person opposite you will not follow a derivation and does not need to. They are working out whether having you involved would make their decisions better or slower. The failure mode is not being too technical. It is answering a question about a decision with a description of your method, leaving the translation to them. What they carry into the debrief is the sentence you handed them, not the analysis underneath it.
What to demonstrate
- Whether a statistical result arrives as something the partner could act on, with the one caveat that would change their decision kept and the rest left out
- Whether you can state what you need from their side, in their terms: instrumentation that does not exist yet, a definition they own, or a holdout they have to agree to
- Whether uncertainty is given as a range someone can plan against, rather than as hedging that invites them to ignore the result
- Whether you ask what decision is actually on the table before explaining anything
How to prepare
- Take a result you know well and write the version for someone who stops reading after one sentence, then the three-minute version, and check the short one is not the long one with the qualifications stripped out
- For a past project, list everything you asked a non-technical partner for and how you phrased it, then rewrite each ask so it names what goes unmeasured without it
- Practise saying where a result does not apply, out loud, in one sentence that a partner could repeat accurately to someone else
Where candidates lose points
Scoring intermittent demand with MAPE
MAPE is undefined whenever the actual is zero, which is most days for a C-class item at a forward-stocking location, and it is asymmetric even where it is defined: under-forecasting is bounded at 100 percent error while over-forecasting is unbounded. Optimising it therefore drives systematic under-forecasting on exactly the items whose stockouts are most expensive, and the bias is invisible in the headline because the zero-actual rows were dropped before averaging. Use WMAPE (sum of absolute errors over sum of actuals), a scaled error such as RMSSE, or a pinball loss at the service quantile the policy targets, and always state the aggregation level and forecast lag, because the same series scores very differently at daily SKU-store level and weekly SKU-region level.
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.
Reaching for a model before the target metric exists
Before naming an algorithm, write down the label, the prediction time, and the action that changes when the score crosses a threshold. If you cannot say what decision the output drives, any modelling choice is guesswork dressed up as method.
Ignoring interference between units in a marketplace experiment
Ask whether one unit's treatment can change another unit's outcome through shared inventory, a matching pool, a social graph or a common budget. Where it can, randomise at a level that contains the spillover, such as region or time slice, and say explicitly what that costs you in statistical power.
Questions & practice
Explain the bias-variance tradeoff in the context of training deep learning models on limited industrial datasets.
Medium · statistics and probability
Approach
- Quantify uncertainty explicitly rather than reporting a point estimate alone.
- Sanity-check the answer against a simple bound or a simulated case.
- Translate the result into the decision it informs, in one plain sentence.
Follow-up
- How would you explain this result to someone who does not know statistics?
- What sample size would you need to detect an effect half this size?
How do you deal with missing sensor data or highly noisy time-series data from industrial equipment?
Medium · statistics and probability
Approach
- Translate the result into the decision it informs, in one plain sentence.
- Quantify uncertainty explicitly rather than reporting a point estimate alone.
- Write down the assumption the method needs before you use the method.
Follow-up
- What sample size would you need to detect an effect half this size?
- Which assumption here is most likely to be violated in practice?
Describe how you would model and forecast monthly energy consumption for a high-capacity industrial plant to optimize utility purchasing.
Medium · machine learning and modelling
Approach
- Check what information would not exist at prediction time, and exclude it.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Tell me about a time you had to explain a complex machine learning mod…
Medium · machine learning and modelling
Tell me about a time you had to explain a complex machine learning model to a non-technical stakeholder, such as a plant operator or shift manager. How did you ensure they trusted your model's recommendations?
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Say how the offline result would be validated online before it is trusted.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- Where could label leakage enter this setup?
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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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)
- 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.
- 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.
- 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.
- 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.
- 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?
Perfect order rate against the original promise in local time
Hard · timezone boundaries · order-grain rollup · semi-join
Compute weekly perfect order rate at order grain. An order qualifies only if every fct_order_line has line_status = 'shipped_full', every line's actual_delivery_at_utc falls on or before original_promised_delivery_date at the ship-from node's local end of day (dim_location.timezone holds IANA names), and no fct_shipment_leg reached through shipment_id carries exception_code in ('damage','address_issue') or leg_status in ('refused','lost'). The denominator is orders whose original_promised_delivery_date lands in the week. Undelivered lines fail. Publish with a fourteen-day lag and declare invoice accuracy as out of scope.
Approach
- Convert the event into local time rather than comparing against a UTC-anchored deadline: (actual_delivery_at_utc AT TIME ZONE 'UTC' AT TIME ZONE loc.timezone)::date <= original_promised_delivery_date. Casting the promise date to a timestamp puts the cut-off at UTC midnight starting the promise day, which is up to a full day early and wrong in both directions depending on the node's offset.
- Evaluate the three components as booleans at line grain, then roll to the order with BOOL_AND, coercing a NULL actual_delivery_at_utc to FALSE explicitly so an undelivered line fails rather than propagating NULL and dropping the order out of the comparison.
- Test the shipment exceptions with EXISTS against fct_shipment_leg, never with a join. One shipment has many legs and one order has many lines, so a join multiplies the order into the denominator and changes the metric.
- Aggregate to order grain first, then count qualifying orders over orders promised in the week. The rate is orders over orders; a line-level average is a different and easier metric.
- Apply the publication lag by restricting to weeks whose promise dates are at least fourteen days old, and emit the three component pass rates beside the headline so any movement is attributable to completeness, timeliness or exceptions.
Worked solution (40 min)
- CTE line_flags: join fct_order_line to dim_location on ship_from_location_id, producing is_full, is_on_time using the AT TIME ZONE conversion with COALESCE to FALSE, and has_exception from an EXISTS over fct_shipment_leg.
- CTE order_flags: GROUP BY order_id with BOOL_AND(is_full), BOOL_AND(is_on_time), BOOL_AND(NOT has_exception) and MIN(original_promised_delivery_date) for bucketing.
- Aggregate per DATE_TRUNC('week', promise date): COUNT() as denominator, COUNT() FILTER (WHERE all three) as perfect_orders, and the three component counts.
- Restrict output to weeks ending at least fourteen days ago.
- Re-run the on-time expression once with a naive UTC comparison and record the delta as evidence the conversion is live.
Expected result: One row per week with orders_in_denominator, perfect_orders, rate, and three component pass rates, where the rate is less than or equal to every component rate and weeks inside the fourteen-day lag are absent from the output.
Verify it yourself
- perfect_orders is less than or equal to the count passing any single component, for every week.
- Switching the deadline to a naive UTC comparison shifts the on-time component by roughly the share of orders at nodes offset from UTC. No change at all means the conversion is not being applied.
- The denominator equals COUNT(DISTINCT order_id) over orders promised in the week and does not change when the legs EXISTS clause is removed.
- No order_id appears in more than one week.
Follow-up
- All three component rates are flat but perfect order fell two points. How is that arithmetically possible, and what does it tell you about where the failures now land?
- A node sits at UTC+13 and many orders are promised on the last day of the month. What does that do to your weekly and monthly buckets?
- How do you handle an order whose lines ship from two nodes in different timezones, and which node's clock owns the promise?
Dead stock cells excluding SKUs used as substitutes
Medium · anti-join · null semantics · dead stock
Find dead stock: sku_id x location_id cells whose latest fct_inventory_daily row has on_hand_qty > 0 and which have no fct_order_line with that sku_id and ship_from_location_id in the last 90 days. Also exclude any SKU that filled another line as a substitute in that window; fct_order_line.substituted_sku_id is NULL on every line that was not substituted. Value each cell at on_hand_qty * standard_cost_cents taken from the snapshot, not from dim_sku. Return the cell, days since its last demand line, and value, ordered by value. Treat line_status = 'cancelled_no_supply' as demand.
Approach
- Take the latest snapshot per sku-location with ROW_NUMBER() OVER (PARTITION BY sku_id, location_id ORDER BY inventory_date DESC) = 1, or an equivalent MAX(inventory_date) join, and keep rows with on_hand_qty > 0.
- Anti-join demand with NOT EXISTS against fct_order_line on both sku_id and ship_from_location_id over the 90-day window, counting every line status including cancelled_no_supply, because unmet demand is still demand and a cell with it is not dead.
- Write the substitute exclusion as NOT EXISTS, or force substituted_sku_id IS NOT NULL inside the subquery. NOT IN over a column that contains NULLs evaluates to NULL for every candidate that is not an explicit match, so the predicate is never true and the result set is empty.
- Value from the snapshot's standard_cost_cents rather than dim_sku, since the dimension carries only the cost in force today and is revised at period close without back-dating.
- Get days since last demand from a LEFT JOIN LATERAL MAX(ordered_at_utc), and report cells that never had a line in a separate bucket instead of as a very large number.
Follow-up
- The query returns zero rows. Name the two likeliest causes and say which you would test first, with the one-line test.
- How do you separate genuinely dead stock from a seasonal item out of season and from a lifecycle_status = 'pre_launch' SKU?
- The same SKU is dead at one node and short at another. Write the query that finds that pattern and say what it implies about the policy.
If a temperature sensor in a blast furnace starts reporting anomalous spikes, how would you programmatically determine if it is a sensor malfunction or a genuine process issue?
Medium · product sense and metrics
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Fix the population and the time window before naming any metric.
- Decompose the metric into the rates that drive it, and say which one you would check first.
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?
Walk us through how you would optimize the raw material mix (such as iron ore and coal) to minimize production costs while strictly maintaining steel grade standards.
Medium · product sense and metrics
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Name one primary metric, then the guardrail that stops it being gamed.
- 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 end-to-end predictive maintenance system for a hot rolling mill? What specific data sources and telemetry would you require?
Medium · product sense and metrics
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Name one primary metric, then the guardrail that stops it being gamed.
- Restate the decision this analysis has to support, and who acts on the answer.
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?
How do you prioritize your tasks when managing multiple data science projects with competing business priorities?
Medium · product sense and metrics
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Fix the population and the time window before naming any metric.
- 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?
- How would you detect that the metric is being gamed rather than genuinely improving?
Separate novelty from steady state in a planner tool rollout
Medium · novelty effect · burn-in · exposure time
An override assistant was given to 18 of 36 planners, randomised at the planner and held for 14 weeks. WMAPE at lag 7 improves 6% relative in weeks 1-3, 2% in weeks 4-8, and is flat after. Downstream unit fill rate does not move until week 6, then gains 0.8 points. Decide whether the early forecast gain is novelty, whether the late service gain is real, and specify the readout window you would pre-register next time.
Approach
- Separate the two candidate stories before touching the data. Novelty is a behavioural effect that fades as a planner stops attending to a new tool; a real effect that is being diluted as easy wins are exhausted looks identical in calendar time. With one simultaneous launch, exposure time and calendar time are collinear and the two are not separable, which is itself the honest first answer.
- Get identification from staggered exposure where it exists: index the effect by weeks since first exposure and compare a late cohort's week-2 effect against an early cohort's week-2 effect. Matching at equal exposure age but different calendar dates isolates novelty; a pattern that aligns on calendar week instead points at seasonality or a demand-side shock.
- Put the two outcomes on their own clocks. Forecast error can respond in the week an override is made, but fill rate cannot respond until the changed order has been placed, received and consumed, which is one lead time plus one review period. A six-week onset is the expected physics of the replenishment loop, not evidence of a delayed behavioural effect.
- Check the mechanism rather than the curve: count override actions per planner per week. Falling override volume alongside a falling effect is novelty. Steady override volume alongside a falling effect means the overrides stopped paying, because the largest corrections were taken first, and that is a different and more durable finding.
- Pre-register a readout window that starts after a burn-in of at least two replenishment cycles for any service metric, states the forecast window separately, and defines the primary on post-burn-in weeks only.
Worked solution (30 min)
- Build a planner-by-week panel with arm, weeks since exposure, WMAPE at lag 7, unit fill rate, and override counts.
- Estimate the effect by weeks since exposure and, separately, by calendar week, and plot both against each other.
- If exposure was staggered, compare cohorts at matched exposure age; if it was simultaneous, state that novelty is not separable in this design and name the design change that would have separated it.
- Compute the system lag directly: median inbound lead time from fct_shipment_leg where direction = 'inbound', plus the review period, and compare it against the observed six-week onset.
- Write the pre-registration: forecast metrics from week 1 on their own clock, service metrics from the first week after two replenishment cycles, primary defined on the post-burn-in span.
Expected result: The decaying forecast gain cannot be attributed to novelty from a single simultaneous launch; separating it requires staggered exposure or the override-volume mechanism check. The six-week onset in fill rate is consistent with the replenishment lag and is not evidence against a real effect. The pre-registered readout is a post-burn-in window of at least two replenishment cycles for service, with the forecast metric reported on its own clock.
Verify it yourself
- The onset week for fill rate should approximately equal median lead time plus the review period; service moving faster than that means something other than the tool is moving it.
- Override volume per planner per week distinguishes the two decay stories on its own and needs no modelling.
- An A/A replay on the pre-period, cut the same way by week, should show no week-shaped pattern; a pattern there means the weekly decomposition is picking up seasonality rather than exposure.
Follow-up
- Planners cover each other's portfolios during absence and sit in the same weekly review. What does that do to a planner-level randomisation?
- Weeks 1-3 contained a promotion. How would you test whether the 6% is a promotion effect rather than novelty, using only data you already have?
Landed cost per unit rose with every lane flat
Easy · mix shift · simpsons paradox · cost per unit
Landed cost per delivered unit rose from 4.12 dollars to 4.49 dollars month over month, yet cost per unit is flat or lower in every individual lane and no contract rate changed. From fct_shipment_leg (linehaul_cost_cents, fuel_surcharge_cents, accessorial_cost_cents, expedite_premium_cents, shipped_units, mode, service_level, origin_location_id, destination_location_id, leg_status, direction), quantify how much of the 37-cent move is mix and how much is rate, then state what you would do about it. Multi-stop loads are allocated across legs by weight.
Approach
- Reproduce the headline by summing the four cost columns and shipped_units over legs with leg_status = 'delivered' and direction IN ('outbound','interfacility'), dividing once. Confirm both facts hold on the same row set; if the lane figures came from an unweighted average of lane rates, the paradox is an artefact of the averaging and the work stops here.
- Write cost per unit as a weighted mean of lane costs, C = SUM(w_i * c_i), where w_i is the lane's share of shipped_units. Compute within = SUM(w0 * (c1 - c0)), mix = SUM(c0 * (w1 - w0)) and the interaction term, and verify they sum to 37 cents.
- If mix dominates, find which weights moved. Cut w by mode, by service_level and by distance band: parcel and ltl cost multiples of ftl per unit for the same goods, and 'expedite' carries expedite_premium_cents, so a migration of units across those categories raises the blend with no rate moving anywhere.
- Separate a rate change from a surcharge change by decomposing the numerator as well. Fuel surcharge and accessorials move independently of contract linehaul, so report all four cost components per unit side by side for both months before accepting that rates held.
- State the action in the units the decomposition produced. A mix problem is solved by load consolidation, order cut-off changes or minimum order quantities. A carrier negotiation only touches the within-lane term, which by hypothesis is the small one.
Follow-up
- Units migrated from truckload to parcel. Is that a transport failure, an order-profile change, or an inventory-positioning failure, and how would you tell them apart?
- You allocated multi-stop cost by weight. Which lanes change rank if you allocate by cube instead, and for what kind of freight?
- How would you build a mix-adjusted cost index that a monthly review can read without redoing this decomposition every time?
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.
Where your data came from
Data people depend on systems owned by other teams, and much of the job is negotiating for instrumentation, access, or a fix to a broken pipeline. Prepare an example of getting something changed upstream that you did not control. Describe what you asked for, what you traded, and how you worked while you waited.
How do you handle highly imbalanced datasets, such as predicting rare equipment failures in a steel mill?
Medium · behavioural and stakeholder questions
Approach
- Pick a story where you drove the decision, not one where you observed it.
- Quantify the outcome, including what you would not claim credit for.
- Name the disagreement or constraint, and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Scope a vague request about rising inventory
Easy · scoping · stakeholder management · inventory turns
A planning director opens with: inventory is up twelve percent on flat shipments, get me an analysis by Friday. You have fct_inventory_daily (inventory_date, sku_id, location_id, on_hand_qty, standard_cost_cents) and fct_order_line (shipped_qty, unit_cogs_cents, requested_ship_date). Nothing else is specified: not the window, not the comparison basis, not whether the twelve percent is units or value. State the three questions you would ask before writing any SQL, name the decision each answer changes, and describe the first cut you would run if nobody answers you before Friday.
Approach
- Ask what decision hangs on the answer: a buy stop, a write-off provision, a policy review and a board slide all need different cuts, and the director usually has one of them in mind.
- Pin the measurement before the cause: units or value, which two windows are being compared, and whether the denominator is average daily on-hand or a period-end snapshot, since a month-end denominator biases turns high by ten to twenty percent and can manufacture the whole movement.
- Ask which part of the network is in scope, because echelon matters: a build at echelon 2 ahead of a promotion and a build of blocked_qty at a plant are different problems with different owners.
- Commit to a default if no answer arrives: value at standard cost, averaged across every daily snapshot in both windows, cut by echelon, then by abc_class and xyz_class, then by lifecycle_status to separate phase_out stock from active cover.
- Say out loud what the first cut cannot settle, so the director is not surprised: it localises the build but does not attribute it to forecast bias, a lot-size change or a supplier pulling orders in.
Follow-up
- The build is concentrated in one product family at two DCs. What are your next two queries, and what would make you stop calling it a planning problem?
- The director wants the number by Friday and the cause by Friday. Which do you drop, and how do you say so?
Walk through an inventory analysis that turned out wrong
Medium · error postmortem · snapshot bias · inventory turns
Six months ago you published inventory turns by node using the month-end on_hand_qty snapshot from fct_inventory_daily as the denominator, and two DCs cut cover on the strength of it. A finance review later showed month-end is systematically the lowest on-hand point of the month, because shipments cluster before close, so your turns were overstated and days of supply understated. Tell the story: what you built, how the error surfaced, what it cost, what you corrected, and the control that now prevents this class of mistake rather than this specific instance.
Approach
- Give the facts in order and own the decision, not just the code: you chose the month-end snapshot because it was one row per sku-location and fast, and you did not check whether the sampling point was representative.
- Quantify the error rather than describing it: recompute the same window against the average of every daily snapshot and state the gap in turns and in days of supply, which in a network with close-period push typically runs ten to twenty percent.
- Separate the consequence from the mistake honestly: say what the two DCs did, whether service actually degraded, and if it did not, say so instead of inflating the damage to sound accountable.
- Describe the correction and the notification: who was told, how quickly, and whether the restated number changed the recommendation.
- Close on the generalised control: a denominator convention written into the metric definition, plus a row-count assertion at each join grain, because the same shape of error appears when a daily snapshot is joined to shipment events on date equality and one shipment with several legs fans the snapshot out.
Follow-up
- How did you decide whom to tell first, and how did you phrase it?
- What made you trust the month-end snapshot in the first place, and what would have caught it in review?