As a Data Scientist at US Foods, you are at the intersection of large-scale logistics, supply chain efficiency, and customer-centric strategy. US Foods operates one of the most complex food distribution networks in the country, and this role is critical in transforming massive, messy, and high-velocity datasets into actionable insights that optimize delivery routes, inventory management, and customer engagement.
You will be responsible for building models that move the needle on core business metrics. Whether you are identifying high-value customers for delivery services or solving complex operations research problems to streamline supply chain performance, your work directly influences the bottom line. This role is ideal for a practitioner who is comfortable navigating ambiguity and enjoys the challenge of applying advanced machine learning and statistical techniques to real-world, industrial-scale problems.
The data you encounter may be intentionally unrefined. Expect to demonstrate your ability to clean, interpret, and derive value from "messy" real-world datasets during your case study.
Preparation focus
editorialNo round sequence has been reported for this company, so work the categories below and confirm the format with your recruiter.
What to demonstrate
- Breadth across SQL, experimentation and product reasoning
- Ability to state assumptions before choosing a method
How to prepare
- Drill the practice exercises below and time yourself
- Prepare three quantified stories about decisions you drove
PracHub editorial advice for the preparation topics above.
Judging merchandising and recommendation changes on the surface they touch
Click-through or attributed revenue on a recommendation slot rises whenever the slot shows items the customer was going to buy anyway, so the surface metric measures capture rather than creation, and the units almost always come from a different slot, a search result or a later visit. The correct read is site-wide net revenue per session over a holdout, adjusted for returns, because surfacing more apparel or more discounted stock reliably moves both the return rate and the discount depth in the wrong direction while the click metric improves.
Crediting promotions and channels by last click, especially coupon codes
A discount code handed to a partner or an influencer is claimed by customers who were already at checkout, so last-click attribution books organic demand as partner-driven, and the reported return on that spend is an artefact of the code's visibility at the basket rather than of any persuasion. The same mechanism makes email and paid search look strong because they sit close to a purchase that other activity created. Incremental effects need a holdout, a geo split or a switched-off period; where none is possible, at minimum report the share of code redemptions from customers whose session began before any partner touchpoint, because that number alone usually collapses the claim.
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.
Over-explaining the method and under-explaining the implication
Lead with the answer and what you would do about it, then give the approach when asked. Roughly one sentence of method per three of implication is the right ratio for a stakeholder-facing answer; the interviewer already knows what a regression is.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
What statistical methods do you use to validate the significance of yo…
What statistical methods do you use to validate the significance of your model's findings?
Approach
- 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.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- What would you monitor after launch to know the model is still valid?
- How would you choose the decision threshold, and who owns that choice?
Explain the components of a confusion matrix and when you would priori…
Explain the components of a confusion matrix and when you would prioritize precision over recall.
Approach
- 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.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
Simulate the buy quantity that maximises expected season profit
You get demand_draws, 10000 samples of total season demand for one seasonal SKU, generated from the historical demand model. There is a single buy before the season, no replenishment, and leftovers clear at the end. Unit economics in cents: full price 6000, landed unit cost 2400, clearance recovery 1500 net of handling. Write a simulator that evaluates expected profit over a grid of buy quantities and returns the argmax. Then state the closed-form answer this must agree with, and quantify the profit lost by buying to the mean demand instead.
Approach
- Write profit for a single demand draw d and quantity q as (price - salvage) * min(d, q) - (cost - salvage) * q, which is the algebraic rearrangement of pricemin(d,q) + salvage(q-d)+ - cost*q and avoids computing two branches.
- Vectorise over the grid: np.minimum.outer(demand_draws, q_grid) gives a draws-by-grid matrix; take the column means to get expected profit per q in one pass rather than looping over draws.
- Derive the closed form before looking at the simulation output. Underage cost is the lost contribution per unit of unmet demand, 6000 - 2400 = 3600; overage cost is the loss per unsold unit, 2400 - 1500 = 900; the critical ratio is 3600 / 4500 = 0.8, so the optimum is the 80th percentile of demand.
- Compare argmax of the simulated curve with np.quantile(demand_draws, 0.8) and check they agree to within one grid step; a systematic gap means the profit function is miscoded, not that the theory is wrong.
- State the preconditions that make the critical ratio valid: one selling season, salvage below cost below price, demand independent of the quantity ordered, and no goodwill cost for a stockout. Adding a lost-sale penalty raises the underage cost and pushes the quantile up.
Worked solution 30 min
- Set q_grid = np.arange(0, demand_draws.max() * 1.2, 5) so the grid spans past the plausible optimum on both sides.
- Build sold = np.minimum.outer(demand_draws, q_grid) and profit = 4500 * sold - 900 * q_grid, then take profit.mean(axis=0).
- Read off q_grid[expected_profit.argmax()] and compare with np.quantile(demand_draws, 0.8).
- Evaluate expected profit at q = demand_draws.mean() and report the shortfall against the optimum in cents and as a percentage.
- Plot or tabulate the curve near the optimum to confirm it is concave and flat-topped, which is why being slightly over is cheaper here than being slightly under.
Follow-up
- A stockout sends some customers to a substitute SKU you also own. How does that change the underage cost, and in which direction does the optimal quantity move?
- The demand draws come from a model fitted on sales history that contains stockouts. What is wrong with the draws, and which direction does the error push the buy?
- How would you extend this to two buys, an initial commitment and a mid-season reorder with a lead time?
Net revenue per order without fanning out multiple return lines
fct_order_line (order_line_id, order_id, quantity, unit_paid_price_cents, line_status, placed_at_utc, delivered_at_utc, currency_code, fx_rate_to_usd) joins one-to-many to fct_return_line (return_line_id, rma_id, order_line_id, quantity_returned, refund_amount_cents, refunded_at_utc); one order line can generate several return lines when a customer returns part of a quantity twice. For orders placed in a given month, return order_id, gross_usd over delivered lines, refund_usd, and net_usd. Attribute every refund to the parent order's placed month, not the refund month. Convert with the parent line's fx_rate_to_usd.
Approach
- Count rows at each grain before joining: lines in the month, return lines against those lines, and the number of order lines with more than one return line. That last count is the size of the fan-out you are about to create.
- Pre-aggregate returns in a CTE keyed on order_line_id: SUM(quantity_returned), SUM(refund_amount_cents). This collapses the many side to one row per key, so the subsequent join is one-to-one.
- LEFT JOIN the aggregate onto the order lines and COALESCE the refund to 0, so lines with no return survive; an inner join here deletes the majority of revenue.
- Apply fx_rate_to_usd at the line, before any SUM, because each line carries its own rate and summing local cents first then applying one rate mixes currencies.
- Filter gross to line_status = 'delivered', but keep refunds attached to their delivered parent rather than filtering on refunded_at_utc, which is what produces placed-month attribution.
- Roll up to order_id last, and keep the line-grain CTE available so any suspicious order can be decomposed.
Worked solution 25 min
- Compute total gross USD from fct_order_line alone for the month and write it down as the reference figure.
- Write the naive join version, sum gross, and confirm it exceeds the reference.
- Build the returns CTE grouped by order_line_id and LEFT JOIN it, then re-sum gross and confirm it now equals the reference.
- Aggregate to order_id with gross_usd, refund_usd, net_usd.
- List the top ten orders by refund_usd / NULLIF(gross_usd, 0) as a face-validity pass.
Follow-up
- Refunds arrive weeks after the sale. How long do you hold this month's number before publishing it, and what do you key that lag off?
- How does this query change if you need net revenue per customer rather than per order, given household_id is nullable?
- A refund exceeds the line's paid amount. Name two legitimate reasons and one bug.
Demand-weighted in-stock rate and censored lost-sales estimate by week
From fct_inventory_snapshot (snapshot_date, sku_id, node_id, forecast_units, minutes_unavailable, was_listed, gross_units_sold, units_cancelled_oos, available_to_promise_units), compute per node per week the demand-weighted in-stock rate: SUM(forecast_units * (1440 - minutes_unavailable) / 1440) over rows with was_listed = TRUE, divided by SUM(forecast_units) over the same rows. Then estimate lost units: for each SKU-node-day with minutes_unavailable > 0, multiply a trailing 28-day mean of gross_units_sold on fully available days by minutes_unavailable / 1440, add units_cancelled_oos, and sum to the node-week. State the estimator's assumptions.
Approach
- Restrict both sides of the rate to was_listed = TRUE and cast before dividing: minutes_unavailable is a SMALLINT, so (1440 - minutes_unavailable) / 1440 in integer arithmetic returns 0 or 1 and destroys the partial-day signal.
- Build the run rate from fully available days only (minutes_unavailable = 0 AND was_listed), because a day that was itself censored cannot be used to say what that SKU would have sold.
- Compute it with a window: AVG(gross_units_sold) OVER (PARTITION BY sku_id, node_id ORDER BY snapshot_date RANGE BETWEEN INTERVAL '28 days' PRECEDING AND INTERVAL '1 day' PRECEDING). Use RANGE for calendar semantics; ROWS over a filtered series gives the last 28 available observations instead, which is a different and also defensible estimator, so say which you chose. Exclude the current day either way.
- Join the run rate back to the censored days, multiply by minutes_unavailable / 1440.0, and add units_cancelled_oos separately: those are realised demand that never became gross_units_sold, so adding them is not double counting.
- Handle the SKUs with no fully available day in the window explicitly. They are the chronically stocked-out items the analysis exists to find; report their count and their forecast_units rather than letting a NULL run rate drop them.
- State the assumptions with the number: demand is uniform within the day, unavailability is uncorrelated with intraday demand peaks, and there is no substitution to another SKU or node. The first two make the estimate a lower bound when stockouts cluster at peak hours; the third makes a node-level total an overstatement of company-level loss.
Follow-up
- The in-stock rate improved while the number of was_listed rows fell. What happened, and how do you make that visible in the metric?
- Why is an unweighted, SKU-count in-stock rate misleading here, and what does weighting by forecast_units instead of by historical sales buy you?
- The buy for next season is being placed off this sales history. What do you hand the planner alongside the forecast?
How would you approach a problem where the target variable is not clea…
How would you approach a problem where the target variable is not clearly defined in the dataset?
Approach
- Say what you would check first and why it is the highest-information step.
- 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?
Score a monthly promotional event on incremental margin
Merchandising runs a sitewide weekend event every month. The current readout is event-week revenue against the prior week. You have fct_order_line (promotion_id, line_discount_cents, discount_funding, unit_paid_price_cents, unit_cost_cents, placed_at_utc, sku_id), fct_return_line and dim_sku. Deliverable: design the scorecard. Name the primary metric, the two effects the primary must be corrected for, how you charge the discount cost, and what has to be held back for the measurement to mean anything.
Approach
- Reject the week-over-week baseline outright. The event is scheduled onto a week chosen because demand was expected to be high, and it is compared against the week its own pull-forward drained. Both halves of the comparison are contaminated in the same direction.
- Set the primary as incremental contribution margin per exposed customer against a holdout, measured over a window extending past the event by at least one category repurchase interval, so pull-forward appears as a post-period deficit rather than being booked as lift.
- Correct for the second effect, cannibalisation, by reading at category level rather than promoted-SKU level. A discount on one SKU pulls units off its full-price neighbours, and a SKU-level read counts that transfer as creation.
- Charge the discount correctly. The depth is paid to every buyer, including those who would have paid full price, so incremental margin equals incremental units times unit margin at the promoted price, minus baseline units times discount per unit. Split by discount_funding, because supplier-funded depth does not consume retailer margin and should not be charged to the event.
- Name the holdback. A randomised customer holdout, or a geo split with pre-period parallelism checked. If the event genuinely cannot be withheld from anyone, say so and fall back to a synthetic control on comparable markets, and state plainly that the estimate is now assumption-dependent rather than measured.
- Net returns before reporting. Promoted units return at different rates than full-price units, so attribute refunds to the parent order's placed date and hold the read until the return window closes.
Worked solution 30 min
- Define the holdout and verify pre-period parallelism on category revenue per customer for at least eight weeks before the event.
- Compute units and net merchandise revenue by arm for the event window and for a post-period of one category repurchase interval, refund-adjusted to placed date.
- Compute contribution margin by arm using unit_paid_price_cents less unit_cost_cents, less shipping and return costs, plus recovered_value_cents.
- Split SUM(line_discount_cents) by discount_funding and charge only the retailer-funded and shared portions to the event.
- Report event-window incremental margin and post-period incremental margin separately, then the sum, so pull-forward is visible rather than netted silently.
Follow-up
- The event lifts revenue 22 percent and incremental contribution margin is negative. Walk me through exactly how that arithmetic works.
- Supplier funding covers 60 percent of the depth. Does the event still lose money, and does that change what you recommend?
- How long does the post-period window need to be, and what data did you use to choose that length?
Revenue up six percent, margin per order down eleven
Net merchandise revenue rose 6% month over month while contribution margin per delivered order fell 11%. You have fct_order_line (quantity, unit_list_price_cents, unit_paid_price_cents, line_discount_cents, discount_funding, promotion_id, unit_cost_cents, shipping_charged_cents, shipping_cost_cents), fct_return_line (refund_amount_cents, return_shipping_cost_cents, restocking_fee_cents, recovered_value_cents, disposition) and dim_sku (category_l1, is_own_brand). Deliverable: attribute the margin decline to named drivers measured in cents per delivered order that reconcile to the full 11%, and label each driver as a policy choice or a mix effect.
Approach
- Write contribution per delivered order as an additive identity before touching data: net merchandise revenue, minus landed cost of units shipped, plus recovered value on returns, minus outbound and return shipping cost, minus payment fees, plus shipping charged and restocking fees, all over delivered orders. Compute every term for both months so the decline reconciles term by term with no residual bucket larger than the smallest named driver.
- Split each term into rate and mix the same way as any blended metric. Discount per order is depth per unit times units per order; a category mix shift changes blended depth with no price change anywhere, and that distinction decides whether merchandising or pricing owns the answer.
- Separate discount_funding before drawing any conclusion about discounting. Supplier-funded depth does not consume retailer margin, so a rise in promotional depth funded by suppliers is not a driver and must be excluded from the discount term.
- Work the returns terms properly: attribute refunds back to the parent order's placed month rather than the refund month, and check recovered_value_cents per returned unit by disposition. A shift from restock_a_grade toward liquidate or destroy cuts margin with no change in return rate at all.
- Work the freight terms: shipping_cost_cents per delivered order against shipping_charged_cents per delivered order. A lowered free-shipping threshold raises orders and revenue while turning charged freight into subsidised freight, which is exactly the pattern of revenue up and margin down.
- Rank the drivers by cents per order, label each policy or mix, and state which single decision would recover the most margin and what it would cost in revenue.
Follow-up
- Your decomposition leaves a residual of a few cents per order. How do you decide whether to chase it or name it?
- The free-shipping threshold change was a deliberate test. What would you need to call it a win or a loss, and over what horizon?
- Finance's gross margin does not match your contribution figure. Which differences are expected by construction and which would worry you?
Roughly 90 minutes a night on weekdays with one longer weekend block. The plan deliberately cuts scope rather than compressing everything, on the assumption that finishing one thing a night beats half-starting four.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Fix the scope and set a baseline
- Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list for everything else and keep it visible all week.
- Take one 20-minute SQL prompt and one 10-minute metric question cold, and write the single sentence that says what blocked each attempt, since that sentence is what decides which two topics get the most evenings.
- Set the week's one rule: one problem finished to completion every night, including the night you only have 40 minutes.
Deliverable: A one-page scope with an explicit not-doing list and two cold attempts, each carrying one sentence on what blocked it.
Practice prompt ↗Practice prompt ↗Worked solution ↗02One query pattern, written three times
- Choose the single pattern most likely to appear (a cohort retention grid, or a funnel counted by user) and write it three times from a blank file rather than editing the previous attempt.
- On the third attempt, write the grain of every CTE as a comment before writing its body.
- Stop at 90 minutes even if the third version is imperfect, and write the one thing you would fix with another hour.
Deliverable: Three independent versions of the same query plus a note on what changed between them.
Practice prompt ↗Practice prompt ↗03Only the statistics you will be asked to defend
- Write, in under 200 words, how you would decide whether a difference between two groups is real: the test, its assumptions, and what you would switch to when an assumption fails.
- Compute a 95 percent confidence interval for a difference in proportions by hand on realistic numbers, then write in one sentence what changes if the two samples are paired rather than independent.
- Write your answer to "what does a p-value mean", check it against a definition, and delete the version that describes it as the probability the hypothesis is true.
Deliverable: A 200-word written answer and one hand-computed interval you can reproduce under pressure.
Practice prompt ↗Practice prompt ↗04One case, and the assumptions holding it up
- Answer one product case aloud in 20 minutes with a recording running, then listen back with a pen and mark every claim you asserted without saying what it rested on: an assumed user behaviour, an assumed data source, an assumed baseline rate, an assumed grain.
- Pick the three assumptions the recommendation actually depends on, write how you would check each one against data, and say which one being wrong would flip the recommendation rather than merely weaken it.
- Write the four-step structure you used onto a card small enough to hold in working memory when you are nervous.
Deliverable: One recording, three load-bearing assumptions each with a written check, and a four-step structure card.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Your own work, timed
- Write a 90-second version and a four-minute version of your main project, and time both out loud rather than reading them.
- Prepare answers to the two follow-ups that always come: what you would do differently, and how you knew it worked.
- Put one number in the first sentence and be able to say exactly where that number came from and what it excludes.
Deliverable: Two timed narratives with one defensible number in the opening line.
Practice prompt ↗06The one full rehearsal, in a longer weekend block
- Run a 60-minute mock covering query work, a case and a behavioural question in a single sitting with no breaks, because sustained attention is the thing evenings have not trained.
- Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
- Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.
Deliverable: Mock notes naming three failure moments with a specific fix written under each.
Practice prompt ↗07Taper
- Write the 20-minute warm-up you will actually do on the morning of the interview: one query you can already write from a blank file, one metric you can define out loud, and nothing you have never seen before.
- Re-read only your own notes from this week, and open no new material.
- Write down the logistics: the tool you will be asked to work in, whether lookups are allowed, and the sentence you will use when you do not know something.
Deliverable: A one-page card holding the case structure, the project numbers, and the logistics.
Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
An answer without a quantity is hard to interrogate, so interviewers keep probing until they find one. Come with the baseline, the change, the window it was measured over, and how confident you were. If the effect never got measured, say so and say what you would have measured. Fabricated precision is worse than an honest gap.
Describe a time you had to choose between two different modeling appro…
Describe a time you had to choose between two different modeling approaches; why did you pick the one you did?
Approach
- Name the disagreement or constraint, and how you resolved it with evidence.
- Close with what you would do differently, concretely.
- State the situation in two sentences and spend the rest on your reasoning.
Follow-up
- How did you know the outcome was caused by your change?
- What did you decide not to do, and why?
How do you handle missing or noisy data in a production-level pipeline…
How do you handle missing or noisy data in a production-level pipeline?
Approach
- Close with what you would do differently, concretely.
- Name the disagreement or constraint, and how you resolved it with evidence.
- State the situation in two sentences and spend the rest on your reasoning.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Choose between three teams asking for the same week
Three requests land on the same Monday. Merchandising wants a size-curve read before a buy deadline on Thursday. Growth wants a channel attribution rebuild that has been requested twice and dropped twice. Supply chain wants a stockout root-cause on a category that cancelled four thousand units last month. You have one week and no help, and each requester believes theirs is first. State what you do, in what order, and what you tell the two people who do not get the week.
Approach
- Sort by the decision behind each request rather than by who sent it. A buy deadline is an irreversible commitment with a fixed date; an attribution rebuild changes no decision this week.
- Ask each requester two questions: which decision changes, and what happens if the answer lands a week later. Those two separate a real deadline from felt urgency without arguing about either.
- Look for the cheap partial before assuming any request consumes the week. If the size curve already exists at style grain, the merchandising read may be two hours rather than four days.
- Decline explicitly with a start date attached instead of leaving a request in a silent queue. Growth has been dropped twice, so a third silent drop is a relationship cost you are choosing to pay; name it rather than incur it by default.
- Escalate the collision upward once, with the three decisions and their dates side by side, so the tradeoff is resolved where it is owned rather than by whoever follows up hardest.
Follow-up
- Growth escalates to your manager saying analytics never supports them. What did you do before that happened, and what do you do now?
- The buy deadline moves to Tuesday. What do you cut from the size-curve read, and what do you refuse to cut?
- 01
Describe a time you had to choose between two different modeling approaches; why did you pick the one you did?
- 02
How do you handle missing or noisy data in a production-level pipeline?
- 03
Three requests land on the same Monday. Merchandising wants a size-curve read before a buy deadline on Thursday. Growth wants a channel attribution rebuild that has been requested twice and dropped twice. Supply chain wants a stockout root-cause on a category that cancelled four thousand units last month. You have one week and no help, and each requester believes theirs is first. State what you do, in what order, and what you tell the two people who do not get the week.
Is this an official US Foods interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at US Foods. Rounds and questions reflect what candidates have reported, not a process US Foods has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How long should I spend on the case study?
While instructions may suggest a specific timeframe, prioritize quality and clarity over speed. If you are unsure about the requirements, reach out to your recruiter or hiring manager immediately for clarification.
PracHub interview research ↗What is the company culture like for data teams?
US Foods is a large, established organization. You may encounter varying levels of technical maturity across different departments. Being an effective communicator who can advocate for data-driven decisions is essential.
PracHub interview research ↗What happens if I don't hear back after a submission?
Always follow up with your recruiter if the timeline they provided has passed. If you are managing multiple offers, be transparent with your contact about your timeline.
PracHub interview research ↗Sources & methodology 3 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
platform · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-22