cswork / libraryOpen practice workspace

Interview guides · Extia

Extia Data Scientist Interview Questions & Guide 2026

Data scientist interview prep for Extia: original practice on experiment design, SQL and metric reasoning, with worked solutions.

The 60-second brief

A Data Scientist at Extia plays a pivotal role in bridging the gap between raw data and actionable business strategy. As a consultant-driven organization, Extia places a high premium on your ability to not only perform complex modeling but also to communicate technical findings to stakeholders who may not have a data science background. You will be tasked with solving diverse problems across various client projects, requiring both technical agility and a strong sense of adaptability.

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

  • Reconstruct pipeline stage history from mutable rows
  • Compute utilisation against a defended availability denominator
  • Segment margin by pricing model before comparing

Overview

Your impact is twofold: you drive technical innovation for clients while simultaneously building your own professional expertise within a supportive, growth-oriented environment. Because Extia operates on a human-centric model, this role is as much about your ability to integrate into a team and understand business needs as it is about your proficiency with algorithms or data pipelines. You are expected to be a problem-solver who thrives in the consulting landscape, where project scopes can shift and the ability to articulate value is paramount.

Extia places significant emphasis on your personality and potential. Be prepared to show not just what you know, but how you learn and how you collaborate with others.

The Extia interview process

Extia candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Phone Screen

Whoever runs this call is usually not a practitioner. They take notes, and a hiring manager skims those notes later, so the real question is whether your work survives being written down by someone outside the field. Test every project sentence against that: could a non-specialist repeat it correctly without knowing what a propensity score is? Carry a plain-language version of each project and one reason you want this particular role that you could not copy onto another application. Vagueness at this stage reads as inexperience, even when the underlying work was genuinely deep.

What to demonstrate

  • Whether a non-specialist can restate your projects accurately, since their paraphrase is what reaches the hiring manager
  • Whether your reason for wanting the role points at the work itself rather than the company's reputation
  • Whether your language signals the level being screened for: what you decided yourself versus what you were handed

How to prepare

  • Write a two-sentence, jargon-free version of each major project: the question nobody could answer, and the decision your work changed. Read it to someone outside data and have them repeat it back
  • Point your 'why this role' answer at something concrete in the job description or the product surface you would be working on, and keep it to two sentences
  • Have two questions ready about measurement: which metric the team is held to, and who acts on an analysis once it lands

Manager Interaction

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.

Behavioral and Technical Discussions

Behavioural answers from data candidates get audited in a way that answers from other roles do not. When you say a model lifted retention, the next question is the denominator, the window, and how you knew the lift was not seasonal. So attach the measurement to each claim while you tell it: what the metric was before, over what period, and against what comparison. Numbers with no baseline read as rounded-up memory, and one unsupported figure tends to make the rest of the story sound rehearsed.

What to demonstrate

  • Whether each impact number arrives with a baseline, a window and a comparison, or as a bare percentage
  • Whether you can name the method that attributed the effect to your work (an experiment, a staged rollout, a seasonal control) or concede the link was correlational
  • Whether the magnitudes stay internally consistent when the interviewer multiplies them against the scale you described earlier

How to prepare

  • For each story, write the impact line as metric, value before, value after, window, and how attribution was established. Any line missing two of those five is a follow-up you will answer badly.
  • Re-derive one headline number from the source table rather than the deck that reported it. Resume numbers drift upward across retellings.
  • Decide in advance which figures you cannot share, and prepare the ratio or relative change you can give instead, so a confidentiality limit does not read as evasion.

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.

Answering a product-sense question with a list of features

Answer with a decision and the measurement that would settle it: the hypothesis, the primary metric, the guardrails, and the result that would make you not ship. A feature brainstorm cannot be wrong, which is exactly why it earns no points.

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.

Questions & practice

Can you explain a complex model you have implemented and how you validated its performance?

Medium · machine learning and modelling

Approach

  1. Say how the offline result would be validated online before it is trusted.
  2. Check what information would not exist at prediction time, and exclude it.
  3. Set a baseline first, so any model has something honest to beat.

Follow-up

  • Where could label leakage enter this setup?
  • How would you choose the decision threshold, and who owns that choice?

Implement billable utilisation against a defended availability denominator

Medium · metric implementation · denominators · proration

Implement billable utilisation for one calendar month at consultant grain, then roll it up to practice_area. Inputs: time_entries (consultant_id, work_date, hours, is_billable, charge_code, status), consultants (consultant_id, practice_area, fte_fraction, home_region, is_billable_role, hire_date, termination_date) and holidays (region, holiday_date). Numerator is approved hours with is_billable true. Denominator is scheduled workdays in the month, clipped to [hire_date, termination_date] and net of that region's holidays, times 8 times fte_fraction, minus approved leave hours. Roll up as sum(numerator) / sum(denominator).

Approach

  1. Build the workday set per region first: business days in the month minus that region's holiday_dates. State the Monday-to-Friday assumption out loud, because a region with a different working week makes np.busday_count wrong rather than approximate.
  2. Prorate by clipping each consultant's interval to [max(month_start, hire_date), min(month_end, termination_date or month_end)] and counting workdays inside the clipped interval, so a mid-month start produces a smaller denominator instead of a fake dip in the ratio.
  3. Subtract approved leave hours (charge_code in leave_paid, leave_unpaid) only for leave falling on days already counted as workdays; leave logged on a public holiday would otherwise be subtracted twice and can push a denominator negative.
  4. Filter to is_billable_role, then drop consultant-months whose denominator is zero or negative (full-month leave, a hire on the last day) rather than emitting inf or NaN, and return the dropped count as part of the result.
  5. Roll up by summing numerators and denominators separately. Averaging per-person ratios gives a 0.2 FTE consultant the same weight as a full-time one and produces a practice number that no individual reconciles to.

Worked solution (35 min)

  1. Per region, workdays = np.busday_count(month_start, month_end + 1 day, holidays=region_holidays); per consultant, recompute on the clipped [start, end] interval so proration and holidays compose.
  2. leave = time_entries[status=='approved' & charge_code.isin(['leave_paid','leave_unpaid']) & work_date.isin(region workdays)].groupby('consultant_id').hours.sum().
  3. denominator = workdays_clipped * 8 * fte_fraction - leave, reindexed to the billable-role consultant list and filled with 0 leave where absent.
  4. numerator = time_entries[status=='approved' & is_billable].groupby('consultant_id').hours.sum(), reindexed and zero-filled.
  5. Drop rows with denominator <= 0 (counting them), compute utilisation_pct = 100 * numerator / denominator, then groupby practice_area and divide summed numerator by summed denominator.

Expected result: A consultant-month frame carrying numerator, denominator and utilisation_pct, a practice-area frame whose ratio equals sum(numerator)/sum(denominator), and an explicit count of consultant-months excluded for a non-positive denominator.

Verify it yourself

  • A full-time consultant with no leave in a 21-workday month has denominator exactly 168.0.
  • Every consultant's denominator is at most workdays * 8 * fte_fraction, with equality only when leave is zero.
  • The practice-area ratio equals the denominator-weighted mean of the per-consultant ratios, and sits between their min and max.
  • Summed numerators across practice areas equal total approved billable hours for in-scope consultants.

Follow-up

  • Utilisation rose two points this month while realisation fell. Reconcile those two movements with one mechanism.
  • A regional lead says their team looks four points below another region. What do you check before you answer, and in what order?

Kaplan-Meier days to payment with unpaid invoices censored

Hard · survival analysis · censoring · kaplan-meier

invoice_lines has invoice_line_id, engagement_id, line_type, issued_at, due_date, paid_at (null when unpaid), amount_usd and status in draft, issued, partially_paid, paid, disputed, written_off. At a given snapshot_date, estimate the median days from issue to full payment. Implement Kaplan-Meier yourself; no lifelines or equivalent. Treat issued, partially_paid and disputed as right-censored at snapshot_date, and decide and justify what to do with written_off. Report the naive mean over paid lines alongside your estimate and state the sign of its bias.

Approach

  1. Build the duration and event table explicitly. Drop draft lines, which have no clock. For status paid, duration = (paid_at - issued_at).days with event = 1. For issued, partially_paid and disputed, duration = (snapshot_date - issued_at).days with event = 0.
  2. Handle written_off as a competing event rather than a censor. Censoring it makes the estimator answer 'time to payment if written-off invoices could still pay', which overstates collection. Either report a cumulative-incidence version alongside, or censor them and say plainly that the result is conditional on eventual collection.
  3. Implement the estimator directly: sort unique event times, at each t take n_i as the count with duration >= t and d_i as the payments at exactly t, and accumulate S(t) = product of (1 - d_i / n_i). Censored rows leave the risk set without causing a drop, which is the whole mechanism and the reason the answer differs from any completed-case average.
  4. Read the median as min{t : S(t) <= 0.5}. If S never reaches 0.5 within observed follow-up, report 'not reached'; interpolating past the last observation invents data that the snapshot does not contain.
  5. Add Greenwood's formula for Var(S(t)) to put a band on the curve, then invert the band at 0.5 for an interval on the median rather than quoting a point estimate alone.
  6. Compare against the mean over paid lines only and name the direction: at any snapshot the paid set over-represents fast payers, so the naive mean is biased low, and the bias widens exactly when collections deteriorate.

Follow-up

  • A large account moved to a monthly payment run. Is administrative censoring still independent of payment time, and what would you check?
  • Finance wants one DSO number against a target. What do you give them, and what do you refuse to give them?
  • Stratify by line_type. Do milestone lines behave like fees lines, and what would it mean for the firm if they do not?

Find signed engagements with no approved billable hour

Medium · anti-join · null semantics · not exists

fct_engagement holds engagement_id, start_date and status. fct_time_entry holds time_entry_id, consultant_id, engagement_id, charge_code, work_date, hours, is_billable and status, and engagement_id is NULL on bench, leave, training and internal rows. Return engagements with start_date in the trailing quarter and status IN ('active','closed_delivered','closed_early') that have no approved billable time entry with work_date within 45 days of start_date, giving engagement_id, start_date and days elapsed. Then explain why NOT IN over a subquery selecting fct_time_entry.engagement_id is the wrong instrument here.

Approach

  1. Express the exclusion as NOT EXISTS with a correlated predicate covering all four conditions at once: te.engagement_id = e.engagement_id AND te.is_billable AND te.status = 'approved' AND te.work_date < e.start_date + INTERVAL '45 days'. NOT IN can only carry a single column, so a multi-condition anti-join forces a contorted subquery even before the NULL problem.
  2. State the NULL semantics precisely: NOT IN (SELECT engagement_id FROM fct_time_entry) evaluates to NULL rather than TRUE for every candidate as soon as one NULL is present in the list, because x <> NULL is unknown. The WHERE clause keeps only TRUE, so the query returns zero rows and reads as a clean bill of health. This table guarantees NULLs, since bench and leave rows carry no engagement.
  3. Note the equivalent LEFT JOIN ... WHERE te.engagement_id IS NULL form. It is correct, but it materialises a join only to discard most of it; NOT EXISTS states the intent and most planners execute both as the same anti-join.
  4. Guard the window against truncation: an engagement that started 10 days ago cannot yet have failed a 45-day test, so require start_date <= current_date - 45 or report the too-early set separately rather than counting them as failures.
  5. Decide on the late-timesheet risk explicitly. A missing entry may mean unstaffed work or an unsubmitted timesheet, so either hold the cutoff back past the measured submission lag or label the recent tail as provisional.

Worked solution (20 min)

  1. Count engagements matching the status and start_date predicates; this is the denominator.
  2. Write the NOT EXISTS version and record its row count.
  3. Write the NOT IN version on the same data and observe zero rows, then confirm with SELECT COUNT(*) FROM fct_time_entry WHERE engagement_id IS NULL that NULLs are present.
  4. Cross-check by counting engagements that DO have a qualifying entry and verifying the two counts sum to the denominator.
  5. Open one engagement from the result and look at its raw time entries to see whether the cause is no staffing or unapproved timesheets.

Expected result: A short list of engagement_id, start_date and days_since_start for engagements that started at least 45 days ago and carry no approved billable hour in their first 45 days. The NOT IN variant returns zero rows on the same data.

Verify it yourself

  • Count of flagged engagements plus count of engagements with at least one qualifying entry equals the count of engagements matching the status and date filters.
  • Every returned engagement has start_date at or before current_date - 45.
  • Spot-checking one flagged engagement in fct_time_entry shows either no rows or only unapproved or non-billable rows.
  • Replacing NOT EXISTS with LEFT JOIN ... IS NULL returns an identical set.

Follow-up

  • Turn this into a time-to-first-billable-hour distribution. What do you do with engagements that never recorded one?
  • Should client_pursuit hours count as the engagement being staffed, and how does that choice change the list?
  • How would you prove the empty result from the NOT IN version is a bug rather than good news?

Deduplicate to the latest issued invoice line per engagement

Easy · window functions · dedup · determinism

fct_invoice_line holds invoice_line_id, invoice_id, engagement_id, line_type, period_end_date, amount_usd, issued_at and status; draft lines have issued_at NULL. Return exactly one row per engagement_id, its most recently issued line, with invoice_line_id, line_type, amount_usd and issued_at. Two lines on the same engagement can share an issued_at value to the second, so the result must be identical on every run against unchanged data. Write it with a window function, then say in one sentence when DISTINCT ON would be the better choice.

Approach

  1. Filter to issued lines (issued_at IS NOT NULL, status <> 'draft') before ranking. Ranking first and filtering afterwards can leave an engagement whose top-ranked row was a draft with no row at all in the output.
  2. Rank with ROW_NUMBER() OVER (PARTITION BY engagement_id ORDER BY issued_at DESC, invoice_line_id DESC). The surrogate key as the final ORDER BY term is what makes ties resolve the same way on every execution; without it the planner is free to return either tied row.
  3. Wrap the ranked query in a CTE or subquery and filter rn = 1, since a window function cannot appear in the WHERE clause of the query that computes it.
  4. Name why RANK() is wrong here: on tied issued_at it assigns 1 to both rows, so the result carries two rows for one engagement and any downstream SUM double counts.
  5. Compare against DISTINCT ON (engagement_id) ... ORDER BY engagement_id, issued_at DESC, invoice_line_id DESC: same answer, one sort, usually cheaper, but the window form generalises the moment you also want rn <= 3 or a second ranking in the same pass.

Follow-up

  • Now return the latest line per engagement per line_type. What changes in the PARTITION BY, and what does that do to the row count?
  • Return the latest and second-latest line together. Which of the two constructs survives that requirement?
  • issued_at is TIMESTAMPTZ and finance reports on a single local calendar. Where can 'latest' flip between the two conventions?

What tools or languages do you prefer for data processing, and why?

Medium

Approach

  1. Clarify what is being asked and what a complete answer would contain.
  2. State your assumptions explicitly before working the problem.
  3. Say what you would check first and why it is the highest-information step.

Follow-up

  • How would you know your answer was wrong?
  • What assumption would you test first?

How do you stay updated with the latest advancements in the field of data science?

Medium

Approach

  1. Work from the decision backwards to the evidence you would need.
  2. State your assumptions explicitly before working the problem.
  3. 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?

Choose a randomisation unit when consultants are a shared pool

Medium · interference · randomisation unit · switchback · sutva

A staffing optimiser proposes consultant allocations to engagements. The proposal on the table is to randomise at the engagement: half of new engagements get optimiser-suggested staffing, half go through the current manual process. The claimed benefit is lower time to first billable hour, measured from fct_engagement.start_date to the earliest fct_time_entry work_date with is_billable = TRUE. Every engagement in a practice area draws from the same capacity-constrained consultant pool. Explain what the engagement-level estimate would actually measure, propose a design that measures what leadership wants, and state the price your design pays.

Approach

  1. Name the violation. SUTVA requires one engagement's outcome to be unaffected by another's assignment, and a fixed consultant pool makes that false by construction: a consultant the optimiser frees is staffed onto a control engagement, so treatment improves and control degrades from the same act.
  2. Say what the biased estimate is. The engagement-level contrast measures displacement, treatment against a control that treatment has actively worsened, so it overstates the firm-level effect. In the limiting case where the optimiser only reorders a fixed queue of consultant-weeks, the firm-level effect is zero while the engagement-level contrast is large and significant.
  3. Move the randomisation unit up to the level that contains the contention, the staffing pool, which here is practice_area crossed with home_region. Units then share no consultants and the interference is internalised. The price is that five practice areas by four regions yields at most 20 clusters, which is small-cluster inference territory.
  4. Or run a switchback inside each pool: randomise each weekly staffing cycle to optimiser or manual so every pool is its own control, turning 20 clusters into 20 pools times many cycles. The price is carryover, since allocations made in a treated week constrain availability in the following control week, so you discard a burn-in window at each switch and you cannot measure any effect whose horizon exceeds the switch interval.
  5. Analyse at the level of randomisation: pool-week means, pool and calendar-week fixed effects, standard errors clustered at pool, and a wild cluster bootstrap rather than the plain cluster-robust sandwich at 20 clusters.

Worked solution (30 min)

  1. Write potential outcomes against the full assignment vector, Y_i(z) rather than Y_i(z_i), and show the dependence on z_j for any j sharing the pool.
  2. Work the fixed-pool case: if the optimiser reorders a conserved queue of consultant-weeks, the sum of days-to-staff across engagements is unchanged, so the pool-level effect is zero while treated engagements are faster by exactly the amount control engagements are slower.
  3. Enumerate candidate units, engagement, account, partner, pool, pool-week, and for each state whether it contains the contention and how many independent units it yields.
  4. Select a pool-week switchback with the cycle length set to the staffing-meeting cadence, a one-week burn-in discarded at every switch, and a target of at least 26 usable pool-weeks per pool.
  5. Pre-specify the analysis: pool-week mean days to first billable hour on a treatment indicator with pool and calendar-week fixed effects, clustered at pool, wild bootstrap with Webb six-point weights.

Expected result: A design memo that rejects engagement-level randomisation on interference grounds, adopts a pool-week switchback over practice_area by home_region pools with a stated burn-in and calendar-week fixed effects, and states plainly that the design cannot detect effects whose horizon exceeds the switch interval.

Verify it yourself

  • On simulated reordering-only data, where the true pool-level effect is zero, the proposed estimator must return an effect near zero; a large estimate means the unit is still wrong.
  • Treated and control pool-weeks should have similar counts of engagement starts and similar practice-area mix, since randomisation runs over time rather than over units.
  • The independent-unit count behind the standard error must be the number of pools, not the number of pool-weeks, unless within-pool serial correlation has been modelled explicitly.

Follow-up

  • How long a burn-in would you discard after each switch, and how would you estimate that length from data rather than assert it?
  • Time to first billable hour is right-censored for engagements not yet staffed at the analysis date. How does that interact with a switchback?
  • If the optimiser's benefit is pure reallocation within a fixed pool, what outcome would show a genuine firm-level gain?

One region's delivery cost fell eighteen percent for two weeks

Medium · pipeline failure · data completeness · freshness checks

Cost per delivered engagement-week fell about 18% in one region for two consecutive weeks while fees were flat, so reported margin jumped. Source is fct_time_entry (consultant_id, engagement_id, work_date, entered_at, hours, cost_rate_usd, charge_code, status), loaded nightly from a regional timesheet system, joined to dim_consultant for home_region. Determine whether delivery genuinely got cheaper or rows are missing, name the evidence that distinguishes the two, and specify the automated check you would add.

Approach

  1. Check row counts and coverage before any ratio: entries per workday and distinct consultant_id with at least one entry per workday, for the affected region against its own trailing four weeks and against other regions in the same weeks.
  2. Use the shape of the loss to separate causes. A load failure removes whole days or whole consultants, so distinct-consultant coverage collapses while hours per reporting consultant stays normal. A real change lowers hours per consultant with coverage intact.
  3. Split the cost identity: cost = hours x cost_rate_usd. Compute mean cost_rate_usd by level. If rates went NULL, zero or defaulted to a single value, the fault is in the dimension join, not the source extract.
  4. Look for the loader's fingerprint: max(entered_at) per region per day, gaps aligned to a calendar boundary, and whether the missing dates fall on a particular day of week, which points at a scheduler that skipped a run rather than at delivery behaviour.
  5. Confirm by waiting one cycle: a failed load backfills on re-run and the anomaly disappears from the restated weeks; a genuine change persists. Do not publish until that test has run.
  6. Automate the check that would have caught it: per-region, per-workday assertions on row count and on distinct billable consultants covered, with thresholds derived from trailing medians rather than fixed constants, plus a freshness assertion on max(entered_at).

Follow-up

  • The same load also feeds utilisation. Why did utilisation not show an equally obvious break?
  • How do you choose the alert threshold so it survives holidays and genuine low-activity weeks?
  • If the rows never arrive, what do you do with the two weeks already reported to leadership?

Suggested practice checklist

For someone who can already write the query and train the model but stalls when asked what to measure or whether a change is worth making. Metric definition and case structure come first; the technical work is kept as maintenance rather than the centre of the week.

Day 1 — Metric anatomy

  • For three products you use daily, write one primary metric, two input metrics that plausibly move it, and one guardrail that would catch a cheap way of moving the primary at the cost of the product.
  • For one of them, specify the metric precisely enough that two analysts would return the same number: numerator, denominator, unit of observation, time window, and how returning and deleted accounts are treated.
  • Pick a ratio metric and write what happens to it when the denominator shrinks for reasons unrelated to the numerator, with a concrete example of that happening.

Deliverable: A one-page metric tree for one product, with the primary metric written as an unambiguous spec.

Day 2 — Diagnosing a drop without guessing

  • Take the prompt "weekly active users fell 8 percent week over week" and write the segmentation plan before proposing any cause: platform, region, tenure cohort, acquisition channel, and whether the movement sits in the numerator or in a changed denominator.
  • List the instrumentation failures that manufacture fake drops (a client release that stopped firing an event, a bot filter change, a shifted date boundary or timezone) and write the query that rules out each one.
  • Rehearse stating the boring explanations first, seasonality and day-of-week composition, before reaching for a product cause.

Deliverable: A drop-diagnosis checklist short enough to recite from memory in under a minute.

Day 3 — Should we build it

  • Take a feature idea and write it as a bet: what you believe is true, what would have to be true for it to pay off, the metric that would confirm it, and the effect size that would justify the engineering cost.
  • Size the opportunity top-down and bottom-up, then reconcile the two numbers in writing instead of quoting whichever is friendlier.
  • Write the counter-metric that would make you kill the feature even if it wins on the primary metric.

Deliverable: A one-page product memo ending in a decision rather than a list of considerations.

Day 4 — The places aggregate numbers lie

  • Construct a Simpson's paradox numerically: two segments where the treatment wins within each segment yet loses overall, and identify the shift in segment weights that causes it.
  • Take a heavy right-tailed quantity such as revenue per user and write why the mean is the wrong summary, which percentile you would report instead, and what a moving mean with a stable median tells you.
  • Write your definition of a session for the product from day one, then name two real behaviours it misclassifies.

Deliverable: One page holding a worked Simpson's paradox table and a session definition with its two known failure cases.

Day 5 — Technical maintenance, aimed at metrics

  • Solve four timed SQL prompts that all end in a ratio metric, so the question of grain stays live in every answer.
  • Compute a 95 percent confidence interval for a proportion on a small sample, and state why the normal approximation is unreliable when either np or n(1 minus p) falls below roughly 10, along with which interval you would use instead.
  • Take one metric from your day-one tree, write the query that computes it correctly, then write the query that computes it wrong in the most plausible way and explain how you would notice.

Deliverable: Four solved prompts plus a matched correct and plausible-wrong query for one metric.

Day 6 — Turning engineering work into data science stories

  • Write three project stories as situation, decision, trade-off, outcome, each carrying one number and one thing you got wrong.
  • For the story you will lead with, prepare an answer to "what would you do differently" that names a decision you made, not a constraint you were handed.
  • Practise the sentence that reframes a systems project as a question project: the question the work answered, ahead of the pipeline it shipped.

Deliverable: Three written stories with the lead story delivered aloud and timed under four minutes.

Day 7 — Mock case and gap list

  • Run a 40-minute mock case with someone playing a product manager who pushes back on your metric choice, and record it.
  • Listen back and mark every moment you proposed a solution before the success metric existed.
  • Rewrite those moments as the question you should have asked, and rehearse the first 90 seconds of the case until scoping comes before solving.

Deliverable: A recorded case plus a rewritten opening 90 seconds.

Where your data came from

Data people depend on systems owned by other teams, and much of the job is negotiating for instrumentation, access, or a fix to a broken pipeline. Prepare an example of getting something changed upstream that you did not control. Describe what you asked for, what you traded, and how you worked while you waited.

How do you handle situations where your technical approach is challenged by a non-technical stakeholder?

Medium · behavioural and stakeholder questions

Approach

  1. Name the disagreement or constraint, and how you resolved it with evidence.
  2. Close with what you would do differently, concretely.
  3. Pick a story where you drove the decision, not one where you observed it.

Follow-up

  • What would you do differently if you ran that project again?
  • How did you know the outcome was caused by your change?

Can you walk me through your previous experiences and why you are interested in joining Extia?

Medium · behavioural and stakeholder questions

Approach

  1. Name the disagreement or constraint, and how you resolved it with evidence.
  2. Close with what you would do differently, concretely.
  3. 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?

Can you describe a project where you had to adapt your methodology to meet a client's specific business requirement?

Medium · behavioural and stakeholder questions

Approach

  1. State the situation in two sentences and spend the rest on your reasoning.
  2. Name the disagreement or constraint, and how you resolved it with evidence.
  3. Close with what you would do differently, concretely.

Follow-up

  • How did you know the outcome was caused by your change?
  • What would you do differently if you ran that project again?