A Data Scientist at Purdue University serves as a vital bridge between complex academic research, operational efficiency, and data-driven decision-making. In an environment defined by massive scale and diverse institutional data, your work directly influences how the university optimizes student success, manages research operations, and streamlines administrative processes. You are not merely a researcher; you are a builder of systems that translate raw data into actionable insights for the Purdue University community.
This role is critical because it requires navigating the intersection of high-level statistical rigor and practical, product-focused application. Whether you are analyzing student engagement metrics or diagnosing fluctuations in institutional key performance indicators, your contributions help shape the strategic direction of one of the nation’s leading research institutions. Expect a challenging but rewarding environment where your ability to communicate complex findings to non-technical stakeholders is just as important as your technical proficiency.
Application Review
reportedA screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.
What to demonstrate
- Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
- Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
- Whether timeline, location and compensation expectations make the rest of the loop worth scheduling
How to prepare
- Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
- Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
- Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
Initial Screening
reportedData Scientist covers at least four different jobs: experimentation, product analytics, causal work on observational data, and applied modelling that ships into a system. A screening call is the cheapest place to find out which of them is being hired for, and doing that diagnosis openly reads as senior rather than fussy. Ask what the last few pieces of work on the team actually were, and roughly how a week splits between querying, modelling and stakeholder time. Then say which parts of that you have done and which you have not. Claiming the whole range is the fastest way to be caught one round later.
What to demonstrate
- Whether you can distinguish the flavours of the role and locate your own experience inside one of them honestly
- Whether you name what you have not done instead of stretching to cover every line of the posting
- Whether your hard constraints (notice period, location, work authorisation, level) surface now rather than at offer stage
How to prepare
- Map the last two years of your time into rough percentages across query writing, experiment design, modelling and stakeholder work, so a question about scope has a real answer
- Mark every responsibility in the posting as done, adjacent or new, and prepare one sentence for each adjacent item naming the closest thing you have actually built
- Decide which logistics are non-negotiable before the call so you can state them in one sentence rather than negotiating live
Technical Assessment
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
Panel Interviews
reportedWhere 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
Final Panel Discussion
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
PracHub editorial advice for the preparation topics above.
Consent and age rules silently truncate the data, not just the joins.
Where age_gated is TRUE, behavioural logging and cross-system joins are restricted, so those learners are missing from the very tables used to compute engagement. An analysis that simply inner-joins will produce a population skewed to older learners and self-serve accounts while appearing complete. Check the age_gated share of every population you report on, and state it.
Pre/post gain studies that select on low pretest scores manufacture improvement.
Any measure with reliability below 1 produces regression to the mean, so a group chosen for scoring in the bottom quartile will score higher on retest with no intervention at all. The apparent gain scales with measurement error, which for a short quiz is large. The fix is a control group selected by the identical rule, or a design that models the pretest as a covariate rather than as a selection filter.
Over-explaining the method and under-explaining the implication
Lead with the answer and what you would do about it, then give the approach when asked. Roughly one sentence of method per three of implication is the right ratio for a stakeholder-facing answer; the interviewer already knows what a regression is.
Defining the cohort on a post-treatment condition
Ask how rows entered the table. Filtering on something that treatment itself influences, such as users who finished onboarding or accounts still active at ninety days, breaks comparability between arms; define the population at an entry point that precedes exposure and keep everyone in it.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Attach the calibration in force without merge_asof
You have responses (response_id, content_item_id, submitted_at, is_correct) and calibration_history (content_item_id, valid_from, valid_to, irt_a, irt_b), where intervals within an item are non-overlapping and the open interval carries valid_to as NaT. Attach to each response the irt_a and irt_b in force at submitted_at. You may not use pandas.merge_asof and you may not apply row-wise. responses has about 5 million rows, calibration_history about 40 thousand. Return the input frame plus two columns, NaN where no interval covers the timestamp.
Approach
- Sort calibration_history by (content_item_id, valid_from) and factorise content_item_id across both frames into a shared integer code, so an unknown item on the response side is detectable immediately rather than joining to nothing.
- Convert both timestamps to int64 seconds and build one composite key per side, code * 2**32 + seconds. With codes well under two billion and seconds near 1.8e9, that stays inside int64 and makes a single global search possible. State the second-level resolution assumption; interval boundaries are set at second granularity, so nothing is lost.
- Call np.searchsorted(calibration_keys, response_keys, side='right') - 1 once over the whole array. That gives, for each response, the position of the latest interval starting at or before it within the same item, because the composite key orders by item first.
- Invalidate bad candidates in two places: index -1, and a candidate whose code does not match the response's code, which happens when a response precedes its item's first interval and lands on the previous item's last row.
- Invalidate a third case that is easy to miss: the candidate has a non-null valid_to and submitted_at is at or after it, meaning the response falls in a coverage gap. Without this the previous interval's parameters leak onto uncovered responses.
- Take the parameters positionally with np.take and write NaN where any invalidation fired.
Worked solution 30 min
- codes = pd.factorize on the concatenated item ids, applied to both frames so the mapping is shared.
- cal_key = cal_code.astype('int64') * (1 << 32) + valid_from_seconds; resp_key built the same way; sort cal by cal_key.
- pos = np.searchsorted(cal_key, resp_key, side='right') - 1.
- valid = (pos >= 0) & (cal_code[pos] == resp_code) & (cal_valid_to_seconds[pos].isna() | (resp_seconds < cal_valid_to_seconds[pos])).
- Assign irt_a and irt_b via np.take(pos) where valid, NaN elsewhere, and report the NaN count by reason.
Follow-up
- A backfill wrote overlapping intervals for 200 items. How do you detect that before the join rather than after, and what do you do with those responses?
- The join is correct but peak memory is unacceptable. What changes, and which part of the approach survives?
- How would you test this without a golden output to compare against?
Audit response rows against the versioned content dimension
Write a check function over fct_assessment_response (response_id, learner_id, content_item_id, content_version_no, attempt_no, submitted_at, scoring_mode, scored_at, score_points, max_points) and dim_content_item (content_item_id, version_no, status, published_at, retired_at). Return one row per check with check_name, failing_count, denominator, and up to five example response_ids. Cover at least four checks: version pairs missing from the dimension, responses submitted before published_at or after retired_at, attempt_no that is duplicated or not gapless from 1 within a learner and item, and rubric_human rows still unscored more than 5 days after submitted_at.
Approach
- Do the existence check as a left merge on the pair (content_item_id, content_version_no) to (content_item_id, version_no) with indicator=True. Joining on content_item_id alone both hides the defect you are looking for and fans rows out by the number of versions per item.
- Evaluate the publication window only on rows that matched, and treat NULL retired_at as open-ended. Report the two directions separately: an early submission points at a publishing race, a late one points at a retirement that never removed the item from a live form.
- For attempt_no, group by (learner_id, content_item_id) and compare the sorted attempts to range(1, n+1). A duplicate and a gap are different defects with different causes, so emit them as two rows.
- For scoring lag, restrict to scoring_mode = 'rubric_human' with scored_at null and submitted_at older than 5 days. Anything more recent is expected lag, not a defect, and counting it makes the check permanently red.
- Give every check its own denominator. A shared total row count makes the version check look negligible and the attempt check look enormous when neither is true, because their natural units are rows and (learner, item) groups respectively.
Follow-up
- Which of these four would you page someone about at 2am, and which is a ticket for the week?
- How do you keep this check from timing out once the fact table is in the billions of rows, without weakening what it detects?
Sessionise a raw heartbeat stream into activity rows
You get a DataFrame heartbeats with columns learner_id, content_item_id, content_version_no, and ts (UTC timestamps, unsorted). Produce one row per learner per session per content item with started_at, ended_at, wall_seconds, and active_seconds. A session closes after 30 minutes with no heartbeat from that learner. active_seconds sums consecutive gaps inside a session, capping each gap at 120 seconds. Attribute each gap to the content item of the earlier heartbeat. State your rule for a gap of exactly 1800 seconds and for a session with a single heartbeat.
Approach
- Sort by learner_id then ts, and compute the gap with a per-learner diff so the first heartbeat of each learner has no gap. A global diff lets one learner's last heartbeat set the next learner's first gap.
- Flag a session break where gap > 1800 seconds, then cumsum that boolean within the learner to get a session index. Say whether exactly 1800 opens a new session; either choice is defensible but it must be stated because it moves the session count.
- Each gap covers the interval before the current heartbeat, so attribute min(gap, 120) to the content_item_id of the previous row via shift, not the current row.
- Group by (learner_id, session_index, content_item_id): sum the attributed capped gaps for active_seconds, take min and max ts for started_at and ended_at, and derive wall_seconds from those two.
- Handle the degenerate group explicitly. A single heartbeat gives active_seconds 0 and wall_seconds 0. Dropping those rows quietly removes real opens and biases any completion or abandonment rate computed later.
- Validate that within every session the summed active_seconds never exceeds the session's wall_seconds, which catches attribution and cap errors in one assertion.
Follow-up
- The client emits a heartbeat every 60 seconds on desktop and every 15 seconds on a managed device fleet. What does the 120-second cap do to the comparison between those two populations?
- Your reconstructed active_seconds disagrees with the stored column by 4 percent overall. How do you localise the disagreement rather than argue about the total?
- A learner has two tabs open on different items at once. What does your output claim, and what should it claim?
How would you handle missing or null data points when joining large da…
How would you handle missing or null data points when joining large datasets across multiple tables?
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.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- What breaks if events arrive late or out of order?
- How does the query change if the join becomes one-to-many?
Describe your process for optimizing a slow-running query that process…
Describe your process for optimizing a slow-running query that processes millions of rows.
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- State the window function and its partition and ordering out loud before writing it.
- Compute rates by summing numerator and denominator separately, never by averaging rates.
Follow-up
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Write a query using SQL window functions to calculate a rolling averag…
Write a query using SQL window functions to calculate a rolling average of student login activity over the last 30 days.
Approach
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- 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
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Find enrollments with no scored work using anti-joins
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).
Worked solution 20 min
- Run SELECT COUNT(*) FROM fct_assessment_response WHERE enrollment_id IS NULL. That one number is the whole explanation.
- Write both versions side by side over the same window and show the row counts differ.
- Write the NOT EXISTS version with the response_count and scored_response_count columns attached.
- Verify the partition of the due-date window: at-risk count plus distinct enrollments with scored work equals total active enrollments in the window.
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?
If we notice a sudden drop in the usage of a specific campus app, how …
If we notice a sudden drop in the usage of a specific campus app, how would you diagnose the root cause?
Approach
- 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.
- 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?
- What would you do if the primary metric and the guardrail moved in opposite directions?
What are the key trade-offs when choosing between a short-term and lon…
What are the key trade-offs when choosing between a short-term and long-term success metric?
Approach
- Fix the population and the time window before naming any metric.
- State what result would change your recommendation, so the answer is falsifiable.
- Restate the decision this analysis has to support, and who acts on the answer.
Follow-up
- Which segment would you cut first, and what would that rule out?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How would you design a metric to measure student engagement with a new…
How would you design a metric to measure student engagement with a new university portal?
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Fix the population and the time window before naming any metric.
- State what result would change your recommendation, so the answer is falsifiable.
Follow-up
- How would you detect that the metric is being gamed rather than genuinely improving?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How would you handle a situation where an experiment shows a positive …
How would you handle a situation where an experiment shows a positive result in one segment but a negative result in another?
Approach
- 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.
- State the primary metric and the minimum effect worth shipping, then size the test.
Follow-up
- What would you do if you could not randomise at all?
- What would you conclude if the result is positive but the test is underpowered?
Explain the concept of statistical significance to someone without a t…
Explain the concept of statistical significance to someone without a technical background.
Approach
- Name the guardrails that would stop a launch even on a positive primary result.
- Decide the analysis before seeing data, including how long it runs and when you look.
- Name the randomisation unit first; it decides the variance and what the test can detect.
Follow-up
- How would you handle interference between treated and control units?
- What would you conclude if the result is positive but the test is underpowered?
Decide what an administrator usage report counts
You must publish a five-line usage report that institutional administrators read before renewal. Once it is published, instructors will assign work to move whatever it counts. Available: fct_lesson_activity (active_seconds, is_assigned, completion_status), fct_assessment_response (max_points, scoring_mode, is_correct, response_seconds, hint_count), fct_enrollment (units_completed, units_total) and dim_learner (first_activity_at, age_gated). Choose the five lines and their source columns, name one metric you refuse to publish and the behaviour it would cause, and state the pairing that keeps each line honest.
Approach
- Start from behaviour rather than from data availability. Publishing a number to the buyer converts it into an assignment, so the test for each line is whether its gamed version is still something you want happening.
- Choose lines that survive that test: seat activation with the never-activated count shown rather than hidden; learners with at least one scored submission in the last four weeks; pace adherence at the current term-week; verified mastery events with the reporting lag printed; and objectives with no coverage yet, which is a gap list, is directly actionable, and cannot be inflated.
- Name the source columns per line so the report is reproducible: first_activity_at against seats_provisioned, fct_assessment_response.submitted_at with scoring_mode, units_completed over units_total against the term dimension, the mastery ledger with its delayed check, and the objective coverage join.
- Refuse active minutes per learner. Publishing it causes seat-time assignments, which is the clearest case of teaching to the number in this domain and the weakest claim the product can defend as learning. Keep it internally as a guardrail where it is useful and harmless.
- Pair every countable line with an integrity partner: pace adherence with assessment integrity (response_seconds above the item floor, hint_count below cap), submissions with mean max_points so splitting one task into five cannot move the line, activation with the raw never-activated count.
- State the population on the report itself, including the age_gated share and any excluded enrollment sources, because those learners are missing from the behavioural tables and the report will otherwise look complete while describing a partial population.
Worked solution 30 min
- For each candidate line, write the one sentence describing how an instructor would move it with no learning, and drop the lines whose gamed version is undesirable.
- Write the five surviving lines with their source columns and windows.
- Attach an integrity or substance partner to each countable line, and write the single sentence justifying the refusal of active minutes per learner.
- Add the population footer: age_gated share, excluded enrollment sources, and the reporting lag on verified mastery.
Follow-up
- An administrator says your report shows fewer active learners than their own dashboard. What are the three likeliest causes?
- A district asks for a per-teacher leaderboard built from these lines. What do you do?
- If you could publish only four lines, which one goes, and what breaks?
Active minutes fell eighteen percent with session count flat
Weekly active learning minutes per active learner fell from 42 to 34 the week a new client build shipped. Distinct learner_id and row count in fct_lesson_activity are both flat week over week. You have fct_lesson_activity (session_id, started_at, ended_at, active_seconds, wall_seconds, device_type, content_version_no, activity_date) and nothing else today. Decide whether this is a real engagement change or an instrumentation change, name the column that settles it, and write the query. Deliverable: a one-paragraph call within the day.
Approach
- Compute the daily median of active_seconds / wall_seconds per session for fourteen days either side of the release. active_seconds is heartbeat-derived and capped per gap; wall_seconds is ended_at minus started_at and is untouched by heartbeat cadence, so the ratio isolates the instrument from the behaviour.
- Hold the denominator fixed alongside it: sessions per learner per week and median wall_seconds per session. If both are flat, nothing about how long learners stayed changed, which leaves only how time was counted.
- Split the ratio by device_type. Managed Chromebook fleets typically run a pinned build and update on a school IT cycle, so that group is a natural unexposed comparison for a client-side change.
- State the mechanism explicitly: active_seconds sums inter-heartbeat gaps with each gap capped at 120 seconds, so a heartbeat interval raised above 120 seconds discards the excess on every gap and shrinks active_seconds proportionally while wall_seconds is unaffected.
- Size it: apply the pre-release ratio to post-release wall_seconds to get counterfactual minutes, and report the difference from the published number as the artefact.
Follow-up
- What would you backfill, and what would you leave as a documented break in the series?
- If wall_seconds had fallen by the same proportion, what would you check next before calling the drop real?
- How would you make this metric robust to the next heartbeat cadence change without re-litigating it?
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.
Half of this section is about translation. Be ready to describe how you explained a result to someone who did not want the method, only the implication, and what you did when the simplified version started being repeated in a way that overstated it. Correcting your own simplification is a strong beat.
Describe a project where you had to pivot your approach due to shiftin…
Describe a project where you had to pivot your approach due to shifting requirements or data limitations.
Approach
- Quantify the outcome, including what you would not claim credit for.
- Name the disagreement or constraint, and how you resolved it with evidence.
- 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?
- What would you do differently if you ran that project again?
Account for an analysis you later discovered was wrong
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?
Tell an executive the usage report they publish is wrong
A quarterly usage report an executive sends to district administrators counts an active learner as anyone with a fct_lesson_activity row in the quarter. You find two defects: accounts created by roster_sync that opened a single item during an automated import are counted in the numerator, and learners with age_gated = TRUE never reach the source table, so they are absent from the denominator. The report has already gone out twice. Deliverable: what you send, to whom, in what order, and what the definition should become. Probed: whether you can deliver an unwelcome data-quality finding without detonating it.
Approach
- Size the error before raising it. Recompute the metric both ways per org: 'the definition is wrong' and 'the number is overstated by 18 points on the largest account' get very different responses.
- Keep the two defects separate, because they push in opposite directions. Roster artefacts inflate the numerator while age-gated truncation shrinks the denominator, so the net error varies by org and a single average hides that.
- Go to the report owner first with the recomputation and a proposed replacement, not to their audience. The person who published it needs the chance to correct it themselves.
- Propose a definition that is defensible and computable today: distinct learners with at least one scored submission in the quarter, with enrollment_source in ('roster_sync','admin_bulk') excluded from activation cuts, and the age_gated share stated as a footnote rather than silently dropped.
- Say what should happen to the two reports already sent, with a recommendation and an owner. The restatement is the uncomfortable part, and leaving it for someone else to raise means the work is unfinished.
Follow-up
- The executive asks you to change the definition quietly from next quarter with no restatement. What do you do?
- How would you stop this class of defect reaching a published report again?
- 01
Describe a project where you had to pivot your approach due to shifting requirements or data limitations.
- 02
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.
- 03
A quarterly usage report an executive sends to district administrators counts an active learner as anyone with a fct_lesson_activity row in the quarter. You find two defects: accounts created by roster_sync that opened a single item during an automated import are counted in the numerator, and learners with age_gated = TRUE never reach the source table, so they are absent from the denominator. The report has already gone out twice. Deliverable: what you send, to whom, in what order, and what the definition should become. Probed: whether you can deliver an unwelcome data-quality finding without detonating it.
Is this an official Purdue University interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Purdue University. Rounds and questions reflect what candidates have reported, not a process Purdue University has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How long should I spend preparing for the technical rounds?
Dedicate at least 2–3 weeks to reviewing SQL and statistics. Focus on solving problems that require multi-step logic rather than simple syntax memorization.
PracHub interview research ↗What is the most common reason candidates do not move forward?
Often, it is not a lack of technical skill, but a failure to clearly explain the "why" behind their decisions. Ensure you can articulate the trade-offs of your approach.
PracHub interview research ↗Is the work culture at Purdue University collaborative or independent?
It is highly collaborative. You will be expected to work with various departments, so emphasize your experience in cross-functional teams.
PracHub interview research ↗Will I be asked to perform a presentation?
Yes, it is common for the process to include a presentation component. Practice explaining your data findings to a non-technical audience.
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