Interview guides · Avery Dennison
Avery Dennison Data Scientist Interview Questions & Guide 2026
Case practice for Avery Dennison data scientist candidates: scope a vague prompt into a measurable question before you analyze it.
The 60-second brief
As a Data Scientist at Avery Dennison, you are stepping into a pivotal role at a global leader in materials science, manufacturing, and intelligent labels (RFID). Your work directly influences how the company optimizes its global supply chain, improves manufacturing efficiencies, and develops smarter, more sustainable products. You are not just analyzing data in a vacuum; you are solving tangible, real-world problems that impact millions of physical products distributed worldwide.
Coding rounds for this role are usually data-manipulation shaped rather than data-structure shaped: group-bys, joins, time windows, ranking within a partition. Confirm the format before spending a week on graph traversal.
Focus areas
- Price a service-level change in working capital
- Trace an on-time miss to one node
- Size safety stock under variable lead times
Overview
This position bridges the gap between advanced analytics and industrial application. You will be expected to leverage machine learning, statistical modeling, and large-scale data processing to uncover insights that drive strategic business decisions. Whether you are building predictive maintenance models for manufacturing equipment, analyzing RFID data to enhance inventory visibility, or optimizing raw material usage, your contributions will have a measurable impact on the bottom line and the company's sustainability goals.
Expect a highly collaborative environment where you will partner with engineers, product managers, and operations leaders. values data professionals who can translate complex technical findings into actionable business strategies. The scale of the data is massive, the problems are complex, and the opportunity to drive meaningful change in a traditional industry is immense.
The Avery Dennison interview process
Avery Dennison candidates report 2 rounds · ≈ 2-4 weeks. The stages below are what candidates describe, not a published process.
HR Screening Interview
Whoever runs this call is usually not a practitioner. They take notes, and a hiring manager skims those notes later, so the real question is whether your work survives being written down by someone outside the field. Test every project sentence against that: could a non-specialist repeat it correctly without knowing what a propensity score is? Carry a plain-language version of each project and one reason you want this particular role that you could not copy onto another application. Vagueness at this stage reads as inexperience, even when the underlying work was genuinely deep.
What to demonstrate
- Whether a non-specialist can restate your projects accurately, since their paraphrase is what reaches the hiring manager
- Whether your reason for wanting the role points at the work itself rather than the company's reputation
- Whether your language signals the level being screened for: what you decided yourself versus what you were handed
How to prepare
- Write a two-sentence, jargon-free version of each major project: the question nobody could answer, and the decision your work changed. Read it to someone outside data and have them repeat it back
- Point your 'why this role' answer at something concrete in the job description or the product surface you would be working on, and keep it to two sentences
- Have two questions ready about measurement: which metric the team is held to, and who acts on an analysis once it lands
Manager Interview
Underneath the questions about your past work sits a resourcing question. Given four things worth doing and one of you, which gets done and what happens to the rest? Managers ask because that is the daily texture of the job, and because the answer shows whether you rank work by effort or by what it changes. The weak version sorts by personal interest or by whoever asked most insistently. The strong version ties each candidate piece of work to a decision somebody downstream is waiting on, and then names the one you would drop and who you would tell.
What to demonstrate
- Whether you rank work by the decision it unblocks or by how interesting the method is
- How you describe a request you declined, and whether you can say who you said it to
- Whether your sense of how long something takes survives one follow-up question about the messy part
- How you decide something is good enough to hand over unfinished
How to prepare
- Write out your current queue and, next to each item, the decision that stays stalled until it lands. Anything with no waiting decision becomes your example of work you would cut
- Rehearse turning down a plausible stakeholder request out loud, including the smaller alternative you offered instead
- Have one case where you shipped a rough answer early and one where you refused to, with the reason that separated them
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.
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.
Building features from data that postdates the prediction time
Check every feature against the timestamp at which the model would actually score, and drop anything computed from a window that includes or follows the label event. For a forecasting use case, split train and test by time rather than at random, and split by entity when the same entity recurs.
Naming a model class before naming the deployment constraints
Set out the latency budget, the label delay, the retraining cadence, the interpretability requirement and the number of labelled examples, then pick the model that fits them. A boosted-tree answer to a problem where each decision must be explained to the affected user is a well-executed answer to the wrong question.
Questions & practice
Can you explain the concept of p-value to someone who has no background in statistics?
Medium · statistics and probability
Approach
- Write down the assumption the method needs before you use the method.
- Sanity-check the answer against a simple bound or a simulated case.
- Say what the estimate is of, and over what population it generalises.
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?
What metrics would you use to evaluate a classification model dealing with highly imbalanced data?
Medium · machine learning and modelling
Approach
- Check what information would not exist at prediction time, and exclude it.
- 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
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
How did you validate the results of the model you built for [Specific Project on CV]?
Medium · machine learning and modelling
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Say how the offline result would be validated online before it is trusted.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- Where could label leakage enter this setup?
How do you check for and handle overfitting in a machine learning model?
Medium · machine learning and modelling
Approach
- Set a baseline first, so any model has something honest to beat.
- 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.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
As-of join snapshots to order lines without merge_asof
Medium · as-of join · fan-out · searchsorted
You have fct_order_line (order_line_id, sku_id, ship_from_location_id, actual_ship_at_utc, shipped_qty, shipment_id) and fct_inventory_daily (inventory_date, sku_id, location_id, available_qty). For every shipped line, attach available_qty from the latest snapshot strictly before the ship date for that exact sku and node, plus the shipment's delivery timestamp from fct_shipment_leg (leg_id, shipment_id, delivered_at_utc, leg_status). The output must have exactly one row per input order line. pandas.merge_asof is not available; implement the as-of match yourself.
Approach
- Collapse fct_shipment_leg to one row per shipment_id before joining anything. A shipment is one or more legs, so a direct line-to-leg join multiplies every line by its leg count and quietly inflates every sum computed afterwards.
- Define the shipment-level delivery as the maximum delivered_at_utc across its legs, and set it null if any leg is not delivered, since the customer has the order only when the last leg lands.
- Sort the snapshot frame by (sku_id, location_id, inventory_date) and the line frame by the same key plus ship date, then use np.searchsorted with side='left' on the sorted dates within each key group to find the insertion point; the matching snapshot is the row at position minus one.
- Guard the boundary explicitly: an insertion point of 0 means no snapshot exists before that ship date, and the result must be null rather than the first available future snapshot. Count those lines and report them.
- Assert the output row count equals the input line count immediately after each merge, before any aggregation. Row-count drift is the only symptom a silent fan-out produces, and it is invisible once the frame has been grouped.
Worked solution (30 min)
- Aggregate legs by shipment_id to produce delivered_at_utc as the max, leg_count, and a delivered_all flag from leg_status.
- Left join that one-row-per-shipment frame onto fct_order_line by shipment_id and assert the row count is unchanged.
- Sort snapshots and lines by the composite key, then compute per-group insertion points with np.searchsorted and subtract one.
- Mask positions below zero to null, take available_qty at the remaining positions, and attach it as available_qty_prior.
- Validate on a single sku-location pair by printing its snapshot dates and one line's ship date and confirming the chosen date by eye.
Expected result: A frame with exactly as many rows as the input order lines, carrying available_qty_prior (null for lines with no earlier snapshot), delivered_at_utc and leg_count, plus a printed count of unmatched lines.
Verify it yourself
- Assert len(output) equals len(fct_order_line) after every join step, not only at the end.
- Assert every non-null matched snapshot date is strictly less than the line's ship date, and that no snapshot date for the same key falls between the match and the ship date.
- Compare against a slow brute-force loop over 200 sampled lines; the two must agree on every row.
- Confirm the unmatched count equals the number of lines whose ship date precedes the first snapshot for their sku-location pair.
Follow-up
- The snapshot is taken at the node's local end of day and actual_ship_at_utc is UTC. Where does that break the strictly-before rule and what do you need from dim_location to fix it?
- How would you extend this to allocate each leg's linehaul cost back to the order lines it carried?
- What changes if a line ships in two partial shipments?
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
- 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.
- 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.
- 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.
- 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.
- 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.
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?
Bullwhip ratio by echelon from daily pipeline deltas
Hard · window functions · bullwhip · variance ratio
fct_inventory_daily gives on_order_qty (ordered, not yet shipped) and in_transit_qty (shipped, not yet received) per sku x location x date; dim_location gives echelon and parent_location_id. There is no replenishment-order table, so derive placements: a new order raises on_order, a shipment moves quantity from on_order to in_transit, and a receipt lowers in_transit, so placed_qty on a date is the positive part of the day-over-day change in (on_order_qty + in_transit_qty). Compute weekly placements per node and the bullwhip ratio against the demand that node received, reported per echelon. State what the derivation misses.
Approach
- Per sku-location, take LAG(on_order_qty + in_transit_qty) OVER (PARTITION BY sku_id, location_id ORDER BY inventory_date) and set placed_qty = GREATEST(pipeline - lag_pipeline, 0). The first date in each partition has no lag and must be dropped, not read as a placement equal to the whole standing pipeline.
- Name the blind spots before anyone else does: an order placed and received inside one day nets to zero, a cancellation is indistinguishable from a receipt, and minimum order quantities plus lot-size multiples make placements lumpy by construction rather than by anyone's behaviour.
- Define received demand by echelon. At the lowest echelon it is demand_qty in the same table. At a parent node it is the sum of its children's placed_qty joined through parent_location_id, not the parent's own demand_qty column, which is close to empty for a pure replenishment node.
- Aggregate both series to weekly buckets before computing dispersion, because day-of-week ordering patterns otherwise dominate the variance, and require a minimum number of weeks before quoting any ratio.
- Compute CV = stddev_samp / NULLIF(avg, 0) on each weekly series and report the ratio of squared CVs, stating that convention explicitly: a raw variance ratio is not level-free and is not comparable across nodes of different size.
- Read the output by echelon and locate where the ratio first crosses one going upstream. That is the node whose ordering rule amplifies, and it is usually not the node where the schedule instability is being felt.
Worked solution (45 min)
- CTE pipeline: select sku_id, location_id, inventory_date, on_order_qty + in_transit_qty AS pipe, and LAG(pipe) over the partition; drop rows where the lag is NULL and count them.
- CTE placements: placed_qty = GREATEST(pipe - lag_pipe, 0), aggregated to sku-location-week.
- CTE received: weekly demand_qty per node for the lowest echelon, and for higher echelons the weekly sum of children's placed_qty joined on parent_location_id.
- Join the two weekly series per node, require a minimum week count, and compute stddev_samp and avg on each side.
- Emit echelon, node, weeks_observed, cv_orders, cv_demand, bullwhip = (cv_orders / cv_demand) ^ 2, and the dropped first-date row count.
Expected result: One row per node with its echelon, weeks_observed, cv_orders, cv_demand and bullwhip as the squared CV ratio, plus an echelon-level rollup and the count of partition-start rows excluded for having no lag value.
Verify it yourself
- Total placed_qty over a long window is close to the total of receipts implied by falls in in_transit_qty. A large shortfall means same-day place-and-receive is common and the derivation is understating placements.
- Nodes at echelon 1 or 2 with no children under parent_location_id are excluded explicitly rather than silently producing a NULL or zero demand denominator.
- Recomputing the CVs on daily instead of weekly buckets changes the ratio. An identical ratio means the weekly aggregation never took effect.
- placed_qty is never negative, and its maximum is bounded by the largest single-day pipeline increase in the raw data.
Follow-up
- A node shows a ratio near 3. Name three ordering rules that produce that and say how you would tell them apart using only these tables.
- Why might a plant's schedule instability be untouchable from inside the plant, and what would you change instead?
- What would you want logged so that placements no longer have to be inferred from pipeline deltas, and what is the smallest such change?
Walk me through your resume and highlight the experiences most relevant to this role.
Medium
Approach
- Say what you would check first and why it is the highest-information step.
- Work from the decision backwards to the evidence you would need.
- Clarify what is being asked and what a complete answer would contain.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Describe your typical process for feature selection and engineering.
Medium
Approach
- State your assumptions explicitly before working the problem.
- Clarify what is being asked and what a complete answer would contain.
- Work from the decision backwards to the evidence you would need.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Measure the demand that never becomes an order line
Hard · censored demand · proxy bias · unobservable metrics
Commercial asks for lost sales by SKU and node. fct_order_line records short-shipped lines (short_reason_code = 'no_stock') and no-supply cancellations, and fct_inventory_daily carries demand_qty, available_qty and stockout_flag, but an order a customer never placed because the item showed unavailable leaves no row anywhere. Define the metric you will publish, the proxy it rests on, the direction and likely size of its bias, and the guardrail that stops the proxy being quoted as a measurement.
Approach
- Separate observable from unobservable in writing. Short-shipped units with short_reason_code = 'no_stock' and cancelled_qty on lines with line_status = 'cancelled_no_supply' are recorded demand that went unmet. Demand that never became a line is absent from the schema at every grain, so no query returns it and no join recovers it.
- Publish the observable part under its own name, unmet recorded demand, and refuse to call it lost sales, because the two quantities differ by exactly the amount nobody can see.
- Build the proxy from uncensored periods: per sku-location, estimate a baseline demand rate from days where stockout_flag is false and available_qty stayed comfortably above that day's demand, adjust for day of week and season, impute the censored days, and take the excess over recorded demand.
- State the bias and its direction. The estimate is a lower bound, because purchases diverted before an order was keyed and demand absorbed by substitution onto another SKU are both invisible. The shortfall is largest on the SKUs with the most stockout days, so it correlates with the quantity being measured and cannot be treated as noise that averages out.
- Bound the size instead of asserting it: report the censored share of sku-location-days, and run the imputation on a holdout of uncensored days that you censor artificially, so the recovery rate is measured on data where the truth is known.
- Put the guardrail on use rather than on the number: any spend justified by this metric must still hold when restated on the observable part alone, otherwise the proxy is carrying the argument and should be labelled as doing so.
Worked solution (40 min)
- Quantify the censoring: share of sku-location-days with stockout_flag true, and share of ordered units on lines with short_reason_code = 'no_stock' or line_status = 'cancelled_no_supply'.
- Compute the observable metric: unmet recorded demand in units and at unit_price_cents, weekly by node and ABC class.
- Fit the baseline rate on uncensored days only, with day-of-week and week-of-year terms, pooled within ABC/XYZ class where a sku-location series is too thin to fit alone.
- Impute the censored days, take the gap, then hold out a random sample of uncensored days, censor them artificially at plausible availability levels, and measure what fraction of known demand the method recovers.
- Publish both series with the censored share and one written sentence naming what the proxy cannot see.
Expected result: Two published series rather than one: unmet recorded demand, which is computable and exact, and estimated unconstrained demand, which is modelled and is a lower bound. The bias statement records that the gap understates true demand because pre-order diversion and substitution are invisible, and that the understatement is largest on high-stockout SKUs, so the metric is least reliable precisely where it is most consequential. The holdout recovery rate is quoted as the only empirical evidence for the imputation.
Verify it yourself
- Estimated unconstrained demand is at least recorded demand on every sku-location-day; a cell below it means the baseline was fitted on censored days.
- The artificial-censoring holdout recovers a stated fraction of known demand; recovery near 100 percent means the artificial censoring was milder than real stockouts and the test is not informative.
- Excluding stockout days from the baseline fit changes the baseline; if the number does not move, the filter is not being applied.
Follow-up
- substituted_sku_id records substitutions. How much of the gap does it close, and what does counting it break in the donor SKU's own demand history?
- How do you use the imputed series in a forecast without letting the imputation feed its own next round?
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
- 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.
- 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.
- 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.
- 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.
- 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
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.
Getting an analysis acted on
Work that nobody used is a common and unflattering pattern in data careers, and interviewers probe for it. Have a story about an analysis that changed a decision, and be specific about how you got it in front of the person who could act. Also have one about work that went nowhere, with your reading of why.
How do you handle situations where the data you need is unavailable or highly unstructured?
Medium · behavioural and stakeholder questions
Approach
- Quantify the outcome, including what you would not claim credit for.
- State the situation in two sentences and spend the rest on your reasoning.
- Pick a story where you drove the decision, not one where you observed it.
Follow-up
- What would you do differently if you ran that project again?
- What did you decide not to do, and why?
Tell me about a time you failed or made a significant mistake at work. What did you learn?
Medium · behavioural and stakeholder questions
Approach
- Quantify the outcome, including what you would not claim credit for.
- State the situation in two sentences and spend the rest on your reasoning.
- Pick a story where you drove the decision, not one where you observed it.
Follow-up
- How did you know the outcome was caused by your change?
- What did you decide not to do, and why?
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?