A Data Scientist at Stackadapt works at the absolute frontier of programmatic advertising, machine learning, and real-time big data processing. Stackadapt operates a state-of-the-art demand-side platform (DSP) that processes hundreds of thousands of ad queries per second, requiring highly optimized predictive models to make bidding decisions in milliseconds. In this role, you are responsible for designing, deploying, and scaling machine learning algorithms that directly impact campaign performance, user targeting, fraud detection, and budget pacing.
The systems you build and refine do not just process static data; they operate in a dynamic, low-latency auction environment where user behavior and market conditions shift continuously. This means your work directly influences the company's core product offerings, client ROI, and overall business growth. You will collaborate closely with data engineers, backend developers, and product managers to translate complex algorithmic concepts into production-ready pipelines.
For those who thrive on solving high-throughput, mathematically rigorous challenges, this position offers an exceptional opportunity. You will work with massive, high-dimensional datasets and apply advanced statistical methods to real-world problems. Succeeding in this role requires a unique combination of deep theoretical knowledge, software engineering discipline, and a strong product-focused mindset.
Initial Screening
reportedMost candidates lose this call inside the first two minutes, during the walkthrough of their own background. The account runs chronologically, sits at the level of tools and titles, and never arrives at a decision anyone could have disagreed with. Anchor on a problem instead of a timeline: what the team could not answer, what you did about it, what happened next. Ninety seconds is enough, and stopping on time leaves room for the half of the call that belongs to you. What you ask about how work gets prioritised signals your level more reliably than the walkthrough does.
What to demonstrate
- Whether your background summary has a shape (problem, decision, consequence) or is a chronological list of tools and employers
- Whether you can account for gaps, short stints and the reason you are looking, unprompted and without hedging
- The substance of the questions you ask back, which an experienced screener reads as a level signal
How to prepare
- Time your opening walkthrough against a clock. If it runs past two minutes, compress the earliest role into a single clause and spend the recovered time on the most recent one
- Write one honest sentence for every gap or short stint visible on your resume and offer it before being asked about it
- Prepare questions about how work arrives and gets prioritised: who writes the request, how often priorities change, and what happens to an analysis after it is delivered
Technical Rounds
reportedA handful of shapes account for most of what gets asked in this format: a ranking or deduplication inside groups, a running or rolling total, a period-over-period comparison, and a cohort tracked forward over time. Recognising the shape quickly is most of the speed here; deriving it from scratch while a clock runs is where the time goes. Know that a window function keeps every row while a GROUP BY collapses them, and know which one the question needs. If the exercise is in Python instead of SQL, the same shapes arrive as groupby with transform, shift and merge, and the same grain mistakes are available.
What to demonstrate
- Whether you reach the right construct without a detour, such as ROW_NUMBER over a partition to deduplicate instead of a self-join against a MAX subquery
- Whether you know what your window frame actually is, since adding ORDER BY inside OVER changes the default frame and silently changes a running total
- Whether the thing runs. A near-miss that throws an error scores below a plainer query that returns the right rows.
How to prepare
- Write each of the four shapes once from memory against a small schema and keep the working version somewhere you will reread it: dedupe with ROW_NUMBER, a running total, a month-over-month change with LAG, and a retention table
- Compute one running total twice on data with tied timestamps, once on the default frame and once with ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, and look at where the two disagree
- If Python is on the table, rebuild the dedupe and the running total with groupby and cumsum, then assert the two implementations return identical rows
Virtual Onsite
reportedWhere a loop ends with a senior leader, that conversation is rarely another skills test. The technical signal already exists by then, so the questions tend to open up: what you would look at first, where a metric you have heard about could mislead, what you would push back on. The decision being made is scope, which in practice means level and how much you would be trusted to own unsupervised. Treating it as a formality is the usual mistake. An open question late in the day is still being scored, and a vague answer reads as someone who has not run anything themselves.
What to demonstrate
- Whether your view of the business has anything specific behind it, given that you are working only from what is public and are expected to say so
- Whether the scope of work you describe owning matches the scope of the role, instead of sitting a level below it
- Whether you can disagree with something concrete and stay useful about it, rather than agreeing with everything said in the room
- Whether your questions are ones only this person could answer, as opposed to ones the recruiter already covered
How to prepare
- Build one view you could defend for two minutes using only public information: what the funnel probably looks like, which metric likely drives decisions, and where that metric could mislead. Being wrong for a stated reason survives this round; having no view does not
- Write down the largest piece of work you have owned from question to decision, who else touched it, and what you decided alone, then check that it reads at the level you are interviewing for
- Prepare one thing you would want changed if you joined and phrase it as a question rather than a verdict, so it opens a conversation instead of closing one
8 candidate reports. Individual accounts describe a particular role and hiring cycle.
Stackadapt Account Executive interview with shifting final rounds
My experience with the recruiter and recruiting manager was frustrating from the start because the logistics never felt stable. I was repeatedly told I'd be meeting one person, only for the meeting to change at the last minute. It became hard to keep track of who the actual hiring manager was, especially after I went through multiple rounds with people who all had the same title. I also received…
Read full experienceStackadapt Account Executive interview: three rounds with clear feedback
The interview process felt unusually smooth and respectful to me. The recruiter communicated throughout, and the company’s values came through in how people treated me. I wasn’t ghosted, and the process was clear. I went through three rounds and spoke with five different people. Those conversations helped me learn about the role and how the team worked. Each one felt honest and grounded rather th…
Read full experienceStackadapt Software Engineer three technical rounds
After a recruiter reached out and invited me to schedule, the process quickly became a sequence of conversations that felt somewhat shuffled compared with what I had been told. I completed an HR screen, then manager and culture-style interviews, followed by three technical rounds. Each technical round combined live coding with a system design prompt. What caught me off guard was that the intervie…
Read full experienceStackadapt Account Executive interview: 10-day project and presentation
The process felt more rigorous than I expected from the outside. After a recruiter screen, I interviewed with a Director about a week later. The conversation focused heavily on scenarios, and I also got deeper industry knowledge questions than I was ready for. The pacing and format changed as the rounds went on. Next was a project and presentation round with a Director and a Manager. I had 10 day…
Read full experienceStackadapt Software Engineer case study with unstable evaluation standards
My process started positively, but the final stage was deeply disappointing and left me uneasy about the evaluation standards. I was asked to complete what was presented as a case-study assignment for an enterprise agent solutions developer role. Although it was part of the interview, the work felt close to a real product and architecture project compressed into a short timeline. The most frustra…
Read full experiencePracHub editorial advice for the preparation topics above.
Reading a recent week's cost per action or return on ad spend before the conversion window has closed.
Spend for a period is final within hours, but conversions attributed to that period keep arriving for as long as the click window allows plus ingestion lag, and offline uploads can land weeks later. The denominator of cost per action is therefore systematically incomplete for recent dates, so recent CPA is biased high and recent ROAS biased low, and a dashboard comparing a fresh week to a matured week will show a regression that does not exist. The correct handling is to freeze a period only after click_window_days plus the observed ingestion lag, and to publish a maturation curve so readers can see how much of a given day's conversions have landed so far.
Randomising users into treatment and control while both arms draw from the same campaign budget.
The arms compete in the same auctions and against the same budget, so treatment winning more impressions directly starves control, and the measured gap includes that cannibalisation rather than only the ad effect. The test looks methodologically clean, the randomisation is genuinely valid, and the lift is still partly manufactured. This is an interference violation, not a randomisation failure, so checking balance on covariates will not catch it. The fixes are to randomise at a unit that contains the budget, such as a geographic market, or to give each arm its own budget and its own pacing, and then be explicit that you are now comparing two separately-budgeted campaigns.
Averaging per-user rates to produce a population rate
Decide which quantity you want: the mean of per-user ratios and the ratio of summed numerator to summed denominator are different estimands, and heavy users dominate one but not the other. For a ratio metric, aggregate numerator and denominator separately and use the delta method for its variance.
Solving silently instead of narrating the reasoning
Say which branch you are taking and why you chose it over the alternative, for example checking the denominator first because it changes what the comparison means. A correct answer that arrives with no visible path scores below a rigorous one that needed a hint.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
Solve a brain teaser involving a grid-based pathfinding probability pr…
Solve a brain teaser involving a grid-based pathfinding probability problem.
Approach
- Say what the estimate is of, and over what population it generalises.
- Sanity-check the answer against a simple bound or a simulated case.
- Write down the assumption the method needs before you use the method.
Follow-up
- What sample size would you need to detect an effect half this size?
- Which assumption here is most likely to be violated in practice?
How do you determine if two random variables are independent, and how …
How do you determine if two random variables are independent, and how does this affect joint probability calculations?
Approach
- Say what the estimate is of, and over what population it generalises.
- Sanity-check the answer against a simple bound or a simulated case.
- Write down the assumption the method needs before you use the method.
Follow-up
- What sample size would you need to detect an effect half this size?
- How would you explain this result to someone who does not know statistics?
Describe Bayes' theorem and walk through a scenario where prior probab…
Describe Bayes' theorem and walk through a scenario where prior probabilities are updated based on new evidence.
Approach
- Translate the result into the decision it informs, in one plain sentence.
- Say what the estimate is of, and over what population it generalises.
- Quantify uncertainty explicitly rather than reporting a point estimate alone.
Follow-up
- Which assumption here is most likely to be violated in practice?
- How would you explain this result to someone who does not know statistics?
Design a real-time click-through rate (CTR) prediction system for a hi…
Design a real-time click-through rate (CTR) prediction system for a high-throughput programmatic bidding platform.
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- 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?
- How would you choose the decision threshold, and who owns that choice?
Explain the time and space complexity of your proposed sorting or sear…
Explain the time and space complexity of your proposed sorting or search algorithm and discuss potential optimizations.
Approach
- Say how the offline result would be validated online before it is trusted.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- Pick an evaluation metric that matches the cost of each error type, not a default.
Follow-up
- What would you monitor after launch to know the model is still valid?
- How would you choose the decision threshold, and who owns that choice?
Check predicted conversion-rate calibration with a reliability table
scored has 4 million rows at bid_request_log grain for one campaign: predicted_cvr, win_flag, and converted, which is observed only where win_flag is true and a conversion landed within 7 days. The win rate is about 2% and the conversion rate among won impressions about 0.4%. Without using a library calibration helper, build a 20-bin equal-frequency reliability table with bin count, mean predicted_cvr, observed rate and an interval around it, then compute count-weighted expected calibration error. Say whether the model is miscalibrated, in which direction, and over which population your answer holds.
Approach
- Restrict to win_flag == True and state the precondition plainly: converted is only defined where the ad served, so the table measures calibration on the won slice. That is the population the advertiser pays for, but it is selected by the bid and the auction, so the result cannot be extended to no-bid or lost opportunities where the prediction is never tested.
- Bin with equal frequency (pd.qcut with duplicates='drop'), not equal width. Prediction distributions in this setting are heavily right-skewed with point masses, so equal-width bins put most of the mass in one bin and leave the tail bins with too few conversions to say anything. Report how many bins survived if edges collapsed.
- Per bin compute n, mean predicted_cvr, observed rate, and a Wilson score interval. At a 0.4% base rate the normal approximation produces negative lower bounds and understates uncertainty in the low bins, so the interval choice is not cosmetic here.
- Compute ECE as the count-weighted mean of |observed - predicted| across bins, and report it next to the base rate: 0.002 of absolute error is small against a 5% base rate and enormous against 0.4%.
- Read the direction from the sign pattern rather than the scalar. Observed below predicted across the top bins is head over-prediction, typically from training on a differently-selected population or from scoring against a conversion window that has not matured; a flat observed rate across rising predictions means the score has little ranking power in this range, which is a different problem from miscalibration.
Worked solution 25 min
- Subset to won rows, record n_won and the observed base rate, and confirm converted has no nulls within that subset.
- bins = pd.qcut(predicted_cvr, 20, labels=False, duplicates='drop'); report the realised bin count.
- groupby(bins).agg(n, pred_mean, obs_rate), then compute Wilson bounds elementwise from n and obs_rate at z = 1.96.
- ece = ((n / n.sum()) * (obs_rate - pred_mean).abs()).sum(); print it alongside the base rate and the ratio of the two.
Follow-up
- The pooled curve looks calibrated but ctv supply is badly off. How do you test for segment-level miscalibration without fishing across dozens of cuts?
- The model retrains daily while conversions take up to 7 days to land. What does that do to the head of the reliability curve, and in which direction?
- How would you turn this diagnostic into a bid correction, and what would you verify before shipping it?
Auction funnel stage counts and stage-to-stage drop-off
bid_request_log holds one row per (auction_id, line_item_id) evaluation, including line items that were considered and did not bid, with columns auction_id, request_ts, line_item_id, response_status (bid, no_bid, timeout, filtered), no_bid_reason and win_flag. ad_impression has impression_id, auction_id, line_item_id, served_ts, is_billable and ivt_status. ad_click has click_id, click_ts, impression_id (nullable), line_item_id (denormalised onto the click row when the click is written), ivt_status and is_billable. Return one row per line_item_id for a given UTC day with: auctions evaluated, auctions bid into, auctions won, impressions served, billable valid impressions, valid clicks, and the rate between each consecutive stage.
Approach
- State the grain of each table out loud before writing a join. bid_request_log is (auction_id, line_item_id); ad_impression is one row per impression; ad_click is one row per click event, carrying its own click_ts and a denormalised line_item_id plus a nullable impression_id, so one impression can produce several click rows and a click can be attributed to a line item without resolving its impression.
- Get the three auction-side stages from a single grouped scan of bid_request_log using COUNT(*) FILTER (WHERE ...). One pass, no self-joins, and the stages are guaranteed consistent with each other.
- Aggregate impressions and clicks in their own CTEs at their own grain, then LEFT JOIN the pre-aggregated results on line_item_id. Joining the raw tables together first multiplies rows at every step and the error compounds down the funnel.
- Decide what a click stage means and say so. COUNT(*) over ad_click counts click events; COUNT(DISTINCT impression_id) counts impressions that received at least one click, and silently drops the clicks whose impression_id is null. They are different numbers and the funnel reads differently under each.
- Say which clock the click stage is bucketed on. Filtering on click_ts places a click in the day it happened, which is not always the day its impression served: a click at 00:04 UTC on an impression from 23:58 the previous night lands in the next bucket, so a single-day CTR is approximate at the boundary. Bucketing clicks on the impression's served_ts instead removes that artefact but costs a join through impression_id and a decision about the null-impression_id clicks, which can then be counted in no bucket at all.
- Compute each rate against the stage immediately above it, with NULLIF on the denominator. The win-rate denominator is bids, not auctions evaluated.
Worked solution 20 min
- Write auctions AS (SELECT line_item_id, COUNT() AS evaluated, COUNT() FILTER (WHERE response_status = 'bid') AS bids, COUNT(*) FILTER (WHERE win_flag) AS wins FROM bid_request_log WHERE request_ts in the day GROUP BY 1).
- Write imp AS (SELECT line_item_id, COUNT() AS served, COUNT() FILTER (WHERE is_billable AND ivt_status = 'valid') AS clean FROM ad_impression WHERE served_ts in the day GROUP BY 1).
- Write clk AS (SELECT line_item_id, COUNT() AS clicks, COUNT() FILTER (WHERE impression_id IS NULL) AS unmatched FROM ad_click WHERE ivt_status = 'valid' AND is_billable AND click_ts in the day GROUP BY 1). This uses the click row's own line_item_id and click_ts, so the stage needs no join to ad_impression; the price of that is the midnight-boundary approximation above, which the unmatched count does not fix.
- LEFT JOIN the three CTEs on line_item_id and compute bids/evaluated, wins/bids, served/wins, clean/served and clicks/clean, each wrapped in NULLIF.
- Print the absolute counts beside the rates so a stage built on 40 rows is visible rather than hidden behind a percentage.
Follow-up
- This line item raised its bid, won more impressions, and its win rate fell. What mix shift produces that, and how do you show it from bid_request_log?
- Group the no-bid rows by no_bid_reason by hour. What shape tells you the budget exhausted early versus the targeting being too narrow all day?
- bid_cpm_usd, pre_shade_bid_cpm_usd and clearing_price_cpm_usd all sit on this table. What does the gap between them mean under first_price versus second_price clearing?
Advertiser spend retention at a three-month horizon by cohort
ad_impression carries line_item_id, served_ts, billed_price_micros_usd and is_billable but no advertiser_id. line_item carries advertiser_id and is SCD type 2: one row per version with valid_from_ts, valid_to_ts and is_current, and exactly one current row per line_item_id. Build monthly cohorts. For each cohort month M, return the distinct advertisers with at least one billable impression in M, the count still billing in month M+3, the count-based retention rate, and a spend-weighted rate using M+3 spend from retained advertisers over cohort-month spend. State which line_item row you join to and why.
Approach
- Resolve advertiser_id through a collapsed mapping, not through the full dimension. SELECT DISTINCT line_item_id, advertiser_id FROM line_item returns one row per line item because advertiser_id does not change across versions. Joining ad_impression to the raw line_item table multiplies every impression by the number of versions that line item has.
- Note the precondition that makes that shortcut legal: it works only because the attribute being read is version-invariant. For daily_budget_usd or bid_value_usd, which do change, you must join on the validity interval instead.
- Build an advertiser-by-month activity table in one pass: GROUP BY advertiser_id and date_trunc('month', served_ts AT TIME ZONE 'UTC'), filtered to is_billable, carrying SUM of spend so both retention variants come from the same aggregate.
- Self-join that table to itself with a LEFT JOIN on advertiser_id AND retained.month = cohort.month + interval '3 months'. The LEFT JOIN keeps cohorts with zero retention in the output instead of making them disappear, which is what an INNER JOIN would do and is indistinguishable from the cohort not existing.
- Say which spend-weighted definition you are reporting, because at least two circulate: M+3 spend from retained advertisers over cohort-month spend from all cohort advertisers (a spend-expansion measure) versus cohort-month spend from retained advertisers over cohort-month spend from all (a dollar-coverage measure).
- Truncate the series at the last cohort month whose M+3 is fully elapsed, otherwise the three most recent cohorts read as zero retention and someone will escalate it.
Follow-up
- Count retention is flat but spend-weighted retention dropped 8 points. What is happening to the book of business?
- An advertiser is dormant in M+3 and spends again in M+4. Is that churn? What does each answer do to the series?
- How would you restate this on rolling 90-day windows instead of calendar months, and which artefact does that remove?
Given a set of constraints, write an optimized dynamic programming sol…
Given a set of constraints, write an optimized dynamic programming solution to find the maximum path sum in a matrix.
Approach
- Name one primary metric, then the guardrail that stops it being gamed.
- Restate the decision this analysis has to support, and who acts on the answer.
- State what result would change your recommendation, so the answer is falsifiable.
Follow-up
- Which segment would you cut first, and what would that rule out?
- How would you detect that the metric is being gamed rather than genuinely improving?
How would you design an A/B test for an advertising campaign where use…
How would you design an A/B test for an advertising campaign where user traffic is highly skewed?
Approach
- Say whether units interfere with each other, and switch design if they do.
- 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.
Follow-up
- How would you handle interference between treated and control units?
- What would you conclude if the result is positive but the test is underpowered?
How would you implement a custom data structure that supports insert, …
How would you implement a custom data structure that supports insert, delete, and get-random operations in O(1) time?
Approach
- Clarify what is being asked and what a complete answer would contain.
- Say what you would check first and why it is the highest-information step.
- State your assumptions explicitly before working the problem.
Follow-up
- What assumption would you test first?
- How would you know your answer was wrong?
Price the trade between ad revenue and viewer retention
A supply-side change raises the number of ad slots per session. Expect eligible revenue per thousand bid requests to rise, and viewer negative feedback per thousand impressions and 28-day viewer retention to fall. The experiment can run four weeks. Deliverable: the primary metric, the guardrail, and a decision rule pre-registered before the readout — including the explicit rate at which you would trade retention for revenue, and how you handle the two quantities maturing at different speeds.
Approach
- Refuse the fake resolution up front. There is no metric definition that makes this trade disappear; the design task is to price it in advance so the decision is not made by whichever number is read first, or by whichever team reads it.
- Set the primary at the level of the trade, not of the impression. Ad load moves both price per opportunity and the number of opportunities, so a per-impression metric hides half the effect. Use revenue per active viewer over the full test horizon, or eligible RPM reported jointly with session volume so the volume term cannot be quietly dropped.
- Convert retention into the primary's units before the test starts. Estimate the value of a retained viewer from historical cohorts — revenue per viewer-month times expected remaining months under the observed churn hazard — so a 0.3-point retention loss becomes a dollar figure directly comparable to the RPM gain. State the assumption explicitly, constant hazard or a fitted survival curve, because the dollar answer is sensitive to which one you used.
- Handle the maturity mismatch honestly. In a four-week test only the earliest cohort has a full 28-day retention window, so retention is both late and underpowered. Pre-register a 14-day proxy validated against 28-day retention on historical cohorts, state its bias direction — it under-detects slow churn, so it is optimistic — and commit to a 28-day confirmation read before any full rollout.
- Write the decision rule with a tripwire. Ship if the dollarised net is positive at the lower bound of the retention confidence interval, not at the point estimate. Hard-stop regardless of revenue if negative feedback per thousand impressions crosses a fixed pre-set threshold, because that metric matures in days and leads the retention loss you cannot yet see.
- Name who owns the exchange rate. A data scientist can compute the frontier and the dollar conversion; choosing the acceptable rate is a business decision, and forcing that choice into writing before the readout is the point of the exercise.
Worked solution 40 min
- Compute historical viewer lifetime value under a stated hazard assumption and convert one retention point into dollars per thousand viewers.
- Run the power calculation for 28-day retention at the available sample and horizon, and write down the minimum detectable effect it actually supports.
- Validate the 14-day proxy against 28-day retention on past cohorts and record the direction and size of its bias.
- Write the dollarised net formula, evaluated at the lower confidence bound of the retention estimate.
- Write the pre-registration: primary, guardrail, proxy and its bias, the negative-feedback tripwire threshold, the ship rule and the confirmation read date.
Follow-up
- Revenue is up 6% and retention is down 0.2 points but not statistically significant. What is your recommendation?
- How would you detect the retention loss concentrating in high-value viewers while the average looks fine?
- If the 14-day proxy and the 28-day metric disagree at the confirmation read, which one governs and why?
One advertiser's conversions doubled the week their SDK shipped
An advertiser's daily conversion_event rows roughly doubled starting 14 August, with no change in their order volume as they report it. That week they added a server_api feed alongside their existing browser_pixel. conversion_event has conversion_id, advertiser_id, conversion_ts, received_ts, conversion_type, order_id, device_id, user_id_hash, click_tracking_id, source, dedup_key and is_duplicate, where is_duplicate is written by our dedup job. Quantify the true conversion count, name the failure precisely, and state what you would tell the account team.
Approach
- Compare row counts against distinct dedup_key counts per advertiser per day. If rows double while distinct keys stay flat, the extra rows are duplicates that the dedup job never collapsed, and the real conversion level never moved.
- Establish why the job failed rather than that it failed: compute the null rate of dedup_key by source, and for non-null keys compare the value format between browser_pixel and server_api on the same order_id. Case, prefixing and whitespace differences are the usual cause and are invisible in a count of non-null keys.
- Use order_id as an independent second key. Distinct order_id per advertiser per day that is flat across 14 August confirms the real outcome count is unchanged and gives you the recovery rule.
- Size the blast radius downstream: duplicated conversions inflate attributed conversions, deflate CPA and inflate ROAS for every line item serving that advertiser, and the attribution_credit rows already written carry the inflation.
- Write the restatement rather than just the diagnosis — which advertiser, which dates, the direction and size of the correction, and whether any optimisation decision was already taken on the inflated numbers.
Follow-up
- The advertiser cannot change their server payload for a quarter. What dedup rule would you run in the meantime, and what does it get wrong?
- How would you detect this class of failure automatically for the other several thousand advertisers?
- If the two sources disagree on conversion_value_usd for the same order, which one wins and why?
Instead of guessing where the week should go, day one measures it under a fixed rubric and allocates the remaining hours in proportion to the gaps. The method is deliberately rigid: the allocation is written down before any studying starts and is not renegotiated when a topic turns out to be unpleasant.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Diagnostic, scored before you study anything
- Sit a 100-minute timed diagnostic in four blocks: 30 minutes of SQL across three prompts, 25 minutes of short-answer statistics, 25 minutes on one modelling or case prompt, and 20 minutes delivering one behavioural story aloud.
- Score each block from 0 to 3 on a fixed rubric where 3 is correct and fluent, 2 is correct but slow or prompted, 1 is partially correct, and 0 is stuck, grading the output rather than how the attempt felt.
- Allocate the hours for days two to five roughly in proportion to 3 minus the score in each block, write the allocation down, and commit to not revising it midweek.
Deliverable: A scored rubric and a fixed hour allocation for the rest of the week.
Practice prompt ↗Practice prompt ↗Practice prompt ↗Worked solution ↗02Largest gap: find the boundary rather than the subject
- Break the weakest area into five named sub-skills (for query work: grain control, window frames, date arithmetic, set logic with NULLs, and reading a query plan) and rate each one, so the rest of the week targets a sub-skill instead of a subject.
- Solve three problems chosen to sit just above where the rating drops off, and for each write the first move you failed to make.
- Re-solve one of them from memory four hours later, on paper, with nothing open.
Deliverable: A five-item sub-skill map with the two blocking sub-skills circled.
Practice prompt ↗Practice prompt ↗Practice prompt ↗03Largest gap: drill the blocking sub-skill
- Do eight short repetitions of the same shape rather than eight different problems, so what you practise is the pattern and not the puzzle.
- Write the rule you now hold in one sentence, then test it against a case built to break it: a ranking function over a column with ties, or a two-sample test on observations that are obviously dependent.
- Have someone else read your one-sentence rule and find the precondition you left out.
Deliverable: One rule statement with its preconditions attached and one counterexample that would have caught the incomplete version.
Practice prompt ↗Practice prompt ↗04Second gap, plus maintenance on your strongest area
- Run the same sub-skill map and boundary protocol on the second-largest gap, compressed into half the day.
- Spend 25 timed minutes on your strongest area to stop it decaying, choosing the hardest problem you can still finish rather than an easy warm-up.
- Compare how the two areas fail: whether you lose time on recall, on setup, or on arithmetic, because the fix differs for each.
Deliverable: A second sub-skill map plus a one-line diagnosis of how each area fails you.
Practice prompt ↗Practice prompt ↗Worked solution ↗05The gap that is not a skill
- Record yourself answering one technical and one behavioural prompt, then count two things in the playback: how many seconds before your first clarifying question, and how many sentences you started without knowing where they ended.
- Rewrite your three most-used stock phrases into shorter versions, and practise saying "I do not know, here is how I would find out" without softening it into a guess.
- Deliver one answer again with a hard 90-second limit to force structure before detail.
Deliverable: Two recordings with a counted improvement in time-to-first-question.
Practice prompt ↗Practice prompt ↗06Retest under day-one conditions
- Sit the same 100-minute diagnostic structure with new prompts of comparable difficulty and score it on the identical rubric.
- Compare block by block, and for any block that did not move, change the method rather than adding hours: a block stuck at 1 usually means the practice was too varied, not too short.
- Write which single block you would still lose the offer on.
Deliverable: A second scored rubric placed next to the first, with one named remaining risk.
Practice prompt ↗Practice prompt ↗07Full loop under interview conditions
- Run a 60-minute mock covering the two blocks that moved least, with an interviewer instructed to interrupt and change direction.
- Write your recovery script for the moment you go blank: restate the question, state your assumption, name the first thing you would check.
- Reduce the week to the rule statements you wrote, each with its preconditions attached, then say every one of them out loud without reading it and cut any you cannot state in a single sentence, since a rule you have to reconstruct mid-answer will not survive being interrupted.
Deliverable: A one-page card holding the recovery script and only the rules you could state from memory.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Data people depend on systems owned by other teams, and much of the job is negotiating for instrumentation, access, or a fix to a broken pipeline. Prepare an example of getting something changed upstream that you did not control. Describe what you asked for, what you traded, and how you worked while you waited.
How do you handle extreme class imbalance when training models for ad …
How do you handle extreme class imbalance when training models for ad fraud detection?
Approach
- Close with what you would do differently, concretely.
- Pick a story where you drove the decision, not one where you observed it.
- Name the disagreement or constraint, and how you resolved it with evidence.
Follow-up
- How did you know the outcome was caused by your change?
- What would you do differently if you ran that project again?
Explaining an incrementality interval to a non-technical budget owner
A 20-market geo holdout has closed. Incremental return on ad spend is estimated at 1.4 with a 90% interval of 0.6 to 2.2. The same account's last-click attributed ROAS is 4.1. A vice president with no statistics background has ten minutes and must decide whether to renew a $3M annual budget. Deliverable: the explanation you give verbally plus one slide. You may not use the words confidence interval, p-value, or significance, and you must give a recommendation rather than only a range.
Approach
- The interviewer is probing whether you can carry uncertainty into a decision instead of either hiding it or hiding behind it, so convert the interval into money at the real budget first: $3M at 0.6 to 2.2 is $1.8M to $6.6M of incremental revenue, with $4.2M as the central estimate.
- Get the break-even ROAS from the advertiser's gross margin and mark where it falls inside the range. That single number turns a statistical interval into two decision regions, and it is the only quantity the executive needs to reason about.
- Explain the 4.1 without calling it wrong: it counts every conversion that followed an ad, including the ones that would have happened anyway, while the test counts only the ones that would not have. Both are computed correctly and they answer different questions.
- State what would narrow the range and what it costs, in the same units: roughly four times the markets or four times the flight length to halve the width, against the cost of running longer at current spend.
- Pre-commit to the action at each end of the range so the recommendation is falsifiable: what you do if the true value is near 0.6, and what you do if it is near 2.2.
Follow-up
- The vice president asks whether it is working, yes or no. What is your one-sentence answer?
- Break-even is 1.0 and the range is 0.6 to 2.2. Do you renew at full budget, and what would you change about the flight?
Scoping a one-line request that attribution is wrong
A sales lead forwards a one-line request: 'attribution is wrong for this advertiser, fix it.' You have read access to conversion_event, attribution_credit and ad_click for the account, and thirty minutes with the account manager. You may not contact the advertiser this week. Deliverable: a one-page scope naming the single question you will answer, the questions you are explicitly not answering, the data you need, and the decision the answer changes. Bring the three clarifying questions you would ask the account manager first.
Approach
- The interviewer is probing whether you convert a complaint into a comparison before you start work, so begin by writing the complaint as 'number A versus number B' and leave B blank until the account manager names it: attributed conversions against the advertiser's own order table, attributed CPA against last month, or our report against a second vendor's. Each has a different investigation.
- Run the two cheap arithmetic checks that resolve a large share of these before any modelling: confirm SUM(credit_fraction) per conversion_id equals 1.0 within one attribution_model and model_version, and measure the duplication rate by counting dedup_key values that appear with more than one distinct source in conversion_event.
- Measure identity coverage for the account: share of conversion_event rows carrying a non-null click_tracking_id and share carrying device_id. A low match rate means the channel is under-credited, which is the opposite complaint and needs the opposite fix.
- Decide the scope from what the answer will change. If the decision is budget reallocation, the honest scope is an incrementality read, not an attribution repair. If the decision is an invoice dispute, the scope is a reconciliation against the advertiser's order count.
- Write the page with an explicit out-of-scope list: model choice, window changes and anything requiring advertiser data you cannot get this week, each with the condition that would bring it back in scope.
Follow-up
- The account manager says the advertiser just wants the numbers to match. What do you tell them is actually achievable, and why is exact agreement not one of the options?
- How does your scope change if the discrepancy is 4% rather than 40%?
- 01
How do you handle extreme class imbalance when training models for ad fraud detection?
- 02
A 20-market geo holdout has closed. Incremental return on ad spend is estimated at 1.4 with a 90% interval of 0.6 to 2.2. The same account's last-click attributed ROAS is 4.1. A vice president with no statistics background has ten minutes and must decide whether to renew a $3M annual budget. Deliverable: the explanation you give verbally plus one slide. You may not use the words confidence interval, p-value, or significance, and you must give a recommendation rather than only a range.
- 03
A sales lead forwards a one-line request: 'attribution is wrong for this advertiser, fix it.' You have read access to conversion_event, attribution_credit and ad_click for the account, and thirty minutes with the account manager. You may not contact the advertiser this week. Deliverable: a one-page scope naming the single question you will answer, the questions you are explicitly not answering, the data you need, and the decision the answer changes. Bring the three clarifying questions you would ask the account manager first.
Is this an official StackAdapt interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at StackAdapt. Rounds and questions reflect what candidates have reported, not a process StackAdapt has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult is the Stackadapt Data Scientist interview process?
The process is generally rated as difficult. It is highly academic and rigorous, with a heavy emphasis on foundational mathematics, probability, and complex algorithmic coding. Candidates are expected to exhibit high precision and fluency across all technical rounds.
PracHub interview research ↗What is the most common reason candidates fail the technical rounds?
Many candidates struggle with the probability theory and brain teaser questions, or fail to write highly optimized code under time constraints. Additionally, failing to clearly articulate your thought process during live coding can lead to a negative evaluation, even if your final code is correct.
PracHub interview research ↗How long does the entire interview process take from start to finish?
The process typically takes between 3 to 6 weeks, depending on candidate availability and scheduling. It is a highly structured process consisting of multiple rounds, including initial screens, technical homework or assessments, and a multi-stage virtual onsite.
PracHub interview research ↗Do I need prior experience in AdTech to be hired as a Data Scientist at Stackadapt?
While prior AdTech or programmatic advertising experience is a strong asset, it is not a strict requirement. Stackadapt values strong fundamental problem-solving, mathematical rigor, and engineering discipline, and is willing to onboard talented scientists who can adapt to the domain.
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