At Steelcase, a Data Scientist plays a pivotal role in bridging the physical and digital worlds. As a global leader in office furniture, interior architecture, and space solutions, Steelcase relies on data-driven insights to design workplace environments that foster collaboration, productivity, and employee well-being. This position sits at the intersection of IoT sensor data, workspace analytics, supply chain logistics, and business intelligence, making it an incredibly diverse and high-impact role.
You will be responsible for transforming complex datasets into actionable strategies. Whether you are analyzing spatial utilization data to help clients optimize their real estate footprints, forecasting demand to streamline global manufacturing, or building predictive models to enhance product development, your work directly influences the future of work. The scale and complexity of the data you handle will require a blend of robust statistical modeling, modern machine learning techniques, and creative problem-solving.
This is not a purely backend engineering role; it is a highly collaborative position that demands strategic influence. You will partner with product managers, workspace designers, and business leaders to turn raw data into compelling narratives. For those who thrive on seeing their digital solutions manifest in physical, real-world environments, this role offers a unique and deeply satisfying career path.
HR Screening Call
reportedData Scientist covers at least four different jobs: experimentation, product analytics, causal work on observational data, and applied modelling that ships into a system. A screening call is the cheapest place to find out which of them is being hired for, and doing that diagnosis openly reads as senior rather than fussy. Ask what the last few pieces of work on the team actually were, and roughly how a week splits between querying, modelling and stakeholder time. Then say which parts of that you have done and which you have not. Claiming the whole range is the fastest way to be caught one round later.
What to demonstrate
- Whether you can distinguish the flavours of the role and locate your own experience inside one of them honestly
- Whether you name what you have not done instead of stretching to cover every line of the posting
- Whether your hard constraints (notice period, location, work authorisation, level) surface now rather than at offer stage
How to prepare
- Map the last two years of your time into rough percentages across query writing, experiment design, modelling and stakeholder work, so a question about scope has a real answer
- Mark every responsibility in the posting as done, adjacent or new, and prepare one sentence for each adjacent item naming the closest thing you have actually built
- Decide which logistics are non-negotiable before the call so you can state them in one sentence rather than negotiating live
Cognitive Assessment
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
Behavioral Panel Interview
reportedRounds of this kind usually include one question about work that did not go well, and it is the part that carries the most information. Anyone can narrate a shipped win. What the interviewer learns from a project that stalled is how you behave without a result to hide behind: whether you noticed the problem yourself, how long it took, and who you told. Answers that route the failure onto a data pipeline or a reorganisation close the topic without answering it, and the follow-up comes back to your own part.
What to demonstrate
- Whether you found the error yourself or someone else found it, and how long it sat before anyone knew
- What you changed afterwards, stated as a check you now run rather than a lesson you now believe
- Whether the mistake you choose has real cost attached, such as a quarter of misdirected roadmap or a metric that was reported upward, instead of one that flatters you
How to prepare
- Choose a failure you caught yourself and be ready to say what tipped you off. A story where someone else caught it is still usable, but you will be asked why you missed it.
- Write down the check you added afterwards and where it lives now, so the correction is a concrete artefact rather than a resolution.
- Rehearse saying the cost out loud. Candidates shrink the number by instinct once the interviewer is in the room.
Technical Interview
reportedMuch of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.
What to demonstrate
- Whether the query you write matches the plan you just described
- What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
- Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly
How to prepare
- Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
- Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
- Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock
PracHub editorial advice for the preparation topics above.
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.
Sizing safety stock as z times sigma_D times the square root of lead time
That form assumes lead time is deterministic. When lead time itself varies, the standard deviation of demand over lead time is sqrt(L_bar * sigma_D^2 + D_bar^2 * sigma_L^2), and the second term dominates whenever supply is unreliable, so the familiar formula can understate the requirement severalfold for a long, variable inbound lane. Two further preconditions are routinely forgotten: demand is assumed independent across periods, which promotions and order batching break, and z maps to cycle service level (the probability of no stockout in a replenishment cycle), not to fill rate, which additionally depends on order quantity through the unit normal loss function. Quoting a z-derived number as a fill rate overstates achieved service, and the gap widens as order quantity shrinks.
Dropping rows with missing values without naming the mechanism
Say whether the values are missing at random, missing by a known process, or missing in a way that depends on the outcome, and handle them accordingly. Deleting incomplete rows silently redefines the population whenever missingness correlates with what you are measuring.
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.
Explain the mathematical difference between L1 (Lasso) and L2 (Ridge) …
Explain the mathematical difference between L1 (Lasso) and L2 (Ridge) regularization, and when you would use each.
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.
- Quantify uncertainty explicitly rather than reporting a point estimate alone.
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?
Walk me through the bias-variance tradeoff and how you diagnose overfi…
Walk me through the bias-variance tradeoff and how you diagnose overfitting in a random forest model.
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- 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.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
How do you handle highly imbalanced datasets when training a predictiv…
How do you handle highly imbalanced datasets when training a predictive classification model?
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.
- Set a baseline first, so any model has something honest to beat.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
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.
Worked solution 45 min
- Split each cell's days into censored (stockout_flag true) and uncensored, and record the censored share.
- Initialise lambda at the mean of shipped_qty over all days, which is a strict lower bound on the answer.
- Iterate the EM update using scipy.stats.poisson.sf for the survival terms, stopping when the change in lambda falls below 1e-8 or after 500 iterations.
- Assemble a per-cell frame with lambda_hat, naive_mean, censored_share, n_days and a converged flag; mark thin cells rather than fitting them.
- On the post-cutover window, compute the true mean of demand_qty per cell and report the absolute error of lambda_hat against the absolute error of naive_mean.
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?
How would you optimize a slow-performing SQL query that is scanning mi…
How would you optimize a slow-performing SQL query that is scanning millions of rows of IoT event data?
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- 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?
- How would you verify this result without re-running the same query?
Write a SQL query using window functions to find the peak utilization …
Write a SQL query using window functions to find the peak utilization hours for a specific office zone.
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- How would you verify this result without re-running the same query?
- How does the query change if the join becomes one-to-many?
Describe how you would handle duplicate records and missing timestamps…
Describe how you would handle duplicate records and missing timestamps in a raw telemetry dataset.
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Say which table is the grain you start from, and join outward from it.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
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?
Which evaluation metrics would you prioritize for a business-critical …
Which evaluation metrics would you prioritize for a business-critical demand forecasting model, and why?
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Name one primary metric, then the guardrail that stops it being gamed.
- State what result would change your recommendation, so the answer is falsifiable.
Follow-up
- Which segment would you cut first, and what would that rule out?
- How would you detect that the metric is being gamed rather than genuinely improving?
Solve spatial reasoning puzzles that require rotating or manipulating …
Solve spatial reasoning puzzles that require rotating or manipulating 3D objects mentally.
Approach
- Clarify what is being asked and what a complete answer would contain.
- Work from the decision backwards to the evidence you would need.
- State your assumptions explicitly before working the problem.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Define success for a later order cut-off at one node
A regional distribution centre wants to move its outbound order cut-off from 14:00 to 17:00 local time. You have fct_order_line (ordered_at_utc, requested_ship_date, promised_ship_date, actual_ship_at_utc, actual_delivery_at_utc, original_promised_delivery_date, line_status), fct_shipment_leg (tendered_at_utc, picked_up_at_utc, promised_delivery_at_utc, delivered_at_utc, expedite_premium_cents, accessorial_cost_cents, exception_code) and dim_location.timezone. Define the primary success metric, two guardrails, and the readout window. State any cost this schema cannot see.
Approach
- Pin the grain to the decision: the change is a local clock change, so bucket lines by the node-local order date derived from ordered_at_utc and dim_location.timezone, because raw UTC dates move every evening order across the boundary the experiment is about.
- Make perfect order rate against original_promised_delivery_date the primary, and keep same-local-day ship rate as the operational read underneath it, since a ship scan is internal effort and a delivery is what the account experiences.
- Set guardrail one on landed cost per delivered unit for outbound legs from this node, which is where a missed carrier cut-off shows up as expedite_premium_cents and accessorial_cost_cents rather than as a service miss.
- Set guardrail two on outbound on-time against promised_delivery_at_utc, split into dock dwell (tendered_at_utc to picked_up_at_utc) and transit, because a later cut-off compresses the runway before it touches transit time.
- Declare the exclusion: warehouse labour and overtime have no table in this schema, so name the cost qualitatively and name the system that would settle it, rather than implying the numbers priced it.
- Fix the window before the data: weekly by local date, a 14-day publication lag so late deliveries and damage claims land in their own period, and a two-week burn-in excluded from both arms.
Worked solution 20 min
- Derive local_order_date by converting ordered_at_utc with the timezone on ship_from_location_id, then flag each line against the old and the new cut-off time.
- Define same-local-day ship rate as lines with actual_ship_at_utc falling on local_order_date over lines flagged before cut-off, re-summing numerator and denominator for any weekly roll-up.
- Define perfect order rate at the order grain: every line shipped_full, actual_delivery_at_utc at or before original_promised_delivery_date end of local day, and no joined leg carrying exception_code in ('damage','address_issue') or leg_status in ('refused','lost').
- Define the cost guardrail as (linehaul + fuel surcharge + accessorial + expedite premium) over shipped_units on delivered outbound legs from this node, monthly by lane.
- Write the readout page: primary, two guardrails, four pre-period weeks, post-period starting at the burn-in end, and the rollback rule stated before anyone looks.
Follow-up
- Same-day ship rate improves but P90 order cycle time is flat. What happened?
- How would you detect the node simply promising later dates instead of shipping faster?
- What single reading would make you roll this back inside a week?
Forecast accuracy collapsed at nodes missing snapshot rows
WMAPE at lag 7 for one region jumped from 31 percent to 58 percent over three weeks with no model change and no retraining. fct_inventory_daily is specified to carry one row per active sku-location-date even when on_hand_qty is zero, and a release changed how the end-of-day cut-off is derived from dim_location.timezone. Using fct_inventory_daily (inventory_date, sku_id, location_id, demand_qty, forecast_qty_lag7, stockout_flag) and dim_location, decide whether demand changed or the table did, and quantify the contaminated share before anyone retrains.
Approach
- Run a completeness check before touching any accuracy number: expected rows per location per day from the active sku-location grid, against actual rows present. If the table is incomplete the accuracy question is not well posed, and this check costs one query.
- Separate the two failure modes a cut-off change produces. Rows missing entirely shrink the denominator, and the sku-days that vanish are not a random sample. Rows present but with demand pushed onto the adjacent date create a one-day shift that inflates absolute error on both days while leaving the weekly total intact.
- Test the shift hypothesis directly by comparing SUM(demand_qty) per ISO week per node before and after the release. If weekly totals match and only the daily split moved, the model is fine and the grain is broken.
- Recompute WMAPE on clean node-days only and report both figures with the excluded row count and the share of demand those rows represent, since the metric definition already requires the excluded count to travel with the number.
- Check whether the affected nodes share a timezone that crosses a daylight-saving boundary or sits far from the offset the pipeline assumed. That grouping is the discriminating evidence between a code defect and genuine demand movement.
Follow-up
- Weekly totals match and only the daily split moved. Does the ordering decision care? At what replenishment frequency does it stop mattering?
- How would you backfill the missing days, and which of them would you refuse to backfill?
- What assertion would you add to the snapshot job so this fails loudly instead of surfacing three weeks later as model drift?
For someone who has spent the last year in notebooks, dashboards or modelling work and has not written raw SQL under time pressure. The first four days rebuild query fluency against a fixture you control and can verify by hand; the last three attach that fluency to the rest of the loop.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Build a fixture you can check answers against
- Create a local Postgres or SQLite database with four tables (users, sessions, events, orders) holding roughly 200 rows you generated yourself, so you know the contents well enough to predict every result.
- Deliberately seed the cases that break queries: a user with no sessions, a session with no events, two orders sharing a timestamp, a NULL in one join key, and one duplicated user row.
- Before writing any SQL, hand-compute five answers on paper (how many users placed at least one order, median orders per ordering user, and three others) and save them as the ground truth for the week.
Deliverable: A one-command seed script plus a text file of five hand-computed answers to grade every later query against.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Joins, filters and NULL semantics
- Answer "which users have no orders" three ways (LEFT JOIN with IS NULL, NOT EXISTS, NOT IN) and confirm that the NOT IN version returns zero rows once the subquery contains a NULL, because the comparison is never TRUE.
- Reproduce the LEFT JOIN that silently collapses to an inner join by putting a right-table predicate in WHERE, then fix it by moving the predicate into the ON clause, and record both row counts.
- Create a fan-out bug on purpose by joining orders to order_items and summing the order total, then correct it with a pre-aggregated subquery and explain in one line which table changed the grain.
Deliverable: One annotated .sql file holding the three join traps, each with the wrong result and the corrected result side by side.
Practice prompt ↗Practice prompt ↗03Window functions and frames
- Write three window queries against the fixture: a running order total per user, the rank of each order within its user by value, and the day gap to that user's previous order, then check each against the day-one ground truth.
- Run ROW_NUMBER, RANK and DENSE_RANK over a column containing ties, print all three side by side, and write one sentence on when each is the correct choice.
- Switch one query from the default frame (RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, which is what you get when ORDER BY is present and no frame is written) to ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and explain why the output differs only when the ORDER BY column has duplicates.
Deliverable: Three verified window queries plus a short note explaining the RANGE versus ROWS difference in your own words.
Practice prompt ↗Practice prompt ↗04The four analytical query patterns
- Write a monthly retention grid: first order month per user, then months-since-first as the column, and verify that month zero equals the cohort size exactly.
- Sessionize the events table under a 30-minute inactivity rule using LAG plus a cumulative sum over a new-session flag.
- Build a four-step funnel that counts distinct users rather than events at each step, and state the rule you applied to a user who reaches step three without ever logging step two.
Deliverable: One file with the retention, sessionization and funnel patterns, each carrying a one-line note on the assumption it bakes in.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Write SQL the way you will have to write it live
- Set a 12-minute timer and solve three medium prompts in a plain editor with no execution and no autocomplete, then run them and tally syntax errors separately from logic errors.
- Narrate one solution aloud while writing it, stating the grain of each intermediate result (one row per user, one row per user-day) before you type its body.
- Rewrite your slowest solution as a CTE chain where every CTE name states its grain, and time yourself re-solving it from blank.
Deliverable: A recording of one narrated solution plus an error tally that separates syntax from logic.
Practice prompt ↗Practice prompt ↗06One day for everything that is not SQL
- Write the preconditions of the two-sample t-test from memory, then check them: independent observations, and a difference in means whose sampling distribution is approximately normal, which at large sample sizes follows from the central limit theorem rather than from normality of the raw values.
- Write the difference between an odds ratio from logistic regression and a relative risk, and state the condition under which the two are close (low outcome prevalence).
- Prepare a 90-second answer to "how would you know this model is any good" that names the metric, the baseline you would beat, and the cost of the errors you care about.
Deliverable: One page of notes covering test preconditions, the odds-ratio caveat and the model-quality answer.
Practice prompt ↗Practice prompt ↗07Full loop rehearsal
- Run a 45-minute mock with someone willing to interrupt: 20 minutes of SQL, 15 minutes defining a metric, 10 minutes on a past project.
- Re-solve from blank the two queries you were slowest on this week and compare the times against day five.
- Write a five-line answer to "walk me through a project" that puts a number in the first sentence and names the decision the work changed.
Deliverable: Mock feedback notes plus a timed project narrative you can deliver without reading it.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Most data work is done by groups, so an interviewer has to work out which piece was yours. An answer that runs on 'we' for several minutes gets interrupted with a question about what you personally did, and by then the answer sounds defensive even when it is true. Mark your own contribution as you go, and name the parts that belonged to someone else instead of leaving them ambiguous. Keep a few specifics back as well, like the name of the metric or who actually objected, so a probe can be answered with something you had not already said.
Describe a time when you had to explain a complex machine learning con…
Describe a time when you had to explain a complex machine learning concept to a business stakeholder who had no technical background.
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
- How did you know the outcome was caused by your change?
- What did you decide not to do, and why?
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?
Quantify your own impact on a safety stock change honestly
In March you re-sized safety stock at twelve regional DCs using the variable lead time formula. Unit fill rate at those nodes rose from 94.1 to 96.5 percent by June. In the same window a supplier that had been running 71 percent inbound on-time recovered to 93 percent, and Q2 volume is seasonally about 8 percent below Q1. Your manager asks for one sentence on impact for a performance review. Write the claim you are willing to defend under challenge, and explain how you bounded the portion attributable to your change.
Approach
- Refuse the naive claim first: the 2.4 point gross movement contains at least three generating processes, and attributing all of it is the sort of claim that collapses the moment someone plots the supplier's on-time series next to it.
- Build a comparison group from nodes that did not get the change, check that their pre-period fill rate moved in parallel with the treated nodes for at least two quarters before March, and estimate the difference in differences with variance clustered at the node, since twelve treated clusters is the effective sample size regardless of how many node-weeks there are.
- Strip the confounders you can measure directly rather than trusting the design alone: restrict to sku-location cells sourced from other suppliers to remove the recovery, and hold the sku mix fixed across periods so the seasonal volume drop does not enter through mix.
- Sanity-check the mechanism, not just the coefficient: if your change worked, the improvement should concentrate in cells whose reorder point rose and in short_reason_code = 'no_stock' lines, and should be absent where the policy did not move. If the gain is spread evenly, something else caused it.
- State the result as an interval with the confounders named, and state the cost side too: extra units held at the applicable cost of capital, so the claim is a net one rather than a service headline.
- Write the sentence so that it survives someone else re-running it, which usually means a smaller number than the gross movement and a named method.
Follow-up
- The comparison nodes are not parallel in the pre-period. What do you do next?
- Your bounded estimate is roughly half the gross movement. How do you present that to a manager who already told his boss the larger number?
- 01
Describe a time when you had to explain a complex machine learning concept to a business stakeholder who had no technical background.
- 02
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.
- 03
In March you re-sized safety stock at twelve regional DCs using the variable lead time formula. Unit fill rate at those nodes rose from 94.1 to 96.5 percent by June. In the same window a supplier that had been running 71 percent inbound on-time recovered to 93 percent, and Q2 volume is seasonally about 8 percent below Q1. Your manager asks for one sentence on impact for a performance review. Write the claim you are willing to defend under challenge, and explain how you bounded the portion attributable to your change.
Is this an official Steelcase interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Steelcase. Rounds and questions reflect what candidates have reported, not a process Steelcase has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the interview process at Steelcase?
Candidates generally rate the process as average to difficult. While the behavioral rounds are friendly and conversational, the online cognitive assessment and the final technical interview are highly rigorous and require thorough preparation.
PracHub interview research ↗What is the online cognitive assessment like?
It is a highly structured, timed test similar to an IQ or cognitive ability test. It features around 41 questions focusing on pattern recognition, logical deduction, and spatial reasoning. It is designed to test how quickly and accurately you can process abstract information.
PracHub interview research ↗Is there a live coding portion during the technical interview?
Unlike many software-heavy companies, Steelcase often conducts a technical round that is more conceptual and academic rather than forcing you to write code in front of an interviewer. However, you must still be prepared to discuss SQL syntax and explain the exact logic of your algorithms.
PracHub interview research ↗What is the culture and working style like at Steelcase?
Steelcase has a highly collaborative, supportive, and design-oriented culture. Employees often praise the friendly work environment, the emphasis on work-life balance, and the beautifully designed corporate campus in Grand Rapids, MI, which serves as a living laboratory for their workspace research.
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