Interview guides · One Park Financial
One Park Financial Data Scientist Interview Questions & Guide 2026
A two-week prep plan for One Park Financial data scientist candidates: write your answer before reading the solution, revisit misses three days later.
The 60-second brief
A Data Scientist at One Park Financial functions as a vital bridge between complex data architecture and high-impact business strategy. As a Lead Marketing Data Scientist, your primary mission is to leverage advanced analytics to optimize customer acquisition, refine marketing spend, and drive growth in the competitive financial services landscape. You are not just building models; you are defining the metrics that dictate how the company engages with its audience.
SQL is seldom the hardest round and is often the one that eliminates people. The working bar is usually window functions, correct deduplication, and joins that do not silently fan out rows, rather than obscure syntax.
Focus areas
- Reconcile amounts in minor units and currency
- Report only matured cohorts for loss metrics
- Set fraud thresholds by expected cost
Overview
Your work directly influences the efficacy of marketing campaigns and the overall health of the business. By translating raw data into actionable insights, you enable stakeholders to make informed decisions that scale operations and improve customer outcomes. This role requires a blend of technical rigor and business acumen, as you will often be tasked with solving ambiguous problems that require both sophisticated modeling and clear communication to non-technical leadership.
Given the focus on "Lead Marketing" in the job title, prioritize your preparation around attribution modeling, customer lifetime value (CLV), and marketing mix modeling.
Where to focus your preparation
Treat the sections below as preparation areas and confirm the format with your recruiter.
Preparation focus
No round sequence has been reported for this company, so work the categories below and confirm the format with your recruiter.
What to demonstrate
- Breadth across SQL, experimentation and product reasoning
- Ability to state assumptions before choosing a method
How to prepare
- Drill the practice exercises below and time yourself
- Prepare three quantified stories about decisions you drove
Where candidates lose points
Using written premium as the denominator of a loss ratio
Premium is written at inception and earned pro rata across the exposure period, so in a growing book written premium runs ahead of earned premium and the loss ratio comes out too low, with the error reversing when the book shrinks. The numerator has the mirror-image problem if it omits incurred-but-not-reported reserves, since recent accident periods then look profitable twice over. Both sides must refer to the same exposure period, which is what an accident-period view at a fixed development age enforces.
Assuming a model is fair because protected attributes are not among its inputs
Postcode, device, tenure, income proxies and even transaction patterns correlate with protected characteristics, so a model can produce a disparate outcome without ever reading the attribute. Credit decisions additionally carry an explainability obligation in many jurisdictions, since a denial has to be accompanied by its principal reasons, which constrains model form and feature engineering rather than being a reporting afterthought. Treating fairness testing and reason-code generation as design constraints from the first model version is far cheaper than retrofitting them to a deployed one.
Writing SQL without stating NULL and tie-breaking behaviour
Before calling a query finished, say what it does with NULLs, ties and empty groups. NOT IN against a subquery containing a single NULL returns no rows at all, and RANK, DENSE_RANK and ROW_NUMBER differ precisely on ties, so name which one the question requires.
Comparing periods without accounting for seasonality or day-of-week
Compare whole weeks against whole weeks and check whether the same swing appeared in prior cycles or prior years before attributing it to anything you changed. Weekday and weekend populations often differ enough that a Tuesday-to-Saturday comparison is meaningless.
Questions & practice
Explain the difference between bagging and boosting, and when you would use each.
Medium · statistics and probability
Approach
- Say what the estimate is of, and over what population it generalises.
- Write down the assumption the method needs before you use the method.
- Translate the result into the decision it informs, in one plain sentence.
Follow-up
- Which assumption here is most likely to be violated in practice?
- What sample size would you need to detect an effect half this size?
What metrics would you use to evaluate the performance of a lead-scoring model?
Medium · machine learning and modelling
Approach
- 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.
- Say how the offline result would be validated online before it is trusted.
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?
How do you detect and mitigate bias in your machine learning models?
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
- 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?
Implement accident-quarter loss ratio at twelve months development
Medium · loss ratio · development age · earned premium
fct_policy_period_monthly arrives as a stack of month-end snapshots: each row carries valuation_month alongside as_of_month, policy_id, product_line, written_premium_minor, earned_premium_minor, paid_loss_minor, case_reserve_minor, ibnr_reserve_minor and loss_adjustment_expense_minor. Compute the accident-quarter loss ratio at exactly 12 months of development: incurred losses over earned premium, both taken from rows whose as_of_month falls in the accident quarter, read from the snapshot 12 months after that quarter closes. Report quarters that cannot reach that age as incomplete rather than dropping them.
Approach
- Derive accident_quarter from as_of_month, then define the evaluation snapshot per quarter as valuation_month equal to the quarter's final month plus twelve months. Every figure in the ratio comes from that one snapshot, not from whichever snapshot happens to be newest.
- Numerator is paid_loss_minor plus case_reserve_minor plus ibnr_reserve_minor over the accident quarter's rows in that snapshot. Loss adjustment expense may be included or not, but the choice applies to every quarter and is named in an output column.
- Denominator is earned_premium_minor over the same rows. Written premium is booked in full at inception, so in a growing book it runs ahead of earned premium and drags the ratio down, with the error reversing when the book shrinks.
- Left-join the full quarter list against available valuation months so a quarter with no 12-month snapshot yields status incomplete and a null ratio, instead of disappearing and shortening the series without saying so.
- Split by product_line, since both the loss ratio level and the speed of development differ by line, and a blended series moves with mix as much as with experience.
Worked solution (30 min)
- Add accident_quarter and a target_valuation column equal to the quarter end plus twelve months.
- Filter rows to those where valuation_month equals the row's target_valuation, then assert each accident_quarter has exactly one distinct valuation_month left.
- Aggregate incurred and earned premium by accident_quarter and product_line and take the ratio.
- Reindex against the full list of accident quarters and product lines, marking rows with no matching snapshot as incomplete with a null ratio.
- Recompute one quarter by hand on a five-policy subset and confirm it matches.
Expected result: One row per accident_quarter and product_line with incurred, earned_premium, loss_ratio, an lae_included flag and status in complete or incomplete. Complete quarters end twelve months before the latest valuation_month, so the four or five most recent quarters carry null ratios.
Verify it yourself
- Assert exactly one distinct valuation_month per accident quarter after filtering; more than one means the snapshot join fanned out.
- For a growing book, earned premium in a quarter is below written premium booked in that quarter; if it is above, either the book is shrinking or the accident-quarter derivation is wrong.
- Incomplete quarters carry null ratios and never appear on the same line as complete ones in any chart.
- Swapping the denominator to written premium shifts a quarter by L(W - E)/(EW), so the sign of the change is the sign of written minus earned premium in that quarter: the ratio falls where the book grew and rises where it shrank. Verify the swap per quarter against sign(W - E) rather than expecting a uniform move; a series that moves in one direction everywhere only means the book grew in every quarter.
Follow-up
- The most recent complete quarter came in four points better than the one before. What do you check before calling it an improvement?
- How would you estimate the 12-month figure for a quarter that is only 6 months developed, and how would you label the estimate?
- Why can an expense ratio legitimately use a different denominator from the loss ratio in the same presentation?
Collapse merchant retry chains before measuring authorization approval
Medium · window functions · gaps and islands · sessionisation
Merchant retry logic turns one declined purchase into several rows in fct_payment_authorization. Collapse attempts into chains: inside a partition of (card_token_id, merchant_id, amount_minor), consecutive rows whose requested_at gap is 15 minutes or less belong to the same chain. Return one row per chain with chain_started_at, attempt_count, amount_minor, channel, and chain_outcome set to 'approved' when any attempt in the chain was approved. Then report a 7-day rolling dollar-weighted approval rate by channel over chains rather than attempts. Exclude is_reversal rows.
Approach
- In a CTE, take LAG(requested_at) OVER (PARTITION BY card_token_id, merchant_id, amount_minor ORDER BY requested_at) and set is_new_chain when the previous value is null or the gap exceeds 15 minutes.
- Turn the flag into a chain identifier with SUM(is_new_chain::int) OVER (same partition, same order, rows unbounded preceding to current row), which is the standard gaps-and-islands construction.
- Aggregate to one row per chain: MIN(requested_at), COUNT(*), and BOOL_OR(auth_result = 'approved') as the chain outcome, because the purchase succeeded if any attempt in the chain did.
- Roll the chains to a daily grain per channel, then apply the rolling window as PARTITION BY channel ORDER BY chain_date RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW. An interval-offset RANGE frame is value-based: it admits every row in the partition whose chain_date falls in the closed window [D - 6 days, D], so a channel with no chains on some dates still gets the right seven-day sums — sparsity is exactly what this construct tolerates. ROWS BETWEEN 6 PRECEDING AND CURRENT ROW is the one that needs a dense grain, because it counts rows and on a sparse grain reaches back further than seven days.
- Left-join a dense date spine only if the output needs a row on days with no chains. That is a presentation requirement, not a correctness one, and it leaves every rolling sum unchanged. The RANGE frame's preconditions are that chain_date is a date or timestamp (an interval offset needs an ordering column it can be added to) and that the aggregation left one row per (channel, chain_date).
- Divide approved chain value by total chain value inside the rolling frame, never the average of daily rates, since averaging rates weights a quiet day the same as a heavy one.
Worked solution (40 min)
- CTE 1: filter out is_reversal rows, then compute prev_requested_at with LAG and the is_new_chain flag.
- CTE 2: build chain_id with a running SUM of the flag over the same partition and order.
- CTE 3: group by partition keys plus chain_id to emit chain_started_at, attempt_count, amount_minor, channel and chain_outcome.
- CTE 4: aggregate chains to (chain_date, channel) with approved value and total value. Add the date spine here only if the report must show empty days.
- Final SELECT: two rolling SUMs over PARTITION BY channel ORDER BY chain_date RANGE BETWEEN INTERVAL '6 days' PRECEDING AND CURRENT ROW, divided at the end.
Expected result: A rolling series with one row per date and channel, where the chain count is strictly below the attempt count on ecommerce and recurring, and the chain-level approval rate is at or above the attempt-level rate for every channel, since collapsing removes failed attempts that later succeeded.
Verify it yourself
- SUM(attempt_count) over all chains equals the filtered attempt row count exactly; if it does not, the chain identifier is not partitioned the same way as the LAG.
- Every chain has exactly one row whose is_new_chain flag is true, so COUNT(DISTINCT chain_id) equals the number of flagged rows.
- A chain whose attempt_count is 1 must have chain_outcome equal to that single row's approved status.
- The rolling denominator on day D equals the sum of the daily denominators over every date present between D-6 and D inclusive — seven terms on a dense grain, fewer on a sparse one, and the same total either way.
- Adding or removing the date spine leaves every rolling sum identical, because spine rows contribute zero. Swapping RANGE for ROWS changes them on any channel whose grain has a gap, which is the direct test of which construct tolerates sparsity.
Follow-up
- This definition chains off the previous attempt, so a chain can span an hour if attempts arrive every 14 minutes. When is that right, and when would you anchor the window to the first attempt instead?
- Two genuine purchases of the same amount at the same merchant, four minutes apart, collapse into one chain. How large is that error and how would you bound it?
- A channel goes dark for three days mid-window. Which of the two frame types would silently widen, and what would the resulting rate look like?
- What changes if the merchant retries with a slightly different amount to dodge a velocity rule?
Vintage ninety-plus rate at twelve months on book
Medium · vintage analysis · window functions · right censoring
From fct_loan_performance_monthly, build a vintage table keyed on origination_month: the share of each cohort that ever reached days_past_due of 90 or more, or charge_off_flag = true, at or before months_on_book = 12. Restructuring resets days_past_due, so for any loan with restructured_flag true, evaluate only the month ends strictly before its first restructured month. Return origination_month, loans_funded, bad_loans and bad_rate. Exclude any cohort that does not yet have a months_on_book = 12 observation for every loan still on book.
Approach
- Establish the cohort denominator from the first month end each loan appears at, months_on_book = 0, so a loan is counted once in its origination_month rather than once per monthly row.
- Find each loan's first restructured month with MIN(as_of_month_end) FILTER (WHERE restructured_flag) OVER (PARTITION BY loan_id), or the equivalent grouped subquery, and keep it null for loans never restructured.
- Flag a loan bad if any row with months_on_book <= 12 and as_of_month_end earlier than that first restructured month has days_past_due >= 90 or charge_off_flag = true, which is what 'pre-restructure worst state' means in practice.
- Gate maturity by requiring the cohort's newest month end to be at least 12 months after origination_month, and report immature cohorts as incomplete rather than letting them appear at a flattering low rate.
- Aggregate to one row per origination_month and read the column downward, not across calendar time, because the whole point is comparing cohorts at equal age.
Follow-up
- Should a restructure inside 12 months count as bad in its own right? Argue both sides and say what you would actually ship.
- A loan that prepaid in full at month 4 never had a chance to go 90 days past due. In or out of the denominator, and why?
- The 2025-11 cohort is two points worse at month 12 than its neighbours. What three queries do you run before you call it a credit-quality change?
Evaluate a staggered country rollout without a randomised control
Hard · difference-in-differences · synthetic control · staggered adoption
A step-up authentication rule was enabled for ecommerce traffic in three issuer_country markets on three different dates across five months; twelve comparable markets never received it. You have fct_payment_authorization and fct_card_dispute at daily grain and cannot randomise. Estimate the effect on the dollar-weighted authorization approval rate and on matured fraud basis points, name the estimator and why the obvious one is wrong here, and justify your inference given that there are only three treated clusters.
Approach
- Rule out the default first. A two-way fixed effects regression with a single post-times-treated indicator is not valid under staggered adoption with effects that vary over time, because it constructs comparisons that use already-treated markets as controls for later-treated ones and can assign negative weights to some of those comparisons, so the coefficient need not lie inside the range of the true effects.
- Use an estimator built for staggered timing: Callaway and Sant'Anna group-time average treatment effects, or the Sun and Abraham interaction-weighted estimator, restricting the comparison group to the twelve never-treated markets and aggregating into an event study indexed on time since adoption.
- Defend parallel trends with evidence, not a single test. Show the pre-period leads with their intervals and state their magnitude relative to the post-period effect, because pre-trend tests are underpowered and failing to reject is not evidence of parallelism. Pre-register the maximum pre-period lead you would tolerate before abandoning the design.
- Fix the inference problem directly. With three treated clusters, cluster-robust standard errors are severely anti-conservative. Fit a separate synthetic control for each treated market against the twelve donors, with non-negative weights summing to one fitted on pre-period outcomes and predictors, then use in-space placebo permutation and the ratio of post-period to pre-period root mean squared prediction error as the test statistic. With twelve donors the smallest attainable one-sided permutation p-value is 1 / 13, about 0.077, so say that before anyone asks for p below 0.05.
- Split the two outcomes by maturity. The dollar-weighted approval rate is observable immediately and can be read on the full post window. Matured fraud basis points require at least 120 days of dispute maturity from the transaction month, so the fraud event study must terminate at the last matured month and the immature months must be marked incomplete rather than plotted as low.
- Enumerate and test the confounds specific to this setting: network mandates or regulatory deadlines that landed on the same dates, merchant-side changes in the treated markets, currency mix and settlement FX, and seasonality. Exclude donors subject to a concurrent mandate, and confirm that donors and treated markets do not share an acquirer whose outage would move both.
Follow-up
- Your synthetic control for one market puts 80 percent of the weight on a single donor. What do you do, and what does the leave-one-out check tell you?
- The approval rate rises and matured fraud basis points also rise. How do you express the trade-off in a single decision-grade number, and what does that require you to assume about the value of a declined good transaction?
- Suppose a fourth market adopts mid-analysis. How does that change the estimator, the donor pool and the permutation inference?
Estimate the marginal effect of approval at a score cutoff
Hard · regression discontinuity · instrumental variables · selection
Policy auto-approves applications with bureau_score at or above 660 and routes 640 to 659 to manual review, which approves about 35 percent of them. You cannot randomise approvals. Using fct_loan_application and a bureau-sourced panel that reports 12-month serious delinquency on any trade line for approved and declined applicants alike, estimate the effect of approval at the margin. State the identifying assumptions you would test rather than assert, the estimator and its tuning choices, and exactly what the estimate does and does not license.
Approach
- Set the design up as a fuzzy regression discontinuity, because crossing 660 changes approval probability sharply but not from zero to one. Let Z = 1{bureau_score >= 660} be the instrument, approval be the treatment, and 12-month serious delinquency be the outcome. The estimate is the ratio of the jump in the outcome to the jump in approval probability, which is two-stage least squares with Z as the instrument and identifies a local average treatment effect for compliers at the cutoff.
- Insist on the bureau panel as the outcome source. Funded loans exist on both sides of 660 only because manual review approves some applicants below it, and those are selected on whatever the reviewer saw; an outcome defined only on funded loans would reintroduce exactly the selection the design is meant to remove.
- Test the assumptions instead of listing them. Check density continuity of bureau_score at 660 with a McCrary-style or local-polynomial density test, since brokers and applicants can sometimes trigger a bureau refresh and a heaped density at the threshold kills the design. Check that pre-determined covariates, including declared_annual_income_minor, channel, product_code and model_version, are continuous at the cutoff. Check policy_rule_hits and the pricing table for any other rule that fires at exactly 660, because a second discontinuity at the same point is not separable from the first.
- Choose the estimator deliberately. Local linear regression with a triangular kernel and an MSE-optimal bandwidth, with bias-corrected robust confidence intervals. Do not fit a high-order global polynomial, which puts weight on observations far from the cutoff and produces artefacts at the boundary. Because bureau_score is an integer, the running variable has mass points, so cluster standard errors by score value or use an approach designed for discrete running variables.
- Respect outcome maturity. Include only application cohorts with a full 12 months of bureau observation; a recent cohort with partial observation will look cleaner and will drag the estimate.
- State the limits in the deliverable. The estimate is the effect at 660 on applicants whose approval status is determined by the threshold. It does not license moving the cutoff to 620, because both the first stage and the outcome relationship differ away from 660 and because a policy change at scale shifts the applicant mix. Report bandwidth sensitivity alongside the point estimate.
Worked solution (40 min)
- Assemble the application-level panel: bureau_score, decision, funded status, and the bureau-sourced 12-month serious delinquency flag, restricted to cohorts with 12 full months of outcome observation.
- Plot the first stage, being approval probability against bureau_score in one-point bins, and confirm a visible jump of roughly 0.65 at 660 (about 1.00 above against about 0.35 below).
- Plot the reduced form, being delinquency against bureau_score in the same bins, and read the jump at 660 off a local linear fit on each side.
- Estimate the Wald ratio as reduced form over first stage, equivalently two-stage least squares with Z = 1{score >= 660}, using a triangular kernel, an MSE-optimal bandwidth, bias-corrected robust intervals, and standard errors clustered by integer score.
- Run the assumption battery: density continuity at 660, covariate continuity, placebo cutoffs at 650 and 670, and bandwidth sensitivity at 0.5x and 2x the selected bandwidth.
- Write the result as a complier average effect at 660 with its interval, its bandwidth sensitivity table, and an explicit sentence on what it does not license.
Expected result: A fuzzy RDD estimate delivered as the Wald ratio, jump in 12-month serious delinquency divided by a first-stage jump in approval probability of about 0.65, fitted by local linear regression with a triangular kernel at an MSE-optimal bandwidth, with robust bias-corrected intervals and standard errors clustered on the integer score. It is reported as a local average treatment effect for compliers at 660 only, accompanied by the density test, the covariate-continuity table and the bandwidth sensitivity, with an explicit statement that it does not support moving the cutoff.
Verify it yourself
- Reduced form divided by first stage must equal the two-stage least squares coefficient to numerical precision; if it does not, the sample or the bandwidth differs between the two fits.
- Placebo cutoffs at 650 and 670 should show no jump in either the first stage or the outcome.
- Pre-determined covariates should be continuous at 660; a jump in income or channel mix at the threshold means applicants or brokers are sorting and the design is compromised.
- The point estimate should be stable when the bandwidth is halved and doubled; large movement means the local linear fit is being driven by observations far from the cutoff.
Follow-up
- Manual reviewers below the cutoff see documents the score does not. What does that do to the monotonicity assumption, and how would you look for defiers?
- You are offered a randomised approval band across 650 to 659 for one quarter. What does it buy you that the discontinuity does not, and how would you price the expected loss of running it?
- The density test shows a modest pile-up just above 660. What are the possible mechanisms, and which of them leave the design usable?
A single day of settled volume comes in thirty percent low
Medium · pipeline failure · null rates · data freshness
Yesterday's settled volume is 30 percent below the same weekday across the previous eight weeks, while authorization counts and approved counts for the day look normal. You have fct_payment_authorization with requested_at, captured_at, captured_amount_minor, settled_at, settlement_amount_minor, settlement_currency, created_at and updated_at, plus warehouse load metadata. Decide within the hour whether this is a real drop or a load problem, and say what you would post to the on-call channel in either case.
Approach
- Check the data before the business. Compare max(updated_at) and row counts per load partition for the affected day against the prior eight same weekdays; a truncated load usually shows as a count deficit confined to a specific hour range.
- Measure null rates per column by requested_at date. Authorization fields present while settled_at and settlement_amount_minor are null points at the settlement feed; a uniform deficit across all columns points at ingestion.
- Separate late arrival from loss. Settlement lands after authorization by design, so re-measure the same day 24 and 48 hours later. A deficit that closes on the next load is lag, not a drop.
- Reconcile against the independent source: tie the day's settled total to the settlement ledger or acquirer file. If the ledger has the money and the warehouse does not, the business number was never wrong.
- Only after those four steps consider a business explanation, and then only if a segment cut produces a coherent story rather than a flat haircut spread evenly across every merchant and channel.
- Close by splitting the alert: a freshness and completeness check on the settlement feed, separate from the volume alert, so the next occurrence is classified automatically.
Follow-up
- How would you make the daily volume alert immune to settlement lag without also hiding a genuine drop?
- What is the right way to restate a published number after a backfill lands?
- Which check catches a partial load that is uniform across the day rather than concentrated in one window?
Suggested practice checklist
Four days spend equal time on query work, statistics, modelling and product judgement at deliberately shallow depth, which produces a scored map of where you actually stand. The last three days spend everything on the two areas the role weights most, and close by re-running day one to measure movement.
Day 1 — Breadth pass: query fluency
- Solve six prompts spanning aggregation, joins, window functions and date arithmetic in 60 minutes total, stopping at 10 minutes each whether or not it works, and mark every prompt as solved, solved slowly, or stuck.
- For each unsolved prompt write the single blocking sentence (I lost the grain, I did not know the frame clause, I could not express the date boundary) instead of reading the solution.
- Translate one pandas transformation you know well into SQL and one SQL query into pandas, checking that both return the same row count and the same totals.
Deliverable: A scored six-row table, one line per prompt, saved for the day-seven re-run.
Day 2 — Breadth pass: statistics and inference
- Answer ten short questions in writing with nothing open: what a p-value is conditional on, what a 95 percent interval covers across repeated samples, when a paired test is the right one, what the bootstrap estimates, why multiple comparisons inflate false positives, how controlling the family-wise error rate differs from controlling the false discovery rate, what power depends on, what a missed real effect costs a product, the three situations where the central limit theorem does not rescue you (small n, very heavy tails, dependent observations), and what a standard error is the standard deviation of.
- Grade yourself against a reference and count only the answers that were exactly right, not the ones that were nearly right.
- Rewrite the two weakest answers the following morning from memory in full sentences.
Deliverable: Ten graded answers with an honest count of exact hits.
Day 3 — Breadth pass: modelling
- Take one tabular dataset end to end in 90 minutes: a leakage-safe split, a baseline that is not a model (majority class or historical mean), one regularized linear model, one gradient-boosted tree, and a single evaluation metric chosen before you look at any result.
- Write why that metric fits the cost structure: precision at a fixed recall for alerting, calibration for anything feeding a price or a threshold, ranking metrics for retrieval, and note that area under the ROC curve is insensitive to class balance in a way that can flatter a rare-positive problem.
- Name the leak you were most likely to introduce (an encoding fit on all rows before splitting, or a feature computed after the label's timestamp) and write the check that would have caught it.
Deliverable: A notebook whose first cell states the metric and the baseline, plus two lines on what beat what and by how much.
Day 4 — Breadth pass: product judgement
- Answer three case prompts aloud at 15 minutes each, timing how long passes before you state a success metric.
- For one case write the first segmentation you would run and the row counts you expect per segment, so that a tiny segment cannot quietly drive the conclusion.
- Take a metric definition you did not write, from a public dashboard, a textbook, or documentation you already have open, and list every place two analysts implementing it would diverge: which rows the denominator admits, whether the unit is an account or a person, what the time window is anchored to, and what happens to data that arrives late. Then write the one question that would close the largest of those gaps.
Deliverable: Three recorded case answers plus an ambiguity list for a metric someone else defined, ending in the single question you would ask about it.
Day 5 — Depth, first area
- Rank the four areas by how many bullet points in the role description each one covers, pick the top one, and spend the entire day inside it.
- Work the six hardest problems you can find in that area and for each write the generalizable move you should have reached for first, rather than the answer.
- Re-solve the two you failed the same evening with notes closed.
Deliverable: Six generalizable moves written as instructions to yourself, not as solutions.
Day 6 — Depth, second area, and the seam between them
- Repeat the depth protocol on the second-ranked area with the same six-problem structure.
- Construct one problem that requires both areas at once, for example a metric redefinition whose effect you must validate with a test whose readout you then have to query.
- Solve your own combined problem end to end and note where the handoff between the two areas cost you time.
Deliverable: One combined problem, solved end to end, with the handoff failure written down.
Day 7 — Integration and re-measurement
- Re-run the six prompts from day one under the same clock and compare both correctness and time.
- Run a 60-minute mixed mock that moves between areas without warning, since switching cost is what breadth passes do not train.
- Write the two areas you would still fail on, and the sentence you will use in the interview when you hit one of them.
Deliverable: A before-and-after score table plus a written plan for the two remaining gaps.
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.
Describe a time you had to explain a complex model to a non-technical stakeholder.
Medium · behavioural and stakeholder questions
Approach
- State the situation in two sentences and spend the rest on your reasoning.
- Pick a story where you drove the decision, not one where you observed it.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- How did you know the outcome was caused by your change?
- What would you do differently if you ran that project again?
How do you handle imbalanced datasets in a credit or marketing context?
Medium · behavioural and stakeholder questions
Approach
- Pick a story where you drove the decision, not one where you observed it.
- Close with what you would do differently, concretely.
- 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?
Defend a vintage finding that contradicts the portfolio dashboard
Medium · vintage analysis · mix shift · stakeholder pushback
The lending dashboard shows blended 90-plus days-past-due falling for four consecutive quarters while originations grew 60 percent. Using fct_loan_performance_monthly, you build a vintage view keyed on origination_month by months_on_book and find the three most recent vintages are worse than their predecessors at the same age. The business lead presents that dashboard weekly and pushes back hard, suggesting you picked favourable cohorts. You get one meeting and the vintage table. Present the finding so it survives the cherry-picking objection and ends in a decision.
Approach
- Reconcile before you contradict: show that aggregating your vintage table along the calendar diagonal reproduces the published blended series, so the disagreement is about age mix rather than about data quality.
- Make the mechanism arithmetic rather than rhetorical: a loan cannot reach 90 days past due before it is 90 days old, so rapid origination growth shifts weight onto young months-on-book where the rate is structurally near zero.
- Show every vintage rather than a selected pair, all indexed at months_on_book equal to 12, with cohort sizes printed beside each curve so nobody can claim the divergence rests on a thin cohort.
- Handle restructuring explicitly, because restructured_flag resets days_past_due: count each loan on its worst pre-restructure state, or recent vintages will look better than they are.
- Close on the decision rather than the chart: state what the divergence implies for the cutoff or the channel mix, and state in advance what evidence would make you withdraw the claim.
Follow-up
- Two cohorts differ at month 12. How do you separate a seasoning effect from a genuine credit-quality effect?
- Someone argues the recent vintages are simply a broker-channel mix shift. How do you test that, and what would confirm it?