The Data Scientist role at Yahoo is pivotal in transforming data into actionable insights, driving strategic decisions that enhance user experience and optimize product performance. In a landscape where data is abundant, the Data Scientist acts as a bridge between raw data and business intelligence, leveraging advanced analytical skills to influence product development and marketing strategies. You'll work on a variety of projects that directly impact Yahoo's services, from personalized content delivery to ad targeting, making your contributions essential to the company's mission of delivering valuable, user-centric experiences.
This role is particularly exciting due to the scale and complexity of the datasets you will handle. As a Data Scientist, you will engage with tools and technologies that allow you to analyze vast amounts of data, uncover patterns, and provide insights that inform key business decisions. You will collaborate with cross-functional teams, including engineering, product management, and marketing, to ensure that your findings translate into real-world applications that resonate with millions of users.
Phone 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
Coding 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
Technical Interviews
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
Final Interviews
reportedA loop is not scored one interview at a time. The people you meet compare notes afterwards, usually in a meeting you are not in, and the outcome turns on what each of them can say about you when asked. That rewards something other than survival: every room needs one specific thing worth repeating, and none of them can contradict another. The common way to lose is to tell the same project four times with different numbers in it, or to be uniformly fine in a way that leaves nobody with anything to argue for.
What to demonstrate
- Whether your account of a project survives being told twice, with the same scale, the same metric definition and the same numbers each time
- Whether each interviewer leaves with one concrete claim they could make on your behalf later, rather than an absence of complaints
- Whether a question you already answered in an earlier room gets the same answer at the same depth, without visible impatience
How to prepare
- Write a one-page fact sheet for your two or three main projects that fixes the numbers you will quote: rows of data, the metric as a single sentence, the effect you measured and how long the work took. Say them aloud from the sheet until they come out identical every time
- For each kind of room you expect, decide the one sentence you want that interviewer repeating in a debrief, then check during the mock that you said it outright instead of implying it
- Rehearse answering the same project question twice in one sitting, the second time as though you had not just answered it, because the thing that needs fixing is the flatness that creeps into a repeated story
1 candidate reports. Individual accounts describe a particular role and hiring cycle.
Yahoo Senior+ Machine Learning Engineer Interview Experience — Great Technical Screen, Then the Role Got Paused
Yahoo News interview (April), Round 1. Question 1: Talk about your background and one of your projects in detail — they dug deep into one particular project. Key points for the answer (aim for a total of 3–6 minutes) and my own suggestions: Quick background (20–30s): one sentence on the role, your responsibilities on the team, and list 1–2 projects. Deep-dive framework (3–4 minutes, using STAR):…
Read full experiencePracHub editorial advice for the preparation topics above.
Collapsing cancellation and payment failure into one churn number.
Involuntary churn from expired or declined payment instruments is a large and volatile share of gross churn, and it responds to retry schedules, card-updater coverage and billing provider, not to anything in the product. It also resolves late, so a period that looks involuntary today can be a successful retry next week, and reading the split before the dunning horizon closes overstates it. Compounding this, cancel-at-period-end means the cancellation request and the entitlement end are different timestamps on different rows, so a churn curve keyed on cancel_requested_ts and one keyed on churn_ts disagree by a full billing period.
Counting plays without a qualification threshold, or changing the threshold without restating history.
Playback arrives as heartbeats, so a play only exists once you decide what counts, and the common 30-second convention is not a neutral analytics choice: in music it is also the boundary at which a play becomes payable, which makes the warehouse definition a payout definition. The threshold interacts violently with content length, so a catalogue of three-minute tracks and one of forty-minute episodes move in opposite directions when you change it, and a skip-heavy surface can add plays while adding no hours. Any metric mixing pre-threshold and post-threshold counts, or pooling short-form and long-form on a per-stream basis, moves by double digits for reasons that have nothing to do with the product.
Sizing estimates built on unnamed, unrevisable assumptions
Write each assumption as a named number you can change, then show the arithmetic so the interviewer can challenge one input instead of the whole answer. Finish by saying which assumption the result is most sensitive to, which matters more than the point estimate.
Reading a dozen metrics with no multiplicity control
Nominate one primary metric before launch and treat the rest as guardrails or exploratory, with Bonferroni or Benjamini-Hochberg applied when you intend to make claims from them. Twenty independent tests at 0.05 under the null produce at least one false positive about 64 percent of the time.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
What metrics would you use to evaluate the performance of a classifica…
What metrics would you use to evaluate the performance of a classification model?
Approach
- Say how the offline result would be validated online before it is trusted.
- 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.
Follow-up
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
Measure catalogue concentration with a Gini written from scratch
One calendar month of fct_stream (content_version_id, played_seconds, is_qualified) joins to dim_content_version (content_version_id, content_id, content_type). Roll versions up to content_id, then report, overall and per content_type: the number of content_ids, the share of qualified hours held by the top one percent, and the Gini coefficient over content_ids by hours. Write the Gini from its definition rather than importing one. State which content_ids are in the population you measure over, and defend that choice.
Approach
- Roll versions to content_id before anything else. A remaster or a dubbed rendition is a separate content_version_id sharing a content_id, so leaving it split spreads one work's hours across rows and reports the catalogue as less concentrated than it is.
- Decide and state the population: content_ids with at least one qualified stream this month measures concentration among what was played, while the full territory-eligible catalogue adds the zero-hours tail and pushes both statistics up. Either is defensible; the two are not comparable to each other.
- Implement Gini on the ascending-sorted hours vector as 2 times sum(i times x_i) over (n times sum(x)) minus (n + 1) over n, with i one-based. Verify it on two hand-made vectors before pointing it at real data.
- For the top one percent, take ceil(0.01 times n) content_ids by hours descending over the total. Say what you did at the boundary, because with a few thousand titles the rounding rule moves the answer visibly.
- Compute each content_type inside its own population, and note that the per-type Ginis do not aggregate to the overall one: concentration is not additive across strata, and the overall figure carries between-type inequality the per-type figures exclude.
Worked solution 25 min
- Filter to is_qualified, join content_id and content_type, then group by content_id summing played_seconds and dividing by 3600.
- Write gini(x): drop negatives, sort ascending, n = len(x), return 2 times (arange(1, n+1) times x).sum() over (n times x.sum()) minus (n + 1) over n. Assert gini([1,1,1]) is 0 and gini([0,0,1]) is 2/3.
- Top one percent: k = ceil(0.01 times n); sort hours descending and divide the k-largest sum by the total.
- Repeat both statistics inside each content_type group, keeping each type's own n.
- Assemble a frame of scope, n_content_ids, top1pct_share and gini, with one overall row plus one row per content_type.
Follow-up
- This month's Gini rose by 0.03. Name three things other than a ranking change that could produce that.
- How would you measure breadth so a ranking team could act on it, rather than reporting one summary number?
- A rights window expired mid-month and removed 400 titles. How do you keep the month-over-month comparison honest?
Permutation test for hours per account across two ranker arms
arm_hours holds one row per account: account_id, arm in {control, treatment}, qualified_hours over a seven-day window. Roughly 40 thousand accounts per arm, about 38 percent of them at zero hours, and the non-zero tail is long. Without calling a library test function, write a permutation test on the difference in mean hours with 10,000 relabellings. Then run it as two parts: the difference in the share of accounts with any hours, and the difference in mean hours among accounts with hours. Report all three and say which belongs in the readout.
Approach
- Shuffle the labels, not the data. Draw a permutation of the arm indicator over accounts, which is the unit that was randomised, and hold the hours vector fixed.
- Make each replication O(n): precompute the grand sum and the arm sizes, so a shuffled difference is the treated subset sum over n_t minus (grand sum minus that subset sum) over n_c. Ten thousand replications then take seconds instead of a minute.
- Use the two-sided p-value (1 + count of permuted absolute differences at or above the observed) divided by (B + 1). The plus one is not cosmetic: it makes the p-value valid rather than optimistic, and it means the smallest reportable value here is 1/10001, not zero.
- For the two-part version, run the same machinery on the 0/1 indicator for the rate, then on the non-zero subset for the conditional mean, and say plainly that conditioning on a post-treatment outcome breaks the randomisation, so the conditional arm is descriptive rather than causal.
- Report the rate test and the overall mean test as the result, with the conditional mean as colour, and give the effect size in hours beside each p-value, because at 80 thousand accounts almost anything is detectable.
Follow-up
- The permutation p-value on the mean is 0.03 and the rate test is flat. What is the most likely explanation, and does it change the decision?
- How would CUPED on pre-period hours change your power here, and what would disqualify a covariate?
- Accounts are households. Does that affect the validity of this test, or only its interpretation?
Write a SQL query to find the top 5 products by sales in a dataset.
Write a SQL query to find the top 5 products by sales in a dataset.
Approach
- State the window function and its partition and ordering out loud before writing it.
- 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?
Implement a function in Python to calculate the mean and median of a l…
Implement a function in Python to calculate the mean and median of a list of numbers.
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- State the window function and its partition and ordering out loud before writing it.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
Follow-up
- What breaks if events arrive late or out of order?
- How does the query change if the join becomes one-to-many?
Rebuffer ratio by point of presence, excluding start failures
fct_stream carries cdn_pop, device_type, network_type, played_seconds, rebuffer_seconds and end_reason (enum including 'playback_error'). For streams with started_at in the trailing 24 hours, return one row per (cdn_pop, device_type, network_type) with two figures: rebuffer_ratio = SUM(rebuffer_seconds) / SUM(played_seconds), computed only over rows with played_seconds > 0; and start_failure_rate = the share of all rows in the cell with played_seconds = 0 and end_reason = 'playback_error'. Restrict output to cells with at least 500 streams and order by rebuffer_ratio descending.
Approach
- Do it in one pass with conditional aggregation: SUM(rebuffer_seconds) FILTER (WHERE played_seconds > 0) over SUM(played_seconds) FILTER (WHERE played_seconds > 0), or the equivalent SUM(CASE WHEN ...) on engines without FILTER. Two separate scans risk the numerator and denominator disagreeing about which rows are in the cell.
- Wrap the denominator in NULLIF(..., 0) so a cell in which every stream failed before first frame returns NULL rather than raising a division error — and so it is visibly absent rather than silently zero.
- The failure rate's denominator is every row in the cell, including the zero-play ones. That is the whole point of the pair: the rows excluded from the ratio have to be counted somewhere, or a point of presence that fails before first frame reports a perfect ratio.
- Apply the 500-stream minimum with HAVING COUNT(*) >= 500 before ordering, otherwise a cell with three streams and one stall tops the list at a ratio no one should act on.
Worked solution 15 min
- Write the cell aggregate exposing the raw components: COUNT(*), the two filtered sums, and the count of zero-play playback errors.
- Derive both rates in an outer SELECT so the raw counts stay visible when a cell looks wrong.
- Recompute the ratio ungrouped over the same filtered rows and confirm it equals the played_seconds-weighted mean of the cell ratios.
Follow-up
- Two points of presence show the same rebuffer ratio but one has twice the start-failure rate. Which do you escalate, and what does the second number tell you that the first cannot?
- How would you decide whether a cell's ratio moved beyond what day-to-day variation explains, given that cell sizes differ by orders of magnitude?
Given a dataset with user interactions, how would you aggregate the da…
Given a dataset with user interactions, how would you aggregate the data to analyze user engagement?
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.
- 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?
- How would you detect that the metric is being gamed rather than genuinely improving?
How would you approach a project to increase user engagement on a plat…
How would you approach a project to increase user engagement on a platform?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- 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?
- Which segment would you cut first, and what would that rule out?
If given a large dataset, how would you determine which data points ar…
If given a large dataset, how would you determine which data points are the most relevant?
Approach
- 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.
- State what result would change your recommendation, so the answer is falsifiable.
Follow-up
- Which segment would you cut first, and what would that rule out?
- How would you detect that the metric is being gamed rather than genuinely improving?
You have a dataset with missing values. How would you handle this?
You have a dataset with missing values. How would you handle this?
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.
- Decompose the metric into the rates that drive it, and say which one you would check first.
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?
What is A/B testing, and how would you design an experiment for it?
What is A/B testing, and how would you design an experiment for it?
Approach
- Name the guardrails that would stop a launch even on a positive primary result.
- Name the randomisation unit first; it decides the variance and what the test can detect.
- Say whether units interfere with each other, and switch design if they do.
Follow-up
- What would you do if you could not randomise at all?
- How would you handle interference between treated and control units?
How do you approach feature selection in a dataset?
How do you approach feature selection in a dataset?
Approach
- Work from the decision backwards to the evidence you would need.
- Clarify what is being asked and what a complete answer would contain.
- 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?
Randomise on account or profile for a personalisation test
You are testing a personalisation change to the home row. Assignment could be on profile_id or on account_id. From dim_profile and fct_stream: 38 percent of accounts have two or more non-deleted profiles, those accounts hold 61 percent of qualified hours, and on multi-profile accounts 23 percent of qualified streams start on a profile other than the one that device last used. The primary metric is qualified hours per account-week. Choose the randomisation unit, name the interference you accept or avoid, and quantify what the choice costs in power.
Approach
- Match the assignment unit to the estimand. The metric denominator is the account-week, so profile-level assignment splits a single metric row across both arms and leaves no defensible way to attribute that row.
- Name the leakage mechanism concretely rather than gesturing at it: a shared TV or speaker plays on whatever profile is active, continue-watching and queue state are visible account-wide, and 23 percent cross-profile starts means a treated profile physically changes what a control profile on the same account is shown.
- State the direction of the damage. Leakage makes control partially treated, so the estimate is attenuated toward zero and a null becomes uninterpretable, which is worse than a wider confidence interval.
- Price the alternative with the clustered design effect, DEFF = 1 + (mbar - 1) * rho, where mbar is mean profiles per account and rho the intra-account correlation of profile-week hours, estimated from a one-way ANOVA on the pre-period.
- Decide on the asymmetry: the clustering cost is bounded and computable, the dilution bias is neither. Randomise on account_id and serve the treated model to every profile inside a treated account.
Worked solution 25 min
- Compute mbar exactly from dim_profile with is_deleted = false rather than assuming it; with 38 percent of accounts at two or more profiles, roughly 1.5 profiles per account is the working figure.
- Estimate rho as the intra-class correlation of profile-week qualified hours within account over four pre-period weeks: rho = between-account variance / (between + within). Around 0.4 is typical when a household shares taste and a device.
- DEFF = 1 + (1.5 - 1) * 0.4 = 1.20, so account randomisation needs 20 percent more accounts for the same power, and at fixed sample size the MDE is sqrt(1.20) = 1.095 times larger, about 9.5 percent worse.
- Write the decision in one sentence: accept a 9.5 percent wider MDE to avoid an attenuation of unknown size on the 61 percent of hours that sit on multi-profile accounts.
Follow-up
- Bound the leakage rather than assuming it: how would you use single-profile accounts as a comparison group to estimate the dilution in a profile-randomised test?
- The serving layer keys on profile_id and cannot read account_id at request time. How do you get account-level assignment anyway?
- Some households share one TV across two billing accounts. Does that break account randomisation, and how would you detect it?
Completion rate fell while every duration decile improved
Duration-normalised completion rate — qualified streams with completion_ratio >= 0.9 over qualified streams with non-null duration_seconds — fell from 0.41 to 0.36 across six weeks. Computed inside each (content_type, duration decile) cell, every cell is flat or up. Using fct_stream (completion_ratio, is_qualified, content_version_id, started_at, start_source) joined to dim_content_version (content_type, duration_seconds, catalogue_added_ts, parent_id), reconcile the two numbers and say which the content team should act on. Deliverable: a decomposition separating mix shift from within-cell change, with the size of each in completion-rate points.
Approach
- Name the mechanism before computing anything. completion_ratio is mechanically decreasing in duration_seconds, so the global rate is a duration-mix-weighted average of cell rates and moves whenever the weights move with every cell rate held fixed. That is not a paradox, it is the aggregation doing what it was always going to do.
- Run the two-term decomposition: total change equals sum over cells of (w_new - w_old) * r_old for mix, plus sum over cells of w_new * (r_new - r_old) for within. Those two terms are exhaustive — the sum telescopes back to the observed change exactly — because this arrangement already carries the whole weight-by-rate interaction inside the within term. There is no third quantity to add. State the convention anyway: the mirror arrangement, mix at r_new plus within at w_old, is equally exact and parks the interaction in mix instead, and the two attributions differ by exactly sum (w_new - w_old) * (r_new - r_old) whenever weights and rates moved together. Report in completion-rate points so the argument is about magnitudes rather than adjectives.
- Find which weights moved and why. Cell share of qualified streams by week, joined to catalogue_added_ts and parent_id, will usually name a season of long episodes, a podcast push, or a shift in content_type as the cause within one query.
- Distinguish a mix shift the product caused from one the calendar caused, by cutting the weight change by start_source. A ranker that began surfacing long-form is a product decision with a durable consequence; a release landing in the window reverses by itself, and the two warrant opposite responses.
- Answer what was actually asked. The within-cell term is the quality signal and it is flat to up, so the content team should not chase it. The headline needs the fixed reference-month weights the metric definition already specifies, and the unweighted version should come off the dashboard rather than be explained every six weeks.
Follow-up
- Fixed reference weights stop the mix moving the number, but a genuine, permanent shift toward long-form then never appears. How do you cover that gap?
- The deciles are cut from some population. What happens to the decomposition if the decile boundaries themselves move between the two periods?
Four days spend equal time on query work, statistics, modelling and product judgement at deliberately shallow depth, which produces a scored map of where you actually stand. The last three days spend everything on the two areas the role weights most, and close by re-running day one to measure movement.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Breadth pass: query fluency
- Solve six prompts spanning aggregation, joins, window functions and date arithmetic in 60 minutes total, stopping at 10 minutes each whether or not it works, and mark every prompt as solved, solved slowly, or stuck.
- For each unsolved prompt write the single blocking sentence (I lost the grain, I did not know the frame clause, I could not express the date boundary) instead of reading the solution.
- Translate one pandas transformation you know well into SQL and one SQL query into pandas, checking that both return the same row count and the same totals.
Deliverable: A scored six-row table, one line per prompt, saved for the day-seven re-run.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Breadth pass: statistics and inference
- Answer ten short questions in writing with nothing open: what a p-value is conditional on, what a 95 percent interval covers across repeated samples, when a paired test is the right one, what the bootstrap estimates, why multiple comparisons inflate false positives, how controlling the family-wise error rate differs from controlling the false discovery rate, what power depends on, what a missed real effect costs a product, the three situations where the central limit theorem does not rescue you (small n, very heavy tails, dependent observations), and what a standard error is the standard deviation of.
- Grade yourself against a reference and count only the answers that were exactly right, not the ones that were nearly right.
- Rewrite the two weakest answers the following morning from memory in full sentences.
Deliverable: Ten graded answers with an honest count of exact hits.
Practice prompt ↗Practice prompt ↗Practice prompt ↗03Breadth pass: modelling
- Take one tabular dataset end to end in 90 minutes: a leakage-safe split, a baseline that is not a model (majority class or historical mean), one regularized linear model, one gradient-boosted tree, and a single evaluation metric chosen before you look at any result.
- Write why that metric fits the cost structure: precision at a fixed recall for alerting, calibration for anything feeding a price or a threshold, ranking metrics for retrieval, and note that area under the ROC curve is insensitive to class balance in a way that can flatter a rare-positive problem.
- Name the leak you were most likely to introduce (an encoding fit on all rows before splitting, or a feature computed after the label's timestamp) and write the check that would have caught it.
Deliverable: A notebook whose first cell states the metric and the baseline, plus two lines on what beat what and by how much.
Practice prompt ↗Practice prompt ↗Practice prompt ↗04Breadth pass: product judgement
- Answer three case prompts aloud at 15 minutes each, timing how long passes before you state a success metric.
- For one case write the first segmentation you would run and the row counts you expect per segment, so that a tiny segment cannot quietly drive the conclusion.
- Take a metric definition you did not write, from a public dashboard, a textbook, or documentation you already have open, and list every place two analysts implementing it would diverge: which rows the denominator admits, whether the unit is an account or a person, what the time window is anchored to, and what happens to data that arrives late. Then write the one question that would close the largest of those gaps.
Deliverable: Three recorded case answers plus an ambiguity list for a metric someone else defined, ending in the single question you would ask about it.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Depth, first area
- Rank the four areas by how many bullet points in the role description each one covers, pick the top one, and spend the entire day inside it.
- Work the six hardest problems you can find in that area and for each write the generalizable move you should have reached for first, rather than the answer.
- Re-solve the two you failed the same evening with notes closed.
Deliverable: Six generalizable moves written as instructions to yourself, not as solutions.
Practice prompt ↗Practice prompt ↗06Depth, second area, and the seam between them
- Repeat the depth protocol on the second-ranked area with the same six-problem structure.
- Construct one problem that requires both areas at once, for example a metric redefinition whose effect you must validate with a test whose readout you then have to query.
- Solve your own combined problem end to end and note where the handoff between the two areas cost you time.
Deliverable: One combined problem, solved end to end, with the handoff failure written down.
Practice prompt ↗Practice prompt ↗07Integration and re-measurement
- Re-run the six prompts from day one under the same clock and compare both correctness and time.
- Run a 60-minute mixed mock that moves between areas without warning, since switching cost is what breadth passes do not train.
- Write the two areas you would still fail on, and the sentence you will use in the interview when you hit one of them.
Deliverable: A before-and-after score table plus a written plan for the two remaining gaps.
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.
What motivates you to excel in your work?
What motivates you to excel in your work?
Approach
- Name the disagreement or constraint, and how you resolved it with evidence.
- Close with what you would do differently, concretely.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Scope a one-line request about home row performance
A director messages you: "Is the new home row working?" Nothing else. A new ranker_version has been serving a fraction of profiles for eleven days. You have fct_impression (surface, slate_position, ranker_version, is_exploration_slot, logging_propensity, experiment_assignment_id, was_clicked) and fct_stream (impression_id, start_source, is_qualified, played_seconds). You get a fifteen-minute call before they go into a rollout meeting. Deliverable: the three questions you ask before writing any SQL, the single primary metric you commit to with its guardrail, and the questions you tell them this data cannot answer.
Approach
- The probe is whether you convert a vague request into a decision before producing a number. Ask what happens at each answer — rollback, widen, iterate — because a question whose answer changes nothing is a report request and should be scoped as one.
- Pin the unit of analysis out loud. fct_impression is at (profile, slate, slot) grain and experiment_assignment_id is per assignment, so the comparison must be aggregated to the assignment unit first; comparing impression-level rates lets a change in slate length move the metric on its own.
- Commit to one primary metric from the tree — qualified hours per active account-week for assigned accounts — and name the guardrail pair explicitly: share of qualified streams with start_source = 'autoplay_continuation', and median completion_ratio within content_type. A ranker can lift qualified stream counts by queueing short items that clear the 30-second threshold, and the guardrail is the only thing that catches it.
- State the refusals with structural reasons, not time reasons: eleven days gives no matured cohort, so month-6 retention and net revenue per active account-month are unanswerable; and logging_propensity is populated only where is_exploration_slot = true, so the positivity condition for an off-policy estimate fails outside those slots.
- Write the scope back in one paragraph — decision, metric, guardrail, the date the read becomes valid — and get it agreed in the thread before querying, so the number that arrives is the number that was asked for.
Follow-up
- They reply "just give me click-through by slate position." What do you say, and what would that number actually tell them?
- The eleven days include a weekend and a large release landing on day six. Does that change the metric you commit to, or only the read date?
- What would have to be true for you to be willing to answer the retention question from this experiment?
Arbitrate three requests for the same analyst week
Three requests land on the same Monday for the same week of your time. Growth wants trial-to-paid conversion recut by signup_channel before a budget meeting on Thursday. The playback team wants rebuffer ratio cut by cdn_pop, device_type and network_type after a bitrate ladder change went out Friday. Catalogue wants a displacement estimate for a title that arrived on a rights window last month. You have roughly four working days. Deliverable: your ordering with the criterion behind it, what you tell the two people who do not get the week, and one thing you ship to all three by Tuesday.
Approach
- The probe is your criterion, not your ordering. Rank by how reversible the pending decision is and how fast the evidence decays, and say so; ranking by requester seniority is the default answer and reads as one.
- Put the playback request first on those grounds: a bitrate ladder change is live and degrading real playback now, and rebuffer ratio is defined on a trailing 24 hours, so the evidence is perishable and the query is small. Cheap and perishable beats expensive and durable.
- Ask each requester what they do differently at each plausible answer. The trial-to-paid recut is a defined tree metric — trailing 28 days, read at trial length plus 21 days so dunning retries have resolved — so it is largely a filter plus an hour confirming that unattributed stays its own line rather than being reallocated pro rata.
- Treat the displacement estimate as the only genuinely new analysis and scope it rather than squeezing it: it needs a matched comparison group and a pre-registered window, because consumption of the rest of the catalogue moves on the release calendar regardless. Defer it with a date and a stated shape, never silently.
- Reply to all three in one thread with the ordering and the criterion visible, so a stakeholder who disagrees argues with the criterion instead of escalating about their position in the queue.
Follow-up
- The catalogue lead escalates to your manager on Tuesday. Walk me through that conversation.
- How does the ordering change if the bitrate ladder change was already rolled back on Saturday?
- All three deadlines are genuine and none can move. What do you actually cut?
- 01
What motivates you to excel in your work?
- 02
A director messages you: "Is the new home row working?" Nothing else. A new ranker_version has been serving a fraction of profiles for eleven days. You have fct_impression (surface, slate_position, ranker_version, is_exploration_slot, logging_propensity, experiment_assignment_id, was_clicked) and fct_stream (impression_id, start_source, is_qualified, played_seconds). You get a fifteen-minute call before they go into a rollout meeting. Deliverable: the three questions you ask before writing any SQL, the single primary metric you commit to with its guardrail, and the questions you tell them this data cannot answer.
- 03
Three requests land on the same Monday for the same week of your time. Growth wants trial-to-paid conversion recut by signup_channel before a budget meeting on Thursday. The playback team wants rebuffer ratio cut by cdn_pop, device_type and network_type after a bitrate ladder change went out Friday. Catalogue wants a displacement estimate for a title that arrived on a rights window last month. You have roughly four working days. Deliverable: your ordering with the criterion behind it, what you tell the two people who do not get the week, and one thing you ship to all three by Tuesday.
Is this an official Yahoo interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Yahoo. Rounds and questions reflect what candidates have reported, not a process Yahoo has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult are the interviews at Yahoo?
The interview process is considered average in difficulty, with a mix of technical and behavioral questions. Adequate preparation is crucial, particularly in technical areas, to ensure you can confidently showcase your skills.
PracHub interview research ↗What differentiates successful candidates?
Successful candidates often demonstrate a combination of strong technical abilities, effective communication skills, and a collaborative mindset. Being able to articulate your thought process during problem-solving is particularly valued.
PracHub interview research ↗What is the company culture like at Yahoo?
The culture at Yahoo emphasizes collaboration, innovation, and a focus on delivering value to users. A positive attitude and the ability to work well within teams are essential for success.
PracHub interview research ↗How long does the interview process typically take?
The interview process can vary, but candidates can expect a timeline of a few weeks from initial application to final interviews. It’s advisable to remain responsive and prepared throughout this period.
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