As a Data Scientist at Northeastern University, particularly within initiatives like the Institute for Experiential AI, you play a vital role in bridging advanced computational research with real-world, practical applications. This position is responsible for designing, deploying, and scaling data-driven solutions that directly support research endeavors, academic partnerships, and operational strategies. You will work alongside researchers, software engineers, and domain experts to tackle complex analytical problems that have tangible impacts on institutional effectiveness and external collaborative projects.
The work you drive involves everything from exploratory data analysis and predictive modeling to rigorous experiment design and metric development. Because Northeastern University operates at the intersection of experiential learning and cutting-edge technological research, your contributions help shape how data informs decisions across diverse academic and applied domains. You will handle messy, real-world datasets, build robust statistical pipelines, and translate intricate technical findings into clear, actionable insights for non-technical stakeholders.
Expect an environment that values intellectual curiosity, research rigor, and collaborative problem-solving. While the work is intellectually demanding and requires deep technical mastery, you will find a culture that encourages open inquiry and values practical innovation. Success in this role requires you to balance theoretical understanding with hands-on execution, ensuring that your models and experiments are both statistically sound and directly applicable to organizational goals.
Preparation focus
editorialNo round sequence has been reported for this company, so work the categories below and confirm the format with your recruiter.
What to demonstrate
- Breadth across SQL, experimentation and product reasoning
- Ability to state assumptions before choosing a method
How to prepare
- Drill the practice exercises below and time yourself
- Prepare three quantified stories about decisions you drove
PracHub editorial advice for the preparation topics above.
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.
Roster sync creates and deactivates accounts in bulk, and it is not behaviour.
An automated roster import at term start can create thousands of accounts in one hour and deactivate thousands more at term end. Signup, activation, and churn series computed without filtering enrollment_source IN ('roster_sync','admin_bulk') will show spikes and cliffs driven entirely by an integration job. It also breaks cohort retention: a roster-created account that never activates is a provisioning artefact, not a churned learner.
Reading experiment results before checking the arm split
Compare observed arm counts against the intended allocation ratio, not an assumed even split, and set the alarm far below the conventional 0.05: at 0.05 roughly one healthy experiment in twenty trips it, which is why sample-ratio checks usually run at p < 0.001 or stricter. The test's power scales with sample size, so it misses a real diversion on a small experiment and fires on an imbalance too small to move the estimate on a very large one. A flag means go find the assignment or logging fault before reading any outcome, not report a mismatch.
Ending an analysis without a recommendation or next step
Close with what you would do and what would change your mind, stated as a condition you can check later. If the evidence is genuinely inconclusive, recommend the specific next measurement and say what it costs in time or exposure.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
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.
Worked solution 20 min
- merged = responses.merge(dim, left_on=['content_item_id','content_version_no'], right_on=['content_item_id','version_no'], how='left', indicator=True); missing = merged._merge == 'left_only'.
- On matched rows: early = submitted_at < published_at; late = retired_at.notna() & (submitted_at > retired_at).
- attempts = responses.groupby(['learner_id','content_item_id']).attempt_no.agg(['count','nunique','max']); duplicated = nunique < count; gapped = (nunique == count) & (max != count).
- lagged = (scoring_mode == 'rubric_human') & scored_at.isna() & (submitted_at < now - 5 days).
- Assemble a frame of check_name, failing_count, denominator, and head(5) of the failing response_ids per check.
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?
Bootstrap a clustered interval for minutes per mastery event
You have weekly with section_id, learner_id, active_minutes, and mastery_events for one ISO week. The guardrail metric is total active_minutes divided by total mastery_events across the population, a ratio of sums rather than a mean of per-learner ratios. Write a cluster bootstrap in numpy: resample sections with replacement, recompute the ratio, and return a 95 percent percentile interval from at least 2,000 replicates. Also return the interval you get resampling learners, and state which one you would report and why.
Approach
- Reduce to a section index first: per section, the total active_minutes and the total mastery_events. Because the statistic is a ratio of sums, a replicate needs only those two totals, which makes thousands of replicates cheap and keeps the resampling unit explicit.
- Resample section indices with replacement up to the original section count, sum both totals over the resampled sections, then divide. Never average per-section ratios: that is a different estimand and it is dominated by whichever sections happen to be small.
- Guard the denominator. A replicate drawing only sections with zero mastery events is undefined. Count how often that happens and report it rather than dropping those replicates silently, because a high rate means the weekly window is too short for this metric and the interval is not the real problem.
- Take the 2.5th and 97.5th percentiles of the replicate ratios. Percentile intervals are adequate here only while the replicate distribution is roughly symmetric; check that before reporting, and move to BCa if it is skewed.
- Repeat with learners as the resampling unit and compare widths. Report the section interval. The learner interval understates width by roughly the square root of the design effect, and it is the one that will be quoted back at you when the guardrail later moves.
Follow-up
- Sections range from 8 to 60 learners. Does resampling sections with replacement bias the point estimate, the interval, or neither?
- How does the interval change if you resample learner-weeks over four weeks instead of one, and what new assumption does that introduce?
- The interval comes back wide enough to contain both a 10 percent improvement and a 10 percent regression. What do you tell the team to do?
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?
Verified mastery events with a delayed retention check
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.
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?
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?
How do you balance competing metrics when optimizing an educational re…
How do you balance competing metrics when optimizing an educational recommendation system for both diversity of content and student completion rates?
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- Fix the population and the time window before naming any metric.
- Name one primary metric, then the guardrail that stops it being gamed.
Follow-up
- Which segment would you cut first, and what would that rule out?
- What would you do if the primary metric and the guardrail moved in opposite directions?
What framework would you use to evaluate the success of a newly launch…
What framework would you use to evaluate the success of a newly launched recommendation feature for academic research grants?
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- State what result would change your recommendation, so the answer is falsifiable.
- Name one primary metric, then the guardrail that stops it being gamed.
Follow-up
- How would you detect that the metric is being gamed rather than genuinely improving?
- What would you do if the primary metric and the guardrail moved in opposite directions?
If daily active users on a university research portal dropped by fifte…
If daily active users on a university research portal dropped by fifteen percent overnight, how would you structure your diagnostic investigation?
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?
How would you design a product metric to measure student engagement in…
How would you design a product metric to measure student engagement in an interactive online learning module?
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- Restate the decision this analysis has to support, and who acts on the answer.
- Name one primary metric, then the guardrail that stops it being gamed.
Follow-up
- Which segment would you cut first, and what would that rule out?
- What would you do if the primary metric and the guardrail moved in opposite directions?
Compute the minimum detectable effect for a section-randomised mastery test
You can randomise 300 class sections per arm, averaging 25 learners per section. The primary metric is weekly verified mastery events per active learner: baseline mean 3.2, learner-level standard deviation 2.4, intraclass correlation within section 0.15. At alpha = 0.05 two-sided and 80% power, compute the minimum detectable effect in absolute and relative terms. Then state how many sections per arm a 5% relative effect would require. Show the design effect explicitly and say what unequal section sizes do to it.
Approach
- Compute the design effect first, because every other number depends on it: DE = 1 + (m - 1) x rho = 1 + 24 x 0.15 = 4.6 for roughly equal sections. Unequal sizes inflate it further, roughly to 1 + ((CV^2 + 1) x mean_m - 1) x rho where CV is the coefficient of variation of section size.
- Use MDE = (z_0.975 + z_0.80) x sqrt(2 x sigma^2 x DE / n_arm) with z_0.975 = 1.96, z_0.80 = 0.8416, and n_arm = 300 x 25 = 7,500 learners.
- Invert the same expression for the section count at a fixed target: delta = 0.05 x 3.2 = 0.16 absolute.
- Defend the rho you used. Estimate it from a pre-period as the between-section share of total variance, and report the MDE at rho = 0.10 and rho = 0.20 as well, since the required sample is close to linear in the design effect.
- State the analysis unit alongside the design: either section means or learner rows with section-clustered standard errors, chosen now and written into the plan rather than selected after the readout.
Worked solution 25 min
- DE = 1 + (25 - 1) x 0.15 = 4.6.
- z sum = 1.96 + 0.8416 = 2.8016, and its square is 7.849.
- MDE = 2.8016 x sqrt(2 x 2.4^2 x 4.6 / 7500) = 2.8016 x sqrt(52.992 / 7500) = 2.8016 x 0.08406 = 0.2355.
- Relative MDE = 0.2355 / 3.2 = 7.4%.
- For delta = 0.16: n_arm = 2 x 7.849 x 5.76 x 4.6 / 0.0256 = 16,247 learners, which is 650 sections per arm.
Follow-up
- Your pre-period estimate of rho has a wide interval. How does the required section count move between rho = 0.10 and rho = 0.25?
- The curriculum team offers 900 more learners but only 12 more sections. What does that actually buy you?
- Would CUPED on pre-period mastery events change this number, and by how much at a given pre-post correlation?
Net revenue retention slid nine points in one quarter
Net revenue retention on institutional licenses fell from 104 percent to 95 percent quarter over quarter. Source: fct_subscription_period (subscription_period_id, account_id, org_id, plan_tier, billing_interval, seats_purchased, seats_provisioned, mrr_usd, period_start, period_end, is_renewal, status, canceled_at, churn_reason). Decompose the nine points into expansion, contraction and non-renewal, and establish whether renewal behaviour changed at all. Deliverable: the decomposition, the cohort definition you used, and a call on whether this is a trend or account news.
Approach
- Pin the cohort in writing before computing anything: orgs holding an active period twelve months before each renewal date, new logos excluded from both numerator and denominator, and non-renewals entering the numerator as zero rather than being dropped. Dropping non-renewals is the most common way this metric is overstated, and correcting it can move the headline by more than the effect under investigation.
- Rebuild the ratio from components on that cohort: starting annualised revenue, expansion, contraction, non-renewal. Check the components sum back to the reported ratio in both quarters; a residual means the two quarters were not computed on the same cohort rule and the comparison is void before any interpretation.
- Test cohort comparability on billing_interval. Multi-year contracts do not present a renewal in every window, so a quarter whose renewal cohort holds a different multi_year share is not comparable to its predecessor. Recompute both quarters holding the interval mix fixed and report that alongside the raw number.
- Rank per-org contributions to the nine points and state how much the top three carry. Institutional revenue is concentrated, so a decomposition that leaves the concentration unstated invites a trend reading of what is account news.
- Audit the inputs: confirm mrr_usd normalisation is consistent (annual divided by twelve) and look for overlapping period_start and period_end within a single account_id, which double counts revenue after a mid-term upgrade.
- Close the loop to something actionable by joining the lost orgs back to seat activation and pace adherence in the preceding term, and say whether the signal was visible early enough for anyone to have acted on it.
Follow-up
- Build the renewal-risk view from this: which signals are actionable while there is still time to act, and at what days-to-renewal would you surface an org?
- An org contracts from 900 seats to 600 but moves to a higher tier and raises MRR. Expansion or contraction, and does your decomposition handle it without double counting?
- How would you present NRR so that a quarter with an unusual renewal cohort is not read as a trend by an executive audience?
Roughly 90 minutes a night on weekdays with one longer weekend block. The plan deliberately cuts scope rather than compressing everything, on the assumption that finishing one thing a night beats half-starting four.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Fix the scope and set a baseline
- Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list for everything else and keep it visible all week.
- Take one 20-minute SQL prompt and one 10-minute metric question cold, and write the single sentence that says what blocked each attempt, since that sentence is what decides which two topics get the most evenings.
- Set the week's one rule: one problem finished to completion every night, including the night you only have 40 minutes.
Deliverable: A one-page scope with an explicit not-doing list and two cold attempts, each carrying one sentence on what blocked it.
Practice prompt ↗Practice prompt ↗Worked solution ↗02One query pattern, written three times
- Choose the single pattern most likely to appear (a cohort retention grid, or a funnel counted by user) and write it three times from a blank file rather than editing the previous attempt.
- On the third attempt, write the grain of every CTE as a comment before writing its body.
- Stop at 90 minutes even if the third version is imperfect, and write the one thing you would fix with another hour.
Deliverable: Three independent versions of the same query plus a note on what changed between them.
Practice prompt ↗Practice prompt ↗03Only the statistics you will be asked to defend
- Write, in under 200 words, how you would decide whether a difference between two groups is real: the test, its assumptions, and what you would switch to when an assumption fails.
- Compute a 95 percent confidence interval for a difference in proportions by hand on realistic numbers, then write in one sentence what changes if the two samples are paired rather than independent.
- Write your answer to "what does a p-value mean", check it against a definition, and delete the version that describes it as the probability the hypothesis is true.
Deliverable: A 200-word written answer and one hand-computed interval you can reproduce under pressure.
Practice prompt ↗Practice prompt ↗04One case, and the assumptions holding it up
- Answer one product case aloud in 20 minutes with a recording running, then listen back with a pen and mark every claim you asserted without saying what it rested on: an assumed user behaviour, an assumed data source, an assumed baseline rate, an assumed grain.
- Pick the three assumptions the recommendation actually depends on, write how you would check each one against data, and say which one being wrong would flip the recommendation rather than merely weaken it.
- Write the four-step structure you used onto a card small enough to hold in working memory when you are nervous.
Deliverable: One recording, three load-bearing assumptions each with a written check, and a four-step structure card.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Your own work, timed
- Write a 90-second version and a four-minute version of your main project, and time both out loud rather than reading them.
- Prepare answers to the two follow-ups that always come: what you would do differently, and how you knew it worked.
- Put one number in the first sentence and be able to say exactly where that number came from and what it excludes.
Deliverable: Two timed narratives with one defensible number in the opening line.
Practice prompt ↗Practice prompt ↗06The one full rehearsal, in a longer weekend block
- Run a 60-minute mock covering query work, a case and a behavioural question in a single sitting with no breaks, because sustained attention is the thing evenings have not trained.
- Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
- Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.
Deliverable: Mock notes naming three failure moments with a specific fix written under each.
Practice prompt ↗Practice prompt ↗07Taper
- Write the 20-minute warm-up you will actually do on the morning of the interview: one query you can already write from a blank file, one metric you can define out loud, and nothing you have never seen before.
- Re-read only your own notes from this week, and open no new material.
- Write down the logistics: the tool you will be asked to work in, whether lookups are allowed, and the sentence you will use when you do not know something.
Deliverable: A one-page card holding the case structure, the project numbers, and the logistics.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
An answer without a quantity is hard to interrogate, so interviewers keep probing until they find one. Come with the baseline, the change, the window it was measured over, and how confident you were. If the effect never got measured, say so and say what you would have measured. Fabricated precision is worse than an honest gap.
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?
Scope a vague request to investigate falling engagement
A curriculum director messages you: engagement is down in middle school, can you dig into it. You have dim_learner, fct_lesson_activity, fct_assessment_response, fct_enrollment and dim_term. Before writing any query you get one fifteen-minute conversation. Deliverable: the questions you ask in that conversation, the written scope you send afterwards, and the first three things you compute, with the reason each comes before the others. Probed: whether you convert an ambiguous request into a decision and a single metric before touching data, rather than after.
Approach
- Find the decision behind the request first: what the director would do differently depending on the answer, and by when. That sets how much of this analysis is worth doing at all.
- Pin the four ambiguities that make 'engagement is down' uncomputable: which population (grade_band = '6_8', which orgs), which metric (active_seconds, activity days, scored submissions), which comparison window, and against which baseline.
- Ask where the belief came from. 'Down' is almost always a chart someone saw, and reproducing that exact chart is faster than building a new one and then arguing about why the two differ.
- Check the calendar before believing the shape at all: a decline spanning a term boundary is the default explanation in this domain, so term-week alignment through dim_term is the first computation, not a later refinement.
- Send the scope back in writing with an explicit out-of-scope list and a time box, so follow-on questions arrive as new requests instead of as scope creep.
Follow-up
- The director cannot name the decision this feeds. Does that change whether you do the work, and how much of it?
- Your term-aligned version shows no decline at all. What do you send, and to whom first?
Defend a null result against an already-announced launch
A section-randomised test of a new practice-sequencing feature ran across 62 class sections in 11 orgs. Primary metric: verified mastery events per active learner. With section-clustered standard errors the effect is +1.8% (95% CI -4.1% to +7.9%). Leadership has already told two district administrators that the feature improves outcomes. You have ten minutes in a review. Deliverable: what you say, what you put on one slide, and what you propose next. Probed: whether you can hold a null under commercial pressure without either caving or lecturing the room on statistics.
Approach
- Lead with the decision, not the p-value: state the interval in the unit the audience already uses (mastery events per active learner per week) and say plainly what the study could and could not have detected.
- Separate the interval's half-width from the minimum detectable effect before you put either on a slide. The stated 95% CI of -4.1 to +7.9 has a half-width of 6.0 points, so the clustered standard error is 6.0 / 1.96 = 3.06 points; the MDE at 80% power and two-sided alpha = 0.05 is (1.96 + 0.8416) * 3.06 = about 8.6 points, roughly 1.43 times the half-width. Quote 8.6, and show that it follows from 62 sections at the section size and intraclass correlation you assumed via the design effect 1 + (m - 1) * rho, so that 'no effect found' is visibly separated from 'too small to see'.
- Check the pre-registered guardrails before conceding anything: median active_seconds per mastery event and the calibrated irt_b distribution of the items backing mastery decisions. If both are flat, the null is about learning, not about a broken pipeline.
- Handle the promise made to the two districts as its own item with a named owner, rather than leaving the correction implicit in a statistics discussion.
- Close with the cheapest decision-grade next step: extend to enough additional already-instrumented sections to reach the effect size leadership actually cares about, with the stopping rule fixed before the extension starts.
Follow-up
- If the interval had been -0.5% to +8.0%, would you support launch, and what exactly changes in your reasoning?
- Leadership asks you to re-run with learner-level standard errors since it is the same data. What do you say?
- What would you have set up at design time so that this meeting was easier?
- 01
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.
- 02
A curriculum director messages you: engagement is down in middle school, can you dig into it. You have dim_learner, fct_lesson_activity, fct_assessment_response, fct_enrollment and dim_term. Before writing any query you get one fifteen-minute conversation. Deliverable: the questions you ask in that conversation, the written scope you send afterwards, and the first three things you compute, with the reason each comes before the others. Probed: whether you convert an ambiguous request into a decision and a single metric before touching data, rather than after.
- 03
A section-randomised test of a new practice-sequencing feature ran across 62 class sections in 11 orgs. Primary metric: verified mastery events per active learner. With section-clustered standard errors the effect is +1.8% (95% CI -4.1% to +7.9%). Leadership has already told two district administrators that the feature improves outcomes. You have ten minutes in a review. Deliverable: what you say, what you put on one slide, and what you propose next. Probed: whether you can hold a null under commercial pressure without either caving or lecturing the room on statistics.
Is this an official Northeastern University interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Northeastern University. Rounds and questions reflect what candidates have reported, not a process Northeastern University has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the interview process, and how much preparation time should I plan for?
The interview process is moderately to highly rigorous, emphasizing practical research skills, technical fluency, and structured problem-solving. Most candidates benefit from dedicating three to four weeks of focused preparation, particularly reviewing SQL window functions, experimental design pitfalls, and behavioral storytelling.
PracHub interview research ↗What differentiates successful candidates from those who are rejected?
Successful candidates stand out by structuring their answers clearly, explaining the trade-offs behind their technical choices, and demonstrating a deep understanding of experimental limitations. They also communicate effectively, treating the interview as a collaborative discussion rather than an interrogation.
PracHub interview research ↗What is the working culture like for data professionals at Northeastern University?
The culture blends academic inquiry with applied innovation, emphasizing collaboration, intellectual curiosity, and rigorous methodology. Teams operate in dynamic environments where research meets real-world application, requiring flexibility and strong cross-functional communication.
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