Interview guides · Brown University
Brown University Data Scientist Interview Questions & Guide 2026
Modeling drills for a Brown University data scientist interview: baselines, regression interpretation, class imbalance, model defense.
The 60-second brief
The role of a Data Scientist at Brown University is critical in leveraging data to drive informed decision-making across various departments and research initiatives. This position is centered around analyzing complex datasets, developing predictive models, and generating actionable insights that support the university's mission of advancing knowledge and promoting scholarly excellence. As a Data Scientist, you will play a pivotal role in enhancing research capabilities, improving operational efficiencies, and delivering impactful results that benefit both the university community and external stakeholders.
Learn the economics of the product category before the loop. Marketplaces, subscription products and ad-supported products turn on different core quantities (match rate and liquidity, retention and churn, fill rate and yield) and fail in different characteristic ways.
Focus areas
- Read item difficulty and discrimination before trusting accuracy
- Align cohorts to term weeks, not calendar weeks
- Model seat activation as the renewal leading indicator
Overview
In this position, you will collaborate with diverse teams, including faculty, researchers, and administrative staff, to tackle intricate problems ranging from optimizing university operations to enhancing student engagement and retention. The impact of your work is far-reaching, influencing strategic decisions that shape the future of the institution. You will have the opportunity to contribute to projects that span various domains, from education analytics to healthcare research, making this a dynamic and rewarding role for those passionate about data-driven solutions.
The Brown University interview process
Brown University candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
HR Screening
Most candidates lose this call inside the first two minutes, during the walkthrough of their own background. The account runs chronologically, sits at the level of tools and titles, and never arrives at a decision anyone could have disagreed with. Anchor on a problem instead of a timeline: what the team could not answer, what you did about it, what happened next. Ninety seconds is enough, and stopping on time leaves room for the half of the call that belongs to you. What you ask about how work gets prioritised signals your level more reliably than the walkthrough does.
What to demonstrate
- Whether your background summary has a shape (problem, decision, consequence) or is a chronological list of tools and employers
- Whether you can account for gaps, short stints and the reason you are looking, unprompted and without hedging
- The substance of the questions you ask back, which an experienced screener reads as a level signal
How to prepare
- Time your opening walkthrough against a clock. If it runs past two minutes, compress the earliest role into a single clause and spend the recovered time on the most recent one
- Write one honest sentence for every gap or short stint visible on your resume and offer it before being asked about it
- Prepare questions about how work arrives and gets prioritised: who writes the request, how often priorities change, and what happens to an analysis after it is delivered
Technical Assessment
A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.
What to demonstrate
- Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
- Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
- Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.
How to prepare
- Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
- Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
- If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
Panel Interview
Where a loop ends with a senior leader, that conversation is rarely another skills test. The technical signal already exists by then, so the questions tend to open up: what you would look at first, where a metric you have heard about could mislead, what you would push back on. The decision being made is scope, which in practice means level and how much you would be trusted to own unsupervised. Treating it as a formality is the usual mistake. An open question late in the day is still being scored, and a vague answer reads as someone who has not run anything themselves.
What to demonstrate
- Whether your view of the business has anything specific behind it, given that you are working only from what is public and are expected to say so
- Whether the scope of work you describe owning matches the scope of the role, instead of sitting a level below it
- Whether you can disagree with something concrete and stay useful about it, rather than agreeing with everything said in the room
- Whether your questions are ones only this person could answer, as opposed to ones the recruiter already covered
How to prepare
- Build one view you could defend for two minutes using only public information: what the funnel probably looks like, which metric likely drives decisions, and where that metric could mislead. Being wrong for a stated reason survives this round; having no view does not
- Write down the largest piece of work you have owned from question to decision, who else touched it, and what you decided alone, then check that it reads at the level you are interviewing for
- Prepare one thing you would want changed if you joined and phrase it as a question rather than a verdict, so it opens a conversation instead of closing one
Where candidates lose points
Adaptive item selection holds observed accuracy flat by construction.
A selector targeting a fixed success probability, say 70%, will keep measured first-attempt accuracy near 70% whether learners are improving or not, because as theta rises the engine simply serves harder items. Reporting 'accuracy improved 3 points' on adaptive content therefore usually means the selector got more conservative, not that anyone learned more. Accuracy is only interpretable on a fixed form with unchanged item versions, which is why the first-attempt accuracy metric above carries both restrictions.
Learner-level standard errors on class-level interventions.
Anything an instructor controls, and anything deployed by school, is assigned at the section or school level, and outcomes within a section are correlated through the shared instructor, schedule, and device fleet. Treating the learner as the unit of independence understates variance by the design effect 1 + (m - 1) * rho for roughly equal cluster sizes. At a typical section size of 25 and rho of 0.15 that is a factor near 4.6 on variance, which routinely converts a null into a 'significant' result.
Building features from data that postdates the prediction time
Check every feature against the timestamp at which the model would actually score, and drop anything computed from a window that includes or follows the label event. For a forecasting use case, split train and test by time rather than at random, and split by entity when the same entity recurs.
Extrapolating a first-week lift inflated by novelty effects
Plot the treatment effect by days since first exposure instead of quoting one pooled average. A lift that decays toward zero across the test window is behaviour that will not persist, and annualising it produces a forecast that misses by an order of magnitude.
Questions & practice
Can you explain the concept of overfitting and how to prevent it?
Medium · machine learning and modelling
Approach
- Set a baseline first, so any model has something honest to beat.
- 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
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
What metrics would you use to evaluate the performance of a regression model?
Medium · machine learning and modelling
Approach
- Check what information would not exist at prediction time, and exclude it.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
Simulate the gain a bottom-quartile selection manufactures
Medium · regression to the mean · simulation · measurement error · selection bias
Observed quiz scores are a true score plus independent noise, both normal, with reliability r equal to true-score variance over observed-score variance. Simulate 200,000 learners, standardise the pretest to mean 0 and SD 1, select the bottom quartile on the pretest, and measure the mean pretest-to-posttest change with no intervention at all. Report the manufactured gain for r in {0.5, 0.7, 0.9, 1.0}, and give the closed form your simulation should reproduce. Use numpy only, no statistical packages.
Approach
- Parameterise by r directly: draw the true score with variance r and each noise term with variance 1 - r, so the observed score has unit variance and reliability exactly r by construction. Draw one true score and two independent noise terms per learner.
- Select on the pretest and only the pretest. Selecting on the true score, or on the average of the two measurements, removes the correlation between selection and the pretest's own noise, and the artefact disappears. That sensitivity is the lesson.
- Compute the mean of posttest minus pretest over the selected group. The true score cancels in the difference, so whatever remains is entirely the difference of two noise draws conditioned on the first being low.
- Check against the closed form. For jointly normal standardised scores, E[posttest | pretest] = r * pretest, so the expected gain is (1 - r) * |E[pretest | bottom quartile]|, and E[pretest | bottom quartile] = -phi(z_0.25) / 0.25 = -1.2711.
- Extend the script with a control group selected by the identical rule from an untreated population and show the difference of differences returns to zero. That is the design fix you would actually propose, not a caveat in a footnote.
Worked solution (25 min)
- For each r: t = rng.normal(0, sqrt(r), n); e1, e2 = rng.normal(0, sqrt(1 - r), n) twice; pre = t + e1; post = t + e2.
- sel = pre <= np.quantile(pre, 0.25); gain = (post[sel] - pre[sel]).mean().
- Compare gain to (1 - r) * 1.2711 and print the absolute difference.
- Repeat the whole loop over the four r values and tabulate simulated against closed form.
- Add the untreated control arm selected by the same rule and report the difference of differences.
Expected result: Mean manufactured gain close to (1 - r) * 1.2711 standard deviations: about 0.636 at r = 0.5, 0.381 at r = 0.7, 0.127 at r = 0.9, and 0 at r = 1.0, each within roughly 0.01 at 200,000 draws. The difference of differences against an identically selected control is zero within Monte Carlo error at every r.
Verify it yourself
- r = 1.0 must give a gain indistinguishable from zero; any systematic positive value means noise leaked into the true-score draw.
- Selecting the top quartile instead gives a mirror-image loss of the same magnitude.
- The Monte Carlo standard error on the selected group of about 50,000 is roughly 0.0045 at r = 0.5, so a discrepancy above about 0.015 is a bug, not sampling noise.
Follow-up
- A published case study reports large gains specifically for learners who started in the bottom quartile. What do you ask for before believing any of it?
- The posttest is twice as long as the pretest, so its reliability is higher. Does the manufactured gain grow or shrink, and why?
- Give a design that measures a real effect on exactly this selected population without a randomised control.
Find enrollments with no scored work using anti-joins
Medium · null semantics · anti-join · correctness
You have fct_enrollment(enrollment_id, learner_id, course_id, section_id, org_id, status, enrolled_at, due_date) and fct_assessment_response(response_id, learner_id, enrollment_id, submitted_at, scored_at), where fct_assessment_response.enrollment_id is NULL for work done outside any enrollment. Return every active enrollment with a due_date in the next 14 days that has no scored response attached, for an instructor at-risk list. Write it as an anti-join. A colleague's NOT IN version returns zero rows against production but the correct count against their small test extract. Explain exactly why, and fix it.
Approach
- Name the mechanism precisely: NOT IN expands to a conjunction of inequality comparisons, and x <> NULL is unknown rather than false, so once a single NULL enters the subquery list the predicate can never evaluate to TRUE and the result is empty. The test extract contained no work outside an enrollment, so it contained no NULLs, so it passed.
- Fix with NOT EXISTS and a correlated equality on enrollment_id. It tests row existence rather than list membership and is unaffected by NULLs elsewhere in the column. LEFT JOIN with an IS NULL filter is equivalent and usually plans the same; NOT IN with an added IS NOT NULL guard also works but leaves the landmine armed for the next reader.
- Decide what no scored work means before writing it. No response at all and responses that exist but are unscored are different at-risk lists, and rubric lag puts already-submitted work in the second. Return both counts rather than collapsing them.
- Filter status = 'active' and due_date BETWEEN CURRENT_DATE AND CURRENT_DATE + 14, comparing DATE to DATE. Casting a DATE against a timestamp midnight quietly drops the final day.
- Guard the complement in the other direction: joining enrollments to responses and counting enrollments fans out one enrollment with 40 responses into 40 rows, so the has-scored-work list needs COUNT(DISTINCT enrollment_id).
Follow-up
- Produce the complement list, the enrollments that do have scored work, without double counting, and state the grain of your join.
- An enrollment whose learner submitted work with enrollment_id NULL has done the work but is not attached to it. How would you attribute those rows, and what does attributing by learner and course risk?
- fct_assessment_response is partitioned by date. How would you bound the scan without changing the answer?
Verified mastery events with a delayed retention check
Medium · window functions · self-join · cohort definition
From fct_assessment_response(response_id, learner_id, objective_id, content_item_id, attempt_no, submitted_at, scored_at, score_points, max_points, scoring_mode, mastery_state_after, mastery_prob_after), count verified mastery events for one calendar month. A mastery event is the first time a (learner_id, objective_id) pair reaches mastery_state_after = 'mastered'. It is verified when a later response on the same objective, submitted at least 7 days after the crossing, scores at or above 0.8 of max_points. Return verified events, eligible events, the verified rate, and the share of crossings with no eligible check.
Approach
- Find the first crossing with ROW_NUMBER() OVER (PARTITION BY learner_id, objective_id ORDER BY submitted_at, response_id) over rows where mastery_state_after = 'mastered', keeping rn = 1 across all time, then filtering that result to the month. Filtering to the month first would count a re-mastering after a lapse as a fresh event.
- Attach the check with a LATERAL or correlated subquery selecting the earliest response on the same (learner_id, objective_id) with submitted_at >= crossing_at + INTERVAL '7 days'. Take the earliest, not the best: best-of turns the metric into did they ever eventually pass, which only rises as time goes by.
- Score the check as score_points >= 0.8 * max_points, guarding max_points > 0 and requiring score_points IS NOT NULL. A rubric row still awaiting grading has scored_at IS NULL and must be excluded from eligibility rather than counted as a failure.
- Set the denominator to pairs with an eligible check, and report eligible / crossings separately. That coverage share is the honest caveat and it falls for objectives that sit at the end of a course.
- State the reporting lag the definition forces: the month cannot close until the last day's crossings have had 7 days plus the rubric scoring lag to produce a check.
Worked solution (35 min)
- Build the all-time first-crossing CTE and assert its row count equals COUNT(DISTINCT (learner_id, objective_id)) within it.
- Filter crossings to the target month and count them.
- Add the LATERAL earliest-eligible-check join and count how many crossings get one.
- Compute verified_events, verified_rate and eligible_coverage, then re-run the whole thing with a 14-day delay to see how coverage responds.
Expected result: One row for the month with mastery_events, eligible_events, verified_events, verified_rate = verified_events / eligible_events, and eligible_coverage = eligible_events / mastery_events.
Verify it yourself
- verified_events <= eligible_events <= mastery_events holds.
- COUNT(DISTINCT (learner_id, objective_id)) in the crossing CTE equals its row count; a mismatch means a re-mastering slipped past the first-crossing filter.
- Widening the delay from 7 to 14 days must lower eligible_coverage. If verified_rate also jumps, selection into who returns after two weeks is driving the number, not retention.
Follow-up
- A learner who never returns to an objective has no eligible check. Excluding them assumes that missingness is unrelated to retention. How would you test that assumption with the data you have?
- If the engine team lowers the mastery threshold, this metric's numerator and denominator both move. Which guardrail catches that, and what would you watch on the item difficulty distribution?
- Objectives late in a course get fewer checks. How do you stop that from making late objectives look systematically better or worse?
Share a project where you had to make a data-driven decision. What was the outcome?
Medium · product sense and metrics
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- State what result would change your recommendation, so the answer is falsifiable.
- Fix the population and the time window before naming any metric.
Follow-up
- Which segment would you cut first, and what would that rule out?
- How would you detect that the metric is being gamed rather than genuinely improving?
How do you prioritize tasks when you have multiple deadlines?
Medium · product sense and metrics
Approach
- Fix the population and the time window before naming any metric.
- 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
- 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?
If tasked with predicting student performance, what factors would you consider, and why?
Medium · product sense and metrics
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Fix the population and the time window before naming any metric.
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?
Given a dataset with customer purchase history, how would you identify potential market segments?
Medium · product sense and metrics
Approach
- 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.
- 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?
Describe your process for designing an experiment to test a new educational intervention.
Medium · a/b testing and experimentation
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.
- Say whether units interfere with each other, and switch design if they do.
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?
Explain the difference between supervised and unsupervised learning.
Medium
Approach
- Work from the decision backwards to the evidence you would need.
- Clarify what is being asked and what a complete answer would contain.
- State your assumptions explicitly before working the problem.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Measure learning transfer you cannot observe directly
Hard · proxy metrics · selection bias · bounds
Leadership wants a metric for whether learners retain and transfer what they learn beyond the platform. No external assessment is available. Design the closest measurable proxy from fct_assessment_response (objective_id, content_item_id, content_version_no, submitted_at, is_correct, mastery_state_after) and dim_content_item (irt_b, version_no). State the construct you are not measuring, the direction of each bias your proxy carries, and bound the reported number given that 62% of mastered learners return for the delayed check and 44% of returners pass it.
Approach
- Name the construct first and concede it: durable, transferable competence demonstrated on unpractised tasks outside the platform. Nothing in the warehouse observes it, and no rearrangement of these tables will.
- Define the closest proxy precisely: a delayed check at least 7 days after first mastery on the objective, drawn from (content_item_id, content_version_no) pairs the learner has not seen, tagged to the same objective_id, with irt_b inside a stated band of the practised items so difficulty is not confounded with recall.
- State each bias with a direction. Survivorship: only returning learners are scored and returners are the more engaged, biasing the number up. Item overlap: any reused item measures memory for that item rather than the objective, biasing up. Range restriction: eligibility requires reaching mastery, so the metric is silent about everyone else. Near transfer only: same objective, same format, so it cannot speak to transfer at all, which is the word leadership used.
- Bound rather than point-estimate. With 62% returning and 44% of returners passing, the worst case (every non-returner would fail) is 0.62 x 0.44 = 27.3% and the best case (every non-returner would pass) is 0.273 + 0.38 = 65.3%. Report [27.3%, 65.3%] and treat the width as the headline finding.
- Narrow the interval by design, not by assumption: schedule the delayed check inside an assignment so return approaches universal. That is the only honest way to shrink the bound, and it turns a 38-point interval into a few points.
- Say what the metric is for: comparing arms or cohorts measured the same way, not asserting an absolute rate of outside-the-platform competence. Revisit only if an institution shares an external measure, and then state that the institutions willing to share are not a random sample.
Worked solution (35 min)
- Write the construct sentence and the one-line statement that it is unobserved in these tables.
- Write the proxy definition with its three restrictions: 7-day minimum delay, non-overlapping item versions on the same objective_id, irt_b matched within a stated band.
- Compute the bounds: 0.62 x 0.44 = 0.273 as the lower bound, 0.273 + 0.38 = 0.653 as the upper bound.
- List the four biases with directions, then write the design change (check embedded in an assignment) that raises the 62% and collapses the interval.
- State the metric's permitted use: between-arm comparison under identical measurement, not an absolute claim.
Expected result: A proxy defined as a 7-day-delayed check on non-overlapping item versions within an irt_b band on the same objective_id; four named biases with directions; the reported quantity given as bounds [27.3%, 65.3%] rather than 44%; and the return rate identified as the lever that narrows the bound.
Verify it yourself
- 0.62 x 0.44 = 0.273 and 0.273 + 0.38 = 0.653.
- The delayed check uses different item versions from those practised, matched on difficulty.
- The answer states that the metric supports comparison between arms, not an absolute claim about performance outside the platform.
Follow-up
- What would make you willing to report a point estimate instead of an interval?
- How would you detect that delayed-check items have leaked into practice content?
- An institution offers end-of-term exam scores. What do you do about the non-random set of institutions that offer them?
Verified mastery rate fell six points with usage flat
Hard · mastery · censoring · decomposition · clustering
Verified mastery rate fell from 0.72 to 0.66 month over month while active learners and submissions per learner held flat. Tables: fct_assessment_response (learner_id, objective_id, content_item_id, content_version_no, attempt_no, submitted_at, is_correct, mastery_state_after, mastery_prob_after) and dim_content_item (content_item_id, version_no, irt_b, irt_a, calibration_n). The metric carries a 30-day reporting lag and requires a delayed retention check at least 7 days after the mastery crossing. Establish whether learning regressed. Deliverable: a ranked list of causes, each eliminated by a named check.
Approach
- Split the rate into its two counts and chart them separately: crossings with an eligible delayed check available, which is the denominator, and crossings that passed it, which is the numerator. A rate that moves while its denominator is also moving is a composition question before it is a learning question.
- Test censoring next, because it is cheap and it invalidates everything downstream. Recompute the prior month's value as it stood at the same maturity as the current month. If the prior month at equal maturity also read 0.66, there is no regression, only an early read against a fully matured comparison.
- Test the decision rule. mastery_prob_after is a posterior from the knowledge-tracing model, so compare its distribution at the crossing response across the two months rather than only counting crossings. A retrained model or a moved threshold changes which learners enter the numerator at all and shows up as a shifted posterior, not as a usage change.
- Test the instrument. Compute the response-weighted mean irt_b of items used in delayed checks in each month, restricted to items with calibration_n at or above 200, and compare irt_a alongside it. A harder or differently discriminating retention form lowers the pass rate with no change in what learners know.
- Segment only once the artefacts are excluded, and segment cluster-aware: cut by grade_band, locale and is_assigned, then check how concentrated the move is across section_id. Outcomes correlate within sections through a shared instructor, schedule and device fleet, so a handful of sections can carry a headline move.
- If a residual survives, size it with the section as the unit of analysis and report an interval that carries the design effect, roughly 1 + (m - 1) * rho for near-equal sections, rather than a learner-level interval that will overstate certainty.
Follow-up
- If the drop survives every check, how would you design the follow-up study to establish cause, and at what unit would you randomise?
- The delayed retention check is itself served by the adaptive engine. What does that do to the verified mastery definition, and how would you fix it?
Suggested practice checklist
For someone who can already write the query and train the model but stalls when asked what to measure or whether a change is worth making. Metric definition and case structure come first; the technical work is kept as maintenance rather than the centre of the week.
Day 1 — Metric anatomy
- For three products you use daily, write one primary metric, two input metrics that plausibly move it, and one guardrail that would catch a cheap way of moving the primary at the cost of the product.
- For one of them, specify the metric precisely enough that two analysts would return the same number: numerator, denominator, unit of observation, time window, and how returning and deleted accounts are treated.
- Pick a ratio metric and write what happens to it when the denominator shrinks for reasons unrelated to the numerator, with a concrete example of that happening.
Deliverable: A one-page metric tree for one product, with the primary metric written as an unambiguous spec.
Day 2 — Diagnosing a drop without guessing
- Take the prompt "weekly active users fell 8 percent week over week" and write the segmentation plan before proposing any cause: platform, region, tenure cohort, acquisition channel, and whether the movement sits in the numerator or in a changed denominator.
- List the instrumentation failures that manufacture fake drops (a client release that stopped firing an event, a bot filter change, a shifted date boundary or timezone) and write the query that rules out each one.
- Rehearse stating the boring explanations first, seasonality and day-of-week composition, before reaching for a product cause.
Deliverable: A drop-diagnosis checklist short enough to recite from memory in under a minute.
Day 3 — Should we build it
- Take a feature idea and write it as a bet: what you believe is true, what would have to be true for it to pay off, the metric that would confirm it, and the effect size that would justify the engineering cost.
- Size the opportunity top-down and bottom-up, then reconcile the two numbers in writing instead of quoting whichever is friendlier.
- Write the counter-metric that would make you kill the feature even if it wins on the primary metric.
Deliverable: A one-page product memo ending in a decision rather than a list of considerations.
Day 4 — The places aggregate numbers lie
- Construct a Simpson's paradox numerically: two segments where the treatment wins within each segment yet loses overall, and identify the shift in segment weights that causes it.
- Take a heavy right-tailed quantity such as revenue per user and write why the mean is the wrong summary, which percentile you would report instead, and what a moving mean with a stable median tells you.
- Write your definition of a session for the product from day one, then name two real behaviours it misclassifies.
Deliverable: One page holding a worked Simpson's paradox table and a session definition with its two known failure cases.
Day 5 — Technical maintenance, aimed at metrics
- Solve four timed SQL prompts that all end in a ratio metric, so the question of grain stays live in every answer.
- Compute a 95 percent confidence interval for a proportion on a small sample, and state why the normal approximation is unreliable when either np or n(1 minus p) falls below roughly 10, along with which interval you would use instead.
- Take one metric from your day-one tree, write the query that computes it correctly, then write the query that computes it wrong in the most plausible way and explain how you would notice.
Deliverable: Four solved prompts plus a matched correct and plausible-wrong query for one metric.
Day 6 — Turning engineering work into data science stories
- Write three project stories as situation, decision, trade-off, outcome, each carrying one number and one thing you got wrong.
- For the story you will lead with, prepare an answer to "what would you do differently" that names a decision you made, not a constraint you were handed.
- Practise the sentence that reframes a systems project as a question project: the question the work answered, ahead of the pipeline it shipped.
Deliverable: Three written stories with the lead story delivered aloud and timed under four minutes.
Day 7 — Mock case and gap list
- Run a 40-minute mock case with someone playing a product manager who pushes back on your metric choice, and record it.
- Listen back and mark every moment you proposed a solution before the success metric existed.
- Rewrite those moments as the question you should have asked, and rehearse the first 90 seconds of the case until scoping comes before solving.
Deliverable: A recorded case plus a rewritten opening 90 seconds.
Rigour against a deadline
Nearly every data role forces a trade between the analysis you want and the one that fits the decision window. Prepare a case where you deliberately shipped something less rigorous, named the weakness to the person relying on it, and said what would change your answer. The naming is the part interviewers listen for.
How do you communicate complex data findings to non-technical stakeholders?
Medium · behavioural and stakeholder questions
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
- What did you decide not to do, and why?
- How did you know the outcome was caused by your change?
Account for an analysis you later discovered was wrong
Hard · postmortem · analytical rigor · ownership
Describe a case where you reported a result and later found it was wrong. Choose one where the error was yours and the number had already been used for a decision. Cover: the claim, the actual defect at the data or design level, how you found it, how long it had been live, who you told and in what order, and what you changed so the same class of defect cannot recur. The interviewer will push on the mechanism, not the apology. Probed: whether you understand your own failure modes well enough to have engineered around them.
Approach
- Pick an error with a nameable mechanism, such as a grain mistake, a survivorship filter, or a join that silently dropped age_gated learners. 'I misread a chart' has nothing testable in it.
- State the blast radius in decisions rather than in dashboards: what was decided, what was spent or promised, and to whom.
- Describe detection honestly, including whether someone else caught it and how long it ran undetected. A slow external catch is a usable answer; a vague one is not.
- Give the disclosure order and the reason for it: the decision owner first, with the corrected number and its direction in the opening sentence, then the wider audience.
- Close on the systemic fix and say whether it has fired since. A control that has never triggered on anything is a resolution, not a fix, and saying so is worth more than claiming otherwise.
Follow-up
- What did the corrected number change about the decision? If nothing changed, why did you escalate at all?
- Has the check you added caught anything since, and on what?
- What class of error would still get past you today?
Explain a risk score to a non-technical sales executive
Easy · communicating uncertainty · renewal risk · stakeholder communication
Your renewal-risk score joins fct_subscription_period to seat activation from dim_learner.first_activity_at and to pace adherence from fct_enrollment. For one institution with 900 seats_provisioned and 31% activation at term-week 6, it outputs a 0.62 probability of non-renewal. A sales VP asks whether you are losing the account or not. You have two minutes and no slides. Deliverable: the spoken answer, plus the one line you would put in the weekly account review so the number is not later quoted as a certainty. Probed: whether you can carry uncertainty and still give a decision.
Approach
- Answer the question that was asked before qualifying it. 'Treat this as at-risk and act this week' is the answer; the probability is the support for it.
- Translate the score into a frequency on a reference class the VP already trusts, such as how many of the last fifty accounts scored in the 0.55-0.70 band did not renew, instead of explaining calibration in the abstract.
- Name the driver that is still movable before period_end: 31% seat activation at term-week 6 can be changed this term, whereas last term's usage cannot, so that is where the conversation goes.
- State what would move the score and by when, so the number arrives attached to an action rather than as a verdict.
- For the written line, use a band and a review date rather than a bare decimal, because a single number in a document will be re-quoted without its interval.
Follow-up
- The VP asks for every account scored above 0.50. What do you tell them about where that threshold came from?
- How would you check whether 0.62 is calibrated at all, and on what sample?