Interview guides · Aganitha Cognitive Solutions
Aganitha Cognitive Solutions Data Scientist Interview Questions & Guide 2026
Aganitha Cognitive Solutions Data Scientist interview guide: reported rounds, practice questions with worked solutions and a 7-day prep plan.
The 60-second brief
A Data Scientist at Aganitha Cognitive Solutions plays a pivotal role in translating complex data into actionable intelligence. You will be tasked with building robust models, architecting data-driven solutions, and driving product innovation within a fast-paced environment. This role is highly impactful, as your work directly influences the technical strategy and product outcomes for the company’s diverse portfolio.
SQL is seldom the hardest round and is often the one that eliminates people. The working bar is usually window functions, correct deduplication, and joins that do not silently fan out rows, rather than obscure syntax.
Focus areas
- Segment margin by pricing model before comparing
- Separate bookings, recognised revenue and collected cash
- Compute utilisation against a defended availability denominator
Overview
Success in this position requires a blend of rigorous analytical thinking and the ability to articulate technical concepts to non-technical stakeholders. You will work across the full lifecycle of data projects, from initial data exploration and pipeline design to model deployment and performance monitoring. Because Aganitha Cognitive Solutions values both technical depth and a "zeal to learn," the role is ideal for those who thrive when solving complex, ambiguous problems that require both machine learning expertise and a strong product-sense.
The Aganitha Cognitive Solutions interview process
Aganitha Cognitive Solutions candidates report 6 rounds · ≈ 4-6 weeks. The stages below are what candidates describe, not a published process.
Initial Screening
Whoever runs this call is usually not a practitioner. They take notes, and a hiring manager skims those notes later, so the real question is whether your work survives being written down by someone outside the field. Test every project sentence against that: could a non-specialist repeat it correctly without knowing what a propensity score is? Carry a plain-language version of each project and one reason you want this particular role that you could not copy onto another application. Vagueness at this stage reads as inexperience, even when the underlying work was genuinely deep.
What to demonstrate
- Whether a non-specialist can restate your projects accurately, since their paraphrase is what reaches the hiring manager
- Whether your reason for wanting the role points at the work itself rather than the company's reputation
- Whether your language signals the level being screened for: what you decided yourself versus what you were handed
How to prepare
- Write a two-sentence, jargon-free version of each major project: the question nobody could answer, and the decision your work changed. Read it to someone outside data and have them repeat it back
- Point your 'why this role' answer at something concrete in the job description or the product surface you would be working on, and keep it to two sentences
- Have two questions ready about measurement: which metric the team is held to, and who acts on an analysis once it lands
Technical Assessments
This round decides whether someone can hand you a schema and a question and trust the number that comes back. Correctness under a clock is the bar, not clever syntax. The habit that separates strong from weak answers is checking the grain: after every join, know how many rows you expect and whether the count moved. Most wrong answers in this format are not wrong logic, they are a fan-out from a key that turned out not to be unique, or a filter applied before an aggregate when it belonged after. Say what you expect before you run it.
What to demonstrate
- Whether your row counts survive each join, and whether you notice on your own when they do not
- Deliberate handling of rows that fail to match, including whether the question needs an inner join or a left join with the non-matches kept and counted
- Whether NULLs are treated on purpose, given that a NULL compares equal to nothing and that COUNT of a column skips it
- Reaching a defensible answer inside the window instead of a refined one after it
How to prepare
- Take a two-table schema, write a join that fans out on purpose, then fix it by collapsing the many-side to one row per key before joining. Repeat until the fix is reflex rather than recall.
- Write a funnel as one query and print the distinct user count at each stage, then confirm each stage is a subset of the one above it rather than assuming it
- Do a few timed runs in a plain text box with no autocomplete and no formatter, since assessment editors often have neither
Coding Abilities Test
Much of what gets scored here happens out loud while you type. Nobody can see your reasoning inside a half-written query, so five silent minutes read as being stuck even when they are not. State the plan in plain language first: which tables, what grain you are aggregating to, and the one filter that defines the population. Then write it. The narration doubles as insurance, because a wrong plan gets caught early and cheaply while a wrong query gets caught at the end with no time left to redo it. A timed statistics section, where one exists, is a separate test with its own clock.
What to demonstrate
- Whether the query you write matches the plan you just described
- What you do with a hint, meaning whether the correction gets absorbed or the first approach gets defended
- Whether you can debug your own wrong output by reading the result set and naming which part of the query produced the anomaly
How to prepare
- Solve three problems while screen-sharing into a recording, then watch it back and mark every stretch longer than thirty seconds where you said nothing
- Practise compressing the plan into one sentence before typing, then check afterwards whether the finished query actually matched it
- Time yourself on statistics questions that carry a business reading, such as what a confidence interval does and does not claim, rather than re-reading notes without a clock
Statistical Knowledge Evaluation
Before 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
Machine Learning Challenges
An added round often puts you in front of someone outside the core hiring team: a partner engineer, a product owner, a domain expert, sometimes a more senior manager. The question they are really asking is not whether you can do the work but whether they would trust a number that came from you. That changes what a good answer looks like. Lead with what the decision cost and what it changed, keep the method available but not central, and be plain about the limits of your evidence. Overstating a result is the fastest way to lose this round.
What to demonstrate
- Whether you can explain a technical choice to someone who will never read your code, without either flattening it into nothing or hiding inside jargon
- Honesty about evidence strength: what the analysis establishes, what it only suggests, and what it cannot say at all
- How you take disagreement, specifically whether you update on a good objection, hold your position with reasons, or fold on contact
How to prepare
- Write the two-sentence version of your most technical project for a non-specialist, then check that neither sentence needs a method name to make sense.
- For one result you are proud of, write the strongest objection someone could raise and a response that concedes the part of it that is correct.
- Prepare one decision that turned out to be wrong: how you found out, what it cost, and what you changed afterwards. A senior cross-functional interviewer asks for this more often than a technical one does.
Discussion of Past Projects
Because the format is not fixed, prepare the reasoning rather than the ritual. Nearly every version of this round draws on the same underlying material: a design you can defend, a metric you can define exactly, an analysis whose assumptions you can state out loud. Only the wrapper changes, whether that is a take-home, a live case, a deep dive on past work, or a rough estimate on a whiteboard. Answers rehearsed to fit one shape stall the moment the shape differs. Practise naming the assumption behind a number, then saying how much the conclusion moves if that assumption is wrong.
What to demonstrate
- Whether your justification for a method survives the question 'why not the simpler thing', including when the simpler thing would have worked
- Precision under pressure: what exactly counts as an active user, a conversion or a success, over what window, with what exclusions
- Whether you carry an argument through to a recommendation instead of stopping at a list of tradeoffs
How to prepare
- For each project you plan to mention, write the metric definition in one sentence: numerator, denominator, time window, exclusions. Say it out loud once, because vagueness shows up in speech before it shows up on paper.
- Rehearse the same project at three lengths: two minutes, ten minutes, and a deep dive on one technical decision. Cutting live is harder than it sounds.
- For your headline result, write down what would have had to be true for it to be wrong, and how you ruled that out.
Where candidates lose points
Using calendar hours, or a current rate card, as the denominator
Available hours is not days x 8. It must subtract approved leave and region-specific public holidays, scale by fte_fraction, and prorate for hire_date and termination_date inside the period; skipping this produces cross-region utilisation gaps that are purely holiday-calendar artifacts and a fake dip every time a cohort of new hires starts. Equally, bill and cost rates change over time, so joining today's dim_consultant row to last year's hours restates history. Use the rate snapshotted on the time entry, or join dim_consultant on work_date BETWEEN effective_from AND COALESCE(effective_to, 'infinity').
Treating accounts as independent observations
Revenue is concentrated: a small number of client_ids typically carries a large share of fees, and engagements within one account share a partner, a rate card and a delivery team. Ordinary standard errors computed over engagements therefore understate uncertainty badly. Cluster at client_id, and with fewer than roughly 40 clusters use a wild cluster bootstrap or a CR2 correction, because cluster-robust standard errors are downward-biased in that regime and will manufacture significance that a replication will not reproduce.
Treating a non-significant result as proof of no effect
Say whether the confidence interval excludes the effect sizes you would have cared about. If it does not, the honest reading is that the test was underpowered, so report the minimum detectable effect the design could have found and what sample size would resolve it.
Never asking what decision the analysis will inform
Open with who makes the decision, what the options are, and by when. The answer determines the precision you need, the segments worth cutting, and whether an observational read suffices or an experiment is required.
Questions & practice
How do you account for seasonality or external noise in your testing framework?
Medium · statistics and probability
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?
What is your approach to assessing time complexity in your algorithmic solutions?
Medium · machine learning and modelling
Approach
- 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.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- Where could label leakage enter this setup?
Simulate the chance a capped engagement crosses its cap
Medium · monte carlo · bootstrap resampling · pricing caps
A capped time-and-materials engagement has not_to_exceed_usd = 400000, has billed 250000 to date, and bills at a blended bill_rate_usd of 250. Fourteen delivery weeks remain before planned_end_date. You have that engagement's last twenty weekly totals of approved billable hours as a pandas Series. Estimate the probability that cumulative billable value crosses the cap before the planned end, and the expected unbillable hours if it does. Resample the observed weeks; do not assume normality. Report a Monte Carlo standard error and justify the number of draws.
Approach
- Reduce the deterministic part first: the cap still affords (400000 - 250000) / 250 = 600 hours, so the whole question is the distribution of the sum of fourteen future weekly hour totals against a fixed threshold of 600.
- Before resampling, check the twenty observed weeks for trend and lag-1 autocorrelation. Independent resampling is defensible only if the weeks are exchangeable; on a ramping engagement use a moving-block bootstrap or model the ramp, because i.i.d. draws understate the upper tail, which is exactly the tail the question is about.
- Draw one (B, 14) array with np.random.default_rng().choice(observed, size=(B,14), replace=True), sum along axis 1, and compute p_hat = mean(total > 600) in one vectorised pass.
- Report expected unbillable hours two ways: unconditional mean(maximum(total - 600, 0)) for expected loss, and the mean conditional on a breach for how bad a breach is when it happens. The second is the number that drives a change-order conversation.
- Attach se(p_hat) = sqrt(p_hat(1 - p_hat)/B) and pick B from the precision you need: plus or minus one point at 95% confidence needs about 1.96^2 * 0.25 / 0.01^2, roughly 9600 draws at the worst case p = 0.5.
- State the assumptions that would flip the answer: constant blended rate, no scope change, no holiday weeks inside the fourteen, and a cap that applies to fees rather than to fees plus expenses.
Worked solution (30 min)
- affordable_hours = (400000 - 250000) / 250 = 600.0; print it, because a wrong threshold makes every later number wrong in a way no simulation reveals.
- Plot or regress the twenty weekly totals against week index and compute lag-1 autocorrelation; record the result as the stated justification for i.i.d. versus block resampling.
- rng = np.random.default_rng(7); draws = rng.choice(weekly.values, size=(10000, 14), replace=True); totals = draws.sum(axis=1).
- p_hat = (totals > 600).mean(); se = np.sqrt(p_hat * (1 - p_hat) / 10000); overrun = np.maximum(totals - 600, 0); report overrun.mean() and overrun[totals > 600].mean().
- Re-run with a second seed and confirm p_hat moves by less than two standard errors before reporting.
Expected result: A probability with its Monte Carlo standard error (about 0.005 at B = 10000 near p = 0.5), expected unbillable hours both unconditionally and conditional on a breach, and an explicit statement of the exchangeability assumption behind the resampling.
Verify it yourself
- Two different seeds agree to within roughly two Monte Carlo standard errors.
- If every observed week exceeds 600/14 = 42.86 hours, p_hat must be exactly 1.0; if every week is below it, p_hat must be 0.0.
- Unconditional expected overrun is zero whenever p_hat is zero, and is always at most the conditional value times p_hat plus rounding.
- Raising the cap by 25000 moves the threshold by exactly 100 hours, and p_hat must fall.
Follow-up
- Hours past the cap still cost money. Restate the result as expected gross margin rather than a probability.
- Two weeks of time are entered but not yet approved. How do you fold them in without double-counting?
- A change order that raises the cap is judged 60% likely. How does that change the number you present, and to whom?
Can you explain when you would use a SQL window function versus a standard group-by operation?
Medium · sql and data manipulation
Approach
- State the window function and its partition and ordering out loud before writing it.
- 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.
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?
Deduplicate to the latest issued invoice line per engagement
Easy · window functions · dedup · determinism
fct_invoice_line holds invoice_line_id, invoice_id, engagement_id, line_type, period_end_date, amount_usd, issued_at and status; draft lines have issued_at NULL. Return exactly one row per engagement_id, its most recently issued line, with invoice_line_id, line_type, amount_usd and issued_at. Two lines on the same engagement can share an issued_at value to the second, so the result must be identical on every run against unchanged data. Write it with a window function, then say in one sentence when DISTINCT ON would be the better choice.
Approach
- Filter to issued lines (issued_at IS NOT NULL, status <> 'draft') before ranking. Ranking first and filtering afterwards can leave an engagement whose top-ranked row was a draft with no row at all in the output.
- Rank with ROW_NUMBER() OVER (PARTITION BY engagement_id ORDER BY issued_at DESC, invoice_line_id DESC). The surrogate key as the final ORDER BY term is what makes ties resolve the same way on every execution; without it the planner is free to return either tied row.
- Wrap the ranked query in a CTE or subquery and filter rn = 1, since a window function cannot appear in the WHERE clause of the query that computes it.
- Name why RANK() is wrong here: on tied issued_at it assigns 1 to both rows, so the result carries two rows for one engagement and any downstream SUM double counts.
- Compare against DISTINCT ON (engagement_id) ... ORDER BY engagement_id, issued_at DESC, invoice_line_id DESC: same answer, one sort, usually cheaper, but the window form generalises the moment you also want rn <= 3 or a second ranking in the same pass.
Worked solution (15 min)
- Count distinct engagement_id over the filtered (issued, non-draft) line set. This is your target row count.
- Write the ROW_NUMBER CTE with both ORDER BY terms and select rn = 1.
- Assert the contract with GROUP BY engagement_id HAVING COUNT(*) > 1 over the result; it must return nothing.
- Deliberately construct or find an engagement with two lines sharing issued_at and confirm exactly one survives.
- Rewrite with DISTINCT ON and diff the two result sets row by row.
Expected result: One row per engagement that has at least one non-draft issued line. Row count equals COUNT(DISTINCT engagement_id) over that filtered set. Engagements holding only draft lines are absent, which is correct here; listing them is an anti-join, not a dedup.
Verify it yourself
- Result row count equals COUNT(DISTINCT engagement_id) on the filtered input.
- GROUP BY engagement_id HAVING COUNT(*) > 1 over the result returns zero rows.
- Two consecutive runs produce byte-identical output when ordered by engagement_id.
- The DISTINCT ON rewrite returns the same invoice_line_id for every engagement.
Follow-up
- Now return the latest line per engagement per line_type. What changes in the PARTITION BY, and what does that do to the row count?
- Return the latest and second-latest line together. Which of the two constructs survives that requirement?
- issued_at is TIMESTAMPTZ and finance reports on a single local calendar. Where can 'latest' flip between the two conventions?
How do you balance trade-offs between short-term user engagement and long-term product health?
Medium · product sense and metrics
Approach
- Fix the population and the time window before naming any metric.
- Name one primary metric, then the guardrail that stops it being gamed.
- Decompose the metric into the rates that drive it, and say which one you would check first.
Follow-up
- How would you detect that the metric is being gamed rather than genuinely improving?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How would you design a metric to measure the success of a new feature?
Medium · product sense and metrics
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- 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
- How would you detect that the metric is being gamed rather than genuinely improving?
- What would you do if the primary metric and the guardrail moved in opposite directions?
How do you optimize complex queries for large datasets?
Medium · product sense and metrics
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
- 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?
If you notice a sudden drop in a key product metric, what steps would you take to diagnose the root cause?
Medium · product sense and metrics
Approach
- State what result would change your recommendation, so the answer is falsifiable.
- Name one primary metric, then the guardrail that stops it being gamed.
- Decompose the metric into the rates that drive it, and say which one you would check first.
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 determine the required sample size for an A/B test to ensure statistical significance?
Medium · a/b testing and experimentation
Approach
- Name the randomisation unit first; it decides the variance and what the test can detect.
- Say whether units interfere with each other, and switch design if they do.
- Name the guardrails that would stop a launch even on a positive primary result.
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?
What are the most common pitfalls you have encountered when designing and interpreting A/B tests?
Medium · a/b testing and experimentation
Approach
- Say whether units interfere with each other, and switch design if they do.
- Name the guardrails that would stop a launch even on a positive primary result.
- State the primary metric and the minimum effect worth shipping, then size the test.
Follow-up
- What would you conclude if the result is positive but the test is underpowered?
- How would you handle interference between treated and control units?
Choose a randomisation unit when consultants are a shared pool
Medium · interference · randomisation unit · switchback · sutva
A staffing optimiser proposes consultant allocations to engagements. The proposal on the table is to randomise at the engagement: half of new engagements get optimiser-suggested staffing, half go through the current manual process. The claimed benefit is lower time to first billable hour, measured from fct_engagement.start_date to the earliest fct_time_entry work_date with is_billable = TRUE. Every engagement in a practice area draws from the same capacity-constrained consultant pool. Explain what the engagement-level estimate would actually measure, propose a design that measures what leadership wants, and state the price your design pays.
Approach
- Name the violation. SUTVA requires one engagement's outcome to be unaffected by another's assignment, and a fixed consultant pool makes that false by construction: a consultant the optimiser frees is staffed onto a control engagement, so treatment improves and control degrades from the same act.
- Say what the biased estimate is. The engagement-level contrast measures displacement, treatment against a control that treatment has actively worsened, so it overstates the firm-level effect. In the limiting case where the optimiser only reorders a fixed queue of consultant-weeks, the firm-level effect is zero while the engagement-level contrast is large and significant.
- Move the randomisation unit up to the level that contains the contention, the staffing pool, which here is practice_area crossed with home_region. Units then share no consultants and the interference is internalised. The price is that five practice areas by four regions yields at most 20 clusters, which is small-cluster inference territory.
- Or run a switchback inside each pool: randomise each weekly staffing cycle to optimiser or manual so every pool is its own control, turning 20 clusters into 20 pools times many cycles. The price is carryover, since allocations made in a treated week constrain availability in the following control week, so you discard a burn-in window at each switch and you cannot measure any effect whose horizon exceeds the switch interval.
- Analyse at the level of randomisation: pool-week means, pool and calendar-week fixed effects, standard errors clustered at pool, and a wild cluster bootstrap rather than the plain cluster-robust sandwich at 20 clusters.
Worked solution (30 min)
- Write potential outcomes against the full assignment vector, Y_i(z) rather than Y_i(z_i), and show the dependence on z_j for any j sharing the pool.
- Work the fixed-pool case: if the optimiser reorders a conserved queue of consultant-weeks, the sum of days-to-staff across engagements is unchanged, so the pool-level effect is zero while treated engagements are faster by exactly the amount control engagements are slower.
- Enumerate candidate units, engagement, account, partner, pool, pool-week, and for each state whether it contains the contention and how many independent units it yields.
- Select a pool-week switchback with the cycle length set to the staffing-meeting cadence, a one-week burn-in discarded at every switch, and a target of at least 26 usable pool-weeks per pool.
- Pre-specify the analysis: pool-week mean days to first billable hour on a treatment indicator with pool and calendar-week fixed effects, clustered at pool, wild bootstrap with Webb six-point weights.
Expected result: A design memo that rejects engagement-level randomisation on interference grounds, adopts a pool-week switchback over practice_area by home_region pools with a stated burn-in and calendar-week fixed effects, and states plainly that the design cannot detect effects whose horizon exceeds the switch interval.
Verify it yourself
- On simulated reordering-only data, where the true pool-level effect is zero, the proposed estimator must return an effect near zero; a large estimate means the unit is still wrong.
- Treated and control pool-weeks should have similar counts of engagement starts and similar practice-area mix, since randomisation runs over time rather than over units.
- The independent-unit count behind the standard error must be the number of pools, not the number of pool-weeks, unless within-pool serial correlation has been modelled explicitly.
Follow-up
- How long a burn-in would you discard after each switch, and how would you estimate that length from data rather than assert it?
- Time to first billable hour is right-censored for engagements not yet staffed at the analysis date. How does that interact with a switchback?
- If the optimiser's benefit is pure reallocation within a fixed pool, what outcome would show a genuine firm-level gain?
One region's delivery cost fell eighteen percent for two weeks
Medium · pipeline failure · data completeness · freshness checks
Cost per delivered engagement-week fell about 18% in one region for two consecutive weeks while fees were flat, so reported margin jumped. Source is fct_time_entry (consultant_id, engagement_id, work_date, entered_at, hours, cost_rate_usd, charge_code, status), loaded nightly from a regional timesheet system, joined to dim_consultant for home_region. Determine whether delivery genuinely got cheaper or rows are missing, name the evidence that distinguishes the two, and specify the automated check you would add.
Approach
- Check row counts and coverage before any ratio: entries per workday and distinct consultant_id with at least one entry per workday, for the affected region against its own trailing four weeks and against other regions in the same weeks.
- Use the shape of the loss to separate causes. A load failure removes whole days or whole consultants, so distinct-consultant coverage collapses while hours per reporting consultant stays normal. A real change lowers hours per consultant with coverage intact.
- Split the cost identity: cost = hours x cost_rate_usd. Compute mean cost_rate_usd by level. If rates went NULL, zero or defaulted to a single value, the fault is in the dimension join, not the source extract.
- Look for the loader's fingerprint: max(entered_at) per region per day, gaps aligned to a calendar boundary, and whether the missing dates fall on a particular day of week, which points at a scheduler that skipped a run rather than at delivery behaviour.
- Confirm by waiting one cycle: a failed load backfills on re-run and the anomaly disappears from the restated weeks; a genuine change persists. Do not publish until that test has run.
- Automate the check that would have caught it: per-region, per-workday assertions on row count and on distinct billable consultants covered, with thresholds derived from trailing medians rather than fixed constants, plus a freshness assertion on max(entered_at).
Follow-up
- The same load also feeds utilisation. Why did utilisation not show an equally obvious break?
- How do you choose the alert threshold so it survives holidays and genuine low-activity weeks?
- If the rows never arrive, what do you do with the two weeks already reported to leadership?
Suggested practice checklist
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.
Day 1 — Diagnostic, 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.
Day 2 — Largest 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.
Day 3 — Largest 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.
Day 4 — Second 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.
Day 5 — The 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.
Day 6 — Retest 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.
Day 7 — Full 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.
Being wrong in public
A number you shipped turned out to be wrong, and someone had already acted on it. That is one of the most useful stories a data person can carry. What is being scored is how fast you noticed, who you told first, and what you changed in the process so the same class of error could not repeat quietly.
Describe a time you had to explain a complex technical finding to a non-technical stakeholder.
Medium · behavioural and stakeholder questions
Approach
- Close with what you would do differently, concretely.
- Name the disagreement or constraint, and how you resolved it with evidence.
- Quantify the outcome, including what you would not claim credit for.
Follow-up
- How did you know the outcome was caused by your change?
- What did you decide not to do, and why?
Defending a fixed-fee overrun finding against the selling partner
Easy · metric definition · pricing model mix · stakeholder pushback
Over the trailing four quarters, fixed_fee engagements in one practice area show a median scope overrun ratio of 1.34, computed as approved client_delivery hours in fct_time_entry divided by fct_engagement.contracted_hours, and inception-to-date gross margin nine points below the time_and_materials book. The partner who sold most of that work says the denominator is wrong because change orders were signed, and each change order is a separate row linked by prior_engagement_id. You have ten minutes with the practice lead. Present and defend the finding.
Approach
- Say out loud what is being probed: whether a specific methodological objection makes you recompute or makes you repeat yourself. Restate the metric as numerator, denominator and window before defending anything.
- Test the objection empirically instead of debating it. Rebuild the denominator by walking the prior_engagement_id chain with a recursive CTE, summing contracted_hours across the original SOW and every extension, and summing approved delivery hours over the same chain.
- Report both numbers and say what each one answers: the original-SOW denominator answers whether the team held the scope that was signed, the chained denominator answers whether the firm estimated the total work correctly. Neither is a trick; they are different questions.
- Keep the margin claim separate from the overrun claim, and keep it stratified. Fixed_fee margin falls with hours worked while uncapped time_and_materials margin does not, so the nine-point gap is only meaningful within pricing_model, and a shift in the fixed_fee share of fees is reported alongside it.
- Close with the decision and a falsifier: if the chained overrun is near 1.0, the problem is scope control on the original SOW, and the check is whether change orders repriced at the standard rate card or at the original blended rate.
Follow-up
- The chained denominator narrows the overrun to 1.11. Does your recommendation change, and which number goes in the practice review?
- How would you distinguish an estimation problem at sale time from a delivery problem during execution, using only these tables?
Your utilisation dashboard caused a staffing decision on incomplete data
Medium · late-arriving data · postmortem · reporting windows
Six weeks ago you shipped a weekly billable-utilisation dashboard keyed on fct_time_entry.work_date. It showed a six-point drop across the three most recent weeks. A practice lead pulled two consultants off an engagement in response. The drop reversed on the next refresh, because time entries are created days to weeks after the work happens and entered_at trails work_date. Describe what you do now: the diagnosis, the change to the artifact, and the conversation with the person who acted on your number.
Approach
- Name the probe: whether you own a reporting-design error rather than reclassifying it as someone else's timesheet compliance problem, and whether you fix the class of bug instead of the single week.
- Quantify before explaining. Measure the backfill curve directly from entered_at: for work_date D, the share of final hours that existed as of D plus k, for k from 1 to 45. That gives an observed tail length instead of a guessed cutoff.
- Change the artifact so the incomplete region cannot be read as a trend. Either end the trended series at snapshot minus the measured tail, or publish an as-of-entered_at series that is internally consistent, and label which one is on screen.
- Tell the person who acted, first and directly, with the corrected series and the specific decision to revisit. A correction that arrives after they notice costs more than the original error.
- Add a standing completeness tile: timesheet submission lag, the share of entries where entered_at date minus work_date exceeds seven days, so the dashboard shows its own reliability rather than depending on you remembering.
Follow-up
- Leadership still wants to see the current week. What do you show, and how do you label it?
- One practice runs a three-day lag and another twenty days. Do you set one firm-wide cutoff or one per practice, and what does that cost in comparability?