As a Data Scientist at Gopuff, you sit at the intersection of rapid hyper-local logistics, real-time consumer demand, and predictive machine learning. This role is pivotal for driving the core operational and product mechanics of an instant e-commerce platform that warehouses and delivers thousands of everyday items in minutes. Whether you are optimizing dispatch algorithms, refining ETA prediction models, or designing causal inference frameworks for driver pricing and incentives, your work directly shapes the day-to-day experience of millions of consumers and delivery partners.
The problems you tackle are characterized by immense scale, physical-world constraints, and high velocity. You will collaborate closely with product managers, software engineers, and operations leaders to translate ambiguous business challenges into robust, production-ready data science solutions. From forecasting granular inventory demands across micro-fulfillment centers to modeling complex supply-chain dynamics, your insights and models dictate how efficiently Gopuff operates in a fast-paced market.
Success in this position requires a rare blend of deep technical rigor, practical business intuition, and relentless ownership. You must be comfortable building systems from scratch, rigorously validating them through experimentation, and explaining complex model performance to cross-functional stakeholders. If you thrive in fast-moving environments where your code and algorithms have an immediate, tangible impact on physical deliveries, this role offers an unmatched platform for professional growth.
Initial Screening
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
Technical 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
Behavioral Interview
reportedMost of the weight in this round sits on the disagreement questions. Data work routinely produces an answer someone senior did not want, and the interviewer is trying to learn what you do in that hour. Both failure modes are common: folding as soon as a director pushes back, and treating the pushback as ignorance to be corrected with a better chart. A strong answer usually contains a specific thing the other person knew that you did not, and describes how you found out whether it changed the conclusion.
What to demonstrate
- Whether you can state the other side's argument accurately before you explain why you disagreed
- What you treated as evidence during the disagreement, such as a rerun under their assumption or a holdout check, rather than persuasion technique
- Whether you distinguish being overruled from being wrong, and can give an example of each
How to prepare
- Write out one disagreement where you turned out to be wrong, and say what in the data misled you. Candidates prepare the story where they were right, and the follow-up asks for the other one.
- For your main disagreement story, be ready to say what result would have made you drop your position. If no such result exists, you were not arguing from the data.
- Practise stating the opposing position out loud in one sentence the stakeholder would accept, then continue the story.
PracHub editorial advice for the preparation topics above.
Randomising individual consumers when supply is shared
A feature that makes treatment consumers book faster consumes the same idle providers the control consumers would have used, so the control group is degraded by the treatment and the measured lift overstates the market-level effect. The bias is largest precisely when supply is tight, which is when the feature is supposed to help, so the experiment is most misleading exactly where the decision matters. The fix is randomising the market or the time block (switchback) and clustering the variance at the randomisation unit, accepting far fewer effective units.
Denominator drift in per-active-user metrics
Orders per active consumer falls when acquisition succeeds, because new cohorts transact less than tenured ones, so the metric penalises the thing the company is trying to do. A team that optimises it will quietly prefer weaker acquisition. Decompose into cohort size times cohort frequency, or hold the cohort fixed and read frequency by tenure bucket, before drawing any conclusion about engagement.
Interpreting a change before checking data quality and logging
Spend the first pass on row volume by day, null rates, duplicate keys, and whether the step change lands on a release or tracking-migration date. A discontinuity that coincides with a deploy is an instrumentation hypothesis before it is a behavioural one.
Treating a non-significant result as proof of no effect
Say whether the confidence interval excludes the effect sizes you would have cared about. If it does not, the honest reading is that the test was underpowered, so report the minimum detectable effect the design could have found and what sample size would resolve it.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Explain how you account for seasonality and time-of-day trends when bu…
Explain how you account for seasonality and time-of-day trends when building regression models for inventory forecasting.
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Check what information would not exist at prediction time, and exclude it.
- Set a baseline first, so any model has something honest to beat.
Follow-up
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
Simulate dispatch cascades and the censoring of wait time
A request is offered to one provider at a time. Each offer resolves 12 seconds after it is sent, and each provider accepts independently with probability 0.55. After six declines the request is marked no_supply. Independently, the consumer abandons at time A drawn from an Exponential distribution with mean 90 seconds; abandonment before a pending offer resolves ends the request unmatched. Simulate 200,000 requests and report: the share matched, the mean time-to-match over matched requests, and the mean over requests that would have matched with abandonment switched off. Give a Monte Carlo standard error for the share.
Approach
- Vectorise the cascade: draw K with np.random.default_rng().geometric(0.55), mark K > 6 as no_supply, and draw A = rng.exponential(90) independently; the match condition is K <= 6 and A > 12*K. Looping request by request is the difference between two seconds and two minutes of runtime.
- Compute both means on the same draws so the comparison is paired and the difference is not itself a Monte Carlo artefact.
- Recognise the structure driving the answer: abandonment censors long cascades harder than short ones, so conditioning on matched requests is not a neutral filter, it is a filter correlated with the quantity being measured.
- Quote the share to three decimals only: the standard error of a proportion is sqrt(p(1-p)/n), roughly 0.0009 at n = 200,000, so further digits are noise.
- Check against the closed form P(match) = sum over k of 0.45^(k-1) * 0.55 * exp(-12k/90) for k = 1..6; a simulation with no analytical check is an untested function.
Worked solution 30 min
- k = rng.geometric(0.55, size=200_000); a = rng.exponential(90.0, size=200_000); t = 12.0 * k.
- supplied = k <= 6; matched = supplied & (a > t).
- share = matched.mean(); se = sqrt(share * (1 - share) / 200_000).
- observed_mean = t[matched].mean(); latent_mean = t[supplied].mean().
- Compare share against the closed form 0.7911 and print the gap in standard errors.
Follow-up
- A change ships that makes consumers abandon sooner. What happens to your reported mean time-to-match, and how would you report latency so that this cannot look like a win?
- How would you estimate the same quantity from production data, where you never observe the latent match time of an abandoned request?
Audit supply-session integrity without shrinking the frame
You are given sessions: session_id, provider_id, market_id, online_at_utc, offline_at_utc (NaT while open), online_seconds, engaged_seconds, en_route_seconds, idle_seconds, offers_received, offers_accepted, orders_completed, end_reason. Write audit(sessions) returning one row per rule with the rule name, violation count, violation share and up to five example session_ids. Cover at least: engaged + en_route + idle not equal to online_seconds; for closed sessions, online_seconds disagreeing with offline_at minus online_at by more than 2 seconds; offers_accepted greater than offers_received or orders_completed greater than offers_accepted; two overlapping sessions for the same provider; offline_at_utc NaT while end_reason is not 'session_still_open'.
Approach
- Express every rule as a boolean Series over the whole frame rather than as a filtered sub-frame, so all rules share one denominator and can be combined or counted together afterwards.
- Apply the duration rule only to closed sessions and keep the 2-second tolerance as a named constant in the output, since clock rounding is a real effect and hiding the tolerance makes the report unreproducible.
- Detect overlaps in one sort: order by (provider_id, online_at_utc), fill NaT offline times with a far-future sentinel, take a per-provider shifted cumulative max of offline_at_utc, and flag rows whose online_at_utc is strictly less than it. That is O(n log n) and needs no self-join.
- Emit rules with zero violations as explicit rows, so a rule that passed is distinguishable from a rule that never ran.
- Keep impossible values and merely suspicious ones in separate rows with the threshold stated: a 30-hour online session breaks no invariant but belongs in the same report.
Follow-up
- One rule fires on 0.4% of rows, all in a single market. How would you decide between an ingestion bug and genuine provider behaviour?
- Which of these rules would you make a blocking pipeline test, and which only a monitored alert, and what distinguishes the two?
Write a SQL query using SQL window functions to calculate the running …
Write a SQL query using SQL window functions to calculate the running 7-day average delivery time per fulfillment center.
Approach
- 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.
- 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?
Given a table of user orders, how would you write a query to identify …
Given a table of user orders, how would you write a query to identify repeat customers who order within 48 hours of their previous transaction?
Approach
- 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.
- 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?
Contribution margin per completed order without ledger fan-out
fct_order has order_id, market_id, order_status, completed_at_utc, gross_booking_cents, provider_payout_cents, consumer_incentive_cents, provider_incentive_cents, tip_cents. fct_money_movement has ledger_id, order_id, entry_type, amount_cents (signed, positive into the platform), currency_code, fx_rate_to_usd, posted_at_utc, settlement_status. Per market per completion month, report net take, ledger cost from entry_type IN ('processing_fee','refund','chargeback') with settlement_status NOT IN ('failed','reversed'), and contribution margin per completed order, all in USD cents. Attribute every ledger entry to the order's completion month, not its posting month.
Approach
- Aggregate fct_money_movement to one row per order_id in a CTE before touching fct_order, converting inside the SUM as amount_cents * fx_rate_to_usd. Joining the order table to the ledger first multiplies gross_booking_cents by the number of ledger rows on that order, which is routinely four to eight.
- Exclude entry_type 'charge' and 'payout' from the ledger side. The consumer charge is already gross_booking_cents and the payout is already provider_payout_cents, so including them counts both sides twice with opposite signs and moves the margin by an amount that looks plausible.
- Keep the signs. Entries are positive into the platform, so refunds, chargebacks and processing fees arrive negative. Add the ledger sum to net take rather than subtracting it, or the sign flips twice and costs are booked as revenue.
- Compute net take from the order columns as gross_booking_cents minus provider_payout_cents minus consumer_incentive_cents minus provider_incentive_cents. Exclude tip_cents from both sides because it passes through to the provider.
- Group by market_id and date_trunc('month', completed_at_utc) with order_status = 'completed', then divide by COUNT(*) of those orders. Attributing on completion month rather than posting month is what stops a slow chargeback from flattering the month that earned it.
Worked solution 30 min
- Run SELECT order_id, COUNT(*) FROM fct_money_movement GROUP BY 1 and look at the distribution; the maximum tells you the size of the fan-out you are avoiding.
- Build the per-order ledger CTE and assert it returns exactly one row per order_id present in the ledger.
- LEFT JOIN it onto fct_order so orders with no ledger entries survive with a COALESCE'd zero rather than disappearing.
- Aggregate to market by completion month, divide by the completed order count, and compare that count to an unjoined count over the same filter.
Follow-up
- A chargeback posts 80 days after completion. What does that do to a margin number published 30 days after month end, and how do you present the number so it is not read as final?
- fx_rate_to_usd is the rate at posting time, not at completion. In which markets and at what volatility does that choice change the decision?
How would you measure the success and potential cannibalization of int…
How would you measure the success and potential cannibalization of introducing a new membership tier?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- State what result would change your recommendation, so the answer is falsifiable.
- 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 do you prioritize competing projects when multiple engineering and…
How do you prioritize competing projects when multiple engineering and product teams request your analytical support?
Approach
- Fix the population and the time window before naming any metric.
- 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
- How would you detect that the metric is being gamed rather than genuinely improving?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How would you design a metric to measure the reliability of our instan…
How would you design a metric to measure the reliability of our instant delivery promise?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- 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.
Follow-up
- Which segment would you cut first, and what would that rule out?
- What would you do if the primary metric and the guardrail moved in opposite directions?
A key engagement metric dropped by 10 percent week-over-week. Walk me …
A key engagement metric dropped by 10 percent week-over-week. Walk me through your framework for diagnosing this drop.
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- State what result would change your recommendation, so the answer is falsifiable.
- Fix the population and the time window before naming any metric.
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?
How do you determine statistical significance and sample size when you…
How do you determine statistical significance and sample size when you have high variance in user order frequency?
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.
- State the primary metric and the minimum effect worth shipping, then size the test.
Follow-up
- What would you conclude if the result is positive but the test is underpowered?
- What would you do if you could not randomise at all?
Can you explain a time when an A/B test result contradicted overall bu…
Can you explain a time when an A/B test result contradicted overall business intuition, and how you investigated it?
Approach
- 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.
- Say whether units interfere with each other, and switch design if they do.
Follow-up
- How would you handle interference between treated and control units?
- What would you do if you could not randomise at all?
What framework would you use to evaluate whether to expand instant del…
What framework would you use to evaluate whether to expand instant delivery to a new geographic zone?
Approach
- Clarify what is being asked and what a complete answer would contain.
- Work from the decision backwards to the evidence you would need.
- Say what you would check first and why it is the highest-information step.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Estimate a single-market fee change without a control group
Regulation forces one market to cut its service fee on a known date. Randomisation is impossible and only that market is affected. You have 52 weeks of pre-period weekly series for every market: completed orders, active consumers, SLA fill rate, provider online hours and net take rate. Estimate the effect on completed orders per active consumer over the 12 weeks after the change. Specify the estimator, the donor pool and its exclusions, the pre-period fit criterion you would accept, and how you would produce a p-value with exactly one treated unit.
Approach
- Choose synthetic control as the estimator. Fit non-negative donor weights that sum to one, matching the treated market pre-period outcome path plus a small set of predictors such as vertical, launch age, price level and supply density. The convexity constraint is the point: it forbids extrapolation beyond the donor support, which an unrestricted regression fit would happily do.
- Build the donor pool by exclusion, not by convenience. Drop markets with their own policy or pricing change inside the window, and drop markets adjacent enough that providers or consumers can cross into the treated market within a session. A spilled-over donor is contaminated toward the treated path and shrinks the estimated effect toward zero.
- Set the fit criterion before looking at the post period. Require a small pre-period RMSPE relative to the effect size that would change the decision, and validate it out of sample by fitting weights on weeks 1 to 40 and checking fit on weeks 41 to 52, so the weights are not tuned to pre-period noise.
- Produce inference by permutation, because there is one treated unit and no cluster to compute a standard error over. Run the identical procedure treating each donor as if it were treated, compute the ratio of post-period to pre-period RMSPE for each, and rank the true treated market. With 30 donors the smallest attainable p-value is 1/31 = 0.032, so state that floor rather than reporting a conventional significance claim.
- Add a placebo in time: move the treatment date 12 weeks earlier and confirm the method produces a gap near zero. A method that manufactures an effect on a date when nothing happened cannot be trusted on the date when something did.
- Report the ratio decomposed into its parts. A fee cut moves completed orders and active consumers together, so completed orders per active consumer can stay flat while both components move substantially, and the decomposition is what the decision actually needs.
Worked solution 35 min
- Assemble the weekly panel and screen the donor pool for policy changes and geographic spillover, recording each exclusion and its reason.
- Fit donor weights on pre-period weeks 1 to 40 and validate the fit on weeks 41 to 52, reporting pre-period RMSPE.
- Compute the post-period gap between the treated market and its synthetic counterpart for each of the 12 weeks.
- Run placebo-in-space over every donor, rank the treated post/pre RMSPE ratio, and convert the rank into a permutation p-value with its 1/(N+1) floor.
- Run placebo-in-time at a fake treatment date 12 weeks early and confirm a near-zero gap.
- Decompose the ratio into completed orders and active consumers and report both alongside the ratio.
Follow-up
- Three markets get the same regulation on three different dates. What changes in the estimator, and what goes wrong with a naive two-way fixed-effects specification?
- Pre-period fit is excellent but the treated market is the largest in the pool. What should you suspect about the weights?
- How would you separate the effect of the fee change from the effect of the consumer-facing price change it caused?
Median time-to-match improved while pre-match abandonment rose
Median time-to-match, computed as matched_at_utc minus requested_at_utc over fct_request rows where matched_at_utc IS NOT NULL, improved from 74 to 61 seconds in one market. Over the same days, request_status = 'abandoned_pre_match' rose from 6% to 11% of requests created. A dispatch change shipped that week. Using fct_request alone, say whether waiting genuinely improved, give an estimator that is not conditioned on matching, and state the assumption that estimator needs.
Approach
- Name the conditioning first. The statistic is computed only on requests that matched, and abandonment removes the longest waits from that subset before they can be observed, so anything that makes consumers quit sooner shortens the measured distribution mechanically.
- Replace the conditional mean with a fixed-horizon rate at the request grain: the share of all requests created in the window that matched within T seconds, T being the market's SLA. It is unconditional, it moves only when matching actually improves, and it is the SLA fill rate the market already reports.
- If the full curve is needed, estimate the cumulative incidence of matching with abandonment as a competing event, not Kaplan-Meier with abandonment as censoring. KM requires the censoring mechanism to be independent of the match hazard, and here people abandon precisely because they are still waiting, so KM would overstate the improvement.
- Distinguish the two stories that both fit the data: the match hazard rose (dispatch got faster), or consumers got less patient, for instance because a new screen surfaces a worse quote. Look at the abandonment hazard by elapsed second and at the quoted_eta_seconds distribution before and after. Worse quotes with an unchanged wait means people are quitting on the quote.
- Report matched requests per 100 created next to any latency number, every time, and state whether the two movements net to more or fewer matches. That net figure is what the decision depends on.
Follow-up
- Give the two-sentence version for a product review, without using the word censoring.
- Abandonment is flat but 'no_supply' expiries rose instead. Does that change your estimator?
- How would you power a switchback on the fixed-horizon metric given market-hour variance?
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 ↗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 ↗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 ↗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.
A number you shipped turned out to be wrong, and someone had already acted on it. That is one of the most useful stories a data person can carry. What is being scored is how fast you noticed, who you told first, and what you changed in the process so the same class of error could not repeat quietly.
Tell me about a time you had to translate an ambiguous business proble…
Tell me about a time you had to translate an ambiguous business problem into a well-defined technical roadmap.
Approach
- Quantify the outcome, including what you would not claim credit for.
- 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 would you do differently if you ran that project again?
Describe an analysis you got wrong after a decision shipped
Describe a number you published that turned out wrong, where someone had already made a decision on it. State the mechanism of the error rather than the feeling; how long it was live; who acted on it and what that cost; how it surfaced and whether you were the one who found it; and the control you put in afterwards. An error caught in review before anyone acted does not qualify for this question. Deliverable: three minutes, ending with the one process change that is still in place today.
Approach
- Choose an error with a real mechanism you can draw in one sentence, not a communication miss; the question is probing whether you understand how your own work fails, and a 'they misunderstood my chart' story answers a different question.
- State the blast radius honestly and numerically: days live, decisions taken, dollars or headcount moved. Vagueness here reads as an error you never actually measured.
- Say how it surfaced, including the unflattering version if someone else found it. Claiming self-detection on an error that a stakeholder caught is the fastest way to lose the room.
- Separate the mechanism from the conditions that let it survive: a wrong formula is one bug, but no reconciliation check and no second reader are the reasons it lived for weeks.
- End on a structural control, not an intention. 'I will be more careful' is not a control; a test that fails the job when two computations of the same metric disagree is.
Follow-up
- How soon after you knew did the decision-maker know, and who told them?
- Has the control you added caught anything since, and how would you know if it had silently stopped working?
- What class of error would that control still miss?
Explain a switchback confidence interval to a non-technical executive
A switchback test of a dispatch-radius change ran 1,152 market-hour blocks across six markets. SLA fill rate moved +1.8 percentage points, 95% interval [-0.4, +4.0], variance clustered at the block. Those markets serve about 250,000 eligible requests a week at 88% fill and 93% completion. An executive with no statistics background wants a ship-or-wait answer inside a five-minute update. Deliverable: the two-minute spoken explanation, your recommendation, and the single condition that would change it. You may not use the words significant, p-value, or confidence interval.
Approach
- Open with the decision and the recommendation, then justify; an executive who hears the caveat first stops listening before the ask arrives.
- Translate both interval bounds into the unit the executive already manages: eligible requests times percentage points times completion rate gives weekly completed orders, so the range becomes 'between about 1,000 fewer and about 9,300 more completed orders a week, best single guess about 4,200 more'.
- Say plainly what the range does and does not rule out: it does not rule out a small loss, and it is wide because the test has 1,152 effective units, not 250,000 consumers. Block-level randomisation is the reason the sample is small, and it is the reason the number is trustworthy at market level.
- Price the two errors against each other: a reversible dispatch parameter with a bounded downside is cheap to ship and cheap to revert, so the decision rule is not 'is the effect proven' but 'is the worst case affordable and detectable'.
- End with the one condition that flips you: name the monitoring metric (provider utilisation and idle time, since a wider radius can raise fill by burning provider hours) and the threshold at which you revert.
Follow-up
- How many more weeks of blocks would it take to halve the width of that range, and is that worth the delay?
- The executive asks 'so is it real or not' - what do you say without reaching for statistical vocabulary?
- What would you monitor post-ship that the experiment itself could not measure?
- 01
Tell me about a time you had to translate an ambiguous business problem into a well-defined technical roadmap.
- 02
Describe a number you published that turned out wrong, where someone had already made a decision on it. State the mechanism of the error rather than the feeling; how long it was live; who acted on it and what that cost; how it surfaced and whether you were the one who found it; and the control you put in afterwards. An error caught in review before anyone acted does not qualify for this question. Deliverable: three minutes, ending with the one process change that is still in place today.
- 03
A switchback test of a dispatch-radius change ran 1,152 market-hour blocks across six markets. SLA fill rate moved +1.8 percentage points, 95% interval [-0.4, +4.0], variance clustered at the block. Those markets serve about 250,000 eligible requests a week at 88% fill and 93% completion. An executive with no statistics background wants a ship-or-wait answer inside a five-minute update. Deliverable: the two-minute spoken explanation, your recommendation, and the single condition that would change it. You may not use the words significant, p-value, or confidence interval.
Is this an official Gopuff interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Gopuff. Rounds and questions reflect what candidates have reported, not a process Gopuff has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How technical are the coding rounds at Gopuff?
The technical rounds focus heavily on practical Python and SQL capabilities tailored to data manipulation, feature engineering, and data science workflows. You should be comfortable writing clean, efficient code without relying heavily on syntax auto-completion, particularly when dealing with aggregations and window operations.
PracHub interview research ↗What is the typical interview timeline from initial screen to offer?
The process typically moves at a steady startup pace, taking roughly three to four weeks from the initial recruiter screen through the final interview panels and leadership sync, depending on scheduling availability.
PracHub interview research ↗Are remote candidates considered for this role?
Yes, Gopuff offers both remote and on-site positions depending on the specific team and role requirements, with certain delivery technology roles tied to specific hub offices like Philadelphia. Check the specific job listing details to confirm location flexibility.
PracHub interview research ↗How can I stand out during the product sense and case study rounds?
Stand out by grounding your answers in the operational realities of hyper-local delivery. Always consider second-order effects, such as how optimizing driver dispatch in one neighborhood might inadvertently impact delivery times in an adjacent zone.
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