Interview guides · Fti Consulting
Fti Consulting Data Scientist Interview Questions & Guide 2026
Data scientist interview prep for Fti Consulting: original practice on experiment design, SQL and metric reasoning, with worked solutions.
The 60-second brief
A Data Scientist at FTI Consulting operates at the intersection of advanced technology, high-stakes litigation, and strategic corporate decision-making. Unlike traditional tech environments where data science might focus purely on optimizing web traffic or ad clicks, FTI Consulting deploys data science to solve complex, real-world crises, regulatory investigations, and sophisticated business challenges. Whether you join the Forensic and Litigation Consulting team or the AI Build Team, your work will have a direct, tangible impact on global corporate clients and legal proceedings.
A large share of questions open as "how would you measure X", where the real work is choosing the metric, fixing its denominator, and defining the population it applies to. Any computation comes last and is frequently not required at all.
Focus areas
- Cluster inference at the account, not the engagement
- Compute utilisation against a defended availability denominator
- Separate bookings, recognised revenue and collected cash
Overview
In this role, you will be responsible for developing end-to-end data solutions, building robust machine learning models, and translating highly technical findings into clear, actionable insights for non-technical stakeholders. The scale and complexity of the data you will handle are immense, often involving highly unstructured forensic datasets, financial records, and proprietary corporate communications. This makes the position both intellectually challenging and highly rewarding, as your findings may be used in courtrooms, regulatory filings, or boardrooms.
To succeed as a Data Scientist at FTI Consulting, you must possess not only exceptional technical capabilities in Python, statistical modeling, and MLOps, but also the communication skills required to mentor junior team members and engage directly with clients. It is a dynamic environment where analytical rigor meets strategic consulting, offering significant professional growth and the opportunity to work alongside industry-leading experts.
The Fti Consulting interview process
Fti Consulting candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
Application Screening
Rounds outside the standard loop often open with something deliberately under-specified: a loose business problem, an open question about a product area, a dataset described in one sentence. The common failure is surveying, listing six plausible approaches and committing to none of them. The thing that separates a strong answer is scoping out loud. State what you are treating as the goal, name the metric you would move, say what you are choosing not to do and why, then take one path through to an actual answer. An interviewer can follow you down a narrow path. Nobody can grade a menu.
What to demonstrate
- Whether you turn an ambiguous prompt into a stated question with a measurable outcome before doing any work
- The judgement visible in what you cut, and whether you say why you cut it rather than silently dropping it
- Whether you land on a concrete recommendation with its caveat attached, rather than an unranked set of options
How to prepare
- Take three vague prompts, such as 'is this feature working', 'why did retention drop', and 'should we expand into a new segment'. For each, write one sentence of goal, one primary metric with its window, and two things you are explicitly not doing.
- Practise giving the recommendation first and the reasoning second, in five minutes. Loosely defined rounds are usually time-boxed, and an answer that arrives last often does not arrive.
- Keep a running assumption list as you talk, on paper or in the shared doc, so the interviewer can challenge one assumption instead of your whole answer.
Automated Assessment
Much of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.
What to demonstrate
- Whether the query you write matches the plan you just described
- What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
- Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly
How to prepare
- Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
- Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
- Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock
Live Interviews
Because the format is not fixed, prepare the reasoning rather than the ritual. Nearly every version of this round draws on the same underlying material: a design you can defend, a metric you can define exactly, an analysis whose assumptions you can state out loud. Only the wrapper changes, whether that is a take-home, a live case, a deep dive on past work, or a rough estimate on a whiteboard. Answers rehearsed to fit one shape stall the moment the shape differs. Practise naming the assumption behind a number, then saying how much the conclusion moves if that assumption is wrong.
What to demonstrate
- Whether your justification for a method survives the question 'why not the simpler thing', including when the simpler thing would have worked
- Precision under pressure: what exactly counts as an active user, a conversion or a success, over what window, with what exclusions
- Whether you carry an argument through to a recommendation instead of stopping at a list of tradeoffs
How to prepare
- For each project you plan to mention, write the metric definition in one sentence: numerator, denominator, time window, exclusions. Say it out loud once, because vagueness shows up in speech before it shows up on paper.
- Rehearse the same project at three lengths: two minutes, ten minutes, and a deep dive on one technical decision. Cutting live is harder than it sounds.
- For your headline result, write down what would have had to be true for it to be wrong, and how you ruled that out.
Where candidates lose points
Trending utilisation or revenue on work_date without accounting for timesheet backfill
Time entries are created days to weeks after the work happens, and the backfill tail often runs two to six weeks. A dashboard keyed on work_date therefore shows the most recent weeks as a decline that reverses on every refresh. The fix is either to hold the reporting window back past the observed backfill tail (measure the tail with the timesheet submission lag metric rather than guessing) or to report an as-of-entered_at snapshot so the series is internally consistent, and to state which one you used.
Pooling margin, realisation or overrun across pricing models
Fixed-fee margin falls with hours worked; uncapped time-and-materials margin rises with hours worked; retainer margin depends on neither. A quarter in which the firm sells more fixed-fee work will show a margin change caused entirely by mix, not by delivery performance, and the aggregate can move in the opposite direction to every individual pricing model. Always stratify by fct_engagement.pricing_model before comparing periods, and report the mix shift alongside the within-stratum change.
SQL that silently fans out on a one-to-many join
State the grain of each table and the grain you want in the result before writing the join. Pre-aggregate the many side to the join key, or use EXISTS or a window function, and verify with a row count against COUNT(DISTINCT id) rather than trusting that the numbers look plausible.
Stopping an experiment the moment it crosses significance
Fix the sample size or duration before launch, or use a method built for continuous monitoring such as a sequential test, always-valid confidence intervals, or group-sequential boundaries. Repeatedly checking a fixed-horizon p-value against 0.05 pushes the real false-positive rate well above 5 percent.
Questions & practice
Explain the concept of bias-variance tradeoff and how you mitigate overfitting in your predictive models.
Medium · machine learning and modelling
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Set a baseline first, so any model has something honest to beat.
- Check what information would not exist at prediction time, and exclude it.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
How do you approach data cleaning and feature engineering when dealing with highly messy, unstructured forensic data?
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.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Collapse time entries into contiguous staffing spells
Medium · sessionisation · gap and island · vectorisation
From approved delivery time entries (consultant_id, engagement_id, work_date, hours, charge_code, status, with engagement_id not null), build staffing spells. Per consultant and engagement, collapse weeks containing any logged hours into contiguous runs, where three or more consecutive zero-hour weeks end a spell. Output one row per spell with consultant_id, engagement_id, start_week, end_week, active_weeks, gap_weeks and total_hours. Consultants sit on several engagements at once, so spells from different engagements may overlap in time and must not be merged. No Python loop over rows.
Approach
- Aggregate to (consultant_id, engagement_id, week_start) with summed hours and keep only weeks with positive hours. The absent weeks are the signal, so materialising zeros here would destroy the thing you are detecting.
- Convert week_start into an integer week index, ((week_start - epoch_monday).dt.days // 7), so gap detection is integer subtraction rather than calendar arithmetic that breaks over month and year boundaries.
- Sort by [consultant_id, engagement_id, week_index], diff the week index inside each pair, and mark a spell start where the diff is null (first row of the pair) or greater than 3. A diff of 1 is adjacent weeks and a diff of 3 is two empty weeks, which the tolerance permits.
- Take spell_id = the cumulative sum of that boolean over the whole frame so ids are globally unique, then a single groupby on [consultant_id, engagement_id, spell_id] yields min and max week, active week count and summed hours; gap_weeks = (end - start + 1) - active_weeks.
- Do not deduplicate overlapping spells across engagements. A consultant on two engagements in the same week is the normal case, and that overlap is the fact any capacity or context-switching question needs.
Worked solution (30 min)
- Filter to status == 'approved', charge_code == 'client_delivery' and engagement_id.notna(); derive week_start by subtracting the weekday offset from work_date.
- wk = df.groupby(['consultant_id','engagement_id','week_start'], as_index=False).hours.sum(); wk = wk[wk.hours > 0]; wk['wi'] = (wk.week_start - pd.Timestamp('1970-01-05')).dt.days // 7.
- wk = wk.sort_values(['consultant_id','engagement_id','wi']); d = wk.groupby(['consultant_id','engagement_id']).wi.diff(); wk['new_spell'] = d.isna() | (d > 3); wk['spell_id'] = wk.new_spell.cumsum().
- spells = wk.groupby(['consultant_id','engagement_id','spell_id']).agg(start_week=('week_start','min'), end_week=('week_start','max'), active_weeks=('wi','size'), total_hours=('hours','sum'), span=('wi', lambda s: s.max() - s.min() + 1)).reset_index(); gap_weeks = span - active_weeks.
- Run the conservation assertion (spell hours sum to input hours) and the toy case below before returning.
Expected result: One row per spell, where a single pair with active week indices [1, 2, 5, 9] produces two spells: weeks 1 to 5 with active_weeks 3 and gap_weeks 2, and week 9 alone with active_weeks 1 and gap_weeks 0.
Verify it yourself
- Summed total_hours across spells equals the summed hours of the filtered input, exactly.
- Within a pair, spells are disjoint, ordered, and separated by at least three empty weeks.
- No spell contains an internal gap longer than two weeks, verified by re-expanding one spell against the week-level frame.
- Two consultants with identical week patterns on the same engagement produce two separate spells, not one.
Follow-up
- Re-run with a one-week and a four-week tolerance. What happens to the spell count, and which tolerance would you defend to a staffing lead?
- Using these spells, how would you measure how many engagements a consultant is split across in a given week, and why is that not just a count of rows?
What are the key differences between various machine learning frameworks, and how do you select the right one for a specific project?
Medium · sql and data manipulation
Approach
- 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.
- Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
Follow-up
- How does the query change if the join becomes one-to-many?
- How would you verify this result without re-running the same query?
Rebuild proposal stage timeline from a mutable event stream
Hard · event streams · window functions · censoring · funnel
fct_proposal holds proposal_id, client_id, expected_value_usd, stage, is_competitive, created_at and decided_at, and its stage column is overwritten in place. fct_proposal_stage_event holds stage_event_id, proposal_id, from_stage, to_stage and occurred_at. For proposals created in the trailing year, rebuild the ordered stage timeline with days spent in each stage, flag durations still open at the snapshot as censored, and build a funnel of distinct proposals and expected value ever reaching qualifying, scoping, submitted and decided. Reconcile each timeline's terminal stage against fct_proposal.stage and report disagreements.
Approach
- Order events per proposal and derive each stage's exit with LEAD(occurred_at) OVER (PARTITION BY proposal_id ORDER BY occurred_at, stage_event_id). The tiebreak on the event key matters because two transitions can share a second. LEAD returns NULL on the last event of every proposal, decided or not, so a NULL lead marks the end of the stream and nothing more — it is not by itself a censoring indicator.
- Close that final interval by state rather than by the NULL. Where decided_at IS NOT NULL, close it at decided_at with is_censored = FALSE; where decided_at IS NULL, close it at snapshot_date with is_censored = TRUE. Only the second group is censored, and marking it lets a consumer choose Kaplan-Meier or a restricted mean. A median computed over completed transitions alone is biased downward, because at any snapshot the still-open records are disproportionately the slow ones, and the bias grows exactly when the pipeline is slowing. A decided_at earlier than the last event's occurred_at yields a negative final interval: report those proposals, do not clamp them.
- Handle re-entry. A proposal can go scoping to submitted and back to scoping, so per-stage entries outnumber proposals. Build the funnel on COUNT(DISTINCT proposal_id) for 'ever reached stage X', and keep the per-entry rows separate for duration work.
- Build the funnel from the reconstructed timeline, never from fct_proposal.stage. That column records only where a proposal came to rest, so every proposal that passed through scoping and moved on is invisible in it and the funnel's middle collapses.
- Reconcile the last to_stage per proposal against fct_proposal.stage. Disagreements mean events are missing or a row was edited outside the event path, and the size of that set is the ceiling on how far anything else here can be trusted.
- If asked for win rate by value, exclude stage IN ('withdrawn','no_decision') from both numerator and denominator and filter is_competitive = TRUE. Those outcomes are not losses, they are not missing at random, and sole-sourced follow-on work inflates the rate.
Worked solution (45 min)
- Count events per proposal and check for proposals with zero events; those exist only in the mutable table and must be reported, not dropped.
- Add the LEAD-based exit timestamp with the event-key tiebreak, then close each final interval with COALESCE(lead_occurred_at, decided_at, snapshot_date) and set is_censored only where decided_at IS NULL, so days_in_stage is defined on every row.
- Aggregate to the funnel with COUNT(DISTINCT proposal_id) and SUM of expected_value_usd per 'ever reached' stage.
- Compute the median days in stage over completed transitions only, and report the censored count beside it so the reader sees what the median excludes.
- Take the last to_stage per proposal with a window function and diff it against fct_proposal.stage, returning the mismatched proposal_ids.
Expected result: Per (proposal_id, stage entry) rows carrying entered_at, exited_at (the next event's occurred_at; decided_at on a decided proposal's final interval; NULL while still open), days_in_stage and is_censored; a funnel table of distinct proposals and summed expected value ever reaching each stage; a median per stage over completed transitions with its censored count; and a reconciliation list of proposals whose terminal event disagrees with the current stage column.
Verify it yourself
- For a proposal with a decision, the sum of days_in_stage across its entries equals decided_at minus its first event date, to within a day.
- Distinct proposals at the funnel's first stage equals the cohort size, and each later stage is less than or equal to the one before it.
- The is_censored rows are exactly the final-event rows of proposals with decided_at IS NULL, and their count equals the number of cohort proposals with no decided_at. Counting NULL leads instead returns one row per proposal — the entire cohort — since LEAD is NULL on every proposal's last event, so the two counts agree only in the degenerate case where nothing has been decided.
- Proposals with more than one entry into the same stage are visible as re-entries, and the funnel does not double count them.
Follow-up
- Estimate median proposal cycle time with the censored proposals included. What does the estimator need from your output?
- Two events for one proposal share occurred_at to the second. How does your ordering resolve it, and how would you detect that it happened?
- Which fields on a won proposal are populated only after the decision, and why does that rule them out of a win-rate model?
How would you design an end-to-end data pipeline to analyze large volumes of unstructured corporate communications for an investigation?
Medium
Approach
- State your assumptions explicitly before working the problem.
- Clarify what is being asked and what a complete answer would contain.
- Say what you would check first and why it is the highest-information step.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Size a rate-card pilot when accounts are the cluster
Easy · power analysis · minimum detectable effect · cluster randomisation · intraclass correlation
The firm wants to pilot a revised rate card. Assignment happens at the client account: one rate card per account, every engagement on it inherits that card. The outcome is realisation rate per engagement, fees billed over the standard-rate value of approved billable hours. You have 120 eligible accounts averaging three engagements each inside the pilot window, a per-engagement standard deviation of 0.12, and an intraclass correlation of 0.35 within account. Leadership will change the card only if realisation moves by at least 2 percentage points. Two-sided alpha 0.05, 80% power. Say whether this pilot can answer the question.
Approach
- Write the minimum detectable effect for a two-sample difference in means with equal allocation: MDE = (z_0.975 + z_0.80) * sigma * sqrt(4/N), coefficient 2.802, and be explicit that N counts engagements while randomisation happens on accounts.
- Convert engagements into independent information with the design effect DEFF = 1 + (m - 1) * rho. At m = 3 and rho = 0.35 that is 1.70, so 360 engagements carry the information of roughly 212.
- Compute the MDE on the effective sample, compare it to the 2-point decision threshold, and express the shortfall as a sample-size ratio rather than a vague 'underpowered'.
- Test whether a longer window rescues the design. Effective observations per cluster are capped at 1/rho, so total effective sample asymptotes at 120/0.35 = 343 no matter how long the pilot runs. Duration cannot fix an ICC problem; only more clusters can.
- Price the real options: more accounts, variance reduction from a pre-period covariate, a larger accepted effect size, or a design that uses within-account variation instead of between-account randomisation.
Worked solution (20 min)
- DEFF = 1 + (3 - 1) * 0.35 = 1.70; effective n = 360 / 1.70 = 211.8.
- MDE constant = z_0.975 + z_0.80 = 1.960 + 0.8416 = 2.802.
- MDE = 2.802 * 0.12 * sqrt(4 / 211.8) = 2.802 * 0.12 * 0.1374 = 0.046.
- Invert for the 2-point target: required effective n = 4 * (2.802 * 0.12 / 0.02)^2 = 1131, so accounts needed = 1131 * 1.70 / 3 = 641.
- Take m to infinity for the duration ceiling: effective n approaches 120 / 0.35 = 343, giving an MDE floor of 2.802 * 0.12 * sqrt(4/343) = 0.036.
Expected result: MDE of about 4.6 percentage points against a 2-point decision threshold, so the pilot as scoped cannot answer the question. Reaching 2 points needs roughly 640 accounts at three engagements each. Extending the window instead bottoms out near 3.6 points, because effective observations per account cannot exceed 1/rho = 2.9.
Verify it yourself
- Setting rho = 0 must collapse DEFF to 1 and reproduce the unclustered MDE of 2.802 * 0.12 * sqrt(4/360) = 0.035.
- Setting rho = 1 must give DEFF = m and an effective sample of 120, the number of accounts, which is the correct degenerate case.
- Required accounts scale as the inverse square of the target effect: halving the target from 4.6 to 2.3 points should roughly quadruple the account count.
Follow-up
- Revenue is concentrated in a handful of accounts. How does a value-weighted estimate change the power calculation, and which estimand does leadership actually want?
- The ICC of 0.35 came from last year's data on the same accounts. What would make that estimate optimistic, and how would you stress it?
- What breaks if you randomise at the engagement instead of the account?
Fees per billable head fell nine percent; rank the causes
Hard · decomposition · seasonality · clustered inference
Recognised fees per billable head fell about 9% quarter over quarter and leadership wants a ranked cause by Friday. You have fct_time_entry, fct_invoice_line, fct_engagement and dim_consultant, plus a workday and regional holiday calendar. Decompose the move into available hours per head, billable utilisation and realised dollars per billable hour, separate calendar effects from behaviour, split within-segment change from mix, and deliver a ranked attribution with uncertainty. Name the one further cut you would run if the leading term is ambiguous.
Approach
- Write the identity before computing anything: fees per head = (available hours per head) x (billable utilisation) x (realised dollars per billable hour), where the last term is recognised fees divided by approved billable hours. Verify the product reproduces the reported 9% exactly; if it does not, the scope of the three inputs disagrees and nothing downstream is trustworthy.
- Decompose in logs: d ln(fees per head) = d ln(available per head) + d ln(utilisation) + d ln(realised rate). The log form is exactly additive for a product, so contributions sum to the total without an interaction residual and cannot attribute more than the whole move.
- Strip the calendar first, because it is the term nobody can act on: available hours per head moves with scheduled workdays, regional public holidays, leave and any change in fte_fraction mix. Quantify how many of the nine points are calendar and quote the remainder as the behavioural move.
- Split each surviving term by practice_area, level, region and pricing_model, and within each split separate within-segment change from mix using the weighted three-term decomposition, since a shift toward lower-rate levels reads as a rate decline that no individual rate produced.
- Attach uncertainty at the unit that generates it: anything fee-side clusters at client_id because engagements in one account share a partner, a rate card and a team. With fewer than roughly forty clusters use a wild cluster bootstrap or a CR2 correction, since cluster-robust standard errors are downward-biased in that regime.
- If realised rate leads and is ambiguous, the disambiguating cut is discount versus write-off versus fixed-fee overrun: compare invoiced fees to the standard-rate value of hours worked, and read written_off_hours and scope overrun by pricing_model.
Follow-up
- Two of the nine points are calendar. How do you say that to an executive without sounding like you are explaining the number away?
- Utilisation is up and realised rate is down. What single operational behaviour produces both, and how would you confirm it?
- What would you need to see to claim this is a demand problem rather than a delivery or pricing one?
Suggested practice checklist
Instead of guessing where the week should go, day one measures it under a fixed rubric and allocates the remaining hours in proportion to the gaps. The method is deliberately rigid: the allocation is written down before any studying starts and is not renegotiated when a topic turns out to be unpleasant.
Day 1 — Diagnostic, scored before you study anything
- Sit a 100-minute timed diagnostic in four blocks: 30 minutes of SQL across three prompts, 25 minutes of short-answer statistics, 25 minutes on one modelling or case prompt, and 20 minutes delivering one behavioural story aloud.
- Score each block from 0 to 3 on a fixed rubric where 3 is correct and fluent, 2 is correct but slow or prompted, 1 is partially correct, and 0 is stuck, grading the output rather than how the attempt felt.
- Allocate the hours for days two to five roughly in proportion to 3 minus the score in each block, write the allocation down, and commit to not revising it midweek.
Deliverable: A scored rubric and a fixed hour allocation for the rest of the week.
Day 2 — Largest gap: find the boundary rather than the subject
- Break the weakest area into five named sub-skills (for query work: grain control, window frames, date arithmetic, set logic with NULLs, and reading a query plan) and rate each one, so the rest of the week targets a sub-skill instead of a subject.
- Solve three problems chosen to sit just above where the rating drops off, and for each write the first move you failed to make.
- Re-solve one of them from memory four hours later, on paper, with nothing open.
Deliverable: A five-item sub-skill map with the two blocking sub-skills circled.
Day 3 — Largest gap: drill the blocking sub-skill
- Do eight short repetitions of the same shape rather than eight different problems, so what you practise is the pattern and not the puzzle.
- Write the rule you now hold in one sentence, then test it against a case built to break it: a ranking function over a column with ties, or a two-sample test on observations that are obviously dependent.
- Have someone else read your one-sentence rule and find the precondition you left out.
Deliverable: One rule statement with its preconditions attached and one counterexample that would have caught the incomplete version.
Day 4 — Second gap, plus maintenance on your strongest area
- Run the same sub-skill map and boundary protocol on the second-largest gap, compressed into half the day.
- Spend 25 timed minutes on your strongest area to stop it decaying, choosing the hardest problem you can still finish rather than an easy warm-up.
- Compare how the two areas fail: whether you lose time on recall, on setup, or on arithmetic, because the fix differs for each.
Deliverable: A second sub-skill map plus a one-line diagnosis of how each area fails you.
Day 5 — The gap that is not a skill
- Record yourself answering one technical and one behavioural prompt, then count two things in the playback: how many seconds before your first clarifying question, and how many sentences you started without knowing where they ended.
- Rewrite your three most-used stock phrases into shorter versions, and practise saying "I do not know, here is how I would find out" without softening it into a guess.
- Deliver one answer again with a hard 90-second limit to force structure before detail.
Deliverable: Two recordings with a counted improvement in time-to-first-question.
Day 6 — Retest under day-one conditions
- Sit the same 100-minute diagnostic structure with new prompts of comparable difficulty and score it on the identical rubric.
- Compare block by block, and for any block that did not move, change the method rather than adding hours: a block stuck at 1 usually means the practice was too varied, not too short.
- Write which single block you would still lose the offer on.
Deliverable: A second scored rubric placed next to the first, with one named remaining risk.
Day 7 — Full loop under interview conditions
- Run a 60-minute mock covering the two blocks that moved least, with an interviewer instructed to interrupt and change direction.
- Write your recovery script for the moment you go blank: restate the question, state your assumption, name the first thing you would check.
- Reduce the week to the rule statements you wrote, each with its preconditions attached, then say every one of them out loud without reading it and cut any you cannot state in a single sentence, since a rule you have to reconstruct mid-answer will not survive being interrupted.
Deliverable: A one-page card holding the recovery script and only the rules you could state from memory.
What the behavioural round is actually scoring
Interviewers here are not checking whether you can describe a project. They want the decision you made, why you made it under the information you had, and what changed afterwards that someone else could measure. A story that ends at 'I built a model' has no ending. Say what the model caused, or what you stopped doing because of it.
Give an example of a time when a project did not go as planned. How did you handle the setback, and what did you learn from it?
Medium · behavioural and stakeholder questions
Approach
- Close with what you would do differently, concretely.
- Pick a story where you drove the decision, not one where you observed it.
- State the situation in two sentences and spend the rest on your reasoning.
Follow-up
- What did you decide not to do, and why?
- What would you do differently if you ran that project again?
Tell me about a time you had to explain a complex machine learning model or statistical analysis to a non-technical stakeholder. How did you structure your explanation?
Medium · behavioural and stakeholder questions
Approach
- Close with what you would do differently, concretely.
- Pick a story where you drove the decision, not one where you observed it.
- Name the disagreement or constraint, and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Tell me about a time you mentored a junior team member or led a technical project. What was your approach to guiding them?
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.
- Name the disagreement or constraint, and how you resolved it with evidence.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?