cswork / libraryOpen practice workspace

Interview guides · APL Logistics

APL Logistics Data Scientist Interview Questions & Guide 2026

Practice explaining analysis before a APL Logistics data scientist interview: the recommendation, the uncertainty, the follow-ups.

The 60-second brief

As a Data Scientist within the APL Logistics Global Technology organization, you are at the forefront of solving some of the world's most complex supply chain challenges. This role, particularly within our Emerging Talent and Apprentice/Intern programs, bridges the gap between raw data and actionable business intelligence. You will not just be crunching numbers; you will be building scalable technology solutions that directly impact how multi-national customers manage their global logistics.

When randomisation is off the table, the skill being checked is naming an identification strategy together with the assumption it rests on: parallel trends for difference-in-differences, relevance and exclusion for an instrument, overlap and conditional ignorability for matching. Say the assumption out loud and say how you would try to break it.

Focus areas

  • Trace an on-time miss to one node
  • Evaluate forecasts at the lag ordering actually uses
  • Size safety stock under variable lead times

Overview

Your work will directly influence critical functional domains such as Warehouse Management Systems (WMS), Transportation Management Systems (TMS), and Customer Experience Management. By leveraging process, data, and technology capabilities, you help our teams optimize routes, forecast inventory needs, and streamline warehouse operations. The impact of your work scales globally, ensuring that goods move efficiently across borders and continents.

This position offers a unique blend of data science, business intelligence, and software engineering exposure. You will collaborate daily with supply chain domain experts, software engineers, and product managers. Expect a dynamic environment where you will touch front-end and back-end programming languages, cloud computing capabilities, and advanced analytics frameworks to create impactful, real-world logistics solutions.

The APL Logistics interview process

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

Initial Behavioral Screen

Rounds of this kind usually include one question about work that did not go well, and it is the part that carries the most information. Anyone can narrate a shipped win. What the interviewer learns from a project that stalled is how you behave without a result to hide behind: whether you noticed the problem yourself, how long it took, and who you told. Answers that route the failure onto a data pipeline or a reorganisation close the topic without answering it, and the follow-up comes back to your own part.

What to demonstrate

  • Whether you found the error yourself or someone else found it, and how long it sat before anyone knew
  • What you changed afterwards, stated as a check you now run rather than a lesson you now believe
  • Whether the mistake you choose has real cost attached, such as a quarter of misdirected roadmap or a metric that was reported upward, instead of one that flatters you

How to prepare

  • Choose a failure you caught yourself and be ready to say what tipped you off. A story where someone else caught it is still usable, but you will be asked why you missed it.
  • Write down the check you added afterwards and where it lives now, so the correction is a concrete artefact rather than a resolution.
  • Rehearse saying the cost out loud. Candidates shrink the number by instinct once the interviewer is in the room.

Technical Evaluation

This round decides whether someone can hand you a schema and a question and trust the number that comes back. Correctness under a clock is the bar, not clever syntax. The habit that separates strong from weak answers is checking the grain: after every join, know how many rows you expect and whether the count moved. Most wrong answers in this format are not wrong logic, they are a fan-out from a key that turned out not to be unique, or a filter applied before an aggregate when it belonged after. Say what you expect before you run it.

What to demonstrate

  • Whether your row counts survive each join, and whether you notice on your own when they do not
  • Deliberate handling of rows that fail to match, including whether the question needs an inner join or a left join with the non-matches kept and counted
  • Whether NULLs are treated on purpose, given that a NULL compares equal to nothing and that COUNT of a column skips it
  • Reaching a defensible answer inside the window instead of a refined one after it

How to prepare

  • Take a two-table schema, write a join that fans out on purpose, then fix it by collapsing the many-side to one row per key before joining. Repeat until the fix is reflex rather than recall.
  • Write a funnel as one query and print the distinct user count at each stage, then confirm each stage is a subset of the one above it rather than assuming it
  • Do a few timed runs in a plain text box with no autocomplete and no formatter, since assessment editors often have neither

Final Round Interview

Where a loop ends with a senior leader, that conversation is rarely another skills test. The technical signal already exists by then, so the questions tend to open up: what you would look at first, where a metric you have heard about could mislead, what you would push back on. The decision being made is scope, which in practice means level and how much you would be trusted to own unsupervised. Treating it as a formality is the usual mistake. An open question late in the day is still being scored, and a vague answer reads as someone who has not run anything themselves.

What to demonstrate

  • Whether your view of the business has anything specific behind it, given that you are working only from what is public and are expected to say so
  • Whether the scope of work you describe owning matches the scope of the role, instead of sitting a level below it
  • Whether you can disagree with something concrete and stay useful about it, rather than agreeing with everything said in the room
  • Whether your questions are ones only this person could answer, as opposed to ones the recruiter already covered

How to prepare

  • Build one view you could defend for two minutes using only public information: what the funnel probably looks like, which metric likely drives decisions, and where that metric could mislead. Being wrong for a stated reason survives this round; having no view does not
  • Write down the largest piece of work you have owned from question to decision, who else touched it, and what you decided alone, then check that it reads at the level you are interviewing for
  • Prepare one thing you would want changed if you joined and phrase it as a question rather than a verdict, so it opens a conversation instead of closing one

Where candidates lose points

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.

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.

Explaining an aggregate move without decomposing the mix shift

Split the change in the aggregate into within-segment movement and movement in segment weights before you explain it. Every segment's rate can fall while the overall rate rises, purely because volume shifted toward segments that already had higher rates.

Crediting a treatment for regression to the mean

Selecting a group because it is extreme (lowest-engagement users, accounts having their worst month, the bottom decile of a score) moves that group's expected next-period value back toward the average even under no treatment, by exactly as much as the selecting measure is imperfectly correlated with its own later value. Compare against units that met the same selection rule and went untreated, or use two pre-periods so the bounce-back is visible before the intervention starts. A pre-post number on a group chosen for being extreme measures the selection rule, not the treatment.

Questions & practice

What factors would you consider if asked to build a model predicting when a truck will arrive at a distribution center?

Medium · machine learning and modelling

Approach

  1. Check what information would not exist at prediction time, and exclude it.
  2. Pick an evaluation metric that matches the cost of each error type, not a default.
  3. Frame the prediction: the label, the moment of prediction, and the action it triggers.

Follow-up

  • Where could label leakage enter this setup?
  • How would you choose the decision threshold, and who owns that choice?

Cluster bootstrap for landed cost per delivered unit

Medium · bootstrap · clustering · ratio estimator · mix shift

You have delivered outbound legs from fct_shipment_leg: leg_id, shipment_id, leg_seq, carrier_id, origin_location_id, destination_location_id, shipped_units, cube_m3, linehaul_cost_cents, fuel_surcharge_cents, accessorial_cost_cents, expedite_premium_cents. In this extract the linehaul for a multi-stop load is booked entirely on leg_seq 1, so allocate it across the load's legs by cube first. Then estimate the difference in landed cost per delivered unit between two carriers on lanes both serve, with a 95 percent interval. Write the resampling yourself; no bootstrap library.

Approach

  1. Allocate the linehaul before anything else, in proportion to each leg's cube over the load's total cube, and keep the other three cost columns where they already sit. State the choice: allocating by weight instead reorders lanes whenever freight is bulky rather than dense.
  2. Restrict to the set of lanes both carriers actually serve in the window. Comparing over all lanes measures which carrier was assigned the cheap lanes, not which carrier is cheaper.
  3. Resample shipments, not legs. Legs of one load share a single allocated linehaul and a single dispatch decision, so treating them as independent draws understates the variance of the estimate.
  4. Recompute the statistic as a ratio of sums on every resample, total allocated cost over total shipped units. Taking the mean of leg-level cost-per-unit values instead gives a different estimand in which a one-unit leg counts as much as a full truckload.
  5. Report both the raw difference and a lane-standardised difference where lane weights are fixed at the pooled volume share, and say which one you would put in front of a decision maker.

Worked solution (35 min)

  1. Compute per-shipment total cube, allocate the leg_seq 1 linehaul across legs by cube share, and form leg_total_cost from the four cost columns.
  2. Build the lane key from origin_location_id and destination_location_id, and keep only lanes with delivered volume from both carriers.
  3. Compute the point estimate per carrier as sum(leg_total_cost) / sum(shipped_units), and take the difference.
  4. Draw 2,000 bootstrap replicates by sampling shipment_ids with replacement within each carrier, rebuilding both sums from the sampled legs and recomputing the ratio difference.
  5. Take the 2.5th and 97.5th percentiles of the replicate differences, then repeat the whole procedure with resampling stratified inside lane to produce the mix-standardised interval.

Expected result: A point difference in cents per delivered unit with a 95 percent percentile interval from 2,000 replicates, reported twice: raw, and standardised to a fixed lane mix. The two differ whenever the carriers' lane mixes differ, and can differ in sign.

Verify it yourself

  • Run the same bootstrap resampling legs independently instead of shipments: that interval should be narrower, and the gap is the intra-load correlation you would have thrown away.
  • Confirm the mean of the bootstrap replicates is close to the point estimate; a large gap indicates a bias worth investigating before quoting the interval.
  • Confirm total allocated linehaul per shipment equals the original leg_seq 1 linehaul to within rounding, and that no leg received a negative allocation.
  • Confirm the interval narrows roughly with the square root of the number of shipments by rerunning on a random half of the loads.

Follow-up

  • The interval crosses zero. What would you need in volume or in window length to resolve a difference of 2 cents per unit?
  • One carrier's accessorials are rising while its linehaul is flat. What is that signature telling you about execution versus rates?
  • How does your interval change if one shipment accounts for 15 percent of the units?

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.

How would you merge two datasets that have mismatched date formats and inconsistent naming conventions?

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. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.

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?

Given a table of transportation logs, write a SQL query to find the route with the highest variance in delivery times.

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. State the window function and its partition and ordering out loud before writing it.
  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?

Explain how you would optimize a query that is running too slowly on a massive inventory database.

Medium · sql and data manipulation

Approach

  1. Compute rates by summing numerator and denominator separately, never by averaging rates.
  2. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
  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?
  • What breaks if events arrive late or out of order?

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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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)

  1. 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.
  2. 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.
  3. Aggregate per DATE_TRUNC('week', promise date): COUNT() as denominator, COUNT() FILTER (WHERE all three) as perfect_orders, and the three component counts.
  4. Restrict output to weeks ending at least fourteen days ago.
  5. 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?

How would you design a metric to measure the efficiency of our warehouse packing process?

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. 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?
  • How would you detect that the metric is being gamed rather than genuinely improving?

Describe how you would visualize seasonal trends in shipping volumes for a retail customer.

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. State what result would change your recommendation, so the answer is falsifiable.

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?

Explain the concept of version control (e.g., Git) and why it is important when working on a cross-functional team.

Medium

Approach

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

Follow-up

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

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?

Perfect order rate falls only in the newest two weeks

Medium · right censoring · reporting lag · metric maturation

A weekly perfect order chart holds at 94 percent for eleven weeks, then reads 91 percent and 84 percent in the two most recent weeks. The metric requires every line shipped_full, actual_delivery_at_utc on or before original_promised_delivery_date, and no joined shipment leg carrying exception_code IN ('damage','address_issue') or leg_status IN ('refused','lost'). It is published on a 14-day lag. Using fct_order_line and fct_shipment_leg, decide whether service regressed and specify what the chart should show for incomplete weeks.

Approach

  1. Start from the structure of the metric: the denominator is fixed at promise date while the numerator requires an event that may not have happened yet, so any week younger than the full delivery-plus-claims window is mechanically depressed. Establish that before hunting for a cause.
  2. Quantify the incompleteness instead of assuming it. Per promise week, report the share of lines with actual_delivery_at_utc IS NULL and the share of shipments whose legs are still leg_status IN ('tendered','in_transit').
  3. Build the maturation curve from history. For each of the eleven settled weeks, recompute the metric as it would have looked at 3, 7 and 14 days after the promise date, so a recent week can be compared against a healthy week at the same age rather than against a settled one.
  4. Only after age-matching, test whether any residual is real by cutting it by ship_from_location_id, mode and exception_code, and asking whether the loss concentrates where a genuine failure would concentrate.
  5. Fix the chart rather than only the analysis: suppress or grey weeks younger than the publication lag, or publish an age-matched estimate with an interval, and write the rule down so the next reader is not caught by the same shape.

Follow-up

  • Damage claims can arrive up to thirty days later. Does that argue for a longer lag or for a different numerator?
  • How would you detect a genuine regression inside the lag window without waiting two weeks for it to settle?
  • P90 order cycle time shows the same maturation shape but biased the other way. Why, and which metric is more dangerous to read early?

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.

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.

Why are you interested in applying data science to the logistics and supply chain industry?

Medium · behavioural and stakeholder questions

Approach

  1. State the situation in two sentences and spend the rest on your reasoning.
  2. Pick a story where you drove the decision, not one where you observed it.
  3. Quantify the outcome, including what you would not claim credit for.

Follow-up

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

How do you handle exceptions and errors in your data processing scripts?

Medium · behavioural and stakeholder questions

Approach

  1. Pick a story where you drove the decision, not one where you observed it.
  2. State the situation in two sentences and spend the rest on your reasoning.
  3. Name the disagreement or constraint, and how you resolved it with evidence.

Follow-up

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

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?