As a Data Scientist at KDA Consulting, you serve as a critical bridge between complex data architecture and actionable business intelligence. You will be tasked with transforming raw, often ambiguous datasets into strategic insights that drive decision-making for KDA Consulting's clients. Because KDA Consulting operates in high-stakes environments—often involving government and enterprise-level projects in the Northern Virginia area—your work directly influences project outcomes, system efficiencies, and long-term organizational strategy.
This role requires more than just technical proficiency; it demands a consultant’s mindset. You will be expected to translate sophisticated statistical models and machine learning outputs into clear, persuasive narratives for stakeholders who may not have a technical background. You will work within cross-functional teams to solve real-world problems, ranging from predictive modeling to operational optimization, ensuring that every project you touch delivers measurable value.
The most successful candidates at KDA Consulting are those who can balance high-level technical rigor with the ability to articulate "why" a specific model or method is the right choice for a client's unique business challenge.
Initial Screening Call
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 Deep-Dives
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
Behavioral Assessments
reportedBehavioural answers from data candidates get audited in a way that answers from other roles do not. When you say a model lifted retention, the next question is the denominator, the window, and how you knew the lift was not seasonal. So attach the measurement to each claim while you tell it: what the metric was before, over what period, and against what comparison. Numbers with no baseline read as rounded-up memory, and one unsupported figure tends to make the rest of the story sound rehearsed.
What to demonstrate
- Whether each impact number arrives with a baseline, a window and a comparison, or as a bare percentage
- Whether you can name the method that attributed the effect to your work (an experiment, a staged rollout, a seasonal control) or concede the link was correlational
- Whether the magnitudes stay internally consistent when the interviewer multiplies them against the scale you described earlier
How to prepare
- For each story, write the impact line as metric, value before, value after, window, and how attribution was established. Any line missing two of those five is a follow-up you will answer badly.
- Re-derive one headline number from the source table rather than the deck that reported it. Resume numbers drift upward across retellings.
- Decide in advance which figures you cannot share, and prepare the ratio or relative change you can give instead, so a confidentiality limit does not read as evasion.
PracHub editorial advice for the preparation topics above.
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.
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.
Accepting a metric definition without asking about the denominator
Pin down the denominator, the eligibility filter and the time window before computing anything: conversion rate per session, per user, per eligible user and per new user are four different numbers with different behaviour. Restate the definition in one sentence and get agreement before you analyse.
Choose a category, try a prompt, then open its approach, worked solution or follow-up when you need it.
If a client asks for a 99% accuracy rate on a model, how do you manage…
If a client asks for a 99% accuracy rate on a model, how do you manage those expectations?
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.
- 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?
Explain the trade-offs between a Random Forest and a Gradient Boosting…
Explain the trade-offs between a Random Forest and a Gradient Boosting Machine.
Approach
- Say how the offline result would be validated online before it is trusted.
- Set a baseline first, so any model has something honest to beat.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
Follow-up
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
How do you approach feature engineering when you have a limited number…
How do you approach feature engineering when you have a limited number of observations?
Approach
- Set a baseline first, so any model has something honest to beat.
- Check what information would not exist at prediction time, and exclude it.
- Say how the offline result would be validated online before it is trusted.
Follow-up
- How would you choose the decision threshold, and who owns that choice?
- What would you monitor after launch to know the model is still valid?
Implement billable utilisation against a defended availability denominator
Implement billable utilisation for one calendar month at consultant grain, then roll it up to practice_area. Inputs: time_entries (consultant_id, work_date, hours, is_billable, charge_code, status), consultants (consultant_id, practice_area, fte_fraction, home_region, is_billable_role, hire_date, termination_date) and holidays (region, holiday_date). Numerator is approved hours with is_billable true. Denominator is scheduled workdays in the month, clipped to [hire_date, termination_date] and net of that region's holidays, times 8 times fte_fraction, minus approved leave hours. Roll up as sum(numerator) / sum(denominator).
Approach
- Build the workday set per region first: business days in the month minus that region's holiday_dates. State the Monday-to-Friday assumption out loud, because a region with a different working week makes np.busday_count wrong rather than approximate.
- Prorate by clipping each consultant's interval to [max(month_start, hire_date), min(month_end, termination_date or month_end)] and counting workdays inside the clipped interval, so a mid-month start produces a smaller denominator instead of a fake dip in the ratio.
- Subtract approved leave hours (charge_code in leave_paid, leave_unpaid) only for leave falling on days already counted as workdays; leave logged on a public holiday would otherwise be subtracted twice and can push a denominator negative.
- Filter to is_billable_role, then drop consultant-months whose denominator is zero or negative (full-month leave, a hire on the last day) rather than emitting inf or NaN, and return the dropped count as part of the result.
- Roll up by summing numerators and denominators separately. Averaging per-person ratios gives a 0.2 FTE consultant the same weight as a full-time one and produces a practice number that no individual reconciles to.
Worked solution 35 min
- Per region, workdays = np.busday_count(month_start, month_end + 1 day, holidays=region_holidays); per consultant, recompute on the clipped [start, end] interval so proration and holidays compose.
- leave = time_entries[status=='approved' & charge_code.isin(['leave_paid','leave_unpaid']) & work_date.isin(region workdays)].groupby('consultant_id').hours.sum().
- denominator = workdays_clipped * 8 * fte_fraction - leave, reindexed to the billable-role consultant list and filled with 0 leave where absent.
- numerator = time_entries[status=='approved' & is_billable].groupby('consultant_id').hours.sum(), reindexed and zero-filled.
- Drop rows with denominator <= 0 (counting them), compute utilisation_pct = 100 * numerator / denominator, then groupby practice_area and divide summed numerator by summed denominator.
Follow-up
- Utilisation rose two points this month while realisation fell. Reconcile those two movements with one mechanism.
- A regional lead says their team looks four points below another region. What do you check before you answer, and in what order?
Dense consultant-week series with a trailing four-week average
fct_time_entry holds consultant_id, engagement_id, charge_code, work_date, hours, is_billable and status. dim_consultant holds consultant_id, is_billable_role, hire_date, termination_date and is_current. Produce one row per billable-role consultant per ISO week over the last 26 weeks with approved billable hours and the trailing four-week average including the current week. Weeks with no time entries must appear as 0, not disappear. No consultant may appear before hire_date or after termination_date. State where you put the right-hand edge of the window and why.
Approach
- Build the week spine with generate_series over date_trunc('week', ...), which is Monday-aligned in Postgres, and CROSS JOIN it to the eligible consultant set, bounding each consultant by hire_date and termination_date. The spine is what converts an absent week into a zero week; no amount of COALESCE on a query driven by fct_time_entry can recover a row that was never there.
- Aggregate time entries to (consultant_id, week_start) in a CTE first, then LEFT JOIN that onto the spine and COALESCE(hours, 0). Aggregating before the join keeps it one-to-one and removes any chance of fan-out.
- Average with AVG(billable_hours) OVER (PARTITION BY consultant_id ORDER BY week_start ROWS BETWEEN 3 PRECEDING AND CURRENT ROW). Use ROWS rather than RANGE: on a dense spine they agree, but ROWS states the intent in row terms and does not change meaning if the spine ever develops a hole.
- Decide what the first three weeks of each consultant's series mean. That window averages over fewer than four rows, so either label them as partial with a COUNT(*) OVER the same frame, or suppress them. Pick one and say so.
- Hold the right edge of the window back past the measured timesheet backfill tail. Entries are created days to weeks after work_date, so the most recent weeks are systematically incomplete and the series will show a decline that reverses on the next refresh. Measure the tail rather than guessing a round number.
Follow-up
- Extend to a 13-week average. Does your choice between ROWS and RANGE change, and why?
- Add the availability denominator so this becomes utilisation. What has to be subtracted from calendar hours, and what has to be prorated?
- Reproduce this series as it would have looked 30 days ago. Which column do you filter on, and why do the two versions differ?
Longest consecutive bench spell per consultant from weekly activity
You have a dense series (consultant_id, week_start, billable_hours, full_week_leave BOOLEAN) covering 26 weeks for every billable-role consultant, with zero-hour weeks present as 0. Return every maximal run of consecutive weeks where billable_hours = 0, as consultant_id, spell_start_week, spell_end_week and week_count, then each consultant's longest run. Weeks flagged full_week_leave must neither break a run nor count toward its length. Mark runs still open at the last week of the series rather than reporting them as finished.
Approach
- Remove full_week_leave weeks from the sequence first, then re-number what remains with ROW_NUMBER() OVER (PARTITION BY consultant_id ORDER BY week_start). Deleting before numbering is precisely what makes a leave week transparent to a run instead of a break in it; filtering afterwards would leave a gap in the sequence and split the spell.
- Flag each surviving week as bench (billable_hours = 0) or active, then compute two row numbers per consultant: one over all surviving weeks, one partitioned additionally by the bench flag. Their difference is constant inside any run of adjacent same-flag weeks, which is the island key.
- Group the bench weeks by (consultant_id, island key) and take MIN(week_start), MAX(week_start) and COUNT(*). Do not island on week_start minus an interval times a row number: that variant assumes the spine has no holes, and the leave removal has just deliberately put holes in it.
- Pick the longest spell per consultant with ROW_NUMBER() OVER (PARTITION BY consultant_id ORDER BY week_count DESC, spell_start_week) so ties resolve deterministically, rather than a MAX that cannot carry the accompanying dates.
- Handle both edges as censoring. A spell touching the last week of the series is still open and its length is a lower bound, so flag it; a spell touching the first week may have started earlier, so either flag it too or exclude it from any length distribution and say which.
Worked solution 40 min
- Filter out full_week_leave rows and count the surviving weeks per consultant.
- Add the bench flag and the two row numbers, then print one consultant's full sequence to see the island key stay constant across a run.
- Group bench weeks by consultant and island key and aggregate to spell boundaries and lengths.
- Add the open-at-the-edge flag by comparing spell_end_week to the consultant's last surviving week.
- Rank spells per consultant and select the longest with the deterministic tiebreak.
Follow-up
- A spell begins before your 26-week window. How do you detect that, and what do you report as its length?
- Rebuild this at daily grain. What changes about weekends, holidays and the island key?
- How would you separate true bench from unbilled delivery work on a live engagement, given only charge codes?
Walk me through your process for performing exploratory data analysis …
Walk me through your process for performing exploratory data analysis on a new, unfamiliar dataset.
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- 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
- 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 system to detect anomalies in real-time sensor …
How would you design a system to detect anomalies in real-time sensor data?
Approach
- 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.
- 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?
- How would you detect that the metric is being gamed rather than genuinely improving?
How do you prioritize tasks when you are working on multiple client-fa…
How do you prioritize tasks when you are working on multiple client-facing projects simultaneously?
Approach
- 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.
- 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?
Estimate a mandatory pricing review at a value threshold
Proposals with expected_value_usd at or above 250,000 must pass a mandatory pricing review before submission; below that the originating partner prices unilaterally. The rule has stood for three years, nothing was randomised, and leadership wants to know whether the review improves realisation on the resulting engagements. About 900 proposals a year land in fct_proposal, and realisation is only observable for those that reach stage = won. Design the identification strategy, state the estimand precisely, and name the two checks that would make you abandon the design.
Approach
- Set up the design. Running variable is expected_value_usd as recorded when the rule is applied, cutoff 250,000, outcome realisation on the resulting engagement. Estimate with local linear regression either side, triangular kernel, MSE-optimal bandwidth and robust bias-corrected confidence intervals. Do not fit a global high-order polynomial, which drags weight from proposals far from the cutoff onto the estimate at it.
- Check compliance before calling it sharp. If some sub-threshold proposals are reviewed voluntarily or some above-threshold ones skip review, the design is fuzzy, which is instrumental variables with the threshold indicator as the instrument. The estimate is a Wald ratio, the jump in realisation divided by the jump in review probability, and it identifies the effect for compliers at the cutoff only.
- Run the manipulation test and interpret it carefully. A density test on expected_value_usd will very likely reject, because proposal values heap at round numbers and 250,000 is exactly such a number. Heaping alone is not sorting, but a partner pricing at 249,000 to dodge review is, and both look the same in the density. Separate them by checking whether excess mass appears only just below the cutoff or at round numbers throughout the range, and by running a donut specification that drops a window around the threshold.
- Check covariate continuity at the cutoff for industry_segment, account_tier, is_competitive, practice_area and originating_partner_id, using the same local linear specification with each covariate as the outcome. A jump in any of them at 250,000 is a jump in the population rather than in the treatment, and it kills the design.
- Confront the outcome-side selection. Realisation exists only for won proposals, and review may itself move the win rate, so conditioning on a win conditions on a post-treatment variable. Estimate the RD on win rate first; if it jumps, switch to an outcome defined over all proposals, such as realised fees per proposal with losses entering as zero, or report Lee bounds rather than a point estimate.
- Size the design before committing to it. Only proposals inside the bandwidth contribute, so 2,700 proposals over three years with a bandwidth capturing perhaps 15% leaves an effective sample near 400 split across the cutoff. Compute the MDE on that number, not on 2,700, and say in advance whether it can detect the effect that would change the policy.
Worked solution 45 min
- Histogram expected_value_usd in fine bins around 250,000 and across the full range, to separate generic round-number heaping from cutoff-specific sorting.
- Estimate the first stage: probability of a recorded review as a function of the running variable, and read the jump at the cutoff. A jump well below one means fuzzy, so move to the Wald ratio.
- Run the local linear RD on realisation with an MSE-optimal bandwidth and robust bias-corrected intervals, then repeat at half and twice that bandwidth.
- Repeat the same specification with each pre-treatment covariate as the outcome, and with placebo cutoffs at 200,000 and 300,000.
- Run the RD on win rate, then on realised fees per proposal defined over all proposals, and compare the three results.
- Report the MDE computed on the in-bandwidth proposal count alongside the estimate.
Follow-up
- If the density test rejects and the donut specification moves the estimate materially, what do you conclude and what do you put in the deck?
- The estimand is local to 250,000 and leadership wants to know whether to lower the threshold to 100,000. What can you honestly say?
- The review is triggered on the value at submission, but the value is revised afterwards. Which version of the running variable do you use, and why?
Days sales outstanding improved while collections got worse
A cash dashboard reports mean days-to-pay as AVG(paid_at - issued_at) over fct_invoice_line where status = 'paid'. It improved from 47 to 39 days last quarter. The finance lead insists collections are worse, and invoice volume rose about 30% after a large batch issued early in the quarter. Using invoice_line_id, engagement_id, issued_at, due_date, paid_at, status and amount_usd, explain the contradiction and deliver the estimate you would report instead, with its assumptions.
Approach
- Name the bias precisely: at any snapshot, the set of paid invoices over-represents fast payers, because slow ones have not finished yet. Unpaid, partially paid and disputed lines are right-censored observations, not absent ones, and averaging over completions alone is biased downward.
- Explain why the bias grew: a large young cohort adds many invoices whose slow half cannot yet appear in the paid set, so a volume increase alone pushes the naive mean down even with unchanged payment behaviour.
- Build the censored dataset: event time = paid_at - issued_at for paid lines; censoring time = snapshot_date - issued_at for status IN ('issued','partially_paid','disputed'). Confirm no placeholder dates were substituted for NULL paid_at.
- Estimate with Kaplan-Meier by issue-month cohort and report both the median and the restricted mean to a fixed horizon such as 90 days, so cohorts of different maturity are compared over the same span. State the independent-censoring assumption: censoring here is administrative, driven by issue date rather than by payment behaviour, which is what makes it defensible.
- Cross-check with a metric that needs no model: share of each cohort's invoiced amount collected by day 30, 60 and 90. If the recent cohort's curve sits below prior cohorts at the same age, collections really did deteriorate.
- Report amount-weighted as well as count-weighted, since one large disputed invoice moves cash without moving the count.
Follow-up
- Disputed invoices may never pay at all. Does that break the censoring assumption, and how would you handle it?
- How would you turn this into a weekly operational report that cannot be gamed by issuing more invoices?
- Proposal cycle time has the same structure. What is the equivalent fix there?
Four days spend equal time on query work, statistics, modelling and product judgement at deliberately shallow depth, which produces a scored map of where you actually stand. The last three days spend everything on the two areas the role weights most, and close by re-running day one to measure movement.
Prepare, practise & reflect
One practical outcome each day. Spend longer where you need it.
0 / 7 done01Breadth pass: query fluency
- Solve six prompts spanning aggregation, joins, window functions and date arithmetic in 60 minutes total, stopping at 10 minutes each whether or not it works, and mark every prompt as solved, solved slowly, or stuck.
- For each unsolved prompt write the single blocking sentence (I lost the grain, I did not know the frame clause, I could not express the date boundary) instead of reading the solution.
- Translate one pandas transformation you know well into SQL and one SQL query into pandas, checking that both return the same row count and the same totals.
Deliverable: A scored six-row table, one line per prompt, saved for the day-seven re-run.
Practice prompt ↗Practice prompt ↗Worked solution ↗02Breadth pass: statistics and inference
- Answer ten short questions in writing with nothing open: what a p-value is conditional on, what a 95 percent interval covers across repeated samples, when a paired test is the right one, what the bootstrap estimates, why multiple comparisons inflate false positives, how controlling the family-wise error rate differs from controlling the false discovery rate, what power depends on, what a missed real effect costs a product, the three situations where the central limit theorem does not rescue you (small n, very heavy tails, dependent observations), and what a standard error is the standard deviation of.
- Grade yourself against a reference and count only the answers that were exactly right, not the ones that were nearly right.
- Rewrite the two weakest answers the following morning from memory in full sentences.
Deliverable: Ten graded answers with an honest count of exact hits.
Practice prompt ↗Practice prompt ↗03Breadth pass: modelling
- Take one tabular dataset end to end in 90 minutes: a leakage-safe split, a baseline that is not a model (majority class or historical mean), one regularized linear model, one gradient-boosted tree, and a single evaluation metric chosen before you look at any result.
- Write why that metric fits the cost structure: precision at a fixed recall for alerting, calibration for anything feeding a price or a threshold, ranking metrics for retrieval, and note that area under the ROC curve is insensitive to class balance in a way that can flatter a rare-positive problem.
- Name the leak you were most likely to introduce (an encoding fit on all rows before splitting, or a feature computed after the label's timestamp) and write the check that would have caught it.
Deliverable: A notebook whose first cell states the metric and the baseline, plus two lines on what beat what and by how much.
Practice prompt ↗Practice prompt ↗04Breadth pass: product judgement
- Answer three case prompts aloud at 15 minutes each, timing how long passes before you state a success metric.
- For one case write the first segmentation you would run and the row counts you expect per segment, so that a tiny segment cannot quietly drive the conclusion.
- Take a metric definition you did not write, from a public dashboard, a textbook, or documentation you already have open, and list every place two analysts implementing it would diverge: which rows the denominator admits, whether the unit is an account or a person, what the time window is anchored to, and what happens to data that arrives late. Then write the one question that would close the largest of those gaps.
Deliverable: Three recorded case answers plus an ambiguity list for a metric someone else defined, ending in the single question you would ask about it.
Practice prompt ↗Practice prompt ↗Worked solution ↗05Depth, first area
- Rank the four areas by how many bullet points in the role description each one covers, pick the top one, and spend the entire day inside it.
- Work the six hardest problems you can find in that area and for each write the generalizable move you should have reached for first, rather than the answer.
- Re-solve the two you failed the same evening with notes closed.
Deliverable: Six generalizable moves written as instructions to yourself, not as solutions.
Practice prompt ↗Practice prompt ↗06Depth, second area, and the seam between them
- Repeat the depth protocol on the second-ranked area with the same six-problem structure.
- Construct one problem that requires both areas at once, for example a metric redefinition whose effect you must validate with a test whose readout you then have to query.
- Solve your own combined problem end to end and note where the handoff between the two areas cost you time.
Deliverable: One combined problem, solved end to end, with the handoff failure written down.
Practice prompt ↗Practice prompt ↗07Integration and re-measurement
- Re-run the six prompts from day one under the same clock and compare both correctness and time.
- Run a 60-minute mixed mock that moves between areas without warning, since switching cost is what breadth passes do not train.
- Write the two areas you would still fail on, and the sentence you will use in the interview when you hit one of them.
Deliverable: A before-and-after score table plus a written plan for the two remaining gaps.
Practice prompt ↗Practice prompt ↗Worked solution ↗Expand any day for tasks and deliverables. Your progress is saved on this device.
Work that nobody used is a common and unflattering pattern in data careers, and interviewers probe for it. Have a story about an analysis that changed a decision, and be specific about how you got it in front of the person who could act. Also have one about work that went nowhere, with your reading of why.
How do you handle missing or corrupted data in a production-level pipe…
How do you handle missing or corrupted data in a production-level pipeline?
Approach
- Quantify the outcome, including what you would not claim credit for.
- State the situation in two sentences and spend the rest on your reasoning.
- Pick a story where you drove the decision, not one where you observed it.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Tell me about a time you failed to meet a project deadline or expectat…
Tell me about a time you failed to meet a project deadline or expectation. What did you learn?
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.
- State the situation in two sentences and spend the rest on your reasoning.
Follow-up
- What did you decide not to do, and why?
- What would you do differently if you ran that project again?
Scoping a one-line question about practice profitability in twenty minutes
A practice leader asks, in one line, whether the data_and_ai engagements are profitable. You have fct_engagement, fct_time_entry and fct_invoice_line, and twenty minutes before they travel. Some engagements are retainer or outcome_based, so contracted_hours is NULL; some invoices are unpaid; pursuit hours sit on charge_code = 'client_pursuit' with engagement_id NULL. Produce the scoping conversation: the questions you ask, the metric you commit to in writing, the exclusions you will have to make, and what you deliver by when.
Approach
- Name the probe: whether you convert an ambiguous one-liner into a decision with a metric attached, or start querying and return a number nobody can act on.
- Ask what changes based on the answer. Repricing the rate card, changing the staffing pyramid, and deciding whether to keep selling fixed_fee are three different questions, and they need different cuts of the same data. Pick the one the leader actually has authority over.
- Commit the metric in writing on the spot: fees plus milestone plus credit_note lines from fct_invoice_line as the revenue side, the sum of hours times cost_rate_usd over all approved entries, billable and non-billable alike, as the cost side, inception to date, reported separately by pricing_model.
- List what you will not answer and why: overrun on retainer and outcome_based work, because contracted_hours is NULL there and needs an explicit predicate rather than a silent NULL drop; cash collected, because unpaid invoices are censored; and pursuit cost, which has no engagement_id and must either be allocated on a stated rule or reported as a separate line.
- Commit two deliverables with dates rather than one vague one: the stratified margin table within two days, the mix decomposition within a week. Name the single assumption that, if wrong, flips the conclusion.
Follow-up
- They insist on one number for a partner meeting. Which single number do you give, and what sentence goes with it?
- If you had to allocate client_pursuit hours to engagements, what rule would you use and how would you show the answer is not sensitive to it?
- 01
How do you handle missing or corrupted data in a production-level pipeline?
- 02
Tell me about a time you failed to meet a project deadline or expectation. What did you learn?
- 03
A practice leader asks, in one line, whether the data_and_ai engagements are profitable. You have fct_engagement, fct_time_entry and fct_invoice_line, and twenty minutes before they travel. Some engagements are retainer or outcome_based, so contracted_hours is NULL; some invoices are unpaid; pursuit hours sit on charge_code = 'client_pursuit' with engagement_id NULL. Produce the scoping conversation: the questions you ask, the metric you commit to in writing, the exclusions you will have to make, and what you deliver by when.
Is this an official KDA Consulting interview guide?
No. It is PracHub's own research and practice material for the Data Scientist role at KDA Consulting. Rounds and questions reflect what candidates have reported, not a process KDA Consulting has published, and they change over time. Confirm the current format and scope with your recruiter.
PracHub interview research ↗How difficult are the technical interviews?
They are challenging but fair. They focus on practical application rather than obscure trivia, so focus on mastering the fundamentals and being able to explain your reasoning clearly.
PracHub interview research ↗How long does the process take?
While it varies by project need, most candidates move through the process in a few weeks. The exact timeline depends on the project the role supports.
PracHub interview research ↗Is there a specific focus on a certain industry?
KDA Consulting works across diverse sectors, so candidates report that a "generalist" ability to adapt your technical skills to new domains counts for a lot.
PracHub interview research ↗What differentiates successful candidates?
The ability to treat the interviewer as a partner. Successful candidates ask clarifying questions, explain their thought process, and show genuine interest in the business problems KDA Consulting is solving.
PracHub interview research ↗Sources & methodology 3 sources ↗
No official company page is cited. Rounds and questions come from candidate reports and PracHub editorial material; each source shows the date it was read.
- 01PracHub interview research ↗
PracHub editorial research into this company and role, maintained with this guide. Candidate-reported, not an employer publication.
PracHub page · Accessed 2026-09-22 - 02PracHub Data Scientist practice ↗
Cross-company practice questions for this role.
PracHub page · Accessed 2026-09-22 - 03PracHub interview preparation framework ↗
The framework the preparation plan follows.
PracHub page · Accessed 2026-09-22