Interview guides · Bee Engineering
Bee Engineering Data Scientist Interview Questions & Guide 2026
Data scientist prep for Bee Engineering: practice defining a consulting and client services metric, picking its guardrails and defending the tradeoff.
The 60-second brief
As a Data Scientist at Bee Engineering, you are stepping into a dynamic, consulting-driven environment where your technical expertise directly solves complex challenges for diverse clients. Bee Engineering operates at the intersection of innovation and practical technology execution, meaning you will not just be building models in a vacuum; you will be delivering actionable intelligence that drives business decisions across various industries.
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
- Separate bookings, recognised revenue and collected cash
- Compute utilisation against a defended availability denominator
- Cluster inference at the account, not the engagement
Overview
Your impact in this position is twofold. First, you act as a technical powerhouse, applying machine learning, statistical analysis, and data modeling to uncover patterns and predict outcomes. Second, you serve as a strategic consultant, bridging the gap between raw data and client needs. You will often be embedded within or working closely alongside client teams, making your ability to translate complex data concepts into clear business value absolutely critical.
What makes this role uniquely interesting at Bee Engineering is the variety of the problem space and the exceptional internal support system. You are not just an outsourced resource; you are a representative of commitment to quality. You will have the opportunity to work on high-scale projects, influence client product roadmaps, and continuously evolve your tech stack as you transition between different client environments and strategic initiatives.
The Bee Engineering interview process
Bee Engineering candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
Internal 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.
Coaching for Client Interview
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.
Client Interview
An added round often puts you in front of someone outside the core hiring team: a partner engineer, a product owner, a domain expert, sometimes a more senior manager. The question they are really asking is not whether you can do the work but whether they would trust a number that came from you. That changes what a good answer looks like. Lead with what the decision cost and what it changed, keep the method available but not central, and be plain about the limits of your evidence. Overstating a result is the fastest way to lose this round.
What to demonstrate
- Whether you can explain a technical choice to someone who will never read your code, without either flattening it into nothing or hiding inside jargon
- Honesty about evidence strength: what the analysis establishes, what it only suggests, and what it cannot say at all
- How you take disagreement, specifically whether you update on a good objection, hold your position with reasons, or fold on contact
How to prepare
- Write the two-sentence version of your most technical project for a non-specialist, then check that neither sentence needs a method name to make sense.
- For one result you are proud of, write the strongest objection someone could raise and a response that concedes the part of it that is correct.
- Prepare one decision that turned out to be wrong: how you found out, what it cost, and what you changed afterwards. A senior cross-functional interviewer asks for this more often than a technical one does.
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.
Using calendar hours, or a current rate card, as the denominator
Available hours is not days x 8. It must subtract approved leave and region-specific public holidays, scale by fte_fraction, and prorate for hire_date and termination_date inside the period; skipping this produces cross-region utilisation gaps that are purely holiday-calendar artifacts and a fake dip every time a cohort of new hires starts. Equally, bill and cost rates change over time, so joining today's dim_consultant row to last year's hours restates history. Use the rate snapshotted on the time entry, or join dim_consultant on work_date BETWEEN effective_from AND COALESCE(effective_to, 'infinity').
Accepting a metric definition without asking about the denominator
Pin down the denominator, the eligibility filter and the time window before computing anything: conversion rate per session, per user, per eligible user and per new user are four different numbers with different behaviour. Restate the definition in one sentence and get agreement before you analyse.
Ignoring interference between units in a marketplace experiment
Ask whether one unit's treatment can change another unit's outcome through shared inventory, a matching pool, a social graph or a common budget. Where it can, randomise at a level that contains the spillover, such as region or time slice, and say explicitly what that costs you in statistical power.
Questions & practice
Imagine a client is unhappy with the accuracy of a predictive model you built. How do you approach the conversation?
Medium · machine learning and modelling
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- 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
- Where could label leakage enter this setup?
- How would you choose the decision threshold, and who owns that choice?
How do you evaluate the performance of a classification model when the dataset is highly imbalanced?
Medium · machine learning and modelling
Approach
- Check what information would not exist at prediction time, and exclude it.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- What would you monitor after launch to know the model is still valid?
- How would you choose the decision threshold, and who owns that choice?
Walk me through the steps you take to prevent overfitting in a complex machine learning model.
Medium · machine learning and modelling
Approach
- Say how the offline result would be validated online before it is trusted.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Simulate the chance a capped engagement crosses its cap
Medium · monte carlo · bootstrap resampling · pricing caps
A capped time-and-materials engagement has not_to_exceed_usd = 400000, has billed 250000 to date, and bills at a blended bill_rate_usd of 250. Fourteen delivery weeks remain before planned_end_date. You have that engagement's last twenty weekly totals of approved billable hours as a pandas Series. Estimate the probability that cumulative billable value crosses the cap before the planned end, and the expected unbillable hours if it does. Resample the observed weeks; do not assume normality. Report a Monte Carlo standard error and justify the number of draws.
Approach
- Reduce the deterministic part first: the cap still affords (400000 - 250000) / 250 = 600 hours, so the whole question is the distribution of the sum of fourteen future weekly hour totals against a fixed threshold of 600.
- Before resampling, check the twenty observed weeks for trend and lag-1 autocorrelation. Independent resampling is defensible only if the weeks are exchangeable; on a ramping engagement use a moving-block bootstrap or model the ramp, because i.i.d. draws understate the upper tail, which is exactly the tail the question is about.
- Draw one (B, 14) array with np.random.default_rng().choice(observed, size=(B,14), replace=True), sum along axis 1, and compute p_hat = mean(total > 600) in one vectorised pass.
- Report expected unbillable hours two ways: unconditional mean(maximum(total - 600, 0)) for expected loss, and the mean conditional on a breach for how bad a breach is when it happens. The second is the number that drives a change-order conversation.
- Attach se(p_hat) = sqrt(p_hat(1 - p_hat)/B) and pick B from the precision you need: plus or minus one point at 95% confidence needs about 1.96^2 * 0.25 / 0.01^2, roughly 9600 draws at the worst case p = 0.5.
- State the assumptions that would flip the answer: constant blended rate, no scope change, no holiday weeks inside the fourteen, and a cap that applies to fees rather than to fees plus expenses.
Worked solution (30 min)
- affordable_hours = (400000 - 250000) / 250 = 600.0; print it, because a wrong threshold makes every later number wrong in a way no simulation reveals.
- Plot or regress the twenty weekly totals against week index and compute lag-1 autocorrelation; record the result as the stated justification for i.i.d. versus block resampling.
- rng = np.random.default_rng(7); draws = rng.choice(weekly.values, size=(10000, 14), replace=True); totals = draws.sum(axis=1).
- p_hat = (totals > 600).mean(); se = np.sqrt(p_hat * (1 - p_hat) / 10000); overrun = np.maximum(totals - 600, 0); report overrun.mean() and overrun[totals > 600].mean().
- Re-run with a second seed and confirm p_hat moves by less than two standard errors before reporting.
Expected result: A probability with its Monte Carlo standard error (about 0.005 at B = 10000 near p = 0.5), expected unbillable hours both unconditionally and conditional on a breach, and an explicit statement of the exchangeability assumption behind the resampling.
Verify it yourself
- Two different seeds agree to within roughly two Monte Carlo standard errors.
- If every observed week exceeds 600/14 = 42.86 hours, p_hat must be exactly 1.0; if every week is below it, p_hat must be 0.0.
- Unconditional expected overrun is zero whenever p_hat is zero, and is always at most the conditional value times p_hat plus rounding.
- Raising the cap by 25000 moves the threshold by exactly 100 hours, and p_hat must fall.
Follow-up
- Hours past the cap still cost money. Restate the result as expected gross margin rather than a probability.
- Two weeks of time are entered but not yet approved. How do you fold them in without double-counting?
- A change order that raises the cap is judged 60% likely. How does that change the number you present, and to whom?
Write a SQL query to find the second highest salary in an employee database.
Medium · sql and data manipulation
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Say which table is the grain you start from, and join outward from it.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- How would you verify this result without re-running the same query?
- What breaks if events arrive late or out of order?
Engagement margin without fan-out across two fact tables
Medium · fan-out · join grain · mix shift
fct_engagement holds engagement_id, pricing_model and contract_value_usd. fct_invoice_line holds engagement_id, line_type, amount_usd and status. fct_time_entry holds engagement_id, hours, cost_rate_usd, is_billable and status. For engagements closed last year, return fees (line_type IN ('fees','milestone','credit_note') and status <> 'draft'), delivery cost (SUM(hours * cost_rate_usd) over approved entries, billable and non-billable alike) and gross margin, grouped by pricing_model. A single SELECT joining the engagement to both fact tables and then aggregating produces wrong numbers: say what the error is, then write the correct query.
Approach
- Do the arithmetic out loud. An engagement with 40 qualifying invoice lines and 900 approved time entries yields 36,000 rows on the double join: SUM(amount_usd) comes back 900 times too large and SUM(hours * cost_rate_usd) 40 times too large. The two inflation factors are different, so the ratio moves too — per engagement the double join replaces the cost-to-fee ratio with (cost / fees) * (line count / entry count), so a true 30 percent margin reads as 1 - 0.7 * (40 / 900), about 97 percent.
- Know which shape of this bug actually survives review. The ratio is preserved only where an engagement carries the same number of qualifying invoice lines as approved time entries, and then only as a row-count-weighted margin, 1 - SUM(cost_i * k_i) / SUM(fees_i * k_i), which still differs from the true pooled margin unless k_i is constant across engagements. So you get either a total absurd enough to tempt someone into a scaling patch, or, on a population where the two counts happen to track each other, a believable-looking ratio sitting on fees and cost that are each wrong by orders of magnitude.
- Aggregate each fact table to engagement grain in its own CTE, then LEFT JOIN both onto fct_engagement. One row per engagement then holds by construction rather than by inspection.
- Include non-billable delivery hours in cost. Rework, unbilled travel and pursuit time on a live account are real fully-loaded cost, and excluding them flatters fixed-fee work specifically, which is the mix you most need to see clearly.
- Treat zero and NULL as different: an engagement with no invoice lines has undefined margin, not zero. Divide by NULLIF(fees, 0) and keep those engagements in a labelled bucket instead of letting an inner join hide them.
- Group by pricing_model before reporting any firm-wide figure, and publish the fee mix next to it. Fixed-fee margin falls as hours rise, uncapped time-and-materials margin does not, so a shift in what was sold moves the pooled number with no change in delivery at all.
Worked solution (30 min)
- Compute standalone control totals: total fees over the filtered invoice-line set and total cost over the approved time-entry set, both for the closed-engagement population.
- Build fees_by_engagement and cost_by_engagement as separate CTEs at engagement grain.
- LEFT JOIN both onto fct_engagement, compute margin with NULLIF on the denominator, and group by pricing_model.
- Run the naive double join on a single engagement and confirm its fee total equals the true total times that engagement's time-entry count, and its cost total the true cost times its invoice-line count.
- Report the fee mix by pricing_model alongside the margin column.
Expected result: One row per pricing_model with total fees, total cost, gross margin as (fees - cost) / fees, and the share of fees that model represents. Engagements with fees of zero or NULL are reported as a separate count rather than folded into the ratio.
Verify it yourself
- Total fees across the grouped output equals the standalone control total for fees; the same holds for cost.
- Joining the two CTEs and counting rows returns exactly the number of qualifying engagements.
- The naive double join on one engagement reproduces both predicted multipliers, confirming the diagnosis rather than assuming it.
- Margin computed per pricing_model and then fee-weighted back together equals the pooled margin over the same population.
Follow-up
- Decompose a period-over-period margin move into a within-pricing-model component and a between-model mix component, and show the two sum to the total.
- Where does not_to_exceed_usd change the time-and-materials picture, and how would you find engagements that crossed it?
- Roll this up to the account through parent_client_id. What must the recursive CTE guard against?
What specific strengths and capabilities would you add to our engineering team?
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
- How would you know your answer was wrong?
- What assumption would you test first?
Walk me through your resume and highlight the data science skills you use most frequently.
Medium
Approach
- Work from the decision backwards to the evidence you would need.
- Say what you would check first and why it is the highest-information step.
- State your assumptions explicitly before working the problem.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Define success for a rate-card increase before any rollout
Hard · pricing · decision threshold · clustering · power
A 6% rate-card increase is proposed for one practice area next quarter. Before it ships, define what success means. Available: fct_proposal (expected_value_usd, stage, loss_reason, is_competitive, submitted_at, decided_at, practice_area), fct_engagement (pricing_model, contract_value_usd, practice_area, client_id) and fct_invoice_line (line_type, amount_usd, billed_hours). Name the primary metric, the guardrail that genuinely opposes it, the unit of analysis, and the numeric threshold that would reverse the decision. State how many account-quarters are needed to detect an effect large enough to change the decision, and what you do if that exceeds what the practice has.
Approach
- Make the primary realised revenue per billable hour, not the list rate. The increase can be conceded straight back through discount and show up as no change at all. Numerator: SUM(amount_usd) on line_type IN ('fees','milestone'). Denominator: SUM(billed_hours) over the same lines.
- Name the opposing guardrail: value-weighted competitive win rate in that practice area, with the share of losses carrying loss_reason = 'price' as the supporting diagnostic. Raising price lifts the primary and depresses the guardrail by construction, so the rollout pays off only if revenue per hour rises faster than volume falls.
- Derive both break-evens before looking at outcome data. Revenue is preserved while the volume loss stays under 6 / 106, roughly 5.7%. For margin, write p for realised price per billable hour and c for avoidable cost per billable hour, and require c < p so the baseline margin is positive. Setting post-change margin (1 - L) x (1.06p - c) equal to pre-change margin (p - c) gives 1 - L = (p - c) / (1.06p - c), so the break-even volume loss is L = 0.06p / (1.06p - c). That is strictly above 5.7% whenever c > 0, collapses to 5.7% at c = 0, and stays below 100% as long as c < p; a practice already below cost at the old rate is not a pricing question. It holds only where c is genuinely avoidable on the volume you lose; on a salaried bench that nobody stands down or resells, no cost is saved and the margin break-even falls back to the revenue one. Report both ends and name the assumption the threshold uses.
- Fix the unit and confront the identification problem. Assignment is at practice_area while the outcome sits at engagement or account, so cluster at client_id. With one treated practice area there is a single treated cluster and a conventional difference-in-differences is not identified; propose a synthetic control over the other practice areas with the donor-pool condition stated, or a pre-registered before-and-after whose parallel-trends check runs on the pre-period with a named failure action.
- Run the power calculation before proposing the rollout and be willing to conclude the practice cannot detect the effect. Competitive decisions in one practice area number in the tens per quarter, so a 3-point win-rate move needs many quarters. If the requirement exceeds what exists, the honest outputs are a staged rollout with a pre-committed stopping rule, or shipping without measurement and saying so, not a manufactured p-value.
Worked solution (40 min)
- Compute realised revenue per billable hour by practice-quarter for eight pre-period quarters from fct_invoice_line fees and milestone lines over billed_hours.
- Compute value-weighted competitive win rate per practice-quarter, cohorted on decided_at, denominator stage IN ('won','lost'), is_competitive = TRUE.
- Derive the two break-even volume losses: 6 / 106 for revenue, and 0.06p / (1.06p - c) for margin using the practice's realised price and avoidable cost per billable hour, then recompute with c treated as unavoidable to get the other end of the range.
- Count competitive decisions per quarter in the practice and compute the minimum detectable win-rate change at 80% power from a two-proportion test, treating that as a floor because clustering raises the real requirement.
- Write the rule: threshold, horizon, stopping condition, and the action taken when the power calculation says the effect is undetectable.
Expected result: Primary metric realised revenue per billable hour; opposing guardrail value-weighted competitive win rate. Revenue break-even volume loss 6 / 106, roughly 5.7%. Margin break-even 0.06p / (1.06p - c), strictly larger than 5.7% for any positive avoidable cost per hour and equal to 5.7% when that cost is zero or unavoidable; the reversal threshold sits in that range with the avoidability assumption stated. Unit of analysis engagement or account, clustered at client_id, with the single treated practice area named as the identification problem and a synthetic control or pre-registered before-and-after proposed in response.
Verify it yourself
- With c < p, the margin break-even volume loss sits between 5.7% and 100%, equalling 5.7% exactly at c = 0. If you have written (p - c) / (1.06p - c) you are holding the retained-volume fraction, the complement of the answer: at c = 0 it returns 94.3% rather than 5.7%.
- The power calculation runs on the count of competitive decisions, not on engagements or invoice lines, since the win-rate guardrail is what triggers the reversal.
- The parallel-trends check is specified with a stated failure action, not merely mentioned as a caveat.
Follow-up
- Realised revenue per hour rose 4% and win rate fell 2 points on 31 competitive decisions. What do you conclude, and what is your interval on the win-rate move?
- How would you separate a price-driven loss from a capability-driven one when loss_reason is entered by the partner who lost the deal?
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
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.
Being wrong in public
A number you shipped turned out to be wrong, and someone had already acted on it. That is one of the most useful stories a data person can carry. What is being scored is how fast you noticed, who you told first, and what you changed in the process so the same class of error could not repeat quietly.
How do you handle missing data or extreme outliers in a dataset before training a model?
Medium · behavioural and stakeholder questions
Approach
- Close with what you would do differently, concretely.
- Name the disagreement or constraint, and how you resolved it with evidence.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- What would you do differently if you ran that project again?
- What did you decide not to do, and why?
Tell me about a time you identified a business problem the client hadn't noticed, using data.
Medium · behavioural and stakeholder questions
Approach
- Quantify the outcome, including what you would not claim credit for.
- Name the disagreement or constraint, and how you resolved it with evidence.
- Close with what you would do differently, concretely.
Follow-up
- What did you decide not to do, and why?
- How did you know the outcome was caused by your change?
Three requests, one week, and the one you defer
Medium · prioritisation · stakeholder management · scope reduction
Three requests arrive in one week. Finance needs days sales outstanding recomputed for a board meeting in four days. A partner wants a proposal win-rate model for a pursuit review in three weeks. Delivery wants a staffing forecast, with no date attached. You have one week of your own capacity and no analyst. Write the prioritisation you send back, the request you defer, and the message you send to the person whose request you defer.
Approach
- Name the probe: whether you prioritise on decision dates and reversibility, or on who asked most forcefully.
- Score each request on four things: what decision it changes, the date that decision is made, the cost of being late, and the cost of being wrong. A board figure has a hard date and a high cost of being wrong; a forecast with no date has neither.
- Reduce scope rather than dropping work. The win-rate model is the largest piece and the easiest to get wrong, because features written after the decision, such as engagement_id and revised pricing, leak the label, and because withdrawn and no_decision proposals are not missing at random. A two-day descriptive win-rate cut by is_competitive and loss_reason answers most of what a pursuit review needs, with the model scoped separately.
- Defer explicitly, with a date and a smaller substitute, rather than leaving a request to decay quietly. Silence is read as agreement and then as failure.
- Put the trade-off in writing so it can be overturned by someone with more context than you have, and say what you would drop if the deferred request becomes urgent.
Follow-up
- The partner escalates to the practice lead. What do you change, and what do you refuse to change?
- What evidence would make you drop the finance work instead?