As a Data Scientist at Tatari, you will sit at the intersection of advanced statistical modeling and the rapidly evolving world of television advertising. Your work is fundamental to the company’s core value proposition: bringing data-driven performance measurement to the historically opaque world of TV media buying. You will analyze complex datasets to help clients understand the direct impact of their TV spend on consumer behavior, effectively bridging the gap between traditional media and digital attribution.
This role requires a high degree of technical autonomy and a product-oriented mindset. You will frequently collaborate with engineering and product teams to refine measurement methodologies, improve internal dashboards, and solve ambiguous problems where standard solutions may not exist. Because Tatari operates in a fast-paced, results-oriented environment, you must be comfortable translating complex analytical findings into actionable business insights that drive real-world advertising strategy.
The role is highly technical and demands proficiency in Python and SQL. Be prepared to demonstrate not just your ability to write code, but your ability to structure data-driven narratives for stakeholders.
Initial Screening Call
reportedData Scientist covers at least four different jobs: experimentation, product analytics, causal work on observational data, and applied modelling that ships into a system. A screening call is the cheapest place to find out which of them is being hired for, and doing that diagnosis openly reads as senior rather than fussy. Ask what the last few pieces of work on the team actually were, and roughly how a week splits between querying, modelling and stakeholder time. Then say which parts of that you have done and which you have not. Claiming the whole range is the fastest way to be caught one round later.
What to demonstrate
- Whether you can distinguish the flavours of the role and locate your own experience inside one of them honestly
- Whether you name what you have not done instead of stretching to cover every line of the posting
- Whether your hard constraints (notice period, location, work authorisation, level) surface now rather than at offer stage
How to prepare
- Map the last two years of your time into rough percentages across query writing, experiment design, modelling and stakeholder work, so a question about scope has a real answer
- Mark every responsibility in the posting as done, adjacent or new, and prepare one sentence for each adjacent item naming the closest thing you have actually built
- Decide which logistics are non-negotiable before the call so you can state them in one sentence rather than negotiating live
Technical Assessment
reportedBefore anything else, this round is a reading test. You are given a small schema and a question phrased in business language, and most of the difficulty sits in the gap between them. Who counts as an active user, does a refunded order still count as an order, is that date column an event time or a load time. Weak answers start typing immediately and compute something precise about the wrong population. Strong ones pin the definition in one sentence, name the column that encodes it, then write the query. On a timed assessment with nobody to tell, write the definition in a comment anyway.
What to demonstrate
- Whether an ambiguous term becomes a specific column and filter before any computation happens
- Whether you read the schema for keys and cardinality rather than only for column names
- Whether the result answers the question at the grain it was asked at, per user or per session or per day
How to prepare
- Take three metrics you already use and write down the exact filter and exact grain behind each, then practise stating one of them in a single sentence out loud
- On a schema you have never seen, spend the first minute writing what one row of each table means and which key it is unique on, then predict which joins can duplicate rows
- Rehearse a version where the definition changes halfway through, and edit the query you have instead of starting over
Take-Home Assignment
reportedA take-home is graded as an argument, not as a notebook. Somebody reads the submission without you in the room, so every choice has to survive on the page: why the question was framed this way, and what was deliberately left out. The gap between a strong and a weak submission is almost never model quality. It is whether the writeup names the specific question it answers and commits to a recommendation, including what evidence would overturn it. A high-accuracy model attached to no conclusion reads as effort that stopped before the decision.
What to demonstrate
- Whether the question you answered is stated outright, and whether it is the question the prompt posed rather than an easier neighbour of it
- Whether the recommendation is specific enough to act on, with the uncertainty attached to it instead of parked in a caveats section at the end
- Whether analytical choices such as the metric definition, the population filter and the time window are justified in the prose, not merely visible in code
How to prepare
- Take a dataset you have already worked with, write the one-paragraph conclusion first, then check whether the analysis you were planning actually supports it and cut whatever does not
- Practise stating a metric in one sentence that fixes the population, the time window and the denominator, then confirm your query computes exactly that sentence and nothing adjacent to it
- Hand a draft to someone outside the problem and ask them to tell you back what you recommended and why; anything they cannot recover is not on the page yet
Team Presentation
reportedAn added round often puts you in front of someone outside the core hiring team: a partner engineer, a product owner, a domain expert, sometimes a more senior manager. The question they are really asking is not whether you can do the work but whether they would trust a number that came from you. That changes what a good answer looks like. Lead with what the decision cost and what it changed, keep the method available but not central, and be plain about the limits of your evidence. Overstating a result is the fastest way to lose this round.
What to demonstrate
- Whether you can explain a technical choice to someone who will never read your code, without either flattening it into nothing or hiding inside jargon
- Honesty about evidence strength: what the analysis establishes, what it only suggests, and what it cannot say at all
- How you take disagreement, specifically whether you update on a good objection, hold your position with reasons, or fold on contact
How to prepare
- Write the two-sentence version of your most technical project for a non-specialist, then check that neither sentence needs a method name to make sense.
- For one result you are proud of, write the strongest objection someone could raise and a response that concedes the part of it that is correct.
- Prepare one decision that turned out to be wrong: how you found out, what it cost, and what you changed afterwards. A senior cross-functional interviewer asks for this more often than a technical one does.
PracHub editorial advice for the preparation topics above.
Reading a recent week's cost per action or return on ad spend before the conversion window has closed.
Spend for a period is final within hours, but conversions attributed to that period keep arriving for as long as the click window allows plus ingestion lag, and offline uploads can land weeks later. The denominator of cost per action is therefore systematically incomplete for recent dates, so recent CPA is biased high and recent ROAS biased low, and a dashboard comparing a fresh week to a matured week will show a regression that does not exist. The correct handling is to freeze a period only after click_window_days plus the observed ingestion lag, and to publish a maturation curve so readers can see how much of a given day's conversions have landed so far.
Randomising users into treatment and control while both arms draw from the same campaign budget.
The arms compete in the same auctions and against the same budget, so treatment winning more impressions directly starves control, and the measured gap includes that cannibalisation rather than only the ad effect. The test looks methodologically clean, the randomisation is genuinely valid, and the lift is still partly manufactured. This is an interference violation, not a randomisation failure, so checking balance on covariates will not catch it. The fixes are to randomise at a unit that contains the budget, such as a geographic market, or to give each arm its own budget and its own pacing, and then be explicit that you are now comparing two separately-budgeted campaigns.
Reading an observational correlation as a causal effect
Name the confounder you are most worried about and the design that would remove it: an experiment, a difference-in-differences with a checked pre-period trend, an instrument, or a regression discontinuity. When none is available, state which direction the bias likely runs and bound the claim accordingly.
Ending an analysis without a recommendation or next step
Close with what you would do and what would change your mind, stated as a condition you can check later. If the evidence is genuinely inconclusive, recommend the specific next measurement and say what it costs in time or exposure.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
If your model results seem counterintuitive, what steps do you take to…
If your model results seem counterintuitive, what steps do you take to validate the findings?
Approach
- 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.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
Check predicted conversion-rate calibration with a reliability table
scored has 4 million rows at bid_request_log grain for one campaign: predicted_cvr, win_flag, and converted, which is observed only where win_flag is true and a conversion landed within 7 days. The win rate is about 2% and the conversion rate among won impressions about 0.4%. Without using a library calibration helper, build a 20-bin equal-frequency reliability table with bin count, mean predicted_cvr, observed rate and an interval around it, then compute count-weighted expected calibration error. Say whether the model is miscalibrated, in which direction, and over which population your answer holds.
Approach
- Restrict to win_flag == True and state the precondition plainly: converted is only defined where the ad served, so the table measures calibration on the won slice. That is the population the advertiser pays for, but it is selected by the bid and the auction, so the result cannot be extended to no-bid or lost opportunities where the prediction is never tested.
- Bin with equal frequency (pd.qcut with duplicates='drop'), not equal width. Prediction distributions in this setting are heavily right-skewed with point masses, so equal-width bins put most of the mass in one bin and leave the tail bins with too few conversions to say anything. Report how many bins survived if edges collapsed.
- Per bin compute n, mean predicted_cvr, observed rate, and a Wilson score interval. At a 0.4% base rate the normal approximation produces negative lower bounds and understates uncertainty in the low bins, so the interval choice is not cosmetic here.
- Compute ECE as the count-weighted mean of |observed - predicted| across bins, and report it next to the base rate: 0.002 of absolute error is small against a 5% base rate and enormous against 0.4%.
- Read the direction from the sign pattern rather than the scalar. Observed below predicted across the top bins is head over-prediction, typically from training on a differently-selected population or from scoring against a conversion window that has not matured; a flat observed rate across rising predictions means the score has little ranking power in this range, which is a different problem from miscalibration.
Worked solution 25 min
- Subset to won rows, record n_won and the observed base rate, and confirm converted has no nulls within that subset.
- bins = pd.qcut(predicted_cvr, 20, labels=False, duplicates='drop'); report the realised bin count.
- groupby(bins).agg(n, pred_mean, obs_rate), then compute Wilson bounds elementwise from n and obs_rate at z = 1.96.
- ece = ((n / n.sum()) * (obs_rate - pred_mean).abs()).sum(); print it alongside the base rate and the ratio of the two.
Follow-up
- The pooled curve looks calibrated but ctv supply is badly off. How do you test for segment-level miscalibration without fishing across dozens of cuts?
- The model retrains daily while conversions take up to 7 days to land. What does that do to the head of the reliability curve, and in which direction?
- How would you turn this diagnostic into a bid correction, and what would you verify before shipping it?
Simulate bid shading profit under first-price auction clearing
auctions holds 200,000 backtest rows for one line_item_id: predicted_cvr (per impression), floor_price_cpm_usd (nullable when the floor is undisclosed), and best_competing_cpm_usd, the highest competing bid, observable only in this sample. Clearing is first price. The advertiser values a conversion at $40. For shading factors s from 0.50 to 1.00 in steps of 0.05, the submitted bid is s * 1000 * 40 * predicted_cvr and the line item wins when that bid clears both the floor and the best competing bid. Return win rate, spend, conversions and profit per thousand auctions, the profit-maximising s, and an uncertainty estimate for it.
Approach
- Separate what is deterministic from what is random before writing any sampling code. Given the bid, winning is deterministic and the price paid under first-price clearing is exactly the submitted bid, so the only stochastic element is whether a won impression converts. Use the closed form sum of predicted_cvr over wins for the expected conversion count and reserve Monte Carlo for the profit distribution, not the mean.
- Vectorise across s: build the bid vector once, then evaluate the 11 shading factors as numpy operations over the full array. A per-row Python loop over 200,000 rows by 11 factors is about two million iterations and turns a 3-second job into minutes.
- Make the win condition explicit and handle nulls deliberately: treat a null floor as no floor, require bid > best_competing_cpm_usd, and require bid >= floor_price_cpm_usd. Ties at exactly the floor behave differently from ties against a competitor, and the convention should be stated rather than inherited from a comparison operator chosen by accident.
- Compute profit per thousand auctions as (40 * conversions - sum of bid/1000 over wins) / n * 1000. Spend must use your own submitted bid, not the competing bid: under first-price clearing every inframarginal win, one you would have taken at a lower bid, now costs more, and that term is what creates an interior optimum.
- Get uncertainty by bootstrapping auction rows, recomputing the whole curve per replicate, and reporting the distribution of the argmax s rather than only a confidence band around the profit level. The decision uses the argmax, and it is far less stable than the profit curve it comes from.
- State the backtest's limit honestly: best_competing_cpm_usd was observed while you bid what you actually bid. If your change alters competitors' behaviour or triggers exchange-side floor adjustments, the counterfactual does not hold and the curve overstates the achievable gain.
Follow-up
- Raising this line item's bid also raises the clearing price faced by another line item in the same account bidding on overlapping supply. How does that change the optimum, and how would you detect it in the logs?
- predicted_cvr over-predicts by 15% at the head of the distribution. Which way does the optimal s move, and roughly how far?
- How would you run this as a live test instead of a backtest, and what is the randomisation unit given that both arms draw on one budget?
Can you explain the nuances of your approach to this SQL query optimiz…
Can you explain the nuances of your approach to this SQL query optimization?
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.
- 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?
How would you handle missing data or outliers in a large advertising d…
How would you handle missing data or outliers in a large advertising dataset?
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.
- Say which table is the grain you start from, and join outward from it.
Follow-up
- How would you verify this result without re-running the same query?
- How does the query change if the join becomes one-to-many?
Daily effective CPM per line item from billable impressions
ad_impression has impression_id, served_ts TIMESTAMPTZ, line_item_id, billed_price_micros_usd BIGINT, is_billable BOOLEAN, ivt_status TEXT (valid, givt, sivt) and currency_code. billed_price_micros_usd is the amount charged for that single impression, in USD micros. Write one query returning, per line_item_id and per UTC calendar day over a supplied date range, the billable impression count, total spend in USD, and effective CPM meaning spend per thousand impressions. Count only rows with is_billable = TRUE and ivt_status = 'valid'. Order by day, then spend descending.
Approach
- Apply the two filters positively rather than by exclusion: is_billable = TRUE AND ivt_status = 'valid'. Writing ivt_status <> 'givt' silently keeps the sophisticated-invalid rows, which is the larger and later-arriving category.
- Bucket with (served_ts AT TIME ZONE 'UTC')::date rather than date_trunc('day', served_ts). date_trunc on a TIMESTAMPTZ resolves in the session's TimeZone setting, so the same query returns different day boundaries for two analysts on the same warehouse.
- Aggregate once: COUNT(*) and SUM(billed_price_micros_usd) grouped by line item and day. Everything else is arithmetic on those two columns.
- Collapse the unit conversion into a single divisor. Micros to USD is a division by 1e6, per-thousand is a multiplication by 1000, so eCPM = SUM(billed_price_micros_usd) / (1000.0 * COUNT(*)). Use numeric literals so a BIGINT sum is not divided with integer arithmetic.
- Return the impression count in the output, not just the rate. eCPM rises mechanically whenever cheap inventory is filtered out, so the rate is uninterpretable without the volume beside it.
Worked solution 15 min
- Count rows before and after the is_billable and ivt_status filters and note the drop; it is usually a few percent, and a sudden change in that drop is itself the finding.
- Bucket the day as (served_ts AT TIME ZONE 'UTC')::date so the result does not depend on anyone's session timezone.
- Group by (line_item_id, day) and emit COUNT(*) AS impressions and SUM(billed_price_micros_usd) AS micros.
- Derive spend_usd = micros / 1e6 and ecpm_usd = micros / (1000.0 * impressions) in an outer select over that aggregate.
- Order by day then spend_usd descending, and reconcile the top row against a line item whose spend you already know.
Follow-up
- eCPM rose 12% week over week while spend was flat. What are the candidate causes, and which column separates a price change from a mix shift?
- How do you compute a period-level eCPM across 30 days, and why is the mean of the 30 daily eCPMs a different number?
- currency_code is not always USD. What does billed_price_micros_usd mean on those rows, and what would you need before the sum is trustworthy?
Given a set of sample data, what trends do you identify and how would …
Given a set of sample data, what trends do you identify and how would you present these to a non-technical client?
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Name one primary metric, then the guardrail that stops it being gamed.
- Decompose the metric into the rates that drive it, and say which one you would check first.
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?
Explain how you would account for external variables (e.g., seasonalit…
Explain how you would account for external variables (e.g., seasonality) when measuring ad performance.
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- 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 would you design a metric to measure the efficacy of a TV ad campa…
How would you design a metric to measure the efficacy of a TV ad campaign?
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- 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.
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 do you approach dashboard improvements to make them more actionabl…
How do you approach dashboard improvements to make them more actionable for users?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- Fix the population and the time window before naming any metric.
- Decompose the metric into the rates that drive it, and say which one you would check first.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
Identify retargeting lift when the advertiser refuses a holdout
An advertiser will not fund a holdout during peak season, so no group may be denied delivery. You may randomise the bid multiplier on a line item by geo_dma, plus or minus 20%, across 50 markets. Retargeting eligibility is a hard rule: a device enters the audience only if its last site visit was within 30 days. Propose an identification strategy, state exactly what quantity it estimates, and say what would invalidate it.
Approach
- Recognise that exposure cannot be randomised because the auction decides it, but the bid can be. Randomising the multiplier by market is an encouragement design: the multiplier is the instrument, impressions per device is the endogenous treatment, and conversions per device is the outcome.
- Run two-stage least squares at the market level with the multiplier as instrument and report the first-stage F. With 50 markets a weak instrument is a live risk; below F of about 10 the 2SLS estimate is biased toward the confounded OLS and its interval undercovers, so report Anderson-Rubin intervals, which stay valid under weak instruments.
- Interrogate the exclusion restriction instead of asserting it. A 20% higher bid does not only buy more impressions, it buys different impressions, winning inventory that previously cleared above the bid and may convert at a different rate. That is a direct exclusion violation, so the honest statement is that this estimates a local effect on marginal impressions won by a bid increase, not the average effect of an impression.
- Report the intention-to-treat number alongside the 2SLS number. The reduced form, conversions per device regressed on the randomised multiplier, requires no exclusion restriction and is the result you can defend without qualification.
- Offer the discontinuity as an independent cross-check: a sharp regression discontinuity at the 30-day recency cutoff comparing devices at 29 and 31 days since last visit. State plainly that this identifies the effect only at the boundary, on the least recent and least valuable segment, which is not the parameter the advertiser wants, and run a density test on the running variable to check for manipulation.
- Say what would make you decline. If the first-stage F is weak and the recency variable is coarse or manipulable, the defensible deliverable is the reduced form with an honest interval, not a headline incrementality number.
Worked solution 45 min
- Randomise 50 markets, stratified on pre-period spend, to a multiplier of 0.8 or 1.2, holding flight dates and budgets otherwise fixed.
- Estimate the first stage: market-level impressions per device on the multiplier indicator with stratum fixed effects, and report F.
- Estimate the reduced form: market-level conversions per device on the same indicator. This is the number defensible without further assumptions.
- Divide to get the Wald ratio, which equals 2SLS for a single binary instrument, and put an Anderson-Rubin interval around it.
- Test exclusion empirically by comparing supply composition won under each multiplier across exchange_id, placement_id, ad_format and the floor_price distribution, and quantify how much of the reduced form a mix shift could account for.
- Run the recency discontinuity separately on observational data as a directional cross-check, with a density test at the cutoff and a bandwidth sensitivity sweep.
Follow-up
- The first-stage F comes back at 6. What do you report?
- How would you test whether the higher multiplier bought systematically different supply?
- The recency variable is stored in whole days. What does that discreteness do to the discontinuity estimate and its inference?
One advertiser's conversions doubled the week their SDK shipped
An advertiser's daily conversion_event rows roughly doubled starting 14 August, with no change in their order volume as they report it. That week they added a server_api feed alongside their existing browser_pixel. conversion_event has conversion_id, advertiser_id, conversion_ts, received_ts, conversion_type, order_id, device_id, user_id_hash, click_tracking_id, source, dedup_key and is_duplicate, where is_duplicate is written by our dedup job. Quantify the true conversion count, name the failure precisely, and state what you would tell the account team.
Approach
- Compare row counts against distinct dedup_key counts per advertiser per day. If rows double while distinct keys stay flat, the extra rows are duplicates that the dedup job never collapsed, and the real conversion level never moved.
- Establish why the job failed rather than that it failed: compute the null rate of dedup_key by source, and for non-null keys compare the value format between browser_pixel and server_api on the same order_id. Case, prefixing and whitespace differences are the usual cause and are invisible in a count of non-null keys.
- Use order_id as an independent second key. Distinct order_id per advertiser per day that is flat across 14 August confirms the real outcome count is unchanged and gives you the recovery rule.
- Size the blast radius downstream: duplicated conversions inflate attributed conversions, deflate CPA and inflate ROAS for every line item serving that advertiser, and the attribution_credit rows already written carry the inflation.
- Write the restatement rather than just the diagnosis — which advertiser, which dates, the direction and size of the correction, and whether any optimisation decision was already taken on the inflated numbers.
Follow-up
- The advertiser cannot change their server payload for a quarter. What dedup rule would you run in the meantime, and what does it get wrong?
- How would you detect this class of failure automatically for the other several thousand advertisers?
- If the two sources disagree on conversion_value_usd for the same order, which one wins and why?
For a candidate whose interviews will centre on A/B testing, metric movement and causal claims. Design comes before arithmetic, arithmetic before analysis, and the week ends by rehearsing the readout rather than the derivation.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Design one test end to end on paper
- Take a single feature change and write the full design: randomization unit, the exact point of exposure, the primary metric with its grain, guardrails, allocation, planned duration, and the decision rule committed before any data exists.
- Write why the randomization unit must sit at or above the level where treatment can spill over, and give one case where user-level randomization is still contaminated (shared accounts or devices, or two participants in the same marketplace).
- State in advance what you will do if the primary metric is flat while a secondary metric is significant.
Deliverable: A one-page test design with a decision rule written before launch.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Power arithmetic until it is automatic
- Compute required sample size per arm for a binary metric with the normal approximation, n is approximately 2 times (z for alpha/2 plus z for power) squared times p(1 minus p) divided by delta squared, for baselines of 2, 10 and 40 percent at a 5 percent relative lift, and note that for a fixed relative lift the requirement falls as the baseline rises because delta grows proportionally with p.
- Redo the calculation for a continuous metric using variance in place of p(1 minus p), and show why a heavy-tailed quantity such as revenue per user needs either far more traffic or a capped version with a stated cap.
- Convert one of the results into weeks given a weekly eligible traffic figure, then list the two honest ways to shorten it (accept a larger detectable effect, or reduce variance) and write why quietly lowering the power target is a decision to miss more real wins, not a speedup.
Deliverable: A small script or sheet that maps baseline, minimum detectable effect, alpha and power to sample size and weeks, cross-checked against a published calculator.
Practice prompt ↗Practice prompt ↗03Variance and the unit-of-analysis problem
- Take a ratio metric whose denominator is not the randomization unit (clicks per session, randomized by user) and compute the standard error twice, once naively at session level and once by the delta method or a user-level bootstrap, then record how much the naive version understates it.
- Implement CUPED on simulated data: choose a pre-period covariate X measured before assignment, estimate theta as Cov(Y, X) divided by Var(X), and analyse Y minus theta times (X minus its mean) in place of Y. Confirm the variance of the adjusted outcome equals the raw variance multiplied by one minus the squared correlation between Y and X, so a correlation of 0.45 removes about 20 percent of the variance and not 80.
- Now run that simulation a few hundred times and confirm the adjusted effect estimate is unbiased for the same effect rather than numerically identical to the raw one. Within any single run the two differ, sometimes by a large fraction of the true effect, because the two arms' pre-period covariate means never coincide exactly in a finite sample; they agree in expectation, which is the property that matters and the one to state out loud.
Deliverable: A notebook showing the adjusted estimator with a measurably smaller variance than the raw one, plus a repeated-simulation table showing the two estimators agreeing on average while differing run by run.
Practice prompt ↗Practice prompt ↗04Validity threats you can actually test for
- Run a sample ratio mismatch check as a chi-square goodness-of-fit test against the intended allocation, and write the three causes you would chase first (assignment logged before exposure, an arm-specific redirect or load failure, bot filtering applied asymmetrically).
- Simulate peeking: generate A/A data, test daily at alpha 0.05 across 14 looks, record the inflated false positive rate, then apply an alpha-spending boundary or commit to a fixed horizon and confirm the rate returns to nominal.
- Write how you would separate a novelty effect from a durable lift using the treatment effect plotted against days since first exposure, and what shape would change your recommendation.
Deliverable: One table showing the peeking false positive rate before and after correction, plus a written SRM triage list.
Practice prompt ↗Practice prompt ↗Worked solution ↗05When randomization is not available
- Write the identifying assumption for difference-in-differences (parallel trends in the absence of treatment), then plot pre-period trends for two candidate control groups and justify rejecting one of them.
- Design a switchback test for a change where user-level randomization would leak across participants, choosing a time-block length against the carryover you expect and saying how you would detect carryover in the data.
- List what an interrupted time series or a synthetic control buys you and the one thing neither can rule out: an unobserved shock that coincides with the launch.
Deliverable: A one-page memo recommending a single quasi-experimental design and naming its weakest assumption explicitly.
Practice prompt ↗Practice prompt ↗06The readout query
- Write the assignment-to-exposure join that returns exactly one row per unit per experiment, and handle units appearing in both arms by excluding and counting them rather than silently keeping one.
- Compute the per-arm metric, its variance and the relative lift with a confidence interval in SQL, then reproduce the identical numbers in a notebook as a cross-check.
- Add a segment breakdown and write the sentence that keeps it from being p-hacking: segments declared in advance, everything else reported as exploratory and corrected for multiplicity.
Deliverable: A single query that outputs the full readout table, matched to a notebook recomputation.
Practice prompt ↗Practice prompt ↗07Present it to someone who will not read the appendix
- Give a 10-minute readout of a real or simulated experiment in the order decision, number, uncertainty, caveat.
- Have your listener ask "can we ship it" in the case where the primary is flat and a guardrail moved, and answer with a recommendation rather than a request for more data.
- Rewrite your opening line so the recommendation lands before any methodology.
Deliverable: A one-page readout whose first line is the recommendation.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Have two ready. In one, the data was on your side and you had to move someone who outranked you. In the other, the pushback was correct and you changed position. The second is the harder story and it lands better, because it shows you separate being right from being attached to an answer. Name the person's actual objection.
Describe how you would reproduce your code results if a stakeholder qu…
Describe how you would reproduce your code results if a stakeholder questioned the methodology.
Approach
- Quantify the outcome, including what you would not claim credit for.
- State the situation in two sentences and spend the rest on your reasoning.
- Pick a story where you drove the decision, not one where you observed it.
Follow-up
- How did you know the outcome was caused by your change?
- What did you decide not to do, and why?
Correcting a published CPA win that was window maturation
Three weeks ago you published a note saying a bid-strategy migration cut attributed CPA by 18%. A colleague points out that you compared the first seven days after migration against a fully matured pre-period, while conversions for the recent dates were still arriving. Recomputed at equal maturity the improvement is 3%, inside noise. The note has been quoted in a quarterly business review deck. Deliverable: what you do in the next 24 hours, what you write and to whom, and the structural change that prevents a repeat.
Approach
- The interviewer is probing sequencing under embarrassment, so establish the corrected magnitude before writing anything: recompute both periods restricted to conversions received within the same number of days after conversion_ts, so a frozen window is compared to a frozen window.
- Build the account's maturation curve from received_ts minus conversion_ts, reporting the share of a click-day's eventual conversions landed by day 1, 3, 7 and 14. It both explains the error and becomes the artefact that prevents the next one.
- Enumerate the decisions taken since publication that cited the 18%: budget moved, line items paused, the deck slide, any advertiser-facing claim. Cost each one, because the correction's urgency is set by what was acted on, not by how wrong the number was.
- Send one message, not a drip, with the corrected number in the first sentence, the affected dates, the direction of the error, and an explicit statement of which decisions it does and does not reverse. Notify whoever presents the deck first.
- Ship the guard: a freeze rule in the query or dashboard so no period is reportable until click_window_days plus observed ingestion lag have elapsed, with immature dates badged rather than hidden.
Follow-up
- The corrected number had gone the other way and the migration looked better than you published. Does anything about your response change?
- How do you decide whether this warrants a written postmortem or a one-line correction?
Explaining an incrementality interval to a non-technical budget owner
A 20-market geo holdout has closed. Incremental return on ad spend is estimated at 1.4 with a 90% interval of 0.6 to 2.2. The same account's last-click attributed ROAS is 4.1. A vice president with no statistics background has ten minutes and must decide whether to renew a $3M annual budget. Deliverable: the explanation you give verbally plus one slide. You may not use the words confidence interval, p-value, or significance, and you must give a recommendation rather than only a range.
Approach
- The interviewer is probing whether you can carry uncertainty into a decision instead of either hiding it or hiding behind it, so convert the interval into money at the real budget first: $3M at 0.6 to 2.2 is $1.8M to $6.6M of incremental revenue, with $4.2M as the central estimate.
- Get the break-even ROAS from the advertiser's gross margin and mark where it falls inside the range. That single number turns a statistical interval into two decision regions, and it is the only quantity the executive needs to reason about.
- Explain the 4.1 without calling it wrong: it counts every conversion that followed an ad, including the ones that would have happened anyway, while the test counts only the ones that would not have. Both are computed correctly and they answer different questions.
- State what would narrow the range and what it costs, in the same units: roughly four times the markets or four times the flight length to halve the width, against the cost of running longer at current spend.
- Pre-commit to the action at each end of the range so the recommendation is falsifiable: what you do if the true value is near 0.6, and what you do if it is near 2.2.
Follow-up
- The vice president asks whether it is working, yes or no. What is your one-sentence answer?
- Break-even is 1.0 and the range is 0.6 to 2.2. Do you renew at full budget, and what would you change about the flight?
- 01
Describe how you would reproduce your code results if a stakeholder questioned the methodology.
- 02
Three weeks ago you published a note saying a bid-strategy migration cut attributed CPA by 18%. A colleague points out that you compared the first seven days after migration against a fully matured pre-period, while conversions for the recent dates were still arriving. Recomputed at equal maturity the improvement is 3%, inside noise. The note has been quoted in a quarterly business review deck. Deliverable: what you do in the next 24 hours, what you write and to whom, and the structural change that prevents a repeat.
- 03
A 20-market geo holdout has closed. Incremental return on ad spend is estimated at 1.4 with a 90% interval of 0.6 to 2.2. The same account's last-click attributed ROAS is 4.1. A vice president with no statistics background has ten minutes and must decide whether to renew a $3M annual budget. Deliverable: the explanation you give verbally plus one slide. You may not use the words confidence interval, p-value, or significance, and you must give a recommendation rather than only a range.
Is this an official Tatari interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Tatari. Rounds and questions reflect what candidates have reported, not a process Tatari has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How long should I expect the entire process to take?
The process typically lasts 2–4 weeks. Factors like team availability and the complexity of the take-home assignment can influence the speed of progression.
PracHub interview research ↗Is the take-home assignment mandatory?
Yes, in most cases, the take-home assignment is a core component of the evaluation. It is used to gauge your technical depth and your ability to communicate findings in a presentation format.
PracHub interview research ↗What is the best way to stand out?
Focus on the "business impact" of your work. While your code must be correct, the candidates who succeed are those who can explain *why* their analysis matters to the client and how it drives better decision-making.
PracHub interview research ↗Will I receive feedback if I am not selected?
Feedback policies vary by team, but candidates have reported that receiving detailed, constructive feedback can be rare. Prepare to be self-reflective about your performance after each round.
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