cswork / libraryOpen practice workspace

Interview guides · Airbus Helicopters

Airbus Helicopters Data Scientist Interview Questions & Guide 2026

Timed data scientist practice for Airbus Helicopters: short SQL and probability sets run end to end, then scored against a rubric.

The 60-second brief

As a Data Scientist at Airbus Helicopters, you are stepping into a role that directly influences the future of aerospace innovation, safety, and operational efficiency. You will not just be building models; you will be analyzing complex telemetry, manufacturing, and supply chain data to ensure that global fleets operate safely and reliably. Your work has a tangible impact on physical products that save lives, connect remote regions, and execute critical missions worldwide.

Scope your preparation by the data you would actually touch, because the title will not tell you. A seat that lives in event logs and weekly readouts rewards fluency in aggregation and metric definitions; a seat that owns a model in production rewards fluency in train/serve skew, retraining cadence and drift monitoring. The fastest way to find out which one you are interviewing for is to ask what the team shipped last quarter and what it gets paged about.

Focus areas

  • Separate true demand from censored, stocked-out sales
  • Size safety stock under variable lead times
  • Evaluate forecasts at the lag ordering actually uses

Overview

This position requires a unique blend of technical rigor and domain adaptability. You will collaborate closely with aerospace engineers, product managers, and operational leaders to translate massive datasets into actionable insights. Whether you are developing predictive maintenance algorithms to anticipate component wear or optimizing manufacturing workflows, your data-driven solutions will drive strategic decisions across the business.

What makes this role particularly exciting is the sheer scale and complexity of the data you will handle. Airbus Helicopters operates at the intersection of heavy engineering and cutting-edge digital transformation. You can expect to navigate ambiguous problem spaces, requiring you to not only deploy advanced machine learning techniques but also to clearly communicate your findings to non-technical stakeholders who rely on your expertise to make high-stakes decisions.

The Airbus Helicopters interview process

Airbus Helicopters candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.

Automated Video Interview

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.

HR Phone Screen

Most 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 and Managerial Interview

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

Where candidates lose points

Computing average inventory from period-end snapshots

Shipments cluster before period close, so the month-end on-hand position is systematically the lowest point of the month; turns computed against it are biased high and days of supply biased low, frequently by ten to twenty percent, and the bias grows precisely when close-period push is strongest. The same shape of error appears when a daily snapshot is joined to shipment events on date equality: a SKU with several legs on one day fans the snapshot out and multiplies the valued inventory. Average across every daily snapshot in the window for the denominator, and join snapshots to events with an explicit as-of condition and a row-count check at each grain before aggregating.

Attributing demand variability to the node where it is observed

Order variance amplifies as it moves upstream: batching to a truckload, minimum order quantities, forecast-driven ordering and promotional pull all convert smooth end demand into lumpy replenishment orders, so a plant can see a coefficient of variation several times that of the underlying consumption. Diagnosing the plant's schedule instability as a plant problem then produces interventions that cannot work, because the generating process sits one or two echelons downstream. Measure the bullwhip ratio explicitly (variance of orders placed by a node over variance of demand it received) at each echelon, and fix the ordering rule at the node where the ratio jumps rather than the node where the pain is felt.

Analysing at a different unit than the one randomised

Say out loud what was randomised (user, device, account, cluster) and make the analysis unit match, or account for the clustering with cluster-robust standard errors, the delta method, or aggregation up to the randomised unit. Randomising users and then running a test over sessions understates variance and inflates the false-positive rate.

Reporting a p-value with no effect size or interval

Give the estimated difference with a confidence interval in the units the business cares about, then say whether that whole interval is worth acting on. A p-value only addresses whether you can rule out exactly zero; it says nothing about magnitude.

Questions & practice

Measure demand amplification hop by hop up the network

Hard · bullwhip · hierarchy traversal · variance

Using dim_location (location_id, parent_location_id, echelon, location_type) and fct_shipment_leg (leg_id, shipment_id, origin_location_id, destination_location_id, direction, tendered_at_utc, shipped_units), quantify how order variability grows upstream. fct_shipment_leg carries no sku_id and no link back to order lines, so shipped_units is the node's whole mixed-SKU flow and the measurement is node-level by construction. For each node compute weekly units flowing out (what it served downstream) and weekly units flowing in (what it ordered up), then the ratio of their variances on detrended, deseasonalised residuals. Walk parent_location_id from a store to echelon 0 and report the ratio at each hop, naming the hop where amplification is introduced. dim_location has no path column; build the chain yourself.

Approach

  1. Date orders by tendered_at_utc, not delivered_at_utc. Tender is the closest observable proxy for the moment the ordering decision was made; dating by delivery shifts the series by transit time and smears the variance you are trying to measure.
  2. Build both series on the same calendar weeks and in the same units. Variance scales with the aggregation window, so a ratio formed from daily inbound against weekly outbound measures the calendar, not the ordering rule. The units are mixed-SKU counts because the leg table carries no sku_id, so a node whose product mix drifts toward smaller or larger pack sizes moves both series for reasons unrelated to its ordering rule; print that caveat next to the number rather than implying a per-SKU result.
  3. Detrend and deseasonalise before taking variances, or compute the ratio on residuals from a simple weekly seasonal baseline. A growing node otherwise scores as amplifying, when all you have measured is its trend.
  4. Walk the parent chain iteratively: start from the store rows, join dim_location to itself on parent_location_id, and repeat until parent is null, capping the loop at the known echelon depth and asserting the path length matches the echelon difference so a data cycle raises rather than hangs.
  5. Read the output as a sequence, not a set of numbers. A pass-through node such as a cross-dock should sit near 1.0, and the hop where the ratio jumps is where a batching rule, a minimum order quantity or truckload rounding lives. That is the node to fix, not the node that is complaining.

Follow-up

  • The ratio at one hop is 4.2 and the node insists it orders exactly to forecast. What ordering rules would produce that number anyway?
  • What would it take to run this for a single SKU family rather than total units, given fct_shipment_leg carries neither a sku_id nor any link to order lines, and which hops would still be unmeasurable after you added that link?
  • What would you expect this measurement to look like during a promotion, and does that change your conclusion?

Recover unconstrained demand from stockout-censored history

Hard · censoring · maximum likelihood · em algorithm

A legacy extract has only inventory_date, sku_id, location_id, shipped_qty and stockout_flag; demand_qty was not populated before a cutover date. On a stockout day, shipped_qty is a lower bound on that day's demand. Model daily demand per sku-location as Poisson and fit its mean by maximum likelihood, treating stockout days as right-censored observations. Return the fitted mean per cell alongside the naive mean of shipped_qty and the censored share. Then validate against the post-cutover window where demand_qty exists.

Approach

  1. Write the likelihood before any code. Uncensored days contribute the Poisson pmf at the observed count; stockout days contribute the survival probability P(X >= y), because all you learned is that demand was at least what you managed to ship.
  2. Solve it as an EM fixed point rather than reaching for a general optimiser: the censored MLE equals the complete-data mean with each censored observation replaced by its conditional expectation, so iterate lambda_next = (sum of uncensored y + sum of E[X | X >= y, lambda]) / n until it stops moving.
  3. Use the closed form for the conditional expectation rather than truncating an infinite sum: for a Poisson, sum over k >= y of k*p(k) equals lambda times P(X >= y-1), so E[X | X >= y] = lambda * P(X >= y-1) / P(X >= y) for y >= 1. That removes the tail-truncation error entirely.
  4. Refuse to fit cells with too little signal. A sku-location with three non-zero days or with every day censored has no identifiable mean; return the naive figure with a flag rather than a confident number.
  5. Validate on the post-cutover window where demand_qty is populated: fit the estimator on shipped_qty and stockout_flag alone, and compare both the censored estimate and the naive mean against the true mean of demand_qty.

Follow-up

  • The fitted mean is 18 percent above the naive mean for A-class items and 2 percent above for C-class. Why would you expect that ordering?
  • The residual variance is three times the fitted mean. What does that break and what distribution would you move to?
  • A stockout is often caused by a demand spike that day. What does that do to your estimate and can you correct it?

As-of join snapshots to order lines without merge_asof

Medium · as-of join · fan-out · searchsorted

You have fct_order_line (order_line_id, sku_id, ship_from_location_id, actual_ship_at_utc, shipped_qty, shipment_id) and fct_inventory_daily (inventory_date, sku_id, location_id, available_qty). For every shipped line, attach available_qty from the latest snapshot strictly before the ship date for that exact sku and node, plus the shipment's delivery timestamp from fct_shipment_leg (leg_id, shipment_id, delivered_at_utc, leg_status). The output must have exactly one row per input order line. pandas.merge_asof is not available; implement the as-of match yourself.

Approach

  1. Collapse fct_shipment_leg to one row per shipment_id before joining anything. A shipment is one or more legs, so a direct line-to-leg join multiplies every line by its leg count and quietly inflates every sum computed afterwards.
  2. Define the shipment-level delivery as the maximum delivered_at_utc across its legs, and set it null if any leg is not delivered, since the customer has the order only when the last leg lands.
  3. Sort the snapshot frame by (sku_id, location_id, inventory_date) and the line frame by the same key plus ship date, then use np.searchsorted with side='left' on the sorted dates within each key group to find the insertion point; the matching snapshot is the row at position minus one.
  4. Guard the boundary explicitly: an insertion point of 0 means no snapshot exists before that ship date, and the result must be null rather than the first available future snapshot. Count those lines and report them.
  5. Assert the output row count equals the input line count immediately after each merge, before any aggregation. Row-count drift is the only symptom a silent fan-out produces, and it is invisible once the frame has been grouped.

Worked solution (30 min)

  1. Aggregate legs by shipment_id to produce delivered_at_utc as the max, leg_count, and a delivered_all flag from leg_status.
  2. Left join that one-row-per-shipment frame onto fct_order_line by shipment_id and assert the row count is unchanged.
  3. Sort snapshots and lines by the composite key, then compute per-group insertion points with np.searchsorted and subtract one.
  4. Mask positions below zero to null, take available_qty at the remaining positions, and attach it as available_qty_prior.
  5. Validate on a single sku-location pair by printing its snapshot dates and one line's ship date and confirming the chosen date by eye.

Expected result: A frame with exactly as many rows as the input order lines, carrying available_qty_prior (null for lines with no earlier snapshot), delivered_at_utc and leg_count, plus a printed count of unmatched lines.

Verify it yourself

  • Assert len(output) equals len(fct_order_line) after every join step, not only at the end.
  • Assert every non-null matched snapshot date is strictly less than the line's ship date, and that no snapshot date for the same key falls between the match and the ship date.
  • Compare against a slow brute-force loop over 200 sampled lines; the two must agree on every row.
  • Confirm the unmatched count equals the number of lines whose ship date precedes the first snapshot for their sku-location pair.

Follow-up

  • The snapshot is taken at the node's local end of day and actual_ship_at_utc is UTC. Where does that break the strictly-before rule and what do you need from dim_location to fix it?
  • How would you extend this to allocate each leg's linehaul cost back to the order lines it carried?
  • What changes if a line ships in two partial shipments?

Dead stock cells excluding SKUs used as substitutes

Medium · anti-join · null semantics · dead stock

Find dead stock: sku_id x location_id cells whose latest fct_inventory_daily row has on_hand_qty > 0 and which have no fct_order_line with that sku_id and ship_from_location_id in the last 90 days. Also exclude any SKU that filled another line as a substitute in that window; fct_order_line.substituted_sku_id is NULL on every line that was not substituted. Value each cell at on_hand_qty * standard_cost_cents taken from the snapshot, not from dim_sku. Return the cell, days since its last demand line, and value, ordered by value. Treat line_status = 'cancelled_no_supply' as demand.

Approach

  1. Take the latest snapshot per sku-location with ROW_NUMBER() OVER (PARTITION BY sku_id, location_id ORDER BY inventory_date DESC) = 1, or an equivalent MAX(inventory_date) join, and keep rows with on_hand_qty > 0.
  2. Anti-join demand with NOT EXISTS against fct_order_line on both sku_id and ship_from_location_id over the 90-day window, counting every line status including cancelled_no_supply, because unmet demand is still demand and a cell with it is not dead.
  3. Write the substitute exclusion as NOT EXISTS, or force substituted_sku_id IS NOT NULL inside the subquery. NOT IN over a column that contains NULLs evaluates to NULL for every candidate that is not an explicit match, so the predicate is never true and the result set is empty.
  4. Value from the snapshot's standard_cost_cents rather than dim_sku, since the dimension carries only the cost in force today and is revised at period close without back-dating.
  5. Get days since last demand from a LEFT JOIN LATERAL MAX(ordered_at_utc), and report cells that never had a line in a separate bucket instead of as a very large number.

Worked solution (30 min)

  1. CTE latest_snap: ROW_NUMBER over sku_id, location_id ordered by inventory_date DESC, filtered to rn = 1 and on_hand_qty > 0.
  2. CTE last_demand: MAX(ordered_at_utc) grouped by sku_id, ship_from_location_id over all of fct_order_line, with no status filter.
  3. Select from latest_snap LEFT JOIN last_demand, keeping rows where the max is NULL or older than 90 days.
  4. Add AND NOT EXISTS (SELECT 1 FROM fct_order_line o WHERE o.substituted_sku_id = latest_snap.sku_id AND o.ordered_at_utc >= now() - interval '90 days').
  5. Project value_cents = on_hand_qty * standard_cost_cents, order by it descending, and run the same query once with NOT IN to see the empty result for yourself.

Expected result: One row per dead sku-location cell with value_cents computed from the latest snapshot's own cost column, days_since_last_demand (or an explicit never-ordered bucket), ordered by value_cents descending. The substitute exclusion removes some rows; it must not empty the result.

Verify it yourself

  • Swapping NOT EXISTS for NOT IN on substituted_sku_id collapses the output to zero rows. That is the diagnostic for the NULL semantics, not a data finding.
  • Total value across returned cells is strictly less than total on-hand value at the same snapshot date.
  • No returned cell appears in SELECT DISTINCT sku_id, ship_from_location_id FROM fct_order_line over the same 90 days.

Follow-up

  • The query returns zero rows. Name the two likeliest causes and say which you would test first, with the one-line test.
  • How do you separate genuinely dead stock from a seasonal item out of season and from a lifecycle_status = 'pre_launch' SKU?
  • The same SKU is dead at one node and short at another. Write the query that finds that pattern and say what it implies about the policy.

Lag-7 forecast accuracy and bias at weekly grain

Easy · forecast accuracy · null handling · aggregation grain

fct_inventory_daily has one row per sku_id x location_id x inventory_date carrying demand_qty, forecast_qty_lag7 (the forecast for that date as published seven days earlier, NULL before the series existed) and stockout_flag. Compute trailing eight-week WMAPE and signed weighted bias at the sku x location x week grain the ordering decision uses: aggregate demand and forecast to the week first, then form errors on the weekly totals. Exclude any week containing a NULL forecast day and report how many cell-weeks that removed. Return one accuracy row per ABC class.

Approach

  1. Roll daily rows to sku-location-week with SUM(demand_qty) and SUM(forecast_qty_lag7), carrying COUNT(*) FILTER (WHERE forecast_qty_lag7 IS NULL) so a partial week is visible rather than quietly summing to an artificially low forecast.
  2. Drop cell-weeks with any NULL forecast day and emit the dropped count as a column: an accuracy figure without its exclusion count cannot be checked by anyone.
  3. WMAPE = SUM(ABS(weekly_demand - weekly_forecast)) / NULLIF(SUM(weekly_demand), 0). Bias = SUM(weekly_forecast - weekly_demand) / NULLIF(SUM(weekly_demand), 0), signed, with cancellation as the whole point of reporting it next to WMAPE.
  4. Join dim_sku for abc_class and group there by re-summing both sides. Averaging per-SKU WMAPE gives a number weighted by nothing in particular.
  5. Report the share of retained cell-weeks containing a stockout day beside the result, because demand_qty on those days is censored at what could be supplied and the error is being scored against a truncated actual.

Follow-up

  • Why is MAPE unusable on a C-class item at a forward-stocking location, and what do you score it with instead?
  • WMAPE improves sharply when you move from sku-location-week to sku-region-week. Which of the two belongs in the planning review, and why?
  • Bias is +6 percent and WMAPE is 45 percent. What does that pair tell you to investigate first?

Diagnose a sample ratio mismatch in an order-line test

Easy · sample ratio mismatch · randomisation unit · collider bias

A promise-date algorithm was randomised 50/50 with the hash taken on order_id. Your analysis table has 180,000 fct_order_line rows in the window: 91,540 control and 88,460 treatment. Lines are excluded when line_status = 'cancelled_by_customer' or when the join to fct_shipment_leg on shipment_id returns no delivered leg. The readout shows treatment up 0.9 points on on-time delivery. Test the split, state what the result implies about the readout, and list the three most likely causes given how this table was built.

Approach

  1. Run the chi-square goodness-of-fit test against the designed 50/50 split: expected 90,000 per arm, deviation 1,540, so chi-square = 2 * 1540^2 / 90000 = 52.7 on 1 degree of freedom, p around 4e-13. That is not sampling noise, and the readout is not interpretable until it is explained.
  2. Check the grain mismatch first, because it is the cheapest explanation: assignment is on order_id but rows are lines. A perfectly balanced order split still yields unequal line counts whenever lines per order differ by arm, and a promise-date change that splits or consolidates orders does exactly that. Recount distinct order_id per arm before touching lines.
  3. Walk the filter chain and recount the ratio at every step: raw assignment log, then all lines, then after the cancelled_by_customer filter, then after the delivered-leg join. The step where the ratio breaks names the cause without any further argument.
  4. Recognise that both exclusions are post-treatment. Requiring a delivered leg conditions on an outcome the treatment moves, which opens a collider path: whichever arm ships more of the difficult lines retains more slow lines and is penalised for succeeding.
  5. Do not report the 0.9-point lift. Rebuild the metric with all assigned orders in the denominator and never-shipped orders scored as failures, then re-run and compare.

Worked solution (20 min)

  1. Compute the test: expected 90,000 per arm, deviation 1,540, chi-square = 2 * (1540^2 / 90000) = 52.7, p about 4e-13.
  2. Recount distinct order_id per arm on the raw assignment log, before any filter or join touches the data.
  3. Recount after each filter in the order the pipeline applies them, recording the arm ratio at each stage.
  4. If the raw order split is balanced, rebuild the readout at order grain with every assigned order in the denominator and unshipped orders counted as not on time.

Expected result: Chi-square 52.7 on 1 df, p about 4e-13: a genuine sample ratio mismatch, so the 0.9-point result is not reportable. The three causes to check, in order, are that the analysis grain (lines) differs from the assignment grain (orders), that the delivered-leg join drops lines at different rates by arm because shipping is itself an outcome, and that the cancellation filter removes post-treatment rows.

Verify it yourself

  • The z form must agree with the chi-square: a 0.856-point deviation over a 0.118-point standard error is 7.26, and 7.26 squared is 52.7.
  • A balanced order-level split alongside an unbalanced line-level split points straight at lines per order, so compare mean lines per order by arm directly.
  • Re-running with no post-assignment filters should move the 0.9-point effect; if it does not move at all, the imbalance sits upstream of the metric and the randomiser itself is suspect.

Follow-up

  • The split is clean at order_id but broken at line level. Is the readout salvageable, and at which grain would you report it?
  • How would you monitor for this automatically on a test that runs for six weeks, and at what threshold would you halt?

An OEE target that makes the plant run the wrong SKUs

Medium · oee decomposition · guardrails · mix shift

A constraint work centre is put on an OEE target. Using fct_production_run (planned_production_seconds, run_seconds, unplanned_downtime_seconds, changeover_seconds, ideal_cycle_seconds_per_unit, planned_qty, total_qty, good_qty, scrap_qty, rework_qty, downtime_reason_code, run_status) and fct_inventory_daily (on_hand_qty, demand_qty), define OEE precisely, decide whether planned changeover sits inside or outside the denominator, and name the guardrail that stops the target being met by running long batches of whatever is easiest. Defend the conflict rather than hiding it.

Approach

  1. Write the metric exactly: SUM(good_qty * ideal_cycle_seconds_per_unit) over SUM(planned_production_seconds), re-summed for every roll-up, and show that it factors into availability times performance times quality so a movement is attributable before anyone argues about it.
  2. Settle the changeover question in writing, because it decides gameability. Leaving planned changeover inside the denominator makes OEE fall whenever variety rises, which is the behaviour the target would then buy; excluding it protects mix but hides real capacity loss. Exclude it and carry changeover_seconds as its own reported series.
  3. Use ideal_cycle_seconds_per_unit per SKU and work centre rather than a line average, since a line-average nameplate rate turns performance into a function of which SKU happened to run.
  4. Set the guardrail on demand-weighted schedule adherence, good_qty against planned_qty at SKU level weighted by what the network is short of, paired with finished-goods days of supply for the SKUs that were skipped.
  5. State the conflict plainly: a plant maximising OEE lengthens runs and drops small-volume SKUs, which raises the score and lowers service, so the two metrics are published together and the target is set on the pair, not on OEE alone.
  6. Scope the metric to constraint work centres, because OEE on a non-constraint rewards making inventory nobody is waiting for, and scope is part of the definition rather than a footnote.

Follow-up

  • Availability rose and performance fell in the same week. Give two explanations and the query that separates them.
  • Where does rework_qty enter your definition, and what does that choice reward?

Forecast accuracy collapsed at nodes missing snapshot rows

Medium · pipeline failure · wmape · data completeness

WMAPE at lag 7 for one region jumped from 31 percent to 58 percent over three weeks with no model change and no retraining. fct_inventory_daily is specified to carry one row per active sku-location-date even when on_hand_qty is zero, and a release changed how the end-of-day cut-off is derived from dim_location.timezone. Using fct_inventory_daily (inventory_date, sku_id, location_id, demand_qty, forecast_qty_lag7, stockout_flag) and dim_location, decide whether demand changed or the table did, and quantify the contaminated share before anyone retrains.

Approach

  1. Run a completeness check before touching any accuracy number: expected rows per location per day from the active sku-location grid, against actual rows present. If the table is incomplete the accuracy question is not well posed, and this check costs one query.
  2. Separate the two failure modes a cut-off change produces. Rows missing entirely shrink the denominator, and the sku-days that vanish are not a random sample. Rows present but with demand pushed onto the adjacent date create a one-day shift that inflates absolute error on both days while leaving the weekly total intact.
  3. Test the shift hypothesis directly by comparing SUM(demand_qty) per ISO week per node before and after the release. If weekly totals match and only the daily split moved, the model is fine and the grain is broken.
  4. Recompute WMAPE on clean node-days only and report both figures with the excluded row count and the share of demand those rows represent, since the metric definition already requires the excluded count to travel with the number.
  5. Check whether the affected nodes share a timezone that crosses a daylight-saving boundary or sits far from the offset the pipeline assumed. That grouping is the discriminating evidence between a code defect and genuine demand movement.

Follow-up

  • Weekly totals match and only the daily split moved. Does the ordering decision care? At what replenishment frequency does it stop mattering?
  • How would you backfill the missing days, and which of them would you refuse to backfill?
  • What assertion would you add to the snapshot job so this fails loudly instead of surfacing three weeks later as model drift?

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.

Bring numbers, including the ones you are unsure of

An answer without a quantity is hard to interrogate, so interviewers keep probing until they find one. Come with the baseline, the change, the window it was measured over, and how confident you were. If the effect never got measured, say so and say what you would have measured. Fabricated precision is worse than an honest gap.

How do you see yourself fitting into the core values of Airbus?

Medium · behavioural and stakeholder questions

Approach

  1. Quantify the outcome, including what you would not claim credit for.
  2. State the situation in two sentences and spend the rest on your reasoning.
  3. Pick a story where you drove the decision, not one where you observed it.

Follow-up

  • How did you know the outcome was caused by your change?
  • What did you decide not to do, and why?

Tell me about a time you had to overcome a significant professional or academic challenge.

Medium · behavioural and stakeholder questions

Approach

  1. Close with what you would do differently, concretely.
  2. Quantify the outcome, including what you would not claim credit for.
  3. 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 did you decide not to do, and why?

Describe a project you are extremely proud of. What was your specific role?

Medium · behavioural and stakeholder questions

Approach

  1. Close with what you would do differently, concretely.
  2. Pick a story where you drove the decision, not one where you observed it.
  3. State the situation in two sentences and spend the rest on your reasoning.

Follow-up

  • What would you do differently if you ran that project again?
  • What did you decide not to do, and why?

How do you handle working on a project where the goals are initially unclear?

Medium · behavioural and stakeholder questions

Approach

  1. Close with what you would do differently, concretely.
  2. Name the disagreement or constraint, and how you resolved it with evidence.
  3. State the situation in two sentences and spend the rest on your reasoning.

Follow-up

  • What would you do differently if you ran that project again?
  • What did you decide not to do, and why?