At Wayfair, data is not just an asset—it is the engine that powers every aspect of the e-commerce experience. As a Data Scientist, you will operate at the intersection of technology, machine learning, and business strategy. Your work will directly impact millions of active customers and influence how billions of dollars in inventory move across a global supply chain. You will be responsible for translating complex, high-dimensional data into actionable algorithms that drive real-time decision-making.
The scope of a Data Scientist at Wayfair is incredibly diverse, spanning several specialized domains. You might find yourself optimizing dynamic pricing engines, developing advanced recommendation systems to personalize the customer storefront, building predictive models for logistics and supply chain routing, or designing sophisticated bidding algorithms for marketing channels. Because Wayfair operates at an immense scale, the models you build must be robust, scalable, and highly performant.
What makes this role uniquely challenging and rewarding is the direct line of sight between your models and business outcomes. You will not build models in a vacuum. Instead, you will work closely with product managers, engineers, and business leaders to deploy your solutions, measure their impact through rigorous experimentation, and iterate rapidly. Success in this role requires not only deep technical expertise but also strong business acumen and the ability to navigate ambiguity.
Online Assessment
reportedA handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.
What to demonstrate
- Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
- Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
- Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.
How to prepare
- Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
- Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
- If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
Recruiter Screen
reportedMost candidates lose this call inside the first two minutes, during the walkthrough of their own background. The account runs chronologically, sits at the level of tools and titles, and never arrives at a decision anyone could have disagreed with. Anchor on a problem instead of a timeline: what the team could not answer, what you did about it, what happened next. Ninety seconds is enough, and stopping on time leaves room for the half of the call that belongs to you. What you ask about how work gets prioritised signals your level more reliably than the walkthrough does.
What to demonstrate
- Whether your background summary has a shape (problem, decision, consequence) or is a chronological list of tools and employers
- Whether you can account for gaps, short stints and the reason you are looking, unprompted and without hedging
- The substance of the questions you ask back, which an experienced screener reads as a level signal
How to prepare
- Time your opening walkthrough against a clock. If it runs past two minutes, compress the earliest role into a single clause and spend the recovered time on the most recent one
- Write one honest sentence for every gap or short stint visible on your resume and offer it before being asked about it
- Prepare questions about how work arrives and gets prioritised: who writes the request, how often priorities change, and what happens to an analysis after it is delivered
Technical Interviews
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
Final Round
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
3 candidate reports. Individual accounts describe a particular role and hiring cycle.
Wayfair Applied Scientist Interview Experience — Product Judgment and a Changed Role
The author describes a Wayfair machine-learning scientist interview beginning with an advertising-bidding case. Virtual-onsite exercises covered homepage module ranking, recommendations sent after a purchase, an AI-assisted bandit simulation, and behavioral questions. The coding session permitted AI tools and web searches with screen sharing, but follow-ups required explanations of bandit strateg…
Read full experienceWayfair Software Engineer Interview Experience — Four-Round Virtual Onsite Rejection
Behavioral round: standard behavioral questions and conversation. Coding: simple coding with no algorithms involved. Calculate moving costs for different items based on their volume and category. The follow-up was how I would implement this in production. I talked about turning it into classes and then discussed object-oriented design. System design: design Shazam, a system that identifies a song…
Read full experienceWayfair Software Engineer Interview Experience: A difficult HackerRank assessment
I started with a straightforward recruiter call about my background. Soon after, I took a HackerRank coding assessment. It ran about 75 to 90 minutes and had two medium-style questions, closer to LeetCode data structures and algorithms than anything company-specific. One problem involved string and array manipulation. The other relied on hash-map thinking and edge-case handling. The difficulty fe…
Read full experiencePracHub editorial advice for the preparation topics above.
Reading revenue or cohort value before the return window closes
Returns arrive days to weeks after delivery and vary enormously by category, so a two-week-old cohort reported on gross revenue is being compared with a mature cohort reported on something close to net. In apparel the gap between the two definitions is routinely twenty to forty percent of gross, more than the effect size of almost any experiment or campaign being evaluated. Attribute refunds back to the parent order's placed date rather than the refund date, hold the reporting lag at the 95th-percentile return-initiation lag for the category, and never let a fresh cohort's gross number sit in the same table as a mature cohort's net number.
Fitting demand models on sales when sales are censored by availability
Units sold equal the minimum of demand and what was sellable, so every day a SKU was out of stock contributes a zero that looks identical to genuine indifference. A model trained on that history forecasts the stockout, the buy shrinks, availability falls further, and the error compounds each cycle, which is why a declining SKU forecast should always be checked against minutes_unavailable before it is believed. The fixes are to restrict the fit to in-stock periods, to model availability explicitly as an exposure term, or to use a censored likelihood; all three require the availability history to be retained at a finer grain than a daily end-of-day snapshot, which is exactly what teams tend to discard.
Stopping an experiment the moment it crosses significance
Fix the sample size or duration before launch, or use a method built for continuous monitoring such as a sequential test, always-valid confidence intervals, or group-sequential boundaries. Repeatedly checking a fixed-horizon p-value against 0.05 pushes the real false-positive rate well above 5 percent.
Accepting a metric definition without asking about the denominator
Pin down the denominator, the eligibility filter and the time window before computing anything: conversion rate per session, per user, per eligible user and per new user are four different numbers with different behaviour. Restate the definition in one sentence and get agreement before you analyse.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
What are the pros and cons of using collaborative filtering versus con…
What are the pros and cons of using collaborative filtering versus content-based filtering for product recommendations on Wayfair's homepage?
Approach
- Sanity-check the answer against a simple bound or a simulated case.
- Quantify uncertainty explicitly rather than reporting a point estimate alone.
- Write down the assumption the method needs before you use the method.
Follow-up
- What sample size would you need to detect an effect half this size?
- How would you explain this result to someone who does not know statistics?
How do you address class imbalance when training a binary classificati…
How do you address class imbalance when training a binary classification model for fraud detection? Which evaluation metrics would you prioritize?
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.
- 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?
- Where could label leakage enter this setup?
Net revenue per order without fanning out return rows
You get two DataFrames. order_lines has order_line_id, order_id, customer_id, quantity, unit_paid_price_cents, line_status, delivered_at_utc. return_lines has return_line_id, order_line_id, quantity_returned, refund_amount_cents, initiated_at_utc. One order line can have several return rows. Produce one row per order_id with gross_cents over delivered lines only, refund_cents from returns initiated within 90 days of that line's delivery, net_cents, and units_kept. The output must have exactly one row per order_id, and gross_cents must equal a total you compute without ever touching return_lines.
Approach
- Filter order_lines to line_status == 'delivered' first, and compute gross_cents = quantity * unit_paid_price_cents per line. Keep that per-line frame as the control total before any merge.
- Aggregate return_lines to one row per order_line_id with groupby('order_line_id').agg(sum of quantity_returned, sum of refund_amount_cents, min of initiated_at_utc) so the right side of the join is unique on the join key.
- Because the 90-day window is per return row, not per order line, apply the window before aggregating: join initiated_at_utc against the parent line's delivered_at_utc, keep rows inside the window, then aggregate. Doing it after aggregation loses the individual initiation dates.
- Left merge the aggregated returns onto the delivered lines with validate='m:1' so pandas raises instead of silently duplicating, then fillna(0) on the refund and quantity columns.
- Group to order_id, sum gross_cents, refund_cents, and units_kept = quantity - quantity_returned, and assert the gross total equals the control total computed in step one.
Worked solution 25 min
- Build a fixture where order 1 has one line of quantity 3 at 2000 cents with two return rows (1 unit refunded 2000, then 1 unit refunded 2000), and order 2 has one clean delivered line of quantity 1 at 5000 cents.
- Compute control_gross = 32000 + 15000 = 11000 from order_lines alone.
- Run the naive merge first and print the gross sum: it reports 17000, because the three-unit line appears twice.
- Run the pre-aggregated version and confirm total gross 11000, total refund 4000, total net 7000, and for order 1 specifically gross 6000, refund 4000, units_kept 1.
- Add an assertion that result.index.is_unique and result['gross_cents'].sum() == control_gross.
Follow-up
- The order line was paid in a non-USD currency with fx_rate_to_usd on the line. Where does the conversion belong, and what breaks if you convert after aggregating to order grain?
- Refunds arrive weeks after the order. Which date do you attribute refund_cents to when you report a monthly net revenue series, and why does the answer change how long you must hold the report back?
- How would the query change if a partial return could be refunded in two instalments under the same rma_id?
Write a SQL query to calculate the month-over-month retention rate of …
Write a SQL query to calculate the month-over-month retention rate of customers who made their first purchase in a specific category.
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.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
Follow-up
- How does the query change if the join becomes one-to-many?
- What breaks if events arrive late or out of order?
How would you handle missing values and outliers in a highly skewed pr…
How would you handle missing values and outliers in a highly skewed pricing dataset using Python?
Approach
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- 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 query to find the top three highest-selling products in each s…
Write a query to find the top three highest-selling products in each sub-category for the past quarter, handling ties appropriately.
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 would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Daily visit-to-order conversion by device, excluding denied-consent sessions
From fct_session (session_id, started_at_utc, device_type, entry_channel, order_id, tracking_consent, is_bot_flagged), return visit-to-order conversion for the last 28 days split by device_type and entry_channel. A session converts when order_id IS NOT NULL. Exclude is_bot_flagged = TRUE, and exclude tracking_consent = 'denied' from both numerator and denominator, reporting the denied share of non-bot sessions as its own column. Then produce the weekly figure from the same base. Output: day or week, device_type, entry_channel, sessions, orders, conversion_rate, denied_share.
Approach
- Filter once in a base CTE (is_bot_flagged = FALSE, started_at_utc in the window) and carry tracking_consent through, so the numerator and denominator can never drift apart in two separate scans.
- Aggregate with conditional counts in a single pass: COUNT(*) FILTER (WHERE tracking_consent <> 'denied') as sessions, and the same filter plus order_id IS NOT NULL as orders.
- Divide at the end with a NULLIF on the denominator and a numeric cast, because integer division floors a 2 percent rate to 0.
- For the weekly number, group the same base on date_trunc('week', started_at_utc) and re-divide the summed counts; an average of seven daily rates weights a quiet Tuesday the same as a peak Saturday.
- Emit denied_share = denied sessions / all non-bot sessions beside the rate, so a consent-banner change that moves the denominator is visible rather than being read as a behaviour change.
Worked solution 20 min
- Write the base CTE with the bot filter and the date window, selecting session_id, started_at_utc, device_type, entry_channel, order_id, tracking_consent.
- Add the grouped aggregate with FILTER clauses for sessions, orders and denied sessions.
- Compute conversion_rate = orders::numeric / NULLIF(sessions, 0) and denied_share = denied::numeric / NULLIF(sessions + denied, 0).
- Duplicate the aggregate with date_trunc('week', started_at_utc) as the grain and confirm the weekly rate is derived from summed counts.
- Compute both weekly figures side by side and the covariance between daily sessions and daily rate, so the size of the gap is a measured number rather than an assumption.
- Spot-check one device and channel by hand for a single day against a raw COUNT.
Follow-up
- Denied-consent sessions can still place orders. What does excluding them do when you reconcile session-attributed orders against total orders in fct_order_line, and how do you present that gap?
- Conversion rose on desktop and rose on mobile_web, but the blended rate fell. What happened, and what would you show to make it obvious?
- How would you handle a session that starts at 23:55 and places its order at 00:04 the next day?
How do you prioritize your work when you are flooded with requests fro…
How do you prioritize your work when you are flooded with requests from multiple product and business teams?
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- 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.
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?
We are considering a new promotional pricing strategy for outdoor furn…
We are considering a new promotional pricing strategy for outdoor furniture. How would you design an A/B test to measure its impact on net revenue and profit margin?
Approach
- Name the guardrails that would stop a launch even on a positive primary result.
- Name the randomisation unit first; it decides the variance and what the test can detect.
- State the primary metric and the minimum effect worth shipping, then size the test.
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?
If an A/B test shows a statistically significant increase in conversio…
If an A/B test shows a statistically significant increase in conversion rate but a decrease in average order value (AOV), how would you decide whether to roll out the feature?
Approach
- State the primary metric and the minimum effect worth shipping, then size the test.
- Decide the analysis before seeing data, including how long it runs and when you look.
- Name the randomisation unit first; it decides the variance and what the test can detect.
Follow-up
- What would you do if you could not randomise at all?
- How would you handle interference between treated and control units?
A ranking test that starves its own control arm
A ranking change promotes high-margin SKUs that have low days_of_cover in fct_inventory_snapshot. In a 50/50 visitor-level test, treatment converts 6 percent better. Inventory is pooled across arms: available_to_promise_units is shared at the node, so demand created by treatment raises minutes_unavailable and units_cancelled_oos for control visitors too. Explain why the 6 percent is biased and in which direction, name the evidence in fct_inventory_snapshot and fct_order_line that would confirm it, and design a version of the test whose estimate is not contaminated. State the analysis unit and what it costs.
Approach
- Name the SUTVA violation precisely: a control visitor's outcome depends on treatment assignment of other visitors through the shared inventory pool, so the estimate is not the effect of the ranking change but the effect of the change plus the damage it does to the comparison group.
- Fix the sign. Treatment depletes stock of the SKUs it promotes, control then sees those SKUs unavailable and converts worse than it would under full control, so the measured contrast overstates the true effect. A rollout to 100 percent removes the starved comparison and the lift shrinks.
- Gather the evidence rather than asserting it: join fct_inventory_snapshot on the promoted SKU set and compare minutes_unavailable and units_cancelled_oos against the pre-period, and check whether control-arm conversion fell relative to its own pre-period rather than only against treatment. Check whether the lift concentrates in SKUs with low days_of_cover.
- Redesign. The cheapest option restricts the promoted set to SKUs with days_of_cover above a threshold, which removes the interference but also removes the case the change was built for. Cluster randomisation on fulfilment node or market works only where inventory pools are genuinely node-partitioned and orders are node-local, which the fct_order_line to fct_inventory_snapshot join on (node_id, sku_id, snapshot_date) lets you verify.
- Where the pool cannot be partitioned, use a switchback: apply one ranking to all traffic in randomised time blocks. Both arms then face the same inventory state within a block. Price it honestly: the analysis unit becomes the block, not the session, and the sample size collapses to the number of blocks.
Worked solution 40 min
- Quantify the interference: for the promoted SKU set, compute the change in SUM(minutes_unavailable) and units_cancelled_oos during the test relative to a matched pre-period, per node.
- Split the treatment effect by days_of_cover decile; a lift concentrated in the lowest deciles is the signature of a starved control rather than a better ranking.
- Design a switchback over 14 days with four six-hour blocks a day, randomising the ranking per block, giving 56 blocks and 28 per arm.
- Compute the block-level MDE: with a between-block coefficient of variation of 12 percent on conversion, MDE_rel = 2.8016 * 0.12 * sqrt(2/28) = 0.090.
- Discard the first 30 minutes of each block as burn-in for in-flight sessions and cluster the standard errors on block, or use randomisation inference over the block assignment.
Follow-up
- Inventory depletes from one block into the next. How long would you make a block, what burn-in would you discard, and what does carryover do to the estimate?
- If you cluster on fulfilment node, how would you check that orders are actually node-local before trusting the design?
Down nine percent against a week that is not comparable
The weekly business review shows merchandise revenue down 9% against the same calendar week last year, and the merchandising lead is proposing an unplanned markdown on the back of it. You have fct_order_line (placed_at_utc, placed_at_local, promotion_id, line_discount_cents, quantity, unit_paid_price_cents, currency_code, fx_rate_to_usd) and dim_customer (billing_country_code). Deliverable: state whether the published comparison is interpretable as it stands, produce the comparison you would defend instead, and quantify how much of the 9% survives it.
Approach
- Establish the calendar the business actually plans on. Retail planning runs on a 4-5-4 fiscal calendar, so map both weeks to fiscal week numbers, and check whether a 53-week fiscal year sits between them, which shifts every subsequent week by one against the Gregorian date.
- Align the promotional calendar, not just the dates. Pull promotion_id activity and weekly promotional depth (line_discount_cents over quantity * unit_list_price_cents) for both years and locate each event. Compare week-before-event, event week and week-after rather than date to date.
- Account for moving holidays per market using placed_at_local and billing_country_code, because an event that moves one week in one country and not another makes a blended comparison uninterpretable in both directions.
- When the weeks cannot be aligned one to one, widen to a window that fully contains the event in both years, typically three or four weeks, and compare the window totals in constant currency. State the window in the headline so nobody re-cuts it to a single week.
- Only on the aligned residual, decompose into traffic, conversion, units per order, price per unit and keep-rate, and say which of those, if any, justifies a markdown.
Follow-up
- The fiscal calendar aligns the weeks but the event still straddles a boundary. What do you publish?
- How would you quantify pull-forward from last year's event so the week after it is not read as a collapse?
- The markdown is proposed anyway. What evidence would change your recommendation from no to yes?
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.
Nearly every data role forces a trade between the analysis you want and the one that fits the decision window. Prepare a case where you deliberately shipped something less rigorous, named the weakness to the person relying on it, and said what would change your answer. The naming is the part interviewers listen for.
Describe a time when you had to explain a highly complex technical con…
Describe a time when you had to explain a highly complex technical concept or model to a non-technical business stakeholder. How did you ensure they understood?
Approach
- Close with what you would do differently, concretely.
- State the situation in two sentences and spend the rest on your reasoning.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- What would you do differently if you ran that project again?
- What did you decide not to do, and why?
Explain a forecast interval to an executive placing a buy
You forecast season demand for a style with a twelve-week lead time. The point forecast is 40,000 units and your eighty percent interval runs 26,000 to 61,000. The executive placing the purchase order asks for one number and says intervals are not actionable. Unsold units are marked down at end of season. A stockout loses the sale and censors the demand history you will forecast on next year. In four minutes, with no slides, give the executive a buy quantity and explain the uncertainty in terms they can act on.
Approach
- Name a quantity first, then explain it. Refusing to give a number reads as evasion, and the buy gets placed anyway without your input in it.
- Translate the interval into the decision. One unit too many costs the markdown loss; one unit too few costs the lost contribution plus the censoring it writes into next year's history. Those costs are not equal, so the right order quantity is not the median of the forecast.
- State the critical ratio rather than asserting a quantile: order the q-quantile of the demand distribution where q = Cu / (Cu + Co), Cu being contribution lost per unit short and Co being unit cost minus salvage recovery per unsold unit. This holds for a single ordering opportunity with no mid-season replenishment and a known salvage value.
- Express the remaining uncertainty as consequences rather than as a range: at your recommended quantity, the probability of selling out before end of season and the expected markdown units if demand lands near the top of the interval.
- Offer the lever that actually shrinks the interval: a smaller initial buy with an in-season reorder if any supplier lead time allows it, or a first-two-weeks sell-through read that updates the quantity before the second tranche.
- Agree what goes in writing: the number, the quantile it corresponds to, and the two per-unit costs it depends on, so the number survives being repeated without you.
Follow-up
- What evidence would make you raise the number, and how quickly could you get it?
- Supply offers a second buy at week six with a shorter lead time but ten percent higher unit cost. How does that change your recommendation?
State the impact of your model without overclaiming
Writing your own review, you want to claim the reorder model you shipped in February. Since launch, demand-weighted in-stock rate on covered categories rose from ninety-one to ninety-five percent and net merchandise revenue on them is up eight percent year over year. In the same window a supplier consolidation shortened lead times, two categories were re-merchandised, and the fiscal calendar shifted the promotional week. Nobody will check your number. Write the impact claim you would actually put in the document, and explain what you did to earn the right to it.
Approach
- Decide what is attributable before deciding what is impressive. Three known changes move the same metrics in the same direction, so the year-over-year revenue figure is an upper bound rather than an estimate of your effect.
- Find the cleanest contrast still available after the fact: categories the model covers against comparable uncovered ones over the same weeks. That is a difference-in-differences read, its identifying assumption is parallel pre-trends, so show the pre-period rather than assert it.
- Claim the mechanism you can trace end to end. The model changed reorder points, reorder points changed minutes_unavailable, availability changed units sold. Each link is measurable, and a confounder has to break a specific one of them.
- Lead with the in-stock movement and put revenue second, because availability is closest to the thing you changed and hardest for the supplier consolidation to explain away.
- Write the confounders into the claim instead of omitting them. A claim that survives a reader naming the consolidation is worth more than a larger one you retract when they do.
- State the counterfactual you cannot rule out, and the design you would run next time to rule it out.
Follow-up
- Your manager wants one number for the promotion packet. Which one, and what sentence goes with it?
- A peer claims the same revenue for the re-merchandising work. How do you resolve that without both of you shrinking your claims to nothing?
- 01
Describe a time when you had to explain a highly complex technical concept or model to a non-technical business stakeholder. How did you ensure they understood?
- 02
You forecast season demand for a style with a twelve-week lead time. The point forecast is 40,000 units and your eighty percent interval runs 26,000 to 61,000. The executive placing the purchase order asks for one number and says intervals are not actionable. Unsold units are marked down at end of season. A stockout loses the sale and censors the demand history you will forecast on next year. In four minutes, with no slides, give the executive a buy quantity and explain the uncertainty in terms they can act on.
- 03
Writing your own review, you want to claim the reorder model you shipped in February. Since launch, demand-weighted in-stock rate on covered categories rose from ninety-one to ninety-five percent and net merchandise revenue on them is up eight percent year over year. In the same window a supplier consolidation shortened lead times, two categories were re-merchandised, and the fiscal calendar shifted the promotional week. Nobody will check your number. Write the impact claim you would actually put in the document, and explain what you did to earn the right to it.
Is this an official Wayfair interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Wayfair. Rounds and questions reflect what candidates have reported, not a process Wayfair has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How technical is the online assessment, and what should I focus on?
The HackerRank assessment is highly technical and contains a mix of SQL, Python (using Pandas), and multiple-choice questions on statistics and machine learning. You should focus on speed and accuracy. Practice intermediate to advanced SQL (joins, window functions, group by) and standard Pandas operations like merging, filtering, and aggregating.
PracHub interview research ↗How much business knowledge do I need for the case study rounds?
You need a strong grasp of basic business and e-commerce metrics. You should understand concepts like revenue, gross margin, contribution margin, customer acquisition cost (CAC), and customer lifetime value (LTV). You must be able to think critically about how a technical model or product change affects these financial metrics.
PracHub interview research ↗What is the culture like for Data Scientists at Wayfair?
The culture is highly data-driven, collaborative, and fast-paced. There is a strong emphasis on ownership; data scientists are expected to drive projects from ideation to production. It is an environment where scientific rigor is highly valued, but speed-to-market and business impact are equally prioritized.
PracHub interview research ↗How long does the entire interview process take?
The process typically takes between 3 to 6 weeks from the initial HackerRank assessment to the final decision. However, this can vary based on candidate availability, team alignment, and hiring volume.
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