The role of a Data Scientist at Epic Games is crucial in shaping the gaming experience and driving business strategies. As a Data Scientist, you will analyze vast amounts of data generated by players across Epic's games and platforms, such as Fortnite and the Epic Games Store. This position not only influences product development but also enhances user engagement and retention by delivering actionable insights into player behavior, preferences, and trends.
Your work will directly impact how teams across the company make decisions, ranging from game design to marketing strategies. By applying statistical analysis, machine learning, and data visualization techniques, you will uncover patterns that can lead to innovative game features and improved player satisfaction. This role is both challenging and rewarding, offering the opportunity to work on complex datasets while collaborating with cross-functional teams in a dynamic gaming environment.
Take-Home Challenge
reportedThe clock is part of the test. Three to six hours is not enough to do everything the dataset supports, so the submission mostly reveals how you spend a fixed budget against an open question. A reviewer sees which paths you took and, by absence, which you abandoned. Work that runs out of time inside the analysis ships a thin conclusion, while work that cuts scope early protects the last hour for writing. The most reliable way to lose here is to leave the scoping decision implicit, so it reads as something you missed rather than something you chose.
What to demonstrate
- Whether the scope you settled on is presented as a decision with a reason, rather than left for the reader to infer from what is missing
- Whether the depth of the work is consistent with the stated time budget, instead of several half-finished directions left open
- Whether the closing section reads as something written on purpose rather than assembled from whichever cells survived
How to prepare
- Run a timed rehearsal on a public dataset with a hard stop, holding the final sixty minutes for writing no matter where the analysis has got to
- Before opening the data, list the questions it could plausibly answer, pick one, and keep the discarded ones as a short note on what you did not attempt and why
- Commit a one-line finding after each analysis step so the writeup is assembled from recorded results rather than from memory at midnight
Technical Interviews
reportedBefore anything else, this round is a reading test. You are given a small schema and a question phrased in business language, and most of the difficulty sits in the gap between them. Who counts as an active user, does a refunded order still count as an order, is that date column an event time or a load time. Weak answers start typing immediately and compute something precise about the wrong population. Strong ones pin the definition in one sentence, name the column that encodes it, then write the query. On a timed assessment with nobody to tell, write the definition in a comment anyway.
What to demonstrate
- Whether an ambiguous term becomes a specific column and filter before any computation happens
- Whether you read the schema for keys and cardinality rather than only for column names
- Whether the result answers the question at the grain it was asked at, per user or per session or per day
How to prepare
- Take three metrics you already use and write down the exact filter and exact grain behind each, then practise stating one of them in a single sentence out loud
- On a schema you have never seen, spend the first minute writing what one row of each table means and which key it is unique on, then predict which joins can duplicate rows
- Rehearse a version where the definition changes halfway through, and edit the query you have instead of starting over
PracHub editorial advice for the preparation topics above.
Comparing retention or spend across progression stages reached.
Reaching level 20 requires having survived long enough to reach level 20, so grouping by max level attained conditions on the outcome you are trying to explain. Every correlate of playing longer then looks causal, and 'players who join a guild retain better' is the canonical version of this error. The defensible framing fixes a cohort at a common age or a common exposure point and measures forward from there, or models the hazard with progression as a time-varying covariate.
Treating the account as the person, and the calendar week as neutral time.
Reinstalls, multi-platform play and shared accounts split or merge humans relative to player_id, which inflates install counts and deflates retention denominators in ways that correlate with platform and campaign. Meanwhile daily actives spike on release day and decay over the following week, so a week-over-week read aliases the content calendar. Anchor comparisons to time since release or to matched days in the release cycle, and report identity-sensitive metrics with an explicit statement of which identity key was used.
Crediting a treatment for regression to the mean
Selecting a group because it is extreme (lowest-engagement users, accounts having their worst month, the bottom decile of a score) moves that group's expected next-period value back toward the average even under no treatment, by exactly as much as the selecting measure is imperfectly correlated with its own later value. Compare against units that met the same selection rule and went untreated, or use two pre-periods so the bounce-back is visible before the intervention starts. A pre-post number on a group chosen for being extreme measures the selection rule, not the treatment.
Dropping rows with missing values without naming the mechanism
Say whether the values are missing at random, missing by a known process, or missing in a way that depends on the outcome, and handle them accordingly. Deleting incomplete rows silently redefines the population whenever missingness correlates with what you are measuring.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Explain your thought process while implementing a specific algorithm.
Explain your thought process while implementing a specific algorithm.
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Check what information would not exist at prediction time, and exclude it.
- Set a baseline first, so any model has something honest to beat.
Follow-up
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
What metrics would you use to evaluate the performance of a model?
What metrics would you use to evaluate the performance of a model?
Approach
- Set a baseline first, so any model has something honest to beat.
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Say how the offline result would be validated online before it is trusted.
Follow-up
- Where could label leakage enter this setup?
- What would you monitor after launch to know the model is still valid?
Discrete hazard of churn indexed by matches played
Given matches (player_id, started_at) for one install cohort, sessions (player_id, session_start_ts), and a data cutoff timestamp, define churn at match k as no session starting in (t_k, t_k + 14 days], where t_k is the start of that player's k-th match. Build the discrete hazard h(k) and the survival curve S(k) for k = 1 to 50. A player-index enters the risk set at k only if the player has not already churned before k and t_k is at or before cutoff minus 14 days. Return k, risk_set, churned, h and S, and name the two largest hazard spikes.
Approach
- Build the match index yourself: sort matches by (player_id, started_at) and set k = groupby('player_id').cumcount() + 1. Never take a stored index without verifying it is dense per player, because one gap shifts every downstream k for that player.
- Decide churn per (player, k) without a cross join. Sort each player's session timestamps once and use np.searchsorted to ask whether any session falls in the half-open window (t_k, t_k + 14d]. A merge of matches to sessions is quadratic in the busiest players and is where this exercise usually dies.
- Keep observability separate from the event. A player-index is usable at k only when t_k is at or before cutoff minus 14 days; a player whose 30th match was yesterday contributes to k = 1 through 29 and then leaves. This is right-censoring on the match axis, and dropping those players outright instead of truncating them biases the entire curve toward whoever plays fastest.
- Compute h(k) = churned_at_k / risk_set_k and S(k) as the cumulative product of (1 - h(j)) for j up to k. The product form is what makes the censoring handling count; a naive share of the original cohort still alive divides by a denominator containing players who could never have been observed at k.
- Read the spikes against the loop rather than the calendar: a bump at a given k usually maps to a difficulty wall, the end of a tutorial reward track, or the point where a faucet stops paying. Name the k values, then name the query that would confirm each one, rather than asserting a cause.
Worked solution 40 min
- Derive t_k per player by sorting and using cumcount, then truncate each player's indices at the last k satisfying t_k at or before cutoff minus 14 days.
- For each surviving (player, k), use a per-player searchsorted over session timestamps to decide whether a session falls in the 14-day window, and take each player's first churn index as their exit.
- Aggregate risk_set and churned counts by k for k = 1 to 50, then compute h(k) and the cumulative-product S(k).
- Rank h(k) and report the two largest, with the k values and the local shape around them.
Follow-up
- Someone reports that players who reach match 50 retain four times better. Rewrite that as a claim you would be willing to defend, and say what it costs you to do so.
- Your definition retires a player who keeps logging in but stops playing matches. Is that churn? What does including or excluding them do to the curve?
- Add a time-varying covariate for whether the player was in a party at match k. What changes about the estimator, and what can you now claim that you could not before?
Solve a coding challenge that involves data manipulation.
Solve a coding challenge that involves data manipulation.
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- How does the query change if the join becomes one-to-many?
- How would you verify this result without re-running the same query?
Contrast elapsed-hour and calendar-day day-seven retention by cohort
dim_player has player_id, install_ts (UTC), is_test_account. fct_session has player_id, session_start_ts (UTC). For each UTC install date in a 60-day window ending nine days ago, compute cohort size and two D7 retention rates: the elapsed bracket, meaning a session starting in [install_ts + 168h, install_ts + 192h), and the calendar version, meaning a session on date(install_ts) + 7. Return both rates, their difference, and each cohort's trailing seven-cohort average of the elapsed rate. Exclude test accounts.
Approach
- Fix the cohort from dim_player first and end the window nine days before today, because a cohort needs a full 192 hours of elapsed observation plus the tail of its calendar D7 window before either number is complete.
- Compute both flags over a single left join to fct_session with two conditional aggregates, or with two EXISTS subqueries against one cohort CTE. Either way the two rates must share one denominator so the difference is definitional and not a population artefact.
- Write the calendar bracket as a half-open timestamp range, session_start_ts >= date(install_ts) + 7 and < date(install_ts) + 8, rather than casting session_start_ts to a date and comparing. The per-row cast defeats any index on session_start_ts and invites an off-by-one at the boundary.
- Add smoothing with AVG(elapsed_rate) OVER (ORDER BY install_date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), which is the right shape for noisy daily cohorts and makes weekday seasonality legible instead of alarming.
- Explain the systematic gap. For an install at 23:50 UTC the calendar D7 window covers elapsed hours 144.2 through 168.2, nearly a full day earlier than the elapsed bracket's 168 through 192, and the two overlap for only ten minutes. Since return probability in a fixed-width window falls as the window moves later, the calendar rate reads higher, and the gap widens with install hour of day.
- Close by naming which definition the existing dashboards use, and commit to never mixing the two inside one chart.
Worked solution 35 min
- Build the cohort CTE with the test-account filter and install_ts < now() - interval '9 days', then group to get cohort_size per install_date.
- Left join fct_session on player_id and use COUNT(DISTINCT player_id) FILTER for each of the two brackets.
- Divide each by cohort_size, compute the signed difference as calendar minus elapsed, and add the seven-cohort moving average with a window function.
- Re-run the same query split by install hour bucket (0-5, 6-11, 12-17, 18-23) and confirm the difference widens with the bucket.
- Hand-check one late-evening installer: list their sessions and mark which fall into each bracket.
Follow-up
- Cut the difference by install hour of day. What shape do you expect, and what would it mean if the gap came out flat?
- Marketing wants retention reported in each market's local time. What breaks in the cohort assignment, and what would you need from dim_player to do that honestly?
- One cohort installed on the day a large event started. Which of the two numbers is more contaminated, and how do you report that cohort?
If tasked with improving user retention, what data points would you an…
If tasked with improving user retention, what data points would you analyze?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- Fix the population and the time window before naming any metric.
- Restate the decision this analysis has to support, and who acts on the answer.
Follow-up
- Which segment would you cut first, and what would that rule out?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How do you prioritize your projects when working under tight deadlines…
How do you prioritize your projects when working under tight deadlines?
Approach
- Restate the decision this analysis has to support, and who acts on the answer.
- Name one primary metric, then the guardrail that stops it being gamed.
- 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?
- What would you do if the primary metric and the guardrail moved in opposite directions?
Given a set of game-related data, how would you identify trends in pla…
Given a set of game-related data, how would you identify trends in player behavior?
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- State what result would change your recommendation, so the answer is falsifiable.
- 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?
- Which segment would you cut first, and what would that rule out?
Explain how you would approach A/B testing for a new game feature.
Explain how you would approach A/B testing for a new game feature.
Approach
- Name the randomisation unit first; it decides the variance and what the test can detect.
- Decide the analysis before seeing data, including how long it runs and when you look.
- Say whether units interfere with each other, and switch design if they do.
Follow-up
- What would you conclude if the result is positive but the test is underpowered?
- What would you do if you could not randomise at all?
How do you ensure your analysis is reproducible?
How do you ensure your analysis is reproducible?
Approach
- State your assumptions explicitly before working the problem.
- Work from the decision backwards to the evidence you would need.
- Say what you would check first and why it is the highest-information step.
Follow-up
- How would you know your answer was wrong?
- What assumption would you test first?
Build the scorecard for a season pass without overstating young cohorts
A season pass (item_class = 'battle_pass') sells for real money and pays premium currency back across its tiers. Two weeks after launch, a deck reports gross bookings per install for the launch-week cohort against last quarter's cohort and claims a 40% lift. Using fct_iap_transaction (price_usd_gross, platform_fee_usd, price_usd_net, status, refund_ts, purchase_ts), fct_currency_ledger and dim_player, rewrite the scorecard: give the primary metric with its maturity rule, two guardrails, and the reason the reported lift is not evidence.
Approach
- Kill the comparison first. A two-week-old cohort has two weeks of purchases and almost no refund exposure, while last quarter's cohort has a full quarter of both. Gross bookings also ignores platform_fee_usd, which is a percentage haircut that differs by store_channel. The two numbers are not one quantity measured twice, so their ratio means nothing.
- Primary: net revenue per install at a fixed cohort age of 90 days, computed only for install cohorts that have reached that age. Fixing the age fixes refund exposure as well: a reversed purchase leaves status = 'completed' whenever the reversal lands, so a cohort's net revenue keeps falling for weeks after purchase and only equal-age reads compare equal amounts of that decay. The launch cohort has no primary number yet, and saying so plainly is the answer rather than a dodge.
- Give the team something honest to read at two weeks: net revenue per install at 14 days of cohort age, compared only against the 14-day value of earlier cohorts. Fixed-age against fixed-age, never as-of-today against as-of-today.
- Guardrail one: refund and chargeback rate at 60-day maturity on pass purchases, restricted to purchase-date cohorts at least 60 days old. This is precisely the exposure the two-week read is structurally blind to.
- Guardrail two: premium-currency faucet volume with source_system = 'pass_tier', reported next to the premium sink-to-faucet ratio. A pass that pays back most of its price in currency is partly a discount on future purchases, and that cost lands in the economy rather than on the pass's own revenue line.
- Decompose so any movement is attributable: net revenue per install equals paying conversion multiplied by net revenue per payer. State which factor moved before recommending anything, because the two imply opposite follow-ups.
Worked solution 30 min
- Write the net revenue definition once, in full: sum of price_usd_net over rows with purchase_ts inside the cohort window and status = 'completed'. There is no second refund term. status is current state, so a reversed purchase has already left that filter, and subtracting it as well deducts the refund twice. If your warehouse instead freezes status at purchase time, the reversal term keyed on refund_ts is required, so confirm which column carries the current state before writing the SQL.
- Write the maturity rule: fixed cohort age, with younger cohorts excluded rather than extrapolated or annualised.
- Build the fixed-age comparison table, every cohort at 14, 60 and 90 days, so a young cohort shows a blank cell rather than a misleading one.
- Add both guardrails with their windows and their cohort restrictions.
- Write the decomposition identity and the rule for which factor you report first.
Follow-up
- The pass pays back 900 premium currency against a 1,000-currency equivalent price. What does that do to next quarter's currency-pack revenue, and which metric in your scorecard would show it first?
- Last quarter's cohort is now 100 days old. Which of its numbers can you compare against the launch cohort today, and which cannot be compared at all?
Revenue per player-day rose while every channel got worse
Net revenue per active player-day over a trailing 28 days rose from $0.1440 to $0.1656, up 15%, while net revenue per active player-day fell about 4% inside every acquisition_channel. Organic share of player-days went from 60% to 75% as a cross-promotion campaign ended. Using dim_player (player_id, acquisition_channel), fct_session (player_id, session_start_ts) and fct_iap_transaction (player_id, purchase_ts, price_usd_net, status), decompose the rise and state whether monetisation improved.
Approach
- Rebuild the metric from segment parts and confirm the rebuild before decomposing. For each channel and period, compute player-days, net revenue and their ratio, then check the player-day-weighted channel ratios reproduce both reported overall figures. A decomposition on a table that does not rebuild the headline attributes arithmetic error to mix.
- Apply the two-term split with the weighting stated. Mix effect is the sum over channels of (share_after minus share_before) times ratio_before; within-segment effect is the sum over channels of share_after times (ratio_after minus ratio_before). Name the pairing, because the alternative assigns the interaction term to the other side.
- Recognise that the denominator moved for a reason unrelated to monetisation. A cross-promotion campaign ending removes player-days that carried near-zero revenue, so the blended average rises mechanically while nothing about how players monetise improved. Check the absolute player-day counts, not only the shares, to confirm the shift came from the low-monetising channel shrinking rather than the high-monetising one growing.
- Run the guardrails attached to this metric rather than stopping at the decomposition. Compute the share of net revenue contributed by the top 1% of payers, and D28 retention of players who have never completed a purchase. A rise in the first alongside a fall in the second means the within-segment decline is a real deterioration of the free experience, not noise.
- Decompose the within-segment 4% one level further into paying conversion per player-day and net spend per converting player-day, so the recommendation points at a mechanism. These are different problems with different owners.
- State the verdict without hedging: total net revenue and the per-channel ratios are the numbers that answer whether monetisation improved, and both say it did not. The blended metric rose because its denominator shrank where revenue was thinnest.
Follow-up
- Total net revenue in absolute dollars is the obvious cross-check. What does it do here, and why is it not sufficient on its own?
- The cross-promotion channel was unprofitable per player-day. Does ending it make this metric a better or a worse measure of the business?
- What would you put in place so that a denominator change of this size cannot be reported as a monetisation win again?
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.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Design 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.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Power 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.
Practice prompt ↗Practice prompt ↗03Variance 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.
Practice prompt ↗Practice prompt ↗04Validity 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.
Practice prompt ↗Practice prompt ↗Worked solution ↗05When 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.
Practice prompt ↗Practice prompt ↗06The 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.
Practice prompt ↗Practice prompt ↗07Present 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.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Most data work is done by groups, so an interviewer has to work out which piece was yours. An answer that runs on 'we' for several minutes gets interrupted with a question about what you personally did, and by then the answer sounds defensive even when it is true. Mark your own contribution as you go, and name the parts that belonged to someone else instead of leaving them ambiguous. Keep a few specifics back as well, like the name of the metric or who actually objected, so a probe can be answered with something you had not already said.
Describe a time when you had to collaborate with a difficult team memb…
Describe a time when you had to collaborate with a difficult team member.
Approach
- Quantify the outcome, including what you would not claim credit for.
- Pick a story where you drove the decision, not one where you observed it.
- Close with what you would do differently, concretely.
Follow-up
- What did you decide not to do, and why?
- How did you know the outcome was caused by your change?
Defend an unpopular readout on a live-ops event
A two-week live-ops event closed with gross bookings up 18% against the prior week. Your readout says it added no net revenue: summed price_usd_net in fct_iap_transaction over the 28 days spanning the event is flat against a matched window one release cycle earlier, and fct_currency_ledger shows premium-currency sinks falling while faucets from source_system = 'pass_tier' rose. The event owner disputes the readout in a review with their director present. Give the argument you would make in that room, and name the one piece of evidence you would concede.
Approach
- Separate the disputed claim from yours. Gross bookings up 18% is true and you are not contesting it. Restate your finding precisely: net of platform fee and of refunds recognised to date, over a window long enough to contain the pull-forward, the number does not move.
- Present the decomposition rather than the aggregate, because the aggregate is what the room is already arguing about. Split the delta into active player-days, paying conversion, and net spend per converting player-day. If conversion is flat and spend per payer spiked inside the event window then fell below baseline after, that is re-timing, not new demand.
- Evidence the re-timing at player grain: take the player_ids who purchased during the event and chart their purchase timing in the four weeks before and after. A pulled-forward purchase shows as a deficit on the same accounts, not as a smaller cohort.
- Bring the ledger in as the second, independent signal. Premium sinks fell while pass_tier faucets rose, so granted currency was banked rather than spent. Report the sink-to-faucet ratio per currency and the balance percentile curve, and exclude is_reversal rows and cs_grant so a correction cannot masquerade as a faucet.
- State the limit of the design out loud before the owner does. There was no holdout, and a matched window still aliases the release calendar. Say which part of your conclusion is robust to that and which is not.
- Close on a decision and a fix: run the next instance with a region-clustered holdout or a staggered start, so the argument is settled by design rather than by seniority.
Follow-up
- The event owner says the banked currency will be spent next month, so the sink drop is timing too. How would you test that claim rather than argue about it?
- If you could add exactly one instrumentation change before the next event, what would it be and what question does it close?
- What would you have said if the net number had been up 3% with an interval spanning zero?
Allocate one analyst-week across three competing escalated requests
Three requests land in the same week and you have five working days. The economy team wants a sink-to-faucet audit per currency after a faucet change shipped ten days ago. Live-ops wants a readout on an event that ends Friday, because the next event is configured from it. Acquisition wants 90-day net revenue per install by channel for a budget meeting in three weeks, and two of the channels launched six weeks ago. All three owners have escalated. Give your allocation, the reasoning you give each owner, and what you refuse or defer.
Approach
- Sort by decision deadline and by reversibility rather than by escalation volume. The event readout is perishable because the population and the live-ops configuration that produced it stop existing on Friday and the next event's config depends on it. The budget meeting is three weeks out. The economy audit has no external deadline but a compounding cost.
- Kill the part that cannot be done correctly at any effort level, and kill it in a ten-minute conversation rather than four days of work. Net revenue per install at 90 days requires cohorts that have reached 90 days of maturity; channels that launched six weeks ago have not, and extrapolating them produces a number that will slope with cohort age. The honest deliverable is matured channels only, with the immature ones listed as excluded and dated for when they qualify.
- Split the economy request into the decision-relevant core and the rest. One day gets the sink-to-faucet ratio per currency_code for the weeks before and after the faucet change, with reversals, transfers and cs_grant excluded, plus the balance percentile curve. A ratio below 1 sustained means balances are accumulating and premium shortcuts will stop selling, which is worth knowing this week. The full per-source audit can wait.
- Give the event readout the largest block, because it is the one with a hard expiry and a downstream configuration decision. Scope it to a decision memo, not a dashboard.
- Publish the allocation in one place with a one-line reason per item, so any escalation argues with the reasoning rather than with you, and the owners can see each other's deadlines.
- Hold back roughly one day. Something breaks most weeks, and an allocation with no slack fails in a way that damages all three commitments instead of one.
Follow-up
- The acquisition owner says a rough number is better than nothing for a budget meeting. What exactly do you give them?
- How would you decide whether the economy audit is genuinely urgent rather than merely important?
- Two weeks of this pattern in a row. What structural change do you propose, and to whom?
- 01
Describe a time when you had to collaborate with a difficult team member.
- 02
A two-week live-ops event closed with gross bookings up 18% against the prior week. Your readout says it added no net revenue: summed price_usd_net in fct_iap_transaction over the 28 days spanning the event is flat against a matched window one release cycle earlier, and fct_currency_ledger shows premium-currency sinks falling while faucets from source_system = 'pass_tier' rose. The event owner disputes the readout in a review with their director present. Give the argument you would make in that room, and name the one piece of evidence you would concede.
- 03
Three requests land in the same week and you have five working days. The economy team wants a sink-to-faucet audit per currency after a faucet change shipped ten days ago. Live-ops wants a readout on an event that ends Friday, because the next event is configured from it. Acquisition wants 90-day net revenue per install by channel for a budget meeting in three weeks, and two of the channels launched six weeks ago. All three owners have escalated. Give your allocation, the reasoning you give each owner, and what you refuse or defer.
Is this an official Epic Games interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at Epic Games. Rounds and questions reflect what candidates have reported, not a process Epic Games has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the interview process at Epic Games?
The interview process is considered rigorous, focusing on both technical skills and cultural fit. Candidates typically report needing several weeks of preparation to feel adequately ready.
PracHub interview research ↗What differentiates successful candidates?
Successful candidates demonstrate strong technical expertise, effective problem-solving skills, and a genuine passion for gaming. They can clearly communicate their insights and collaborate with diverse teams.
PracHub interview research ↗What is the company culture like at Epic Games?
The culture at Epic Games emphasizes innovation, creativity, and collaboration. The company seeks individuals who are not only skilled but also align with its core values and mission.
PracHub interview research ↗How long does the interview process usually take?
The timeline can vary, often taking several weeks from the initial screen to the final decision, especially around holiday breaks.
PracHub interview research ↗Sources & methodology 3 sources ↗
Official role evidence, timestamped platform data and clearly labeled preparation advice.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
platform · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
platform · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
platform · Accessed 2026-09-22