At Replit, a Data Scientist is not just an analyst; you are a strategic partner in democratizing software creation. Whether you are optimizing the marketing funnel to bring in the next million developers or analyzing trace data to improve the reasoning capabilities of the Replit AI Agent, your work directly accelerates the mission of "Autonomy for All." You sit at the intersection of complex user behavior, large-scale data engineering, and product strategy.
In this role, you will move beyond simple reporting to answer ambiguous, high-impact questions. You might be asked to define what "success" looks like for an AI coding assistant or to build a multi-touch attribution model that justifies ad spend across a complex user journey. You are expected to treat data as a product—building semantic layers in dbt, designing rigorous experiments, and shipping insights that influence the roadmap of the core IDE or the growth engine of the company.
The environment is fast-paced and deeply technical. You will collaborate with engineers who are building the future of computing, meaning you must be as comfortable discussing code execution logs and LLM evaluations as you are discussing retention cohorts and LTV/CAC ratios.
Recruiter Screen
reportedWhoever runs this call is usually not a practitioner. They take notes, and a hiring manager skims those notes later, so the real question is whether your work survives being written down by someone outside the field. Test every project sentence against that: could a non-specialist repeat it correctly without knowing what a propensity score is? Carry a plain-language version of each project and one reason you want this particular role that you could not copy onto another application. Vagueness at this stage reads as inexperience, even when the underlying work was genuinely deep.
What to demonstrate
- Whether a non-specialist can restate your projects accurately, since their paraphrase is what reaches the hiring manager
- Whether your reason for wanting the role points at the work itself rather than the company's reputation
- Whether your language signals the level being screened for: what you decided yourself versus what you were handed
How to prepare
- Write a two-sentence, jargon-free version of each major project: the question nobody could answer, and the decision your work changed. Read it to someone outside data and have them repeat it back
- Point your 'why this role' answer at something concrete in the job description or the product surface you would be working on, and keep it to two sentences
- Have two questions ready about measurement: which metric the team is held to, and who acts on an analysis once it lands
Hiring Manager Screen
reportedExpect a live problem with pieces of it missing, closer to a conversation than an exam. A metric moved, or somebody wants to know whether a change worked, and you are asked how you would find out. The manager is watching the first ninety seconds, specifically whether you establish what decision hangs on the answer before you start proposing methods. Candidates who open with a technique get steered back. Once the decision is clear, describe what the data would look like if the story were true, and say what you would accept as evidence that it is not.
What to demonstrate
- Whether you fix the decision the analysis serves before choosing an approach
- How you continue when you are told the data you just asked for does not exist
- Whether you state what would change your mind, not only what would confirm the hypothesis you started with
- How you size an effect before you have measured it
How to prepare
- Take a metric you know well and practise explaining in under two minutes the four things that could have moved it and how you would separate them
- Pick a recent launch or experiment and write the single number you would ask for first, plus what you would conclude if it came back flat
- Practise being interrupted: have someone remove a data source halfway through your answer and carry on without restarting
Technical 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
Onsite Interview
reportedA day of back-to-back interviews samples your floor, not your ceiling. Four hours in, the habits that carry a good answer are the first to go: restating the question before solving it, asking what the data would have to look like, checking a number before quoting it. What the day decides is whether the tired version of you is still someone to leave alone with an ambiguous problem. The round that sinks a candidate is usually not the hardest one. It is the one immediately after the round that went badly.
What to demonstrate
- Whether the late rounds get the same clarifying questions as the first one, or whether you start answering immediately to save effort
- Whether a weak answer stays in the room it happened in, instead of following you into the next conversation as apology or distraction
- Whether the quality of your questions holds up, since fatigue removes curiosity about the problem before it removes knowledge of the method
How to prepare
- Rehearse the length, not just the content: book four mock interviews of different types in one afternoon with short gaps, because the one you need to observe is the fourth
- Put the two or three questions you ask at the start of any problem on a card in front of you, so that under fatigue it is a habit you run rather than a decision you make
- Decide in advance what the gap between rooms is for: water, one line of notes on anything you promised to follow up, and an explicit close on the round that just ended so it does not travel
- Prepare a different closing question for each interviewer, so the end of a long day does not produce the same one four times
PracHub editorial advice for the preparation topics above.
Randomising an experiment at the user level when users share an account
Two problems fire at once. Colleagues in one workspace see each other's work and talk to each other, so a treated user changes the behaviour of a control user in the same account, which violates the no-interference assumption and biases the estimate toward zero. Separately, outcomes within an account are strongly correlated, so the effective sample size is roughly n / (1 + (m - 1) * rho) for m users per account and intra-class correlation rho, not n. With rho around 0.3 and twenty users per account that is a design effect near 6.7, meaning a user-level confidence interval is about two and a half times narrower than it should be and results cross significance thresholds on noise alone. Randomise the account and cluster the standard errors.
Reporting a mean over accounts when account revenue is heavy-tailed
When a small number of accounts hold most of the revenue, the sample mean is dominated by whichever of them happens to be in the sample, and the sample variance keeps growing as more data arrives instead of stabilising. In that regime the usual central-limit-based confidence interval understates uncertainty, and a single renewal or a single large account's batch job can flip the sign of a measured effect. The fixes are to pre-register a winsorisation or capping rule before looking at the outcome, to report account counts crossing a threshold alongside the revenue figure, or to define the estimand on a bounded transform. Choosing the cap after seeing the result is a separate and worse problem, because the cap then encodes the answer.
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.
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.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
"Given a dataset of ad spend and conversions, build a simple attributi…
"Given a dataset of ad spend and conversions, build a simple attribution model in Python."
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- 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?
- What would you monitor after launch to know the model is still valid?
"How would you handle missing values in a dataset before training a pr…
"How would you handle missing values in a dataset before training a propensity model?"
Approach
- Check what information would not exist at prediction time, and exclude it.
- 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
- How would you choose the decision threshold, and who owns that choice?
- Where could label leakage enter this setup?
Simulate how the renewal calendar distorts monthly churn rates
Simulate 1,200 accounts on annual contracts. Draw each account's renewal month from a deliberately lumpy calendar: 30% renew in January and the remaining 70% are spread evenly over the other eleven months. At each renewal an account churns with probability 0.18, independent of month; survivors renew and come back twelve months later. Run 24 simulated months. For each month compute two rates: churned accounts over all live accounts, and churned accounts over accounts whose term ended that month. Report the mean and the month-to-month standard deviation of each series, and state which one belongs in an executive summary.
Approach
- Build the panel with numpy state arrays rather than a per-account loop: a next_renewal_month vector, an alive boolean vector, and a loop over the 24 months only. Looping over 24 months is fine; looping over 1,200 accounts inside it is what makes the simulation too slow to iterate on.
- Maintain the live set honestly. An account that churned in month m must leave the denominator from m+1 onward and can never be renewal-eligible again; if it stays, the naive rate drifts downward for reasons that have nothing to do with churn and the calendar effect gets buried.
- Compute both series over the same months and compare dispersion, not only level. The eligible-base rate should sit near 0.18 with binomial noise scaled by that month's renewal count; the naive rate spikes in January and collapses in thin months.
- Quantify the gap instead of describing it: the ratio of the two means is roughly the reciprocal of the average monthly renewal-eligible fraction, and the naive series' standard deviation is driven by the signing calendar rather than by customer behaviour.
- Check against the closed form before trusting the output. With the live set maintained correctly the eligible-base rate is an unbiased estimator of 0.18 in every month, so a systematic offset means the bookkeeping is wrong, not that the simulation found something.
Worked solution 30 min
- rng = np.random.default_rng(0); p = [0.30] + [0.70/11]*11; next_renewal = rng.choice(12, size=1200, p=p); alive = np.ones(1200, bool)
- For m in range(24): eligible = alive & (next_renewal == m); churn = eligible & (rng.random(1200) < 0.18); record churn.sum(), eligible.sum(), alive.sum() at month start; alive &= ~churn; next_renewal[eligible & ~churn] += 12
- naive = churned / live_at_start; eligible_rate = churned / eligible, left as NaN where eligible == 0.
- Report naive.mean(), naive.std(ddof=1), np.nanmean(eligible_rate), np.nanstd(eligible_rate, ddof=1) and the ratio of the two means.
Follow-up
- Compounded over twelve months the naive rate lands close to the true annual churn. Does that rescue it?
- How would you report churn in a month where only nine accounts were renewal-eligible?
- Eighteen-month terms are now being sold alongside annual ones. What breaks?
"Write a query to calculate the retention rate of users by cohort (mon…
"Write a query to calculate the retention rate of users by cohort (month of signup)."
Approach
- State the window function and its partition and ordering out loud before writing it.
- 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.
Follow-up
- How does the query change if the join becomes one-to-many?
- What breaks if events arrive late or out of order?
Find paid seats that never called the API
dim_user_membership carries user_id, account_id, seat_type, is_service_account, deactivated_at and last_seen_at. fct_api_request carries user_id, which is null whenever the caller is a service account or an unattended key, plus account_id, request_at and http_status. For a single account, list every licensed_paid seat with is_service_account = false and deactivated_at null that issued no request at all in the trailing 90 days, returning user_id and last_seen_at. A first draft writes NOT IN against a subquery over fct_api_request.user_id. State exactly what that draft returns and why, then write the correct query.
Approach
- Read the column comment first: user_id is nullable on the fact, so the subquery almost certainly contains at least one NULL for any account that runs a service account or an unattended key.
- Work the three-valued logic out loud. x NOT IN (a, NULL) expands to NOT (x = a OR x = NULL); the second disjunct is UNKNOWN, so for any x not equal to a the whole predicate is UNKNOWN and the row is filtered out. The draft returns zero rows, which reads as full seat utilisation.
- Rewrite as NOT EXISTS with the 90-day and status predicates inside the correlated subquery. Putting them in the outer WHERE instead turns the anti-join into a different question and silently changes the answer.
- Correlate on both user_id and account_id. A membership is (user_id, account_id) and one person can hold memberships in several accounts, so correlating on user_id alone marks a seat as active because that human was busy somewhere else.
- Filter the seat side to seat_type = 'licensed_paid', is_service_account = false and deactivated_at IS NULL, and say what the resulting count means next to contracted_seats on the current subscription row.
Worked solution 15 min
- Confirm the hazard with one query: SELECT count(*) FROM fct_api_request WHERE user_id IS NULL AND account_id = :account_id. Any non-zero result proves the draft returns nothing.
- Write the seat side: SELECT user_id, last_seen_at FROM dim_user_membership WHERE account_id = :account_id AND seat_type = 'licensed_paid' AND NOT is_service_account AND deactivated_at IS NULL.
- Attach AND NOT EXISTS (SELECT 1 FROM fct_api_request r WHERE r.user_id = m.user_id AND r.account_id = m.account_id AND r.request_at >= now() - interval '90 days').
- Compare the row count against the same query written as a LEFT JOIN with a WHERE r.user_id IS NULL; the two must agree exactly.
- Divide the active seat count by contracted_seats from the account's current fct_subscription_period row and state the utilisation figure.
Follow-up
- Adding AND user_id IS NOT NULL to the subquery also fixes NOT IN. Why is NOT EXISTS still the form you would leave in the repository?
- last_seen_at looks like a shortcut for the whole query. What does it actually record, and where does it disagree with API activity?
- This is a seat-reduction risk list. What threshold would you attach before handing it to an account team, and what happens to seats below it?
"We noticed that the number of active projects per user is decreasing,…
"We noticed that the number of active projects per user is decreasing, but revenue is increasing. What could be happening?"
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- Fix the population and the time window before naming any metric.
- State what result would change your recommendation, so the answer is falsifiable.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
"How would you define and measure 'activation' for a new user on Repli…
"How would you define and measure 'activation' for a new user on Replit?"
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Fix the population and the time window before naming any metric.
- 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?
"If we launch a feature that helps users write code faster, how do we …
"If we launch a feature that helps users write code faster, how do we know if it's actually helpful and not just generating low-quality code?"
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- Decompose the metric into the rates that drive it, and say which one you would check first.
- 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?
- What would you do if the primary metric and the guardrail moved in opposite directions?
"Explain the difference between a Type I and Type II error in the cont…
"Explain the difference between a Type I and Type II error in the context of a feature launch."
Approach
- State the primary metric and the minimum effect worth shipping, then size the test.
- 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.
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?
"How would you analyze an A/B test where the randomization unit was 'u…
"How would you analyze an A/B test where the randomization unit was 'user' but the metric is 'team collaboration'?"
Approach
- Decide the analysis before seeing data, including how long it runs and when you look.
- Name the guardrails that would stop a launch even on a positive primary result.
- 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?
- How would you handle interference between treated and control units?
Define success for widening the free usage allowance
A proposal triples the free-tier included allowance on the requests_thousands SKU. Finance expects the count of weekly active organisations to rise. You have fct_usage_daily (billable_quantity, included_quantity_applied, overage_quantity, net_amount_cents, cogs_cents, is_restated), dim_account (account_status, is_internal, converted_to_paid_at) and fct_api_request (traffic_class, http_status, environment). Define the primary metric this change should be judged on, two guardrails, and the numeric decision rule you would agree before launch. State explicitly how the obvious metric can be satisfied without the product getting better for anyone.
Approach
- Name the mechanism before naming any metric. A larger allowance moves quantity out of overage_quantity into included_quantity_applied, so net_amount_cents falls while cogs_cents is unchanged, and accounts that previously sat under the production volume floor now cross it without paying anything. A count of active accounts therefore moves for reasons that have nothing to do with the product.
- Set the primary metric at the account grain: weekly active organisations with at least one successful request (http_status < 400) in a workspace where environment = 'production' and traffic_class in ('interactive','batch'), over accounts with is_internal = false. Report accounts that existed before launch separately from the post-launch signup cohort, so the number is not quietly an acquisition metric.
- Attach the two guardrails that close the gaming routes. First, gross margin per account, (sum(net_amount_cents) - sum(cogs_cents)) / sum(net_amount_cents) computed per account per month and reported as a distribution, specifically the count and revenue share of margin-negative accounts. Second, the free and trial share of weekly active organisations.
- Add the conversion link the change is supposed to buy: free-to-paid conversion within 90 days for the affected cohort, read from converted_to_paid_at. Without it, the primary metric rewards permanent free use indefinitely.
- Write the decision rule with numbers before launch: ship if weekly active organisations rise by at least the pre-agreed threshold, 90-day free-to-paid conversion does not fall, and the count of margin-negative accounts stays under a stated cap. Note that the margin guardrail can only be read after the metering settling window has closed, since fct_usage_daily rows restate in place.
Worked solution 20 min
- Compute per-account monthly gross margin from fct_usage_daily as (sum(net_amount_cents) - sum(cogs_cents)) / sum(net_amount_cents), grouped by account_id and calendar month, restricted to usage_date values older than the measured metering settling window.
- Simulate the allowance change on the trailing settled month: for each account, move min(overage_quantity, allowance_delta) from overage_quantity into included_quantity_applied and recompute net_amount_cents at that account's existing list and discount rates, leaving cogs_cents untouched.
- Recount weekly active organisations under the simulated state with the production volume floor applied, and split the delta into accounts that were already active and accounts newly crossing the floor.
- Report the before and after margin distribution, the count of accounts crossing into negative margin, and the revenue share those accounts hold.
Follow-up
- Weekly active organisations jump 14% in the first week after launch. How much of that can you attribute to the change with no control group, and what would you need to do better?
- An account settles at usage permanently just below the new allowance and never pays. Does your primary metric count it as a success, and should it?
Consumption per account always dips in the last four days
Your consumption dashboard reads billable units per paying account from fct_usage_daily (account_id, sku_code, usage_date, billable_quantity, net_amount_cents, is_restated, first_written_at, restated_at, updated_at). Every refresh shows the final three to five days declining, and a review is scheduled on that shape. Establish empirically how long a usage_date takes to settle, separately per sku_code, and specify the trailing exclusion window every reported figure should use. Derive the number from the data; do not adopt a convention.
Approach
- Treat settlement as a measurable curve rather than a belief: for each historical usage_date, compare the total captured as of age d days against that date's final settled total.
- Do it per sku_code, because metering paths differ. A per-request SKU lands within hours, while a storage-month SKU is produced by a daily sweep and lands later, so one global lag number is wrong for at least one of them.
- Pick the age at which a stated percentile of dates reaches a stated completeness threshold, for example the tenth percentile date reaching 99.5 percent of final, and take the slowest SKU's age as the dashboard's exclusion window.
- Separate late arrival from restatement. Late rows raise totals and are fixed by waiting; restatements can move either way and are not, so report the share of the gap from each.
- Encode the exclusion inside the query rather than in the chart, so anyone reusing the SQL inherits the rule, and never compare a fresh partial period against a settled one.
Follow-up
- Month-end invoicing needs a number before settlement completes. How would you publish an early estimate with an honest uncertainty band attached?
- What monitor would tell you the settling time has changed, without anyone remembering to re-run this analysis?
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 situation where you had to make a decision with imperfect …
"Describe a situation where you had to make a decision with imperfect or incomplete data."
Approach
- State the situation in two sentences and spend the rest on your reasoning.
- Quantify the outcome, including what you would not claim credit for.
- Close with what you would do differently, concretely.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Announce a metric fix that cuts the headline number
Weekly active organisations, the count on the company dashboard, has never excluded rows where dim_account.is_internal is true, and it counts traffic with traffic_class in synthetic_monitor and load_test. Correcting both reduces that count by 11 percent and removes most of the growth reported over two quarters. The figure appears in a board deck and in two teams' quarterly goals, one written on the count and one on the weekly active organisation ratio, whose denominator is accounts whose account_status was in ('trial','free','active_paid') through the week. Decide the order in which you tell people, what the dashboard shows during the transition, and what you propose happens to goals already set against the old definition.
Approach
- The interviewer is probing whether you can land a correction as an operational change with a plan attached, rather than as an announcement other people then have to clean up after.
- Quantify each exclusion separately before telling anyone: internal accounts, synthetic monitors, load tests. Three known quantities are a discussion; one alarming total is an argument.
- Be precise about which side of the metric each exclusion touches, because one team's goal is on a count and the other's is on a ratio. The traffic-class filters remove requests, so they shrink the numerator only. Dropping internal accounts removes them from the ratio's denominator as well, since internal accounts carry ordinary account_status values and therefore sit in that denominator. Internal accounts are active in almost every week while the real base is not, so the numerator loses a larger share than the denominator and the ratio falls by less than the count does. Compute both and say which one the 11 percent is before anybody assumes.
- Check whether the trend changes, not only the level. A constant 11 percent shift is a rebasing and nothing more. A shift that widens over time means the reported growth was partly internal or synthetic, which makes the existing goals unachievable as written and changes what you are asking teams to do.
- Sequence the disclosure: the metric owner and the two teams whose goals move first and privately, then the board channel with a written bridge, then the dashboard. The dashboard is last because a number that changes without explanation is read as instability rather than as a fix.
- Run both series for one reporting period with the bridge visible, restate history rather than letting the series break at a date, and set the date the old series is removed.
- Propose the goal treatment yourself: rebase each target by the shift measured on the metric that target is written against, rather than leaving each team to negotiate individually, which is where corrections of this kind usually die.
Follow-up
- One team's quarterly goal is now unreachable. Rebase the target or let it miss, and what does each choice teach the organisation?
- How would this have been caught when the metric was first defined?
- What else on that dashboard shares this failure mode, and how would you find out this week?
Report an underpowered consumption test to a non-technical executive
An account-randomised packaging change ran six weeks across 900 paying accounts. The effect on billable units per account per month is plus 4.1 percent, with a 95 percent interval from minus 3.2 to plus 11.8 after clustering standard errors at the account and applying the pre-registered winsorisation at the 99th percentile. An executive with no statistical background wants one number this week to decide a full rollout. Produce a three-sentence spoken answer, one chart, and an explicit recommendation of ship, stop or keep running, with the cost of each option stated.
Approach
- The interviewer is probing whether you can be decision-useful without either hiding the uncertainty or hiding behind it. Start from the decision rather than the statistics: establish what the executive would do differently at plus 4 percent versus zero, because if the action is identical the interval does not matter.
- Translate the interval into consequences in units the executive already reasons about. Multiply both endpoints by the cohort's baseline consumption and contracted rates to give an annualised revenue range, so the answer is a range of dollars rather than a range of percentages.
- Price the option to wait. Using the observed variance, state roughly how many additional account-weeks halve the interval width, so keep running becomes a quantified choice instead of a stall.
- Offer a cheaper path to the same decision: a lower-variance proximate outcome such as successful billable units on the new SKU, or CUPED using each account's pre-period consumption, quoting the expected variance reduction as one minus the squared pre-post correlation.
- Give a recommendation and name the single observation that would reverse it. A strong answer commits; a generic one recites the interval and leaves the decision on the table.
Follow-up
- The executive says it clearly works and is just not provable, so ship it. What is your answer?
- How much of the interval width comes from clustering and how much from the revenue tail, and what would you do about each?
- If you had to ship this week with no more data, which guardrail would you watch for the first fortnight and at what threshold would you roll back?
- 01
"Describe a situation where you had to make a decision with imperfect or incomplete data."
- 02
Weekly active organisations, the count on the company dashboard, has never excluded rows where dim_account.is_internal is true, and it counts traffic with traffic_class in synthetic_monitor and load_test. Correcting both reduces that count by 11 percent and removes most of the growth reported over two quarters. The figure appears in a board deck and in two teams' quarterly goals, one written on the count and one on the weekly active organisation ratio, whose denominator is accounts whose account_status was in ('trial','free','active_paid') through the week. Decide the order in which you tell people, what the dashboard shows during the transition, and what you propose happens to goals already set against the old definition.
- 03
An account-randomised packaging change ran six weeks across 900 paying accounts. The effect on billable units per account per month is plus 4.1 percent, with a 95 percent interval from minus 3.2 to plus 11.8 after clustering standard errors at the account and applying the pre-registered winsorisation at the 99th percentile. An executive with no statistical background wants one number this week to decide a full rollout. Produce a three-sentence spoken answer, one chart, and an explicit recommendation of ship, stop or keep running, with the cost of each option stated.
Is this an official Replit interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Replit. Rounds and questions reflect what candidates have reported, not a process Replit has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How technical is the interview process?
The process is quite technical. You will be expected to write working SQL and Python code. It is not just a "theory" interview; you need to demonstrate that you can pull and clean data yourself.
PracHub interview research ↗What is the work culture like for Data Scientists?
Replit values autonomy. You won't be handed a ticket with a predefined query to write. You are expected to find the most impactful problems, define the analysis, and drive the solution. It is a high-ownership environment.
PracHub interview research ↗Do I need experience with AI/LLMs for the Marketing Data Scientist role?
No, deep AI experience is not required for the Marketing track, though an interest in the product is essential. For the AI Agent track, familiarity with LLM evaluation and trace data is highly preferred.
PracHub interview research ↗Is this role remote?
The job postings indicate an in-office requirement (typically Monday, Wednesday, Friday) in Foster City, CA. Replit values in-person collaboration.
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