At Total Quality Logistics, the Data Scientist role serves as a critical engine for innovation within the logistics and supply chain sector. You will be responsible for transforming complex, high-volume operational data into actionable intelligence that drives efficiency across one of the largest freight brokerage firms in North America. Your work directly impacts how the company optimizes shipping routes, manages carrier relationships, and improves overall service reliability.
This role requires a blend of rigorous analytical thinking and practical business intuition. You will not just be building models; you will be identifying opportunities to solve real-world logistical challenges, such as predictive load matching and pricing optimization. Because Total Quality Logistics operates in a fast-paced, high-stakes environment, your ability to communicate data-driven insights to non-technical stakeholders is just as vital as your technical proficiency in machine learning and statistics.
The logistics industry is inherently dynamic. Expect to focus heavily on how your models handle uncertainty, seasonality, and rapid shifts in market demand.
Recruiter Screen
reportedA screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.
What to demonstrate
- Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
- Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
- Whether timeline, location and compensation expectations make the rest of the loop worth scheduling
How to prepare
- Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
- Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
- Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
Technical Assessments
reportedThis 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 Interviews
reportedA day of back-to-back interviews samples your floor, not your ceiling. Four hours in, the habits that carry a good answer are the first to go: restating the question before solving it, asking what the data would have to look like, checking a number before quoting it. What the day decides is whether the tired version of you is still someone to leave alone with an ambiguous problem. The round that sinks a candidate is usually not the hardest one. It is the one immediately after the round that went badly.
What to demonstrate
- Whether the late rounds get the same clarifying questions as the first one, or whether you start answering immediately to save effort
- Whether a weak answer stays in the room it happened in, instead of following you into the next conversation as apology or distraction
- Whether the quality of your questions holds up, since fatigue removes curiosity about the problem before it removes knowledge of the method
How to prepare
- Rehearse the length, not just the content: book four mock interviews of different types in one afternoon with short gaps, because the one you need to observe is the fourth
- Put the two or three questions you ask at the start of any problem on a card in front of you, so that under fatigue it is a habit you run rather than a decision you make
- Decide in advance what the gap between rooms is for: water, one line of notes on anything you promised to follow up, and an explicit close on the round that just ended so it does not travel
- Prepare a different closing question for each interviewer, so the end of a long day does not produce the same one four times
PracHub editorial advice for the preparation topics above.
Averaging rates across SKU-locations instead of re-summing
Fill rate, turns, OEE and on-time rate are all ratios whose denominators differ by orders of magnitude between cells, so an unweighted mean gives a slow-moving C item at a small node the same vote as a high-volume A item at a national node. The blended figure then moves whenever the portfolio mix moves, and it can improve in every cell while the company-level ratio worsens, or the reverse, which is Simpson's paradox with a warehouse attached. Always sum numerator and denominator to the reporting level and divide once, and when a rate must be compared across nodes, standardise on a fixed SKU mix before reading anything into the difference.
Treating shipped units as demand
Shipments are censored at available inventory: on a stockout day the recorded quantity is a supply ceiling, not customer intent, and orders that were never placed because the item showed as unavailable leave no row at all. A forecast fitted on that history learns the constraint, under-forecasts the fast movers that stock out most often, and produces the replenishment that causes the next stockout, so the error compounds in one direction rather than averaging out. The fix is to model demand_qty rather than shipped_qty, flag stockout days with stockout_flag and treat them as censored (fit with a censored likelihood, or estimate unconstrained demand from uncensored periods and comparable locations), and to report how much of the history was censored alongside any accuracy number.
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.
Optimising accuracy on a heavily imbalanced target
State the base rate first, then choose the metric from the relative cost of a false positive against a false negative: precision and recall at the operating threshold, PR-AUC, or expected cost. At a 1 percent positive rate, predicting the majority class for everyone scores 99 percent accuracy and is worthless.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
What are the common experimentation pitfalls you should avoid when tes…
What are the common experimentation pitfalls you should avoid when testing a new pricing model?
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Set a baseline first, so any model has something honest to beat.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Audit a daily inventory snapshot for silent corruption
You receive fct_inventory_daily with inventory_date, sku_id, location_id, on_hand_qty, allocated_qty, blocked_qty, available_qty, in_transit_qty, demand_qty, shipped_qty, stockout_flag and standard_cost_cents. The table is supposed to carry one row per active sku-location per date, including days with no movement. Write a check suite that returns one row per named check with the number of sku-location-days affected, the share of the scope, and the on-hand value at standard cost sitting behind the failures. Do not repair anything; the deliverable is the evidence.
Approach
- Start with the arithmetic identity the table declares: available_qty must equal on_hand_qty minus allocated_qty minus blocked_qty. Report exact row counts rather than a boolean, because a handful of violations is a feed bug and a uniform offset is a definition change upstream.
- Check sign constraints separately from the identity. Negative on_hand_qty usually means receipts posted out of order, while negative available_qty is legitimate at some sites when allocation is allowed to over-commit, so flag it and ask rather than assuming corruption.
- Check calendar completeness per sku-location by comparing the observed row count against the number of dates between that pair's first and last appearance. Count the missing dates without reindexing the frame, because filling them with zeros converts a feed gap into a plausible run of zero-demand days.
- Check stockout_flag in one direction only: available_qty of 0 at the cut-off with stockout_flag false is a contradiction, while flag true with positive available_qty is not, since the flag records an intraday touch of zero that a late receipt can recover.
- Weight every failure by on_hand_qty times standard_cost_cents so the summary orders checks by money at risk rather than by row count, and state the scope denominator on each row.
Worked solution 20 min
- Define the scope explicitly as the distinct sku-location pairs and the date range under audit, and store the scope row count for use as every check's denominator.
- Evaluate the identity, sign and stockout-flag checks as boolean masks over the frame and record the count and affected value for each.
- For completeness, group by sku_id and location_id, take min and max inventory_date and the row count, and compare the count to the number of calendar days spanned.
- Assemble one output row per check with check_name, failing_rows, share_of_scope and failing_on_hand_value_cents, sorted by value descending.
- Spot-print five failing rows per check so the output is actionable rather than a set of counts.
Follow-up
- Someone proposes asserting shipped_qty is at most demand_qty on the same row. Why does that fire on thousands of healthy rows?
- Half the missing dates fall on Sundays at one set of nodes. What is the most likely explanation and does it change the severity?
- Which of these checks would you run as a blocking gate before a nightly planning job, and which as a monitored report?
Recover unconstrained demand from stockout-censored history
A legacy extract has only inventory_date, sku_id, location_id, shipped_qty and stockout_flag; demand_qty was not populated before a cutover date. On a stockout day, shipped_qty is a lower bound on that day's demand. Model daily demand per sku-location as Poisson and fit its mean by maximum likelihood, treating stockout days as right-censored observations. Return the fitted mean per cell alongside the naive mean of shipped_qty and the censored share. Then validate against the post-cutover window where demand_qty exists.
Approach
- Write the likelihood before any code. Uncensored days contribute the Poisson pmf at the observed count; stockout days contribute the survival probability P(X >= y), because all you learned is that demand was at least what you managed to ship.
- Solve it as an EM fixed point rather than reaching for a general optimiser: the censored MLE equals the complete-data mean with each censored observation replaced by its conditional expectation, so iterate lambda_next = (sum of uncensored y + sum of E[X | X >= y, lambda]) / n until it stops moving.
- Use the closed form for the conditional expectation rather than truncating an infinite sum: for a Poisson, sum over k >= y of k*p(k) equals lambda times P(X >= y-1), so E[X | X >= y] = lambda * P(X >= y-1) / P(X >= y) for y >= 1. That removes the tail-truncation error entirely.
- Refuse to fit cells with too little signal. A sku-location with three non-zero days or with every day censored has no identifiable mean; return the naive figure with a flag rather than a confident number.
- Validate on the post-cutover window where demand_qty is populated: fit the estimator on shipped_qty and stockout_flag alone, and compare both the censored estimate and the naive mean against the true mean of demand_qty.
Follow-up
- The fitted mean is 18 percent above the naive mean for A-class items and 2 percent above for C-class. Why would you expect that ordering?
- The residual variance is three times the fitted mean. What does that break and what distribution would you move to?
- A stockout is often caused by a demand spike that day. What does that do to your estimate and can you correct it?
Write a query using SQL window functions to calculate the running aver…
Write a query using SQL window functions to calculate the running average of carrier load assignments over the last 30 days.
Approach
- State the window function and its partition and ordering out loud before writing it.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
Follow-up
- What breaks if events arrive late or out of order?
- How would you verify this result without re-running the same query?
Explain how you would optimize a query that is performing poorly on a …
Explain how you would optimize a query that is performing poorly on a table with millions of rows.
Approach
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- Say which table is the grain you start from, and join outward from it.
- 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?
Bullwhip ratio by echelon from daily pipeline deltas
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.
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?
If a primary operational metric suddenly drops by 10%, how do you inve…
If a primary operational metric suddenly drops by 10%, how do you investigate the root cause?
Approach
- Fix the population and the time window before naming any metric.
- Restate the decision this analysis has to support, and who acts on the answer.
- Decompose the metric into the rates that drive it, and say which one you would check first.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
How would you decide whether to launch a new feature that improves car…
How would you decide whether to launch a new feature that improves carrier retention but slightly decreases load volume?
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- Name one primary metric, then the guardrail that stops it being gamed.
- Fix the population and the time window before naming any metric.
Follow-up
- How would you detect that the metric is being gamed rather than genuinely improving?
- Which segment would you cut first, and what would that rule out?
How would you design a metric to measure the success of a new load-mat…
How would you design a metric to measure the success of a new load-matching algorithm?
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Fix the population and the time window before naming any metric.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
How would you handle a situation where an A/B test shows positive resu…
How would you handle a situation where an A/B test shows positive results but the user feedback is negative?
Approach
- Say whether units interfere with each other, and switch design if they do.
- Name the guardrails that would stop a launch even on a positive primary result.
- Decide the analysis before seeing data, including how long it runs and when you look.
Follow-up
- How would you handle interference between treated and control units?
- What would you conclude if the result is positive but the test is underpowered?
Explain the concept of statistical significance and how you determine …
Explain the concept of statistical significance and how you determine the sample size needed for an A/B test.
Approach
- Name the randomisation unit first; it decides the variance and what the test can detect.
- Say whether units interfere with each other, and switch design if they do.
- Name the guardrails that would stop a launch even on a positive primary result.
Follow-up
- What would you do if you could not randomise at all?
- What would you conclude if the result is positive but the test is underpowered?
A fill rate that improves by cancelling what it misses
Unit fill rate is defined as SUM(shipped_qty) over lines shipped on or before requested_ship_date, divided by SUM(ordered_qty) over lines with requested_ship_date in the week, excluding lines with line_status = 'cancelled_by_customer'. A node is now paid on it. Using fct_order_line (line_status, short_reason_code, ordered_qty, shipped_qty, cancelled_qty, substituted_sku_id, ordered_at_utc, requested_ship_date, account_id, sku_id, ship_from_location_id), list the routes by which this number rises without service improving, and specify the audit series that detects each.
Approach
- Attack the denominator first: removing a line removes a miss, and the only exclusion the definition grants is customer cancellation, a status written by the same operation being scored.
- Name re-entry: a short line closed and re-keyed as a fresh order arrives with a new requested_ship_date, so the miss leaves the scoring window entirely instead of being cancelled inside it.
- Name intake suppression: a line never created because the item showed unavailable enters neither side of the ratio, which is the only route that leaves no trace in this table and therefore needs demand-side evidence to detect.
- Name numerator inflation: substitution counted as a fill without saying so, partial shipments credited at ordered_qty, and shipping early against a requested date that was itself edited.
- Attach one audit series to each route from the same table: weekly cancelled_by_customer share by node, share of accounts re-ordering the same sku within seven days of a cancellation, substitution share, and median hours from ordered_at_utc to terminal status.
- Close with the structural fix: publish cancellation mix beside the rate, and pair it with perfect order rate, so that cancelling an order cannot improve both numbers at once.
Worked solution 20 min
- Compute the weekly fill rate per node by re-summing shipped_qty and ordered_qty, never by averaging line-level ratios.
- Compute cancellation mix beside it: cancelled_qty split by line_status in ('cancelled_by_customer','cancelled_no_supply') as a share of ordered_qty, per node per week.
- Compute the re-entry series: lines whose (account_id, sku_id, ship_from_location_id) reappears within seven days after a cancellation or a short ship.
- Compute substitution share and median hours from ordered_at_utc to terminal status, both by node and week.
- Quantify the exposure algebraically: moving x units of unmet demand out of the denominator takes a rate r to r divided by (1 minus x/D), then read that against normal week-over-week variation.
Follow-up
- Which of these routes still works if you score lines rather than units?
- A node's cancelled_by_customer share doubled in one week. What confirms or clears it before you accuse anyone?
Perfect order rate falls only in the newest two weeks
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
- 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.
- 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').
- 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.
- 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.
- 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?
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 ↗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 ↗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 ↗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 ↗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 ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Half of this section is about translation. Be ready to describe how you explained a result to someone who did not want the method, only the implication, and what you did when the simplified version started being repeated in a way that overstated it. Correcting your own simplification is a strong beat.
Tell me about a time you had to explain a complex technical concept to…
Tell me about a time you had to explain a complex technical concept to a non-technical stakeholder.
Approach
- Quantify the outcome, including what you would not claim credit for.
- Close with what you would do differently, concretely.
- 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?
Walk through an inventory analysis that turned out wrong
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?
Disagree with a planning manager about a safety stock cut
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
- 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.
- 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.
- 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.
- 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.
- 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?
- 01
Tell me about a time you had to explain a complex technical concept to a non-technical stakeholder.
- 02
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.
- 03
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.
Is this an official Total Quality Logistics interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Total Quality Logistics. Rounds and questions reflect what candidates have reported, not a process Total Quality Logistics has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How long should I prepare for the technical rounds?
Plan on at least 2–3 weeks of focused practice. Prioritize refreshing your knowledge on SQL and common statistical frameworks, as these are foundational to the team's daily work.
PracHub interview research ↗What is the company culture like for the Data Science team?
The culture is fast-paced, results-oriented, and highly collaborative. Total Quality Logistics values individuals who are proactive in identifying problems and persistent in finding data-driven solutions.
PracHub interview research ↗Are there remote work options for this role?
Requirements vary based on the specific team and location. Please discuss specific location expectations with your recruiter during the initial screening call.
PracHub interview research ↗Sources & methodology 3 sources ↗
No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
PracHub page · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
PracHub page · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
PracHub page · Accessed 2026-09-22