cswork / libraryOpen practice workspace

Interview guides · Finacle

Finacle Data Scientist Interview Questions & Guide 2026

Timed data scientist practice for Finacle: short SQL and probability sets run end to end, then scored against a rubric.

The 60-second brief

As a Data Scientist at Finacle, you are at the intersection of high-scale digital banking infrastructure and cutting-edge AI innovation. Finacle, a business unit of EdgeVerve Systems, powers financial institutions across 100+ countries, meaning your work directly influences how over a billion people manage their finances. You aren't just building models in a vacuum; you are developing AI-driven solutions that must be scalable, secure, and explainable in a highly regulated industry.

How much statistics you need depends on the flavour of the seat. Experiment-facing work wants you deep enough to notice that repeated looks at accumulating data inflate the false positive rate of a fixed-sample test; modelling-facing work wants estimation and honest uncertainty intervals.

Focus areas

  • Separate authorization, settlement and dispute outcomes cleanly
  • Set fraud thresholds by expected cost
  • Read vintage curves, not blended portfolio averages

Overview

Your role involves moving from prototype to production-grade API deployment. You will collaborate with cross-functional teams to tackle complex challenges, such as optimizing customer experiences, enhancing revenue streams, and implementing GenAI and LLM solutions. The environment is fast-paced, blending the stability of a global leader with the entrepreneurial spirit of a startup. Success here requires a blend of rigorous statistical thinking, hands-on coding expertise, and the ability to articulate technical value to non-technical stakeholders.

The Finacle interview process

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

Online Assessment

A handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.

What to demonstrate

  • Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
  • Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
  • Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.

How to prepare

  • Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
  • Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
  • If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows

Technical Deep-Dive

This round decides whether someone can hand you a schema and a question and trust the number that comes back. Correctness under a clock is the bar, not clever syntax. The habit that separates strong from weak answers is checking the grain: after every join, know how many rows you expect and whether the count moved. Most wrong answers in this format are not wrong logic, they are a fan-out from a key that turned out not to be unique, or a filter applied before an aggregate when it belonged after. Say what you expect before you run it.

What to demonstrate

  • Whether your row counts survive each join, and whether you notice on your own when they do not
  • Deliberate handling of rows that fail to match, including whether the question needs an inner join or a left join with the non-matches kept and counted
  • Whether NULLs are treated on purpose, given that a NULL compares equal to nothing and that COUNT of a column skips it
  • Reaching a defensible answer inside the window instead of a refined one after it

How to prepare

  • Take a two-table schema, write a join that fans out on purpose, then fix it by collapsing the many-side to one row per key before joining. Repeat until the fix is reflex rather than recall.
  • Write a funnel as one query and print the distinct user count at each stage, then confirm each stage is a subset of the one above it rather than assuming it
  • Do a few timed runs in a plain text box with no autocomplete and no formatter, since assessment editors often have neither

Leadership and Behavioral Interviews

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

Recalibrating an underwriting cutoff on approved and funded applicants only

Rejected applicants have no repayment outcome, and they were rejected because the incumbent model scored them badly, so the missingness depends directly on the outcome being modelled. Reject inference by augmentation or parcelling fills the gap using the incumbent model's own assumptions, which means it can confirm those assumptions but cannot test them. The only genuinely new information about the reject region comes from bureau performance on rejects who borrowed elsewhere, or from a deliberately randomised approval band around the cutoff.

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.

Analysing at a different unit than the one randomised

Say out loud what was randomised (user, device, account, cluster) and make the analysis unit match, or account for the clustering with cluster-robust standard errors, the delta method, or aggregation up to the randomised unit. Randomising users and then running a test over sessions understates variance and inflates the false-positive rate.

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

How do you choose between different statistical distributions when modeling financial transaction data?

Medium · statistics and probability

Approach

  1. Quantify uncertainty explicitly rather than reporting a point estimate alone.
  2. Say what the estimate is of, and over what population it generalises.
  3. Write down the assumption the method needs before you use the method.

Follow-up

  • What sample size would you need to detect an effect half this size?
  • Which assumption here is most likely to be violated in practice?

Describe the assumptions behind linear regression and how you validate them.

Medium · machine learning and modelling

Approach

  1. Frame the prediction: the label, the moment of prediction, and the action it triggers.
  2. Pick an evaluation metric that matches the cost of each error type, not a default.
  3. Set a baseline first, so any model has something honest to beat.

Follow-up

  • How would you choose the decision threshold, and who owns that choice?
  • What would you monitor after launch to know the model is still valid?

Simulate false alarms in a merchant chargeback monitoring rule

Medium · simulation · rare events · monitoring thresholds

Baseline matured first-chargeback rate is 12 per 10,000 settled transactions. A monitoring rule alerts when a merchant's observed monthly rate exceeds twice baseline. For monthly settled transaction counts of 500, 2,000, 10,000 and 50,000, simulate the false-alarm probability per merchant-month under the baseline, and the power to detect a merchant whose true rate is 30 per 10,000. Then, for a portfolio of 4,000 merchants split 60, 25, 10 and 5 percent across those four counts, give the expected number of false alarms per month.

Approach

  1. Recognise the rule is a threshold on an integer count, not on a continuous rate. At n = 500, twice baseline is 24 per 10,000, so the first observable value above it is 2 chargebacks, or 40 per 10,000. Derive the trigger count for every n before simulating anything.
  2. Draw binomial counts with numpy at p = 0.0012 and take the share at or above the trigger for the false-alarm rate, then repeat at p = 0.0030 for power. Use at least 200,000 draws per cell so a probability near 0.001 has a usable standard error.
  3. Cross-check every simulated cell against the Poisson approximation with lambda = n*p, which is tight here because p is tiny. A mismatch almost always means the trigger count is off by one.
  4. Weight the per-merchant false-alarm probabilities by the portfolio mix, and report the share of expected alerts contributed by each size band rather than only the total.
  5. Close on the operating consequence: a fixed multiplicative threshold is not a constant false-alarm rate across merchant sizes, so either the threshold scales with n or small merchants need a minimum volume before the rule applies.

Worked solution (30 min)

  1. For each n, compute trigger = floor(2 * 0.0012 * n) + 1 and print the four values before simulating.
  2. Simulate 200,000 binomial draws per n at p = 0.0012 and take the share at or above the trigger.
  3. Repeat at p = 0.0030 and record power for the same triggers.
  4. Compute the Poisson tail 1 - CDF(trigger - 1, lambda = n*p) for both p values and confirm agreement within Monte Carlo error.
  5. Multiply the false-alarm probabilities by 2400, 1000, 400 and 200 merchants and sum.

Expected result: Trigger counts of 2, 5, 25 and 121. False-alarm probability roughly 12 percent at n = 500, roughly 10 percent at n = 2,000, under 0.1 percent at n = 10,000 and effectively zero at n = 50,000. Power against 30 per 10,000 roughly 44, 72, 85 and above 99 percent. Expected false alarms about 390 per month, with over 99 percent of them coming from the two smallest bands.

Verify it yourself

  • The four trigger counts are derived, not guessed: each is the smallest integer strictly above 0.0024n, giving 2, 5, 25 and 121. Derive them in exact or integer arithmetic, because 20.0012*10000 evaluates to 23.999999999999996 in binary floating point and floor-plus-one silently returns 24.
  • Simulated probabilities match the Poisson tail at lambda = n*p within about two Monte Carlo standard errors.
  • Power exceeds the false-alarm rate at every n; if it does not, the null and alternative rates are swapped.
  • Doubling the draw count moves each probability by less than its own simulated standard error.

Follow-up

  • How would you set a threshold that holds the false-alarm rate roughly constant across merchant size?
  • The rule reads the transaction month, but disputes arrive for up to 120 days afterwards. What does that do to the alert and how would you fix it?
  • What does a month of these false alarms cost, and how would you decide whether it is worth paying?

Explain the difference between a CTE and a temporary table in terms of performance and readability.

Medium · sql and data manipulation

Approach

  1. Handle the rows that do not match: a LEFT JOIN with a NULL check is usually the question.
  2. State the window function and its partition and ordering out loud before writing it.
  3. Check whether any join is one-to-many before aggregating, or the sums inflate.

Follow-up

  • How does the query change if the join becomes one-to-many?
  • What breaks if events arrive late or out of order?

Write a query using SQL window functions to calculate the moving average of customer transactions over a 30-day period.

Medium · sql and data manipulation

Approach

  1. State the window function and its partition and ordering out loud before writing it.
  2. Compute rates by summing numerator and denominator separately, never by averaging rates.
  3. Check whether any join is one-to-many before aggregating, or the sums inflate.

Follow-up

  • What breaks if events arrive late or out of order?
  • How would you verify this result without re-running the same query?

Attribute chargebacks to transaction month without fanning out

Medium · fan-out · cohort attribution · maturity

Report the matured first-chargeback rate. Numerator: fct_card_dispute rows whose dispute_stage is first_chargeback, representment, pre_arbitration or arbitration, attributed to the requested_at month of the linked fct_payment_authorization row rather than to opened_at. Denominator: settled authorizations in that same transaction month, meaning settled_at is not null and is_reversal is false. One authorization can carry more than one dispute case. Report only transaction months whose last day is at least 120 days old, and mark the remainder incomplete rather than showing them as low.

Approach

  1. Compute the denominator from fct_payment_authorization alone, grouped by the requested_at month, before any dispute table is mentioned, so the join cannot touch it.
  2. Compute the numerator as a separate aggregate: join disputes to their authorization only to recover requested_at, then count dispute rows per transaction month with the stage filter.
  3. Join the two aggregates on the month key, which keeps the grain at one row per month and makes double counting structurally impossible rather than something you have to remember.
  4. Apply the maturity gate on the month's last day plus 120 days against the current date, because a transaction on the final day of the month is the least mature one in the cohort.
  5. Emit an explicit status column of 'final' or 'incomplete' instead of filtering immature months away silently, so a reader cannot mistake absence for zero.

Worked solution (30 min)

  1. CTE denom: SELECT date_trunc('month', requested_at) AS txn_month, COUNT(*) AS settled_txns FROM fct_payment_authorization WHERE settled_at IS NOT NULL AND NOT is_reversal GROUP BY 1.
  2. CTE numer: join fct_card_dispute to fct_payment_authorization on auth_id, filter dispute_stage to the four stages at or beyond first_chargeback, group by the same txn_month expression, count dispute rows.
  3. LEFT JOIN numer onto denom on txn_month so months with zero disputes appear as zero rather than disappearing.
  4. Derive the rate with a numeric cast and a status column driven by (txn_month + interval '1 month - 1 day') + interval '120 days' <= current_date.

Expected result: One row per transaction month with settled_txns, chargeback_cases, a rate in basis points, and a status of 'final' or 'incomplete'. The final months form a roughly flat series; the incomplete months at the right edge are visibly and correctly labelled rather than sloping to zero.

Verify it yourself

  • settled_txns for a given month is identical whether or not the dispute CTE is joined, which is the direct test that no fan-out occurred.
  • COUNT(DISTINCT auth_id) in the numerator is at or below the dispute row count; if they are equal, no authorization in the data carries two cases and the fan-out risk is latent rather than absent.
  • Every month flagged 'final' has its last day at least 120 days before the current date.
  • Attributing by opened_at instead shifts the series later and flattens the right edge, which demonstrates why the attribution key matters.

Follow-up

  • Should the numerator count dispute cases or disputed authorizations? Which one reconciles to the loss line, and which one to the operations queue?
  • Some reason codes allow filing well beyond 120 days. How would you estimate the tail on a month you have decided to call final?
  • How would you present the incomplete months so that a weekly reader does not read the right-hand slope as an improvement?

If you noticed a sudden 10% drop in user engagement on our mobile platform, how would you diagnose the root cause?

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. State what result would change your recommendation, so the answer is falsifiable.
  3. Fix the population and the time window before naming any metric.

Follow-up

  • What would you do if the primary metric and the guardrail moved in opposite directions?
  • How would you detect that the metric is being gamed rather than genuinely improving?

Describe a time you had to define a product metric from scratch. What were the trade-offs?

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. Name one primary metric, then the guardrail that stops it being gamed.
  3. Fix the population and the time window before naming any metric.

Follow-up

  • Which segment would you cut first, and what would that rule out?
  • How would you detect that the metric is being gamed rather than genuinely improving?

How would you design a metric to measure the success of a new personalized banking feature?

Medium · product sense and metrics

Approach

  1. Restate the decision this analysis has to support, and who acts on the answer.
  2. State what result would change your recommendation, so the answer is falsifiable.
  3. Decompose the metric into the rates that drive it, and say which one you would check first.

Follow-up

  • What would you do if the primary metric and the guardrail moved in opposite directions?
  • How would you detect that the metric is being gamed rather than genuinely improving?

What are the most common experimentation pitfalls you have encountered in your previous roles?

Medium · a/b testing and experimentation

Approach

  1. Name the guardrails that would stop a launch even on a positive primary result.
  2. Name the randomisation unit first; it decides the variance and what the test can detect.
  3. State the primary metric and the minimum effect worth shipping, then size the test.

Follow-up

  • What would you conclude if the result is positive but the test is underpowered?
  • How would you handle interference between treated and control units?

If you have a low sample size, how do you adjust your testing strategy?

Medium · a/b testing and experimentation

Approach

  1. Name the guardrails that would stop a launch even on a positive primary result.
  2. Say whether units interfere with each other, and switch design if they do.
  3. Name the randomisation unit first; it decides the variance and what the test can detect.

Follow-up

  • How would you handle interference between treated and control units?
  • What would you do if you could not randomise at all?

Design an authorization approval rate a team cannot game

Easy · approval rate · metric gaming · mix shift

A payments team is given authorization approval rate as its quarterly target, defined as approved authorizations over all authorizations in fct_payment_authorization. Using auth_id, card_token_id, merchant_id, amount_minor, transaction_currency, auth_result, is_reversal, parent_auth_id, channel, issuer_country and requested_at, list three ways the team can raise that number without a single additional customer purchase succeeding. Then write the definition you would put on the dashboard instead, with its exclusions, and name the one guardrail you would always read beside it.

Approach

  1. Enumerate the rows in the table that are not purchases: zero-amount account verifications, reversals (is_reversal = true), incremental authorizations (parent_auth_id not null) and merchant retries of a declined attempt. Each is a lever on the numerator or the denominator that no customer would ever notice.
  2. Name the mix levers. Recurring and card-present traffic approve at higher rates than ecommerce and cross-border, so routing changes or a marketing push into an easy channel move the blended rate with no change in decisioning quality at all.
  3. Work the retry arithmetic rather than asserting it. A declined purchase that is retried three times and succeeds on the fourth contributes one approval and four denominator rows, which is below a healthy blended rate, so suppressing retries raises the published number while some purchases that would have succeeded on a retry now simply fail.
  4. Replace the definition: dollar-weighted, retry chains collapsed to a single attempt per (card_token_id, merchant_id, amount_minor) within a 15-minute window, excluding reversals, zero-amount verifications and incremental authorizations, with all amounts converted into one reporting currency before summing because amount_minor is in the minor unit of transaction_currency and that unit is not always two decimals. Cut by channel and issuer_country so mix shift shows up as mix shift.
  5. Guardrail: net fraud loss in basis points of settled volume, read only on transaction months with at least 120 days of dispute maturity. The fastest way to approve more is to decline less risk, and that bill arrives two to four months later.

Worked solution (25 min)

  1. Compute the naive rate for one week: approved rows over all rows.
  2. Apply the exclusions one at a time (zero-amount, is_reversal, parent_auth_id not null), recording the rate after each, so you can say what each row type was worth to the headline number.
  3. Add a retry-collapsing CTE keyed on (card_token_id, merchant_id, amount_minor) over a 15-minute window, keeping the last attempt in each chain, and recompute.
  4. Recompute dollar-weighted in a single reporting currency, then split by channel and issuer_country.
  5. Write the final one-line definition with its exclusions, plus the guardrail sentence.

Expected result: Four rates for the same week (naive count, count after exclusions, count after retry collapsing, dollar-weighted after both), with the largest single gap attributed to a named row type, and a published definition that states every exclusion and the currency it reports in.

Verify it yourself

  • Excluding zero-amount verifications should lower the rate, since those rows approve at a higher rate than purchases. If it raises the rate, confirm that the amount_minor = 0 filter is not also catching rows with a null amount.
  • Collapsing retry chains raises the rate and shrinks the denominator. The numerator falls only by the number of chains that contained more than one approval.
  • Declines skew toward higher-value, cross-border and card-not-present transactions, so expect the dollar-weighted rate to sit below the count-weighted one. If it sits above, check for amounts summed across currencies before believing it.

Follow-up

  • The blended rate is flat but ecommerce cross-border fell 200 basis points. How do you present that?
  • Why weight by amount rather than by count, and when does the weighted version mislead?
  • Your 15-minute retry window merges two genuine purchases of the same amount at the same merchant. How would you bound that error?

Settled volume jumps after a new acceptance corridor launches

Medium · minor units · currency conversion · reconciliation

Settled payment volume per active customer rose 12 percent in the month a new acceptance corridor went live. The pipeline sums settlement_amount_minor from fct_payment_authorization and divides by 100 to get major units. Columns available: amount_minor, transaction_currency, captured_amount_minor, settlement_amount_minor, settlement_currency, settlement_fx_rate, settled_at, is_reversal, issuer_country, acquirer_country. Confirm or refute the 12 percent, and specify exactly the conversion the metric should be using.

Approach

  1. Split the month-over-month increase by settlement_currency. If one currency carries nearly all of it while its transaction count barely moved, the problem is arithmetic rather than demand, and that is a two-minute check.
  2. Look up each currency's ISO 4217 exponent. Dividing a three-decimal currency by 100 instead of 1000 overstates it tenfold; dividing a zero-decimal currency by 100 understates it hundredfold. Neither is a rounding issue.
  3. Rewrite the conversion to scale settlement_amount_minor by ten to the power of that currency's exponent, then convert to the reporting currency. Do not reuse settlement_fx_rate for this; it is the rate applied between transaction and settlement currency at settlement time, not a reporting-currency rate.
  4. Check the other half of the series too. settlement_amount_minor is denominated in settlement_currency while amount_minor is in transaction_currency, so any series that mixes the two is uninterpretable regardless of the exponent fix.
  5. Exclude reversals and refunds, recompute, then reconcile the corrected total to the settlement ledger for the same period and show the tie-out in the write-up.
  6. Recompute the per-customer denominator on the corrected month, since a new corridor adds customers as well as volume and the ratio can move either way once the numerator is right.

Follow-up

  • Where else in the warehouse does a hardcoded divide-by-100 appear, and how would you find every instance?
  • What test would fail the build the next time a currency with a different exponent is onboarded?
  • The reporting-currency rate is itself a choice. Which rate, on which date, and why does finance care about the answer?

Suggested practice checklist

For a candidate whose interviews will centre on A/B testing, metric movement and causal claims. Design comes before arithmetic, arithmetic before analysis, and the week ends by rehearsing the readout rather than the derivation.

Day 1 — Design one test end to end on paper

  • Take a single feature change and write the full design: randomization unit, the exact point of exposure, the primary metric with its grain, guardrails, allocation, planned duration, and the decision rule committed before any data exists.
  • Write why the randomization unit must sit at or above the level where treatment can spill over, and give one case where user-level randomization is still contaminated (shared accounts or devices, or two participants in the same marketplace).
  • State in advance what you will do if the primary metric is flat while a secondary metric is significant.

Deliverable: A one-page test design with a decision rule written before launch.

Day 2 — Power arithmetic until it is automatic

  • Compute required sample size per arm for a binary metric with the normal approximation, n is approximately 2 times (z for alpha/2 plus z for power) squared times p(1 minus p) divided by delta squared, for baselines of 2, 10 and 40 percent at a 5 percent relative lift, and note that for a fixed relative lift the requirement falls as the baseline rises because delta grows proportionally with p.
  • Redo the calculation for a continuous metric using variance in place of p(1 minus p), and show why a heavy-tailed quantity such as revenue per user needs either far more traffic or a capped version with a stated cap.
  • Convert one of the results into weeks given a weekly eligible traffic figure, then list the two honest ways to shorten it (accept a larger detectable effect, or reduce variance) and write why quietly lowering the power target is a decision to miss more real wins, not a speedup.

Deliverable: A small script or sheet that maps baseline, minimum detectable effect, alpha and power to sample size and weeks, cross-checked against a published calculator.

Day 3 — Variance and the unit-of-analysis problem

  • Take a ratio metric whose denominator is not the randomization unit (clicks per session, randomized by user) and compute the standard error twice, once naively at session level and once by the delta method or a user-level bootstrap, then record how much the naive version understates it.
  • Implement CUPED on simulated data: choose a pre-period covariate X measured before assignment, estimate theta as Cov(Y, X) divided by Var(X), and analyse Y minus theta times (X minus its mean) in place of Y. Confirm the variance of the adjusted outcome equals the raw variance multiplied by one minus the squared correlation between Y and X, so a correlation of 0.45 removes about 20 percent of the variance and not 80.
  • Now run that simulation a few hundred times and confirm the adjusted effect estimate is unbiased for the same effect rather than numerically identical to the raw one. Within any single run the two differ, sometimes by a large fraction of the true effect, because the two arms' pre-period covariate means never coincide exactly in a finite sample; they agree in expectation, which is the property that matters and the one to state out loud.

Deliverable: A notebook showing the adjusted estimator with a measurably smaller variance than the raw one, plus a repeated-simulation table showing the two estimators agreeing on average while differing run by run.

Day 4 — Validity threats you can actually test for

  • Run a sample ratio mismatch check as a chi-square goodness-of-fit test against the intended allocation, and write the three causes you would chase first (assignment logged before exposure, an arm-specific redirect or load failure, bot filtering applied asymmetrically).
  • Simulate peeking: generate A/A data, test daily at alpha 0.05 across 14 looks, record the inflated false positive rate, then apply an alpha-spending boundary or commit to a fixed horizon and confirm the rate returns to nominal.
  • Write how you would separate a novelty effect from a durable lift using the treatment effect plotted against days since first exposure, and what shape would change your recommendation.

Deliverable: One table showing the peeking false positive rate before and after correction, plus a written SRM triage list.

Day 5 — When randomization is not available

  • Write the identifying assumption for difference-in-differences (parallel trends in the absence of treatment), then plot pre-period trends for two candidate control groups and justify rejecting one of them.
  • Design a switchback test for a change where user-level randomization would leak across participants, choosing a time-block length against the carryover you expect and saying how you would detect carryover in the data.
  • List what an interrupted time series or a synthetic control buys you and the one thing neither can rule out: an unobserved shock that coincides with the launch.

Deliverable: A one-page memo recommending a single quasi-experimental design and naming its weakest assumption explicitly.

Day 6 — The readout query

  • Write the assignment-to-exposure join that returns exactly one row per unit per experiment, and handle units appearing in both arms by excluding and counting them rather than silently keeping one.
  • Compute the per-arm metric, its variance and the relative lift with a confidence interval in SQL, then reproduce the identical numbers in a notebook as a cross-check.
  • Add a segment breakdown and write the sentence that keeps it from being p-hacking: segments declared in advance, everything else reported as exploratory and corrected for multiplicity.

Deliverable: A single query that outputs the full readout table, matched to a notebook recomputation.

Day 7 — Present it to someone who will not read the appendix

  • Give a 10-minute readout of a real or simulated experiment in the order decision, number, uncertainty, caveat.
  • Have your listener ask "can we ship it" in the case where the primary is flat and a guardrail moved, and answer with a recommendation rather than a request for more data.
  • Rewrite your opening line so the recommendation lands before any methodology.

Deliverable: A one-page readout whose first line is the recommendation.

The project you argued against

Saying no well is a senior skill and it is rarely rehearsed. Think of a time you told someone their analysis was not worth doing, or that the experiment could not answer their question at the sample size available. Explain what you offered instead. Refusal without an alternative reads as obstruction rather than judgement.

Describe a challenging project where you had to pivot your approach due to technical constraints.

Medium · behavioural and stakeholder questions

Approach

  1. Quantify the outcome, including what you would not claim credit for.
  2. Pick a story where you drove the decision, not one where you observed it.
  3. Name the disagreement or constraint, and how you resolved it with evidence.

Follow-up

  • What did you decide not to do, and why?
  • How did you know the outcome was caused by your change?

Turn a one-line fraud-number request into a scoped brief

Easy · scoping · metric definition · denominators

A stakeholder messages: what is our fraud rate, and is it going up? You have fct_payment_authorization, fct_card_dispute and dim_customer. At least four defensible answers exist: count-weighted or value-weighted, attributed to the transaction month or to the dispute filing month, and gross or net of recoveries and successful representments. You get one reply before someone else produces an uncaveated number. Write that reply: the clarifying questions you ask, the single default you will produce if nobody answers, and what the default excludes.

Approach

  1. Establish the decision behind the question first, because a risk-rule change, a board number and a merchant contract negotiation need different denominators, and asking which one is not stalling.
  2. Offer a short menu rather than an open question: a stakeholder can choose between two named options but cannot specify a denominator from scratch.
  3. Commit to a default so the reply is useful even if nobody answers, for example net fraud loss in basis points of settled volume, attributed to the requested_at month, matured months only.
  4. State the exclusions in the same breath as the default: non-fraud dispute categories, transaction months with less than 120 days of maturity, and first-party abuse that arrives coded as consumer_dispute.
  5. Give a delivery time for the default and a longer one for the fuller cut, so the choice between them carries a visible cost.

Follow-up

  • They come back wanting it by merchant for a contract negotiation. What changes in the definition and in the maturity rule?
  • How would you separate first-party abuse from third-party fraud in this data, and what would you refuse to conclude from the split?

State honestly what your cutoff change actually contributed

Hard · impact attribution · swap set · counterfactual

Six months ago your recommendation moved a credit cutoff, using fct_loan_application and fct_loan_performance_monthly. Since then approval rate rose four points and the 12-month vintage 90-plus rate on affected cohorts is flat. In the same window the bureau changed a score attribute, marketing shifted channel mix toward broker, and the internal funding rate moved. Your performance review asks for impact in currency terms. Give the number you would stand behind, the counterfactual it rests on, and the part of the observed movement you would not claim.

Approach

  1. Define the counterfactual before computing anything: the claim is not what happened after the change, it is what would have happened had the old cutoff scored the same applications, which means replaying the old threshold on the post-change population.
  2. Build the swap set: applications the new cutoff approves that the old one declined, applications the old one approved that the new one declines, and everyone else held out as unaffected. Only the swap groups carry your effect. Note that the swap-out group has no outcome under the new rule, because those loans were never funded, so its forgone margin must be estimated from matched pre-change approvals rather than observed.
  3. Price each swap group at months_on_book equal to 12 on the measure the cutoff was meant to move: interest and fees collected, minus net charge-offs, minus funding cost at the internal transfer rate.
  4. Strip the confounders explicitly. Cohorts affected by the bureau attribute change are either recomputed on the old attribute or excluded; channel mix is held fixed by reweighting to the pre-change mix; funding cost is charged at the rate in force each month rather than one blended average.
  5. State the residual you will not claim, with its size, and give a range rather than a point wherever cohorts have not yet reached 12 months on book.

Follow-up

  • The swap-in group is only 6 percent of applications. How does that change the way you present the number, and to whom?
  • What would you have needed to set up at launch to make this attribution clean, and why was a randomised band around the cutoff not used?