Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Scenario Problems: Expectation, Variance, and Random Processes

These are the expectation problems that actually get asked in ML, quant, and data-science interviews, each stated the way an interviewer states it. The single most important habit in this material is naming the technique out loud before you compute: “this is linearity of expectation over indicators,” “this is first-step analysis,” “this is the law of total expectation.” Candidates who name the tool are already 80% done; candidates who start writing distributions get stuck. There are only about seven tools in the whole subject — linearity of expectation, indicator variables, law of total expectation/variance, first-step recursion, symmetry, the tail-sum formula, and optional stopping — and every problem below is one of them wearing a costume. Every numeric answer in this file has been verified by Monte Carlo simulation, and the recursive problems were additionally checked by solving the linear system numerically. Read the Trap lines: they are the specific wrong turns that cost people offers.


A. Linearity of expectation — the workhorse

The theme of this whole section: , and this holds whether or not the indicators are independent. You never need the distribution of the sum. That is the entire trick, and it is worth an enormous amount.


Q: I shuffle a standard 52-card deck. A “fixed point” is a card that ends up in the position it started in. What’s the expected number of fixed points?

The technique. Indicator variables plus linearity of expectation — no need to touch the distribution of fixed points (which is a messy near-Poisson thing).

Solution. Let if card lands in position , else . Then .

For a uniformly random permutation, card is equally likely to land in any of the 52 positions, so

By linearity,

The answer is exactly 1, and remarkably it is 1 for any : . Note that the are dependent (if 51 cards are fixed, the 52nd must be too) — and linearity does not care.

Sanity check. Do by hand. Permutations: has 2 fixed points, has 0. Mean . ✓ For : fixed-point counts over the 6 permutations are , summing to 6, mean . ✓ Monte Carlo with , 100,000 shuffles: 0.9955.

Follow-up: “What’s the variance?”. Compute . Since , the first sum is 1. For , , and there are such ordered pairs, so the second sum is also 1. Hence and . Mean 1, variance 1 — the count converges to Poisson(1), which is why .

Trap: Trying to derive the distribution of fixed points first (this leads to the derangement / inclusion-exclusion formula , which is correct but takes ten minutes). Linearity gets it in one line. Also: worrying that the indicators are dependent. They are, and it is irrelevant.


Q: 100 people check their hats at a restaurant. The attendant loses the tickets and hands the hats back at random, one per person. How many people expect to get their own hat back? And how does that change if there are 1,000 people?

The technique. Same indicator-plus-linearity move; the point of the question is whether you realize the answer doesn’t scale with .

Solution. if person gets their own hat. Person receives a uniformly random hat, so .

With 1,000 people, . Still exactly 1. The number of matches does not grow with the crowd — each person becomes correspondingly less likely to be matched, and the two effects cancel exactly.

Sanity check. Monte Carlo, , 100,000 trials: mean 1.0045, variance 1.0065 — matching the analytic mean 1 and variance 1.

Follow-up: “What’s the probability nobody gets their own hat?” → This is the derangement probability. Inclusion–exclusion gives For it equals to about 158 decimal places. So roughly 37% of the time no one is matched, 37% of the time exactly one person is, consistent with Poisson(1).

Trap: Saying “with more people there will be more matches.” The expectation is invariant. A related trap is confusing with “usually exactly one person gets their hat” — the modal outcomes are 0 and 1, each about 37%.


Q: There are 50 distinct collectible cards. I buy 50 random packs (one card each, uniform, with replacement). How many distinct cards do I expect to have?

The technique. Linearity over indicators — but index the indicators by coupon type, not by draw. Choosing the right index set is the whole skill.

Solution. Let if coupon type appears at least once in the draws. A given draw misses type with probability , and draws are independent, so By linearity, with types and draws,

That is of the collection. As the fraction tends to — the same constant that governs bootstrap resampling (see E1). It is not a coincidence; it is literally the same computation.

Sanity check. Monte Carlo, 100,000 trials: 31.800 vs analytic 31.7915. ✓ Small case by hand: types, 2 draws. Outcomes give distinct counts , mean . Formula: . ✓

Follow-up: “What if I buy 100 packs instead of 50?”. Doubling the spend takes you from 63.6% to 86.7% of the set — sharply diminishing returns, which is the real lesson (and it is why the full collection takes packs; see B4).

Trap: Indexing by draw (“”). That is actually valid but each term requires conditioning on the history, giving a much harder sum. Index by type and the probabilities become independent-draw computations.


Q: I throw 100 balls independently and uniformly into 100 bins. How many bins do I expect to be empty?

The technique. Indicators on bins plus linearity. Structurally identical to the coupon problem, complemented.

Solution. Let if bin is empty. Each of the balls independently misses bin with probability , so With : As with , the fraction empty . More generally with load factor , the empty fraction is — the standard hash-table occupancy result.

Sanity check. Monte Carlo, 100,000 trials: 36.596 vs analytic 36.6032. ✓ Limit check: , close to the exact 36.60 as expected for finite . ✓

Follow-up: “How many bins have exactly one ball?”, so . For : . Note the near-symmetry: about 37% of bins empty, 37% singletons, 26% with two or more. This is exactly Poisson(1) thinning, and it is the basis of the “expected number of hash collisions” question.

Trap: Using and reporting the approximation as if it were exact when is small. For the exact answer is while — a 5% error. Say which one you’re giving.


Q: I shuffle the numbers 1 through 10 into a random order. An inversion is a pair with but the value at larger than the value at . Expected number of inversions?

The technique. Linearity over indicators indexed by pairs, plus a symmetry argument for each pair’s probability.

Solution. There are pairs of positions. For any pair, the two values are in one of two relative orders, and by symmetry each is equally likely: Therefore For : .

Sanity check. Monte Carlo, 200,000 permutations of 10: 22.496 vs 22.5. ✓ Hand check : the 6 permutations have inversion counts , sum 9, mean 1.5, and . ✓

Follow-up: “What’s the variance, and what does this tell you about sorting?”; for that is (simulated variance: 31.18 ✓). The mean matters algorithmically: insertion sort runs in , so on random input its expected cost is — the average case is asymptotically as bad as the worst case, which is why it is not used at scale. The maximum possible is , exactly twice the mean, as symmetry (reversing a permutation maps inversions to ) requires.

Trap: Trying to enumerate permutations by inversion number (that generates the Gaussian binomial / Mahonian numbers — a real rabbit hole). The pairwise symmetry argument is two lines.


Q: Data streams in as a random sequence of distinct values. I keep a running maximum and log a “record” every time the running max is beaten. How many records do I expect to log?

The technique. Indicators indexed by position, with the key insight that position is a record iff the largest of the first values happens to be last — pure symmetry.

Solution. Let if element is a left-to-right maximum. Element is a record exactly when it is the largest among the first elements. Those elements are in uniformly random relative order, so each is equally likely to be the largest: By linearity, For : . Approximation: . ✓

Sanity check. Monte Carlo, 200,000 permutations of 100: 5.1919 vs 5.18738. ✓ Hand check : records are 2 for and 1 for , mean . ✓

Follow-up: “What if the stream has a million elements?”. This logarithmic growth is why “log every new max” is a safe instrumentation choice even on huge streams — you will emit ~14 lines, not a million. The variance is where , so the count is tightly concentrated around .

Trap: Guessing or “about .” The growth is logarithmic. Also: forgetting that element 1 always counts as a record (), which is what makes the sum start at 1.


Q: In an Erdős–Rényi random graph with nodes and edge probability , what’s the expected number of triangles?

The technique. Linearity over indicators indexed by triples of vertices; each triple’s probability is a product because the three edges are independent.

Solution. For each of the vertex triples, let if all three of its edges are present. The three potential edges are independent Bernoulli(), so . Hence For , : , so .

Sanity check. Monte Carlo, 300,000 graphs (counting triangles as ): 1.1381 vs 1.14. ✓ Sanity on scale: with we’d get all 1140 triangles, and scales as , so at we expect . ✓

Follow-up: “At what do triangles start appearing, as grows?”. So the threshold is : below that and triangles vanish; above it they proliferate. At exactly the expected count converges to , a constant — the classic Poisson regime where the number of triangles is asymptotically Poisson.

Trap: Writing but then trying to “correct” for overlapping triangles sharing edges. Triangles are dependent (two triangles can share an edge) and linearity is still exact. The dependence only matters if you’re asked for the variance — and there the shared-edge term appears.


Q: I shuffle two separate decks of 52 cards and deal them side by side, one card at a time. How many positions do you expect to show the identical card from both decks? What if I only require the ranks to match?

The technique. Indicators plus linearity, once again — and here the version with independent decks is cleaner than it looks.

Solution. Exact match. Let if position shows the same card in both decks. Condition on deck A’s card at position ; deck B’s card there is uniform over 52, so . Then (Equivalently: relabel so deck A is the identity — this reduces to the fixed-point problem A1.)

Rank match. A standard deck has 4 cards of each rank. Deck B’s card at position matches deck A’s rank with probability , so

Sanity check. Monte Carlo, 200,000 double-shuffles: exact matches 0.99996 (vs 1), rank matches 4.0054 (vs 4). ✓ Consistency check: the 4 rank matches should decompose as 1 exact match plus 3 same-rank-different-suit matches, and indeed . ✓

Follow-up: “What’s the probability of at least one exact match?”. By the derangement result, , so . This is the standard “two decks, will any position match?” bar bet — the answer is yes about 2 times in 3, which surprises people who reason “only 1 expected match out of 52, so it must be rare.”

Trap: Using for the rank-match probability. That would be right if both cards came from the same deck (drawing without replacement), but the decks are independent, so it’s . Simulation caught exactly this error during verification: the analytic value 3.059 was wrong, the sim said 4.005, and the sim was right.


B. Waiting times and first-step analysis

The move here is always the same: define as the answer, take one step, write in terms of itself and the states you can land in, and solve. If your recursion has more than one unknown, name a state variable and get a system.


Q: Fair coin. Expected number of flips to see the first head?

The technique. First-step analysis (or recognize the geometric distribution).

Solution. Let be the answer. Flip once — that costs 1. With probability we get a head and stop; with probability we get a tail and are back exactly where we started: For a general success probability : .

Sanity check. Monte Carlo, 200,000 trials: 1.9950 vs 2. ✓ Tail-sum confirmation: . ✓

Follow-up: “Expected flips to see the first head, given that the first flip was a tail?” → By memorylessness of the geometric, the count restarts: . The flip you already spent is sunk, and the remaining wait is a fresh geometric.

Trap: Answering for “number of failures before the first success,” which is , not 2. Be explicit about whether the successful trial is counted.


Q: Fair coin. Expected number of flips to get two heads in a row? Most people say 4. Why is it 6?

The technique. First-step analysis with states — you need to track partial progress, because a tail after a head destroys progress differently than a tail from scratch.

Solution. States: = “no current head,” = “one head so far.” Let be expected additional flips from each.

From : flip (cost 1); heads (prob ) , tails : From : flip (cost 1); heads done, tails : Substitute: , so and

Why not 4? The tempting argument is “, so two heads costs .” That would be right if failures were free, but they aren’t: after getting one head, a tail wipes out your progress and you pay the full 6 again. Formally, the general result for heads in a row at rate is which for gives , and for gives .

Sanity check. Monte Carlo, 300,000 trials: 6.0020 vs 6. ✓ Also verified : sim 13.998 vs 14. ✓ Exhaustive small check by enumerating all sequences: the probability HH has not appeared within 6 flips is exactly , and the partial expectation from sequences finishing by flip 6 is — a mean of 6 requires the remaining 33% of mass to average about 11 more flips, which matches from the state where you’re mid-run. ✓

Follow-up: “Expected flips for three heads in a row?”. Each additional required head multiplies the “last leg” cost by . For a biased coin with and : .

Trap: (“”). That is the answer to “expected flips to get heads total, in any positions,” which for genuinely is 4. Consecutive is strictly harder. Interviewers ask this specific problem because the wrong answer 4 is the right answer to a neighboring problem, which is a great test of whether you understood the question.


Q: Which takes longer on average with a fair coin — waiting for HT or waiting for HH? Give both numbers.

The technique. First-step analysis on states, plus the deep reason: overlap structure. Patterns that can partially overlap themselves take longer.

Solution. For HH, from above: .

For HT. States: = “no H yet,” = “trailing H.” The second equation is the key asymmetry: from , a head does not destroy progress — you still have a trailing H, so you stay in . Solving: , then .

So , even though both patterns have the same probability of appearing at any given pair of positions.

The reason. HH overlaps itself: the suffix “H” of HH is also a prefix of HH, so a failed attempt (H then T) throws you all the way back. HT has no self-overlap, so a “failure” (H then H) costs you nothing. Conway’s leading-number formula makes this exact: . For HH: overlaps of length 2 and 1, giving . For HT: only the full length-2 overlap, giving .

Sanity check. Monte Carlo, 300,000 trials each: HT 4.0027 (vs 4), HH 6.0020 (vs 6). ✓ All four length-3 patterns verified against Conway’s formula: HTT (sim 7.977), HHT (sim 8.003), TTH (sim 8.002), HTH (sim 9.990). ✓

Follow-up: “Which is longer, HTH or HTT?” → HTH takes 10; HTT takes 8. HTH self-overlaps (its trailing H is a prefix), HTT does not. Same probability per window, different waiting time — and this drives Penney’s game, where the second player can always choose a pattern that beats the first player’s.

Trap: Arguing “both have probability per pair of flips, so both take flips.” Per-window probability governs the long-run density of occurrences, not the waiting time to the first one. Both patterns occur at density ; HH just clumps (occurrences come in runs), so the gaps between clumps are longer.


Q: There are 50 distinct cards in a set, one uniformly random card per pack. How many packs until you have the complete set? Give the formula and the number.

The technique. Decompose the total wait into independent geometric stages, then linearity of expectation. (This is the coupon-collector problem.)

Solution. Let be the number of packs bought while you hold exactly distinct cards, i.e. the wait for the -th new card. When you have distinct cards, a pack is new with probability so with . The total is , and by linearity For : , so Asymptotically . ✓

Intuition for where the cost lives: the last card alone costs packs on average, and the last five cards cost packs — more than half the total. The tail dominates.

Sanity check. Monte Carlo, 60,000 trials: 224.73 vs 224.960. ✓ Hand check : ; directly, you get card 1 in one pack then wait Geometric() more, total 3. ✓

Follow-up: “What’s the standard deviation? Should I budget 225 packs?” → The stages are independent, so variances add: where . For : , so (simulated 61.93 ✓). That is a 28% coefficient of variation, and the distribution is right-skewed (Gumbel-like tail). Budget 225 and you complete the set less than half the time; the simulated 95th percentile is 341 packs, consistent with the Gumbel tail giving .

Trap: Answering or “50 cards times 50 tries.” Also: forgetting that the harmonic sum runs over how many you still need, not how many you have — get the direction wrong and you compute starting from the wrong end (same total, by symmetry, but people often mangle it).


Q: Expected number of rolls of a fair six-sided die until you’ve seen all six faces?

The technique. Coupon collector with — the same geometric-stage decomposition.

Solution. .

Stage by stage: rolls — the last face alone takes 6 rolls on average, more than the first four faces combined.

Sanity check. Monte Carlo, 400,000 trials: 14.705 vs 14.7. ✓ Independent check via inclusion–exclusion on the tail: ; summing numerically gives 14.7. ✓

Follow-up: “What if I need to see all six faces at least twice?” → No longer a clean harmonic sum (the “double dixie cup” problem); the asymptotic is , and simulation (200,000 trials) gives 24.12 rolls for — a 64% surcharge over 14.7 for the second copy. The honest interview answer is: “the geometric decomposition breaks because stage probabilities now depend on the whole count vector, so I’d set up a Markov chain on the multiset of counts, or simulate.”

Trap: (“each face takes 6 rolls”). The faces are collected in parallel, not in sequence — only the last one costs 6.


Q: I roll a fair die repeatedly until I get a 6. You then tell me that every single roll I made was an even number. Given that, what’s the expected number of rolls I made?

The technique. Law of total expectation applied correctly to a conditional event — compute , not “re-solve the problem on a smaller die.”

Solution. Let = {every roll, including the final 6, was even}. The sequence must be rolls from followed by a 6: Sum to get the normalizer: And the unnormalized first moment, using : Therefore

Why not 3? The trap answer says: “given all rolls are even, it’s effectively a three-sided die , so the wait is Geometric() with mean 3.” That is the answer to a different question — the expected wait if you only ever roll a 3-sided die. Conditioning on re-weights the sequences: long sequences are much less likely to be all-even (each extra roll multiplies the survival by instead of ), so the conditioning drags the expectation down, not up. Notably, is even smaller than the unconditional .

Sanity check. Monte Carlo by rejection, 3,000,000 attempted sequences: retained fraction 0.2500 (vs ✓), conditional mean 1.4999 (vs 1.5). ✓ Direct check of the first two terms: given , and ; already with only of mass left, so the mean is near 1.5, nowhere near 3. ✓

Follow-up: “What if instead I tell you the first roll was even (nothing about the rest)?” → Now the conditioning touches only one roll. — carefully: given roll 1 , it is a 6 with probability (done, ) and in with probability (then a fresh unconditional wait of 6 more). So . Conditioning on one roll barely moves things; conditioning on all rolls is drastic.

Trap: Collapsing to a three-sided die and answering 3. This is the single most instructive conditioning trap in the interview canon: the event you conditioned on has a probability that depends on , so it reshapes the distribution of . Whenever the conditioning event’s likelihood varies with the quantity you’re averaging, you must use .


Q: You walk into a casino with $50 and bet $1 per hand on a fair coin flip, playing until you either hit $100 or go broke. What’s the probability you go broke, and how many hands do you expect to play? Redo it for a real casino game where you win with probability 0.4737.

The technique. First-step analysis / gambler’s ruin recursion — and for the fair case, the martingale + optional stopping shortcut is instant.

Solution. Let be your current bankroll, the target (), the win probability, .

Ruin probability. Let . One step gives For the recursion is linear, so : (Martingale shortcut: your bankroll is a martingale, so by optional stopping . One line.)

Expected duration. Let . Then with . For the fair case the solution is (Martingale shortcut: is a martingale, so .)

Biased case. With , the general solutions are Take American roulette red: , , . Start with $20, target $40: An 89% chance of ruin from a bet with only a 5.26% house edge — the tiny edge compounds ferociously over hundreds of hands. (For the original $50/$100 problem at these odds, the same formula gives a ruin probability of 0.99487 — you lose everything 995 times in 1,000.)

Sanity check. Fair case, 20,000 simulated walks: ruin 0.4988 (vs 0.5), duration 2498.0 (vs 2500). ✓ Roulette case, 100,000 walks: ruin 0.89154 (vs 0.891602), duration 298.02 (vs 297.618). ✓ Recursions additionally solved as linear systems (): , — matching the closed forms to 7 digits. ✓ Tiny hand case : , sim 0.6931. ✓

Follow-up: “What if I bet $10 a hand instead of $1?” → In the fair game, ruin probability is unchanged at 0.5 (it depends only on the ratio in bankroll units: 5 units out of 10), but the duration collapses to hands. In the biased game, bigger bets help you: with $20/$40 at 10-unit bets you hold 2 units and target 4, so with gives instead of 0.8916. Fewer hands means fewer chances for the edge to grind you down — this is the “bold play is optimal against an unfavorable game” result.

Trap: Two of them. First, thinking the fair-game ruin probability depends on the bet size (it doesn’t; only matters). Second, believing that a fair game means you break even in a useful sense — is true, but the outcome is always $0 or $100, never $50.


Q: I deal cards off a shuffled 52-card deck one at a time. How many cards do I expect to deal before I see the first ace?

The technique. Symmetry / spacings — or equivalently the tail-sum formula. Don’t set up a recursion; the gap structure is the fast route.

Solution. The 4 aces divide the other 48 cards into 5 gaps: before the first ace, between consecutive aces, and after the last. By symmetry all 5 gaps have the same expected size, and they sum to 48, so each has expected size . The number of cards dealt including the first ace is General form for special cards in a deck of : .

Tail-sum derivation, for the skeptic. , and . Summing gives exactly.

Sanity check. Monte Carlo, 300,000 shuffles: 10.607 vs 10.6. ✓ Degenerate check: with special cards, formula gives ✓; with it gives , the expected position of a single marked card ✓.

Follow-up: “How many cards until the last ace?” → Four gaps of 9.6 sit before the last ace along with all 4 aces: . Equivalently, by the reflection symmetry of the deck, . Simulated: 42.379. ✓ A nice corollary: the expected position of the -th ace is .

Trap: Answering . That’s the average spacing between aces measured one way, but it double-counts: there are 5 gaps, not 4, because of the segment after the last ace. The form is the one to memorize.


C. Conditional expectation and the law of total expectation

Whenever the problem has two stages — a random thing that determines the distribution of another random thing — the tool is and . Say “law of total expectation” and the problem usually solves itself.


Q: An insurance book gets a Poisson(10) number of claims per month, and each claim’s size is independent with mean $500 and standard deviation $300. What are the mean and standard deviation of the monthly total?

The technique. Random sums: Wald’s identity for the mean, law of total variance for the variance.

Solution. Let with independent of the i.i.d. (, ).

Mean. , so

Variance. and , so For Poisson, , so this collapses to the compound-Poisson formula giving .

Notice where the risk lives: of the 3.4M variance, M (74%) comes from count uncertainty and only M from severity uncertainty. Knowing how many claims you’ll get matters more than knowing how big they are.

Sanity check. Monte Carlo, 400,000 months (gamma-distributed severities matching ): mean 4999.4 (vs 5000), variance 3,410,335 (vs 3,400,000), sd 1846.7 (vs 1843.9). ✓ Degenerate check: if severity were deterministic at 500 (), M, matching the formula’s second term alone. ✓

Follow-up: “What if is binomial instead — say 20 policies each filing with probability 0.5?” → Now still but , so and . The mean is identical; the risk is 20% lower because the binomial count is less dispersed than Poisson. Under-dispersed counts mean less aggregate risk.

Trap: Writing and forgetting the term. That undercounts the risk by a factor of nearly 4 — a genuinely expensive mistake in a risk role.


Q: A box has one 4-sided die and one 6-sided die. I pick one at random and roll it. What’s the expected value, and what’s the variance?

The technique. Law of total expectation and law of total variance, with the mixing variable being “which die.”

Solution. Let be the die chosen. , .

For the variance, use . A fair -sided die has variance , so and .

  • Within-die (unexplained): .
  • Between-die (explained): each w.p. , so its variance is .

This decomposition is the ANOVA/within-between split, and it’s the same identity behind bias–variance and behind : the between-group term is the variance your knowledge of would explain away.

Sanity check. Monte Carlo, 500,000 rolls: mean 3.0017 (vs 3), variance 2.3371 (vs 2.33333). ✓ Direct check: the pmf is , ; these sum to 1 and give , so . ✓

Follow-up: “If I tell you the roll was a 5, what’s the probability I used the d6?” → It must be the d6: . And if the roll was a 3? Bayes: . Low rolls are evidence for the d4.

Trap: Computing as the average of the two variances (2.0833) and stopping. You must add the variance of the conditional means, or you’ll systematically understate uncertainty in every mixture model you ever build.


Q: A deployment pipeline has 4 sequential stages. Each stage succeeds with probability 0.8, and any failure sends you back to stage 1 to redo everything. How many stage-attempts does a full successful deployment take on average?

The technique. First-step analysis with a restart — the “if you fail you start over” recursion. This is the same structure as “k heads in a row.”

Solution. Let = expected additional stage-attempts when you are about to attempt stage (so means done). One attempt costs 1; with probability you advance, otherwise you restart at stage 1:

To get closed form, note that if you attempt the whole pipeline “run” repeatedly, the number of stages completed in a failed run is what makes this messy — so solve directly. Unrolling from down, or observing that the probability a fresh run succeeds outright is , gives With , : , so So a 4-stage pipeline that “should” take 4 attempts takes 7.2 — an 80% overhead purely from redoing work.

Sanity check. Monte Carlo, 300,000 deployments: 7.1986 vs 7.20703. ✓ Recursion solved numerically as a linear system: , matching the closed form exactly. ✓ Degenerate checks: → take the limit, ✓; , the plain geometric ✓.

Follow-up: “What if I add a checkpoint so a failure only sends me back one stage?” → Then — a gambler’s-ruin-style birth–death chain with a reflecting barrier at stage 1. Solving the , system numerically gives stage-attempts (simulated 6.118 ✓), versus 7.207 without checkpoints. And the gap widens with : at , full restart costs 41.57 attempts while checkpointing costs 16.11 — the restart cost grows like (exponentially) while the checkpointed cost grows only linearly in . That exponential-vs-linear split is exactly why long ML training runs checkpoint.

Trap: Answering . That’s the cost if failures only made you redo the current stage. Restart-from-scratch is strictly worse because you lose completed work — the same reason two-heads-in-a-row costs 6, not 4.


Q: A new hire’s chance of closing a deal improves with practice: on their -th attempt they succeed with probability (so attempt 10 is a certainty). How many attempts until their first close?

The technique. Tail-sum formula — the right tool whenever per-trial success probabilities are non-constant, because the tail probabilities are simple products while the pmf is not.

Solution. .

So Term by term: . Summing:

The distribution is sharply concentrated: , and — the “guaranteed” tenth attempt is almost never needed.

Sanity check. Monte Carlo, 400,000 hires: 3.6627 vs 3.66022. ✓ Bound check: a constant- worker with (the first-attempt rate) would need attempts, and one with needs 1; 3.66 sits between, closer to the low end because the probability ramps fast. ✓

Follow-up: “What if improvement is slower — , capped at 1?” → Same tail-sum, now with 100 terms: attempts. For generally the answer scales like (since and ): for , ✓, and for , , close to the exact 3.66. Square-root, not linear.

Trap: Using or . Averaging the probabilities and inverting is not the same as inverting and averaging (Jensen), and it also ignores that you’re much more likely to stop early, so the later, higher probabilities get little weight. Here over 10 attempts giving — badly wrong.


Q: A metric is drawn from one of two populations: 70% of the time it’s , and 30% of the time it’s . What are the mean and variance of the observed metric?

The technique. Law of total expectation and law of total variance, with an explicit within/between decomposition.

Solution. Let index the component.

  • Within: .
  • Between: takes value 0 w.p. 0.7 and 5 w.p. 0.3, so its variance is .

The headline: 73% of the total variance is between-component. Neither component has sd above 2, yet the mixture has sd 2.67 — and the mixture is bimodal, so the mean 1.5 sits in a low-density valley and is a poor summary. This is the standard argument for segmenting a metric before reporting its mean.

Sanity check. Monte Carlo, 600,000 draws: mean 1.4901 (vs 1.5), variance 7.1089 (vs 7.15). ✓ Direct moment check: , so . ✓

Follow-up: “How much variance would I remove by learning which population each point came from?” → Exactly the between term, 5.25 of 7.15, i.e. — that ratio is the of the group label as a predictor. The irreducible residual variance is 1.9.

Trap: Computing the mixture variance as — the average of the component variances. That is the within term only, and it understates the true variance here by a factor of 3.8. Mixture variance is always at least the average component variance, with equality only if the component means coincide.


Q: I draw 10 independent Uniform(0,1) values. What’s the expected maximum? The expected minimum? The expected range?

The technique. Order statistics via the tail-sum/CDF integral, plus a symmetry argument that makes the answer memorable.

Solution. Let . Then for , and using : For the minimum, , so General: , , and the -th smallest has mean .

The symmetry picture. The points cut into gaps, which are exchangeable, so each has expected length . The minimum is one gap (); the max is gaps (); the range is gaps:

Sanity check. Monte Carlo, 400,000 draws of 10: max 0.90933 (vs 0.909091), min 0.09107 (vs 0.090909), range 0.81826 (vs 0.818182). ✓ Hand check : ✓. Consistency: by the symmetry ✓, and ✓.

Follow-up: “What’s the expected median of 9 uniforms, and the third smallest of 10?” → Median of 9 is the 5th of 9: (simulated 0.49996 ✓) — the sample median is unbiased for the population median here. Third smallest of 10: (simulated 0.2724 ✓).

Trap: Assuming of uniforms is close to 1 for small and reporting “about 1.” The gap decays only like , so with you’re 9% short — which matters a lot when this is used to estimate an unknown upper bound (the German-tank problem: the unbiased estimator is , not ).


Q: I roll two fair dice. What’s the expected value of the larger of the two? (Ties count as that value.)

The technique. Tail-sum formula on a discrete variable — — which is far cleaner than enumerating the 36 outcomes.

Solution. Let . Then , so .

Faster, with symmetry. , so . And . Then . ✓

Sanity check. Monte Carlo, 600,000 rolls: max 4.47199 (vs 4.47222), min 2.52925 (vs 2.52778), and sim max + min . ✓ Also , the expected absolute difference — verifiable independently.

Follow-up: “What’s for three dice? For dice?”. For : … careful — that’s the sum , giving . As , geometrically.

Trap: Answering 3.5 (“the max of two fair dice is still a fair die on average”) or averaging and . Taking a max is a nonlinear operation: , and by Jensen .


Q: Traffic to a landing page is Poisson with mean 1,000 visitors a day, and each visitor independently clicks the CTA with probability 2%. What’s the expected number of clicks, and its variance?

The technique. Law of total expectation for the hierarchical mean, then Poisson thinning for the exact distribution.

Solution. Let and . For the variance, law of total variance: Variance equals the mean — because Poisson thinning says exactly. That’s the elegant answer: independently keeping each point of a Poisson process with probability yields a Poisson process with rate .

So , a 22% coefficient of variation. If you observe 24 clicks tomorrow, that’s under 1 sd above the mean — not a signal.

Sanity check. Monte Carlo, 300,000 days: mean 19.996 (vs 20), variance 19.891 (vs 20). ✓ Also confirmed the thinned distribution is Poisson: simulated vs Poisson(20) pmf . ✓

Follow-up: “If traffic were fixed at exactly 1,000 (not random), how would the variance change?” → Then with variance instead of 20. Slightly tighter: you’ve removed the contribution from traffic randomness. When is small, binomial and Poisson are nearly identical, which is why so much web-analytics math treats clicks as Poisson without apology. The practical corollary: for A/B test power at 2% CTR, you need on the order of visitors per arm — with (a 10% relative lift), that’s about 78,000 per arm, roughly 78 days of this traffic.

Trap: Reporting only the mean and treating 20 as precise, or computing the variance as by accident (right number, wrong reasoning — it works here only because Poisson thinning makes both terms conspire). Show the two-term decomposition so it’s clear you know why.


D. Continuous and geometric scenarios

Two moves dominate: turn the probability into an area or volume in the sample space, or exploit a memorylessness/order-statistics structure. Draw the square.


Q: Two people agree to meet between 12:00 and 1:00. Each arrives at a uniformly random time in that hour, independently, and waits 15 minutes before leaving. What’s the probability they meet?

The technique. Geometric probability — represent the sample space as the unit square and compute an area.

Solution. Let be the arrival minutes, independent. They meet iff . The joint density is uniform on the square, so the probability is the fraction of the square’s area in the band .

The complement is two right triangles (the corners where ), each with legs : Therefore General form for wait in window : .

Sanity check. Monte Carlo, 1,000,000 pairs: 0.437468 vs 0.4375. ✓ Limit checks: gives ✓; gives ✓; gives , and simulating a 30-minute wait yields 0.7500 ✓.

Follow-up: “What’s the expected wait for whoever arrives first?” → That’s for two uniforms on , which is minutes (simulated 20.003 ✓) — but conditional on meeting, the expected gap is smaller. Compute: . With , (simulated 7.143 ✓). So when they do meet, the first arrival waits about 7 minutes.

Trap: Answering (“the second person has to land in a 15-minute window”). The window is 15 minutes on each side, and it’s truncated at the edges of the hour — which is exactly what the triangle-area computation handles. Also common: forgetting that the wait is symmetric (either person can arrive first), which halves the answer if you only count one direction.


Q: I break a stick at two independent uniformly random points. What’s the probability the three pieces can form a triangle?

The technique. Geometric probability again — the sample space is the unit square (or the 2-simplex), and the triangle inequality carves out a region whose area you compute.

Solution. Let be the break points. The three piece lengths are determined by the ordered pair. The triangle inequality for pieces with is equivalent to the single condition because .

Work on the unit square. If , pieces are , and we need That’s a triangle with vertices , of area . By symmetry the region for has the same area . Total:

Cleaner via complement. The triangle fails iff some piece exceeds , and at most one piece can, so the three failure events are disjoint. Each piece exceeds with probability — e.g. the first piece is iff both break points land in , probability — so and . ✓

Sanity check. Monte Carlo, 1,000,000 sticks: 0.250014 vs 0.25. ✓ Independent check: simulated ✓, and , also confirmed.

Follow-up: “What if I break the stick once, then break the longer piece?” → Now . The sequential procedure isn’t the same as two simultaneous uniform cuts — this is the standard demonstration that “break at random” is ambiguous, and the answer depends on the procedure. Break the randomly chosen piece instead and you get .

Trap: Answering from a vague symmetry hand-wave, or trying to integrate the triangle inequality as three separate conditions without noticing they collapse to . The collapse is the insight.


Q: Two points are dropped uniformly at random on a 1-meter segment. What’s the expected distance between them? What if they’re dropped in a 1×1 square?

The technique. Direct integration for the line (with the order-statistics shortcut as a check); for the square, the same integral in 2D — and here the honest interview answer is “I’d set up the integral and note the closed form is ugly.”

Solution. On the line. with independent: Order-statistics shortcut: the two points split into 3 exchangeable gaps of expected length each; the distance between the points is the middle gap, so . ✓

In the unit square. By independence of coordinates, the horizontal and vertical gaps are i.i.d. with density on , and we want . Evaluating the double integral gives the known closed form

Sanity check. Monte Carlo, 1,000,000 pairs each: line 0.33316 (vs 0.33333), square 0.521564 (vs 0.521405). ✓ Bounds for the square: the distance must exceed the mean of a single coordinate gap () and be less than the diagonal . Tighter: since for each coordinate, Jensen gives , and indeed . ✓

Follow-up: “Give me a fast approximation you’d trust in an interview.” → Use as an upper bound and note it overshoots by 11%. Or scale the 1D answer: as a lower-ish estimate. Saying “it’s between 0.47 and 0.58, and the exact value involves a log” is a strong answer. (For reference, in the unit cube it’s .)

Trap: Computing as . That’s Jensen’s inequality being violated in your favor by accident; the square root of a sum of squares of means is not the mean of the square root.


Q: A dart lands uniformly at random on a circular board of radius 1. What’s the expected distance from the bullseye? What’s the probability it lands in the inner half of the radius?

The technique. Area-weighting: uniform on a disk means the radius has density proportional to , not constant. Getting the density right is the whole problem.

Solution. Uniform on the disk means , so the density is on . So half the radius contains only a quarter of the area — the classic area-vs-radius confusion. Equivalently, the median distance from center is with , i.e. : half the darts land in the outer 29% of the radius.

Sanity check. Monte Carlo, 1,000,000 darts (sampled as ): 0.666675 (vs 0.66667), 0.249767 (vs 0.25). ✓ Second check via rejection sampling in the bounding square: 1,000,000 uniform points in land inside the unit circle a fraction 0.785795 of the time, vs ✓ — which also confirms the classic “dart in inscribed circle” answer of .

Follow-up: “Standard dartboard scoring gives the bullseye a tiny area. If a dartboard has concentric rings of equal area, what radii separate them?” → Equal area means the -th boundary is at . For : . Equal-area rings are progressively thinner going outward, which is why fair-difficulty ring designs look non-uniform.

Trap: Taking and answering , . Sampling both uniform gives a distribution clustered at the center, not uniform on the disk — this is a real bug people ship when generating random points in a circle. The fix is .


Q: Draw a “random chord” of a circle. What’s the probability it’s longer than the radius?

The technique. There isn’t one number — the answer depends on the sampling scheme. Naming that is the correct answer; then compute all three. (This is Bertrand’s paradox in a slightly disguised form.)

Solution. Take radius . A chord at perpendicular distance from the center has length , so Now the three natural samplings:

Scheme 1 — random endpoints. Fix one endpoint, pick the other uniformly on the circumference. With central angle , chord length is , and :

Scheme 2 — random distance along a radius. Pick a direction, then along that radius, and draw the perpendicular chord:

Scheme 3 — random midpoint uniform in the disk. Then has density (as in the dartboard problem), so

Three defensible schemes, three different answers: , , . “Random chord” is underspecified. Scheme 3 is the one that’s invariant under the natural scaling of the disk; Scheme 1 is the one that’s invariant under rotation of the endpoints; the physically realizable answer depends on your mechanism (e.g. throwing a straw at a circle gives Scheme 2-ish behavior).

Sanity check. Monte Carlo, 1,000,000 chords per scheme: Scheme 1 0.666427 (vs 0.6667), Scheme 2 0.866549 (vs 0.86603), Scheme 3 0.750312 (vs 0.75). ✓ All three verified independently, confirming the ambiguity is real and not an algebra slip.

Follow-up: “Which one would you use in practice?” → State the mechanism first. If chords come from two random points on a boundary (network links between random nodes on a ring), Scheme 1. If from a random line sweeping the plane (Buffon-style needle drops, stereology, integral geometry), Scheme 2 — that’s the one satisfying the invariance measure used in geometric probability. If from a random center point (a random cut through a random interior location), Scheme 3. The interview lesson generalizes far beyond circles: “pick a random X” is not a distribution until you say how.

Trap: Confidently giving one number. Also: the classic version asks for “longer than the side of the inscribed equilateral triangle” (), where the three answers are — memorizing those and reciting them here gets the wrong problem.


Q: Buses arrive according to a Poisson process, one every 10 minutes on average. You’ve been waiting 10 minutes already. How much longer do you expect to wait?

The technique. Memorylessness of the exponential: . Say the word “memoryless” and you’re done.

Solution. Inter-arrival times are , mean 10 minutes. Memorylessness: The conditional distribution of remaining wait is identical to the original exponential, so Your 10 minutes of waiting bought you nothing. The bus is not “due.”

Sanity check. Monte Carlo, 4,000,000 exponentials with mean 10, conditioning on : mean residual 9.9939 (vs 10). ✓ Also ; simulated 0.22300 ✓.

Follow-up: “Suppose buses instead arrive exactly every 10 minutes, and you arrive at a uniformly random time. Now what?” → Your wait is with mean 5 minutes; after already waiting 10 minutes, the remaining wait is 0 (impossible — the bus would have come). Deterministic schedules have decreasing residual life. And the flip side, the inspection paradox: if inter-arrival times are exponential with mean 10, a randomly arriving passenger’s total observed gap has mean 20 (size-biased), of which they wait 10 — even though the average gap is only 10. This is why “the average bus comes every 10 minutes but I always seem to wait 10 minutes” is not a complaint about the bus company.

Trap: Answering 0 (“it’s been 10 minutes, so it’s about to arrive”) or something less than 10 (“the wait is getting shorter”). Both encode the gambler’s-fallacy intuition that a Poisson process has memory. The exponential is the unique continuous distribution with this property, and if the interviewer’s process weren’t exponential the answer would change — so it’s worth asking.


Q: Two independent processes are running: one fails on average every 5 hours, the other every 8 hours, both exponentially distributed. How long until the first failure, and which one is more likely to fail first?

The technique. Minimum of independent exponentials: rates add, and the winner’s probability is its share of the total rate.

Solution. Let , , independent. Then so and Which fires first: Independently: the minimum’s timing and the identity of the winner are independent, which is the fact that makes competing-risks and continuous-time Markov chain simulation work.

Sanity check. Monte Carlo, 1,000,000 pairs: 3.07868 (vs 3.076923), 0.615394 (vs 0.615385). ✓ Bound check: ✓, and but half of the smaller mean.

Follow-up: “And the time until both have failed?” → Use : (simulated 9.9434 ✓). Note is not of the means — it exceeds 8 substantially. With a third process failing every 10 hours, hours (simulated 2.359 ✓), so adding redundancy to the count of things that can break shortens the time to first breakage fast — the reason large distributed systems always have something failing.

Trap: Averaging the means to get 6.5, or taking the smaller mean (5) as the answer. The min of exponentials is strictly faster than either component, and by an amount that follows the harmonic-style rate addition, not any averaging of times.


Q: Support tickets arrive as a Poisson process at 5 per hour. What’s the probability exactly 3 arrive in the next hour? And given that exactly 3 arrived, what’s the expected time of the first one, and how many do you expect in the first half hour?

The technique. Poisson pmf for the first part; then the conditional uniformity property — given , the arrival times are distributed as i.i.d. uniforms on , so order statistics take over.

Solution. Count. With , :

Given . The three arrival times behave exactly like 3 i.i.d. draws (this is the defining conditional property of the Poisson process). Therefore:

  • First arrival is the minimum of 3 uniforms: hour .
  • Number in is Binomial, so .

The second result is worth stating out loud: given the total, the split between two sub-intervals is binomial, not Poisson — conditioning on the count destroys the Poisson-ness.

Sanity check. Monte Carlo, 1,000,000 hours: 0.140079 (vs 0.140374) ✓. Then 1,000,000 draws of 3 sorted uniforms: 0.249890 (vs 0.25) ✓, 1.500397 (vs 1.5) ✓.

Follow-up: “Unconditionally, what’s the expected time of the first ticket?”, so hour minutes — shorter than the 15 minutes we got conditional on exactly 3 arriving. That makes sense: conditioning on only 3 arrivals (below the mean of 5) is evidence the hour was quiet, pushing the first arrival later. Conditioning on would give hour minutes.

Trap: Answering “given 3 in an hour, expect in the half hour” for the right reason but then claiming the half-hour count is Poisson(2.5). It isn’t — it’s Binomial(3, 0.5), with variance , not . Another trap: computing as hour (“three arrivals, evenly spaced over the hour”). Evenly spaced would put the first at ; uniform order statistics put it at , because the gaps include one after the last arrival.


E. ML-flavored expectation problems

These are the ones that show up when the interviewer wants to know whether you understand your own tooling. The math is section-A math; the framing is bootstrap, minibatch, retry policy, bandit.


Q: I draw a bootstrap sample: draws with replacement from a dataset of points. What fraction of the original data appears in the bootstrap sample?

The technique. Indicators plus linearity, indexed by data point — plus the limit .

Solution. Let if point appears at least once. Each of the draws misses point with probability , and draws are independent, so By linearity the expected count of distinct points is , so the expected fraction is For the exact value is — already at the limit to four digits.

The complement, , is the out-of-bag set: the points not in this bootstrap sample. That’s where random-forest OOB error estimates come from, and it’s why OOB validation is nearly free — every tree gets a held-out 37% for free.

Sanity check. Monte Carlo, 20,000 bootstrap samples with : distinct fraction 0.632324 vs exact 0.632305 and limit 0.632121. ✓ Hand check : samples give distinct counts , mean 1.5, fraction 0.75; formula ✓. Note is far from the limit — the convergence is from above, monotone decreasing.

Follow-up: “How many times does a given point appear, and what’s the distribution?” → Multiplicity is Binomial, mean exactly 1, variance , converging to Poisson(1). So , once , twice , three or more . The mean multiplicity is 1 while the coverage is only 63% — the duplicates account for the difference, and they’re what makes bootstrap resampling introduce variance rather than just subsample.

Trap: Guessing 50% (“half the data, roughly”). Also: confusing this with subsampling without replacement, where draws from points trivially recovers 100%. The whole statistical content of the bootstrap comes from the with-replacement duplication.


Q: My training set has 1,000 examples and I sample minibatches of 256 with replacement. How many distinct examples does a batch contain?

The technique. Same indicator-and-linearity computation, now with batch size decoupled from dataset size.

Solution. Let , . Example is absent from the batch with probability , so So a nominal batch of 256 delivers about 226 distinct examples — you’re wasting about 12% of your compute on duplicates. Using the approximation , essentially identical.

Sanity check. Monte Carlo, 50,000 batches: 225.963 vs 225.9572. ✓ Limit checks: gives (with : exact 9.955 ✓), and saturates at .

Follow-up: “Does this matter? Should I sample without replacement?” → For the loss is duplicated slots — with that’s 0.03 examples, utterly negligible, which is why with-replacement sampling is harmless at scale. It only bites when is appreciable: at you get only 63% coverage (the bootstrap result). Standard practice — shuffle once per epoch and take contiguous slices — is sampling without replacement within an epoch, giving exactly distinct examples and slightly lower gradient variance. The with-replacement analysis matters when you implement a sampler yourself, or when using weighted/importance sampling where replacement is the natural formulation.

Trap: Assuming a batch of 256 has 256 distinct examples when your sampler uses replacement, then being confused why effective batch size seems smaller than configured. Also: assuming this is a bug. It’s a 12% effect at this ratio and a rounding error at realistic ratios.


Q: Before I train anything, what accuracy and log-loss should a random baseline get on a 5-class problem? What if the classes are imbalanced at 70/20/10?

The technique. Expectation of an indicator (accuracy is just ) and direct computation of expected log-loss; then note that “random” itself needs specifying.

Solution. Balanced, 5 classes, uniform random prediction. For log-loss, predicting the uniform distribution for every example gives loss nats (or bits) on every example, hence in expectation. That is the entropy of the label distribution, and it is the best achievable score with no features.

Imbalanced, priors . Three different “baselines”:

  • Sample from the priors: .
  • Always predict the majority class: . Strictly better.
  • Uniform random over 3 classes: .

And the log-loss floor for a featureless model is the label entropy nats, achieved by predicting the priors — not by predicting the majority class with certainty, which yields infinite loss.

Sanity check. Monte Carlo, 1,000,000 examples: uniform-random accuracy on 5 classes 0.200414 (vs 0.2) ✓; prior-sampling accuracy on the imbalanced problem 0.539876 (vs 0.54) ✓; majority-class accuracy 0.699356 (vs 0.7) ✓.

Follow-up: “My model gets 72% on the imbalanced problem. Is it good?” → It beats the majority baseline (70%) by 2 points, which is close to noise on a small test set — with test examples the standard error on accuracy is , so 72% vs 70% is under . Report balanced accuracy, macro-F1, or AUC instead, and compare log-loss against the 0.8018 entropy floor. “Better than random” is a meaningless bar when random can mean anything from 33% to 70%.

Trap: Quoting as the random baseline on an imbalanced problem. With 70/20/10 the honest bar is 70%, not 33%, and reporting a 65%-accurate model as “double the random baseline” is how bad models get shipped.


Q: Quicksort picks a pivot uniformly at random and partitions. How many comparisons does it make on average to sort distinct elements? Take .

The technique. Two routes. (a) First-step recursion on the pivot rank, then solve; (b) the slick one: linearity of expectation over pairs, asking for each pair whether it is ever compared.

Solution. Route (b), the elegant one. Consider the sorted values . Elements and () are compared iff the first pivot chosen from the set is or — because if any middle element is picked first, and are split into different subarrays and never meet. All elements of that set are equally likely to be the first pivot, so By linearity, For : , so Asymptotically , i.e. about 39% more than the information-theoretic lower bound of .

Route (a), the recursion. , which telescopes to the same closed form.

Sanity check. Monte Carlo, 40,000 random permutations of 100, counting actual comparisons: 647.98 vs 647.850. ✓ Hand check : formula gives comparison ✓. : ; enumerate — with any pivot you make 2 comparisons, then the 2-element side costs 1 more with probability (pivot was min or max), so ✓.

Follow-up: “What about a million elements, and how does this compare to mergesort?” comparisons. Mergesort does about million — roughly 24% fewer comparisons, yet quicksort is usually faster in practice because of cache locality and in-place partitioning. Note also that the distribution is tightly concentrated: is exponentially small, so randomized quicksort essentially never hits its worst case.

Trap: Setting up the recursion, failing to solve it, and asserting “ by the Master Theorem.” The Master Theorem doesn’t directly apply (the split is random), and the interviewer asking for a number wants the constant. The pair-indicator argument is the one to know — it converts a recursion into a one-line sum.


Q: I’m averaging i.i.d. measurements with standard deviation 10. What’s the variance of the average with ? If I want to halve my error bars, how much more data do I need?

The technique. Variance of a sum of independent variables adds; scaling pulls out as a square. Then the vs distinction.

Solution. With i.i.d., : So — the standard error.

The key asymmetry: variance falls like , but the error bar falls like . To halve the standard error from 1 to 0.5 you need Four times the data for twice the precision. For one more decimal place (10× precision), 100× the data.

Sanity check. Monte Carlo, 200,000 averages of 100 draws from : 1.00133, 1.00067 (vs 1). ✓ Confirmed the scaling directly: at the simulated sd was 0.4998 ✓.

Follow-up: “What if the measurements are positively correlated with pairwise correlation ?” as . With and , the variance floor is , not 0 — so no amount of extra data gets your standard error below . This is the single most important practical caveat: correlated samples (repeated measures on the same users, autocorrelated time series, augmented copies of the same image) have an effective sample size , which here caps at no matter how many points you collect. Reporting on clustered data is how A/B tests produce fake wins.

Trap: Saying “to halve the error, double the data.” That halves the variance, not the standard error. Also: computing on data that isn’t independent — the step silently requires zero covariance.


Q: I want the average of a ratio — say revenue per user. Is the same as ? If not, how do I estimate it?

The technique. Jensen’s inequality to get the direction, then the delta method (second-order Taylor expansion) to get the magnitude.

Solution. They are not equal in general. Concretely, let and , so we’re comparing to : A 9.9% gap. The direction is guaranteed: is convex, so by Jensen , always.

Delta method. Expand around : Taking expectations kills the linear term, leaving Here , , so the estimate is — capturing most of the 0.0493 gap (it recovers 0.0417 of it), with the remainder in higher-order terms.

For a general ratio the delta method gives That variance formula is the standard tool for A/B tests on ratio metrics (CTR, revenue-per-session), where the denominator is itself random.

Sanity check. Monte Carlo, 2,000,000 draws: 0.549513 vs exact ✓; 0.500187 vs 0.5 ✓; delta approximation 0.541667 sits between, confirming it’s a lower-order correction. ✓ Second check with a realistic CTR setup (, ): simulated 0.099978 vs the pooled ratio 0.1 — nearly identical here because the denominator’s coefficient of variation is only 10%, so the correction term is tiny. ✓

Follow-up: “Which should I actually report for CTR across users?” → It depends on the estimand. The ratio of sums estimates the population-level click rate and weights users by their impression volume; the mean of ratios estimates the average user’s rate and weights every user equally. They answer different questions and can move in opposite directions (Simpson’s paradox territory). Ratio-of-sums is usually the business metric; be explicit, and use the delta method for its variance since the denominator is random.

Trap: Reporting as “the CTR” and being surprised it doesn’t match the dashboard, or computing a naive standard error that treats the denominator as fixed. The latter systematically understates variance when denominators are small and variable.


Q: I’m running -greedy over three arms with true means 0.5, 0.4, and 0.3. With , what’s my expected per-pull reward once I’ve correctly identified the best arm? What’s the regret?

The technique. Law of total expectation over the explore/exploit branch — a two-line mixture computation.

Solution. Each pull: with probability exploit (pull the known-best arm, mean 0.5); with probability explore (pull a uniformly random arm, mean ). Per-pull regret is , i.e. . Over pulls, cumulative regret is linear in , because a fixed never stops exploring.

(Convention note: some implementations explore only among the non-best arms. Then and per-pull regret is 0.015. State your convention.)

Sanity check. Monte Carlo, 1,000,000 pulls (uniform-over-all-arms convention): mean reward 0.489596 vs 0.49. ✓ Limit checks: gives 0.5 (pure exploit, zero regret but no learning) ✓; gives 0.4 (pure random) ✓.

Follow-up: “How should I set ?” → Decay it. A fixed gives regret; gives regret, matching the lower-bound order, where is the gap to the second-best arm. Better still, use UCB or Thompson sampling, which achieve without hand-tuning a schedule and which explore adaptively — spending pulls on arms that are plausibly best rather than uniformly. The concrete cost of getting this wrong: at over a million pulls you’ve thrown away 10,000 units of reward, versus a few hundred for a log-regret algorithm.

Trap: Computing as , using the worst arm for the exploration branch instead of the average. Also: forgetting that during the learning phase the “best arm” isn’t yet identified, so 0.49 is the asymptotic ceiling for fixed , not the average over a full run.


Q: A service call fails independently 10% of the time. My client retries up to 3 times after the initial attempt. What’s the expected number of attempts per request, and what’s the probability a request ultimately fails?

The technique. Tail-sum formula on a truncated geometric: , where “more than attempts” simply means “the first all failed.”

Solution. Let be the per-attempt failure probability, and allow up to 4 total attempts (1 initial + 3 retries). Then for , and always, so So retries buy you a 3.5-nines success rate at a cost of only 11.1% extra load. That is an extraordinarily good trade, and it’s why retry policies are ubiquitous.

For the uncapped policy, — barely different, because the cap only matters in the tail.

Sanity check. Monte Carlo, 300,000 requests: capped 1.10973 (vs 1.111) ✓; uncapped, 200,000 requests: 1.11139 (vs 1.11111) ✓; , simulated 1.00e-4 ✓. Hand check with , cap 4: , and simulated 1.8745 ✓.

Follow-up: “The backend starts failing 90% of the time. What happens?” attempts per request — the retry policy has tripled the load on an already-failing backend, which is the classic retry-storm/metastable-failure mode: degradation triggers retries, retries increase load, load increases degradation. And the request still fails of the time. This is why production retry policies need exponential backoff with jitter, a retry budget (cap retries as a fraction of total traffic, e.g. 10%), and a circuit breaker that stops retrying entirely when the failure rate crosses a threshold. The expectation calculation is what makes the danger quantitative: the amplification factor is , which is 1.11 at and 3.44 at .

Trap: Answering 4 (“up to 4 attempts”) instead of 1.111 — the cap is almost never reached when is small. The opposite trap is assuming retries are cheap unconditionally; the expected-attempts formula is a function of the failure rate, and it blows up exactly when you can least afford it.


Appendix: Verification code

Every number above was checked by Monte Carlo. Below is the code for the eight trickiest, where the analytic answer is most easily botched. All were run at the trial counts shown; reported simulated values appear in the Sanity check lines.

import numpy as np, math
rng = np.random.default_rng(0)
H = lambda n: sum(1.0 / i for i in range(1, n + 1))

V1 — B6, the conditioning trap (expected rolls to a 6, given all rolls even). Rejection sampling on the conditioning event. Confirms , refuting the tempting answer 3.

acc = []
for _ in range(3_000_000):
    c, ok = 0, True
    while True:
        r = rng.integers(1, 7); c += 1
        if r == 6: break
        if r % 2 == 1: ok = False; break
    if ok: acc.append(c)
print(len(acc) / 3_000_000, np.mean(acc))   # 0.2500 (=P(A)=1/4), 1.4999  vs 1/4, 1.5

V2 — B3, pattern waiting times (HH vs HT and all length-3 patterns). Verifies Conway’s leading-number formula .

def waitpat(pat):
    s = ''
    while True:
        s += 'H' if rng.random() < 0.5 else 'T'
        if s.endswith(pat): return len(s)

for pat, ana in [('HH',6),('HT',4),('HHH',14),('HTH',10),('HTT',8),('HHT',8),('TTH',8),('THH',8)]:
    print(pat, ana, np.mean([waitpat(pat) for _ in range(200_000)]))
# HH 6 6.002 | HT 4 4.003 | HHH 14 13.998 | HTH 10 9.990 | HTT 8 7.977 | ...

V3 — B7, gambler’s ruin: simulation and numerical solution of the recursion. Two independent confirmations of the closed forms, agreeing to 7 digits.

def gr(k, N, p):
    steps = 0
    while 0 < k < N:
        k += 1 if rng.random() < p else -1; steps += 1
    return (k == 0), steps

p, N, k = 18/38, 40, 20; q = 1 - p; r = q / p
h_ana = (r**k - r**N) / (1 - r**N)
d_ana = k/(q-p) - (N/(q-p)) * (1 - r**k) / (1 - r**N)
sims = [gr(k, N, p) for _ in range(100_000)]
print(h_ana, np.mean([s[0] for s in sims]))   # 0.891602  0.89154
print(d_ana, np.mean([s[1] for s in sims]))   # 297.6175  298.02

# solve the recursions as linear systems: h(k)=p h(k+1)+q h(k-1);  d(k)=1+p d(k+1)+q d(k-1)
for rhs, bc in [(np.zeros(N+1), (1.0, 0.0)), (np.ones(N+1), (0.0, 0.0))]:
    A = np.zeros((N+1, N+1)); b = rhs.copy()
    A[0,0] = A[N,N] = 1; b[0], b[N] = bc
    for i in range(1, N):
        A[i,i] = 1; A[i,i+1] -= p; A[i,i-1] -= q
    print(np.linalg.solve(A, b)[k])           # 0.8916020103548459 ; 297.61752786967634

V4 — C3, restart-on-failure pipeline: closed form, simulation, and recursion.

p, n = 0.8, 4
def run():
    st = c = 0
    while st < n:
        c += 1
        st = st + 1 if rng.random() < p else 0
    return c
print((1 - p**n) / (p**n * (1 - p)), np.mean([run() for _ in range(300_000)]))  # 7.20703  7.1986

A = np.zeros((n+1, n+1)); b = np.ones(n+1); A[n,n] = 1; b[n] = 0
for i in range(n):
    A[i,i] = 1; A[i,i+1] -= p; A[i,0] -= (1 - p)
print(np.linalg.solve(A, b)[0])              # 7.20703125  (exact match)

V5 — D5, Bertrand’s chord, all three sampling schemes. Confirms that the three answers genuinely differ — the ambiguity is real.

M = 1_000_000
th = rng.random(M) * 2 * math.pi
print(np.mean(2 * np.sin(th/2) > 1))                      # 0.6664  vs 2/3
d = rng.random(M)
print(np.mean(2 * np.sqrt(1 - d**2) > 1))                 # 0.8665  vs sqrt(3)/2 = 0.8660
dm = np.sqrt(rng.random(M))                               # midpoint uniform in disk
print(np.mean(2 * np.sqrt(1 - dm**2) > 1))                # 0.7503  vs 3/4

V6 — C1, compound Poisson mean and variance. The term people forget is ; this catches its omission immediately.

lam, mu, sd = 10, 500.0, 300.0
shape, scale = (mu/sd)**2, sd**2/mu               # gamma matched to (mu, sd)
S = np.array([rng.gamma(shape, scale, rng.poisson(lam)).sum() for _ in range(400_000)])
print(lam*mu, S.mean())                            # 5000      4999.4
print(lam*(sd**2 + mu**2), S.var())                # 3,400,000 3,410,335
print(lam*sd**2, "<- what you get if you forget Var(N)mu^2")   # 900,000: wrong by 3.8x

V7 — E4, quicksort comparisons vs . Counts real comparisons in a real partition, not a model of one.

def qs(a):
    if len(a) <= 1: return 0
    p = a[rng.integers(len(a))]
    return (len(a) - 1) + qs(a[a < p]) + qs(a[a > p])

n = 100
print(2*(n+1)*H(n) - 4*n, np.mean([qs(rng.permutation(n)) for _ in range(40_000)]))
# 647.850  647.98

V8 — E1/E2/A3/A4, the family (bootstrap, minibatch, coupons, empty bins). One formula, four interview questions.

def distinct(N, B, trials=50_000):
    return np.mean([len(np.unique(rng.integers(0, N, B))) for _ in range(trials)])

for N, B in [(1000, 1000), (1000, 256), (50, 50), (100, 100)]:
    print(N, B, N*(1 - (1 - 1/N)**B), distinct(N, B))
# 1000 1000  632.305  632.324   <- bootstrap: 63.2% coverage, 1 - 1/e
# 1000  256  225.957  225.963   <- minibatch with replacement
#   50   50   31.792   31.800   <- distinct coupons after n draws
#  100  100   63.397   63.404   <- so 100 - 63.40 = 36.60 empty bins

The toolkit, one more time

Signal in the questionToolProblems
“Expected number of things”Indicators + linearityA1–A8, E1, E2, E4
“How long until…”, progress can resetFirst-step analysis on statesB1–B3, B7, C3
“Collect all…”, stages with changing ratesSum of geometrics + linearityB4, B5
Two-stage / random parameterTotal expectation & total varianceC1, C2, C5, C8, E7
“Given that…” where the event’s likelihood variesB6, D8
Continuous, “random point/time”Area/volume, or order statisticsC6, C7, D1–D4
Max/min, non-constant per-trial ratesTail-sum B8, C4, C6, C7, E8
Fair game, stopped processMartingale + optional stoppingB7

If you can name the row before you write anything, you will not get stuck.