Interview guides · American Airlines
American Airlines Data Scientist Interview Questions & Guide 2026
Diagnose a metric move for American Airlines data scientist prep: split by segment, rule out a logging change, separate mix shift from behaviour.
The 60-second brief
A Data Scientist at American Airlines plays a pivotal role in keeping one of the world's largest passenger fleets moving efficiently. Operating at an immense scale, the decisions made by data science teams directly impact flight scheduling, revenue management, fuel optimization, and customer satisfaction. The airline industry generates vast amounts of complex, real-time data, and your job is to transform this raw information into actionable operational strategies.
Ask early whether the loop includes an asynchronous take-home or a timed live case, because the two are graded on different things. A take-home is read as an artifact: the question you decided to answer, what you did about missing or malformed records, and a conclusion stated plainly enough for someone to act on. A reviewer who cannot rerun your notebook discounts the result whatever score is printed in it. Hold to the stated time box and write down what you would have done with more of it, since the follow-up round is usually a live defence of the same work.
Focus areas
- Decompose rate changes into mix and within-segment
- Compute occupancy from sellable nights, never property averages
- Model demand against availability, not observed bookings
Overview
At American Airlines, the data science organization is not just a supporting function; it is a core driver of business value. You will work on sophisticated optimization algorithms, predictive models, and statistical analyses to tackle highly complex problems. Whether you are predicting maintenance needs before a delay occurs, optimizing crew scheduling, or dynamic pricing for tickets, your work has a direct, visible impact on millions of customers and thousands of daily flights.
This role requires a unique blend of technical expertise, business acumen, and cross-functional collaboration. You will partner with engineering, product, and operations teams to deploy models into production. Success in this position means not only building highly accurate machine learning models but also understanding the commercial and operational realities of the aviation industry to ensure your solutions are practical and scalable.
The American Airlines interview process
American Airlines candidates report 3 rounds · ≈ 3-5 weeks. The stages below are what candidates describe, not a published process.
Initial Screening
A screening call is a matching exercise run by someone who will not evaluate your statistics. They are checking that the work described on your resume is work you personally did, and that its scope matches the level the role is written for. Logistics get settled in the same half hour so nobody spends an interviewer's afternoon on a mismatch. The answer that fails is the one narrated in the plural. If every sentence is 'we built' and 'the team decided', there is nothing specific to write down about you. Name the piece that was yours, the decision you made inside it, and what changed after.
What to demonstrate
- Whether the ownership implied by your resume survives one round of follow-up about who actually did which part
- Whether your described scope (data size, stakeholders, what shipped) matches the seniority the role is written at
- Whether timeline, location and compensation expectations make the rest of the loop worth scheduling
How to prepare
- Rewrite your top three resume bullets in the first person singular, each with the decision you made and what moved afterwards, then say them out loud once so the 'we' does not return under pressure
- Attach one number to each project: the baseline, the change, and the window it was measured over. Where impact was never measured, say that plainly rather than inventing a figure
- Settle your compensation range before the call and give it as a range with a reason behind it, such as current total comp or a competing timeline, instead of deflecting the question twice
Technical Assessment
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
Final Round
Where a loop includes a partner from outside the data team, that conversation usually carries the same weight as the technical ones and gets the least preparation. The person opposite you will not follow a derivation and does not need to. They are working out whether having you involved would make their decisions better or slower. The failure mode is not being too technical. It is answering a question about a decision with a description of your method, leaving the translation to them. What they carry into the debrief is the sentence you handed them, not the analysis underneath it.
What to demonstrate
- Whether a statistical result arrives as something the partner could act on, with the one caveat that would change their decision kept and the rest left out
- Whether you can state what you need from their side, in their terms: instrumentation that does not exist yet, a definition they own, or a holdout they have to agree to
- Whether uncertainty is given as a range someone can plan against, rather than as hedging that invites them to ignore the result
- Whether you ask what decision is actually on the table before explaining anything
How to prepare
- Take a result you know well and write the version for someone who stops reading after one sentence, then the three-minute version, and check the short one is not the long one with the qualifications stripped out
- For a past project, list everything you asked a non-technical partner for and how you phrased it, then rewrite each ask so it names what goes unmeasured without it
- Practise saying where a result does not apply, out loud, in one sentence that a partner could repeat accurately to someone else
Where candidates lose points
Reporting on the booking date when the question is about the stay date, or the reverse
The same booking contributes to demand in one period and to revenue, occupancy and supplier payout in another, so almost every headline number has two defensible values that can differ by tens of percent. A promotion that moves bookings this week for stays in March produces a revenue 'drop' on the stay axis and a spike on the booking axis, and both are real. Cancellations make it worse, because a cancellation dated today removes revenue from a stay date months out and will silently restate a period that was already reported closed. The only defence is to name the date axis in the title of every chart and every metric definition, and to keep a pace view (bookings-on-hand for a future stay date, by days out) as a separate artefact rather than trying to serve both from one table.
Reading cancellation, completion or repeat rates on cohorts that have not matured
A cohort of bookings made last week for stays six months out cannot have cancelled at the check-in gate yet, so its cancellation rate is mechanically near zero and its completion rate mechanically near zero as well, in opposite directions. Comparing that cohort with a mature one is not a noisy comparison, it is a guaranteed wrong one, and the bias always makes the recent period look different in a way that invites a false story about a recent change. Because lead time is heavily right-skewed, the mean lead time is a bad maturity threshold; use the cohort's 95th percentile, or report a hazard at a fixed age (cancelled within k days of booking) with k capped at the youngest cohort's elapsed age. The same applies to repeat rate, where the honest answer is often that the cohort in question is not readable for another nine months.
Ignoring interference between units in a marketplace experiment
Ask whether one unit's treatment can change another unit's outcome through shared inventory, a matching pool, a social graph or a common budget. Where it can, randomise at a level that contains the spillover, such as region or time slice, and say explicitly what that costs you in statistical power.
Stopping an experiment the moment it crosses significance
Fix the sample size or duration before launch, or use a method built for continuous monitoring such as a sequential test, always-valid confidence intervals, or group-sequential boundaries. Repeatedly checking a fixed-horizon p-value against 0.05 pushes the real false-positive rate well above 5 percent.
Questions & practice
Explain the mathematical foundation of Logistic Regression and how you would interpret its coefficients.
Medium · machine learning and modelling
Approach
- Pick an evaluation metric that matches the cost of each error type, not a default.
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- 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?
- Where could label leakage enter this setup?
How would you approach building a predictive maintenance model for aircraft engines using sensor telemetry data?
Medium · machine learning and modelling
Approach
- Frame the prediction: the label, the moment of prediction, and the action it triggers.
- 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
- What would you monitor after launch to know the model is still valid?
- Where could label leakage enter this setup?
Expand bookings into stay nights without losing cents
Easy · pandas · reshaping · revenue allocation · vectorisation
You are given a pandas DataFrame bookings with columns booking_id, check_in_date, check_out_date, nights, unit_revenue_usd (the booking total, two decimal places), about 200,000 rows. Write a function returning stay_nights at one row per booking per stay date, with columns booking_id, stay_date, night_index (1-based) and unit_revenue_usd allocated across the nights so the per-booking sum equals the original to the cent. No per-row Python loop and no apply over rows. State your rule for the departure date.
Approach
- Confirm the grain rule first: a stay night is the arrival date through the night before check_out_date, so nights = (check_out_date - check_in_date).days and the departure date is never a row. Assert this against the stored
nightscolumn and report mismatches rather than trusting either side. - Build the expansion arithmetically instead of materialising date lists: counts = nights.to_numpy(); starts = np.repeat(np.cumsum(counts) - counts, counts); offsets = np.arange(counts.sum()) - starts. That gives a 0-based night offset per output row in one pass, and night_index = offsets + 1.
- Compute stay_date as np.repeat(check_in_date.to_numpy(), counts) + offsets.astype('timedelta64[D]'). This is O(total nights) with no grouping and no Python-level iteration.
- Allocate revenue in integer cents, not floats: cents = np.rint(unit_revenue_usd * 100); base = cents // counts; remainder = cents - base * counts; give the first
remaindernights of each booking one extra cent. Dividing floats by nights leaves sub-cent drift that re-sums to 99.99 or 100.01 on a large fraction of bookings. - Verify by grouping the output back to booking_id and comparing integer cents to the input, then state which downstream numbers depend on this reconciliation (net revenue per sellable night, take rate, contribution margin per stayed night all read the night grain).
Worked solution (25 min)
- Assert (check_out_date - check_in_date).dt.days equals nights; raise on any mismatch and print the offending booking_ids rather than silently trusting the column.
- Build counts, starts and offsets with np.repeat and np.arange as above; total output rows equals counts.sum().
- Derive stay_date by adding the day offsets to the repeated check_in_date, and night_index as offsets + 1.
- Allocate integer cents with floor division plus largest-remainder top-up on the first
remaindernights of each booking. - Reconcile: group the output by booking_id, sum the cents, compare exactly to the input cents, assert zero differing rows.
Expected result: Output row count equals bookings.nights.sum(). A three-night booking of 100.00 USD splits 33.34 / 33.33 / 33.33 and sums to exactly 100.00. Every booking's maximum stay_date is check_out_date minus one day, and night_index runs 1..nights with no gaps.
Verify it yourself
- len(stay_nights) == bookings['nights'].sum()
- Per-booking sum of allocated cents equals the input cents exactly, for all rows, with no tolerance needed
- stay_nights.groupby('booking_id')['stay_date'].max() == check_out_date - 1 day, and .min() == check_in_date
- night_index per booking has min 1, max nights, and nunique equal to nights
Follow-up
- The booking is later amended from three nights to five. What has to happen to the already-written night rows, and which of them may not be rewritten?
- Nights of one booking fall in two calendar months and two tax jurisdictions. Does your equal-split allocation still defend the monthly revenue number, and when would you weight nights by the nightly listed price instead?
Write a SQL query to calculate the rolling average of flight delays by airport over a seven-day window.
Medium · sql and data manipulation
Approach
- Say which table is the grain you start from, and join outward from it.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- Compute rates by summing numerator and denominator separately, never by averaging rates.
Follow-up
- What breaks if events arrive late or out of order?
- How does the query change if the join becomes one-to-many?
Explain the difference between a LEFT JOIN and an INNER JOIN in the context of combining flight schedules with crew assignments, and how mismatched keys are handled.
Medium · sql and data manipulation
Approach
- Compute rates by summing numerator and denominator separately, never by averaging rates.
- Check whether any join is one-to-many before aggregating, or the sums inflate.
- State the window function and its partition and ordering out loud before writing it.
Follow-up
- How does the query change if the join becomes one-to-many?
- How would you verify this result without re-running the same query?
Sessionise search streams with a thirty-minute inactivity gap
Medium · sessionisation · window-functions · event-streams
fct_search has search_id, visitor_id, traveller_id (NULL while logged out), searched_at_utc, device_type, trip_intent_key and is_bot_flagged. Sessionise non-bot searches: a new session begins when the gap since that visitor's previous search on the same device exceeds 30 minutes. Return one result with a session identifier per search row, and a second result giving median and 90th-percentile searches per session, plus median sessions per trip_intent_key. Partition on visitor_id and device_type.
Approach
- Filter bots out first, then take LAG(searched_at_utc) OVER (PARTITION BY visitor_id, device_type ORDER BY searched_at_utc, search_id). The search_id tiebreak keeps ordering stable when two rows share a timestamp to the second.
- Raise a boundary flag where the previous timestamp is NULL or the gap exceeds 30 minutes. The NULL case is the first row of each partition and must count as a boundary, which an explicit IS NULL test or a COALESCE handles.
- Convert flags into a session index with SUM(flag) OVER (PARTITION BY visitor_id, device_type ORDER BY searched_at_utc ROWS UNBOUNDED PRECEDING). A running sum, not a row number, is what makes consecutive rows share one value.
- Concatenate visitor_id, device_type and the index into a session key, then aggregate once at session grain and once at trip_intent_key grain.
- Report medians and a high percentile rather than means: searches per session is heavily right-skewed by a small number of long comparison sessions, and the mean tracks that tail.
Worked solution (30 min)
- Check what share of non-bot search rows have traveller_id NULL; that number is the argument for partitioning on visitor_id and is worth saying before writing the window.
- Build the LAG and gap columns and inspect the gap distribution around the 30-minute mark before committing to the threshold.
- Add the boundary flag and the running sum, then verify that no session contains an internal gap above the threshold.
- Aggregate to session and intent grain and report median and 90th percentile side by side.
Expected result: One row per non-bot search with a stable session key, and a summary where median searches per session sits in the low single digits while the 90th percentile is several times higher.
Verify it yourself
- The maximum within-session gap is at or below 30 minutes.
- Summing searches across all sessions equals the filtered search row count exactly.
- A visitor with exactly one search produces exactly one session, not zero; if it produces zero, the NULL LAG is not being treated as a boundary.
Follow-up
- Why 30 minutes? What would you look at in this data to choose or defend the threshold?
- One trip intent spans four sessions across two devices. What does that do to a conversion metric denominated on sessions, and which denominator would you use instead?
- How do you stitch a logged-out visitor to a traveller_id when they sign in halfway through a session, and what does tracking_consent = 'denied' do to that plan?
If a major storm is expected to disrupt operations at a major hub like Dallas/Fort Worth (DFW), how would you use data to minimize the impact on connecting passengers?
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.
- Fix the population and the time window before naming any metric.
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?
How do you stay updated on the latest trends in data science, and how have you applied a new technique to a recent project?
Medium · product sense and metrics
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.
- Decompose the metric into the rates that drive it, and say which one you would check first.
Follow-up
- What would you do if the primary metric and the guardrail moved in opposite directions?
- Which segment would you cut first, and what would that rule out?
What is Principal Component Analysis (PCA), and how would you use it to reduce dimensionality in a dataset with hundreds of flight-performance metrics?
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.
- 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?
What metrics would you track to measure the success of a newly implemented dynamic pricing algorithm?
Medium · product sense and metrics
Approach
- Decompose the metric into the rates that drive it, and say which one you would check first.
- State what result would change your recommendation, so the answer is falsifiable.
- 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?
Fix a test that was peeked at daily across fourteen metrics
Medium · peeking · sequential-testing · multiple-comparisons
A 21-day test was watched on a dashboard of 14 metrics refreshed every morning. On day 6 one guardrail, traveller-initiated cancellation rate, crossed p = 0.03 and the test was stopped. Quantify how much six daily looks inflate the false-positive rate, quantify the family-wise rate across 14 independent metrics at alpha = 0.05, specify the monitoring scheme you would have set up instead including the boundary values, and say what can still be concluded from the stopped test.
Approach
- Give the peeking numbers rather than a warning. Repeated fixed-sample testing at alpha = 0.05 with k equally spaced looks gives an actual type I error of roughly 0.083 at k = 2, 0.142 at k = 5, 0.193 at k = 10 and 0.246 at k = 20, and it tends to 1 under continuous monitoring. Six looks sits near 0.15.
- Give the multiplicity number: 1 - 0.95^14 = 0.512 under independence. The 14 metrics are correlated so the true family-wise rate is lower, but it is nowhere near 0.05, and combined with daily looks something was always going to cross.
- State the inferential consequence plainly: the stopping time is a function of the data, so the day-6 nominal p-value is not a p-value and the effect estimate at a data-dependent stopping time is biased away from zero. Report the point estimate with no significance claim attached, not a corrected p-value invented afterwards.
- Specify the replacement: one pre-registered primary metric with a pre-registered readout date, plus a group-sequential boundary for the looks you genuinely need. Pocock at five equally spaced looks tests each at nominal alpha = 0.0158; O'Brien-Fleming spends almost nothing early, with nominal boundaries near 0.000005, 0.0013, 0.0084, 0.0228 and 0.0417. Choose O'Brien-Fleming when you expect to read at the planned end and want the final look to keep most of its alpha.
- Handle the guardrail panel differently from the primary. Guardrails want sensitivity, so control FDR with Benjamini-Hochberg at q = 0.1 across the family rather than FWER, and frame each as a one-sided non-inferiority test against a margin written down in advance, for example cancellation rate must not rise by more than 0.5 percentage points.
- Keep a separate operational circuit breaker with a catastrophic threshold, documented explicitly as a safety rule rather than as evidence, so that stopping for a real emergency never has to masquerade as a statistical decision.
Worked solution (30 min)
- Read the peeking inflation for six looks off the equally-spaced schedule: about 0.15 against a nominal 0.05.
- Compute 0.95^14 = 0.4877 so the family-wise rate is 0.512, and state that correlation between metrics lowers this but does not rescue it.
- Combine informally: with roughly 14 metrics and 6 looks the number of independent-ish opportunities is large enough that at least one crossing under the null is the expected outcome, not a surprise.
- Write the replacement plan: one primary metric, O'Brien-Fleming boundaries over the looks actually required, BH at q = 0.1 across guardrails, non-inferiority margins fixed in advance, readout date fixed in advance.
- Re-state the salvage: the day-6 cancellation estimate is a point estimate with an optimistically biased magnitude and no valid p-value, so the honest action is to rerun under the new scheme.
Expected result: Six daily looks lift the false-positive rate from 0.05 to roughly 0.15; 14 independent metrics at alpha = 0.05 give a 51.2% chance of at least one false positive. The day-6 result carries no valid inference and the test must be rerun under a pre-registered sequential scheme.
Verify it yourself
- Simulate the exact monitoring rule under the null by bootstrapping the pre-period and applying the same 14-metrics-by-6-days stopping rule; the empirical false-positive rate from that simulation, not a textbook number, is what you quote in the write-up.
- Verify the chosen alpha-spending function sums to 0.05 across the planned looks.
- Confirm the guardrail non-inferiority margins exist in a document dated before the test started; if they do not, they are being chosen against the data.
Follow-up
- The business has a genuine reason to stop early. What is the correct analysis in that case?
- Why FDR rather than Bonferroni for the guardrail panel, and what would change your mind?
- You choose an always-valid confidence sequence so the dashboard can be watched continuously. What do you give up?
App conversion jumped while bookings stayed flat after a release
Easy · instrumentation · conversion-rate · platform-cut · release
Qualified intent-to-booking rate on app_ios rose from 4.1% to 5.6% the day after a client release. Desktop and mobile_web are unchanged, and app_ios bookings are flat in absolute terms. You have fct_search (search_id, trip_intent_key, visitor_id, searched_at_utc, device_type, results_returned_count, is_bot_flagged) and fct_booking (trip_intent_key, booked_at_utc). Decide whether this is a product win or a logging change, and say what you would tell the team that shipped it. Deliverable: a one-paragraph verdict plus the two numbers that settle it.
Approach
- Stop looking at the ratio. Plot the numerator (distinct trip_intent_key with a booking within the 7-day window) and the denominator (distinct eligible trip_intent_key) as separate absolute series by device_type. A ratio that moves because one side collapsed is not a behaviour change, and the levels say which side it was.
- If the denominator fell, find which searches stopped arriving. Cut fct_search row counts by device_type and by results_returned_count bucket at hourly resolution across the rollout, so the changepoint lines up with the deploy rather than with a calendar boundary.
- Compute searches per trip_intent_key by device and week. Searches per intent is an interface property, not a demand property, so a release that removed a re-sort control or stopped logging refinements moves it first and moves it only on the affected platform.
- Check whether the loss is selective. The denominator excludes results_returned_count = 0 by definition, so zero-result searches disappearing changes the denominator's composition as well as its size, and the two have different implications.
- Exploit the rollout shape. A staged release leaves un-upgraded clients on the same days, which is the cleanest available comparison and costs nothing to construct.
Follow-up
- Searches per intent fell from 9.2 to 5.8 on iOS only. What would make you call that a real interface improvement rather than lost events?
- How would you make this metric robust to a logging change, so the next one is caught by the metric rather than by somebody noticing?
- The release also rotated visitor_id per session. What does that do to trip_intent_key, and in which direction does it push this rate?
Suggested practice checklist
Roughly 90 minutes a night on weekdays with one longer weekend block. The plan deliberately cuts scope rather than compressing everything, on the assumption that finishing one thing a night beats half-starting four.
Day 1 — Fix the scope and set a baseline
- Read the role description and write the three things the loop will almost certainly test, then write an explicit not-doing list for everything else and keep it visible all week.
- Take one 20-minute SQL prompt and one 10-minute metric question cold, and write the single sentence that says what blocked each attempt, since that sentence is what decides which two topics get the most evenings.
- Set the week's one rule: one problem finished to completion every night, including the night you only have 40 minutes.
Deliverable: A one-page scope with an explicit not-doing list and two cold attempts, each carrying one sentence on what blocked it.
Day 2 — One query pattern, written three times
- Choose the single pattern most likely to appear (a cohort retention grid, or a funnel counted by user) and write it three times from a blank file rather than editing the previous attempt.
- On the third attempt, write the grain of every CTE as a comment before writing its body.
- Stop at 90 minutes even if the third version is imperfect, and write the one thing you would fix with another hour.
Deliverable: Three independent versions of the same query plus a note on what changed between them.
Day 3 — Only the statistics you will be asked to defend
- Write, in under 200 words, how you would decide whether a difference between two groups is real: the test, its assumptions, and what you would switch to when an assumption fails.
- Compute a 95 percent confidence interval for a difference in proportions by hand on realistic numbers, then write in one sentence what changes if the two samples are paired rather than independent.
- Write your answer to "what does a p-value mean", check it against a definition, and delete the version that describes it as the probability the hypothesis is true.
Deliverable: A 200-word written answer and one hand-computed interval you can reproduce under pressure.
Day 4 — One case, and the assumptions holding it up
- Answer one product case aloud in 20 minutes with a recording running, then listen back with a pen and mark every claim you asserted without saying what it rested on: an assumed user behaviour, an assumed data source, an assumed baseline rate, an assumed grain.
- Pick the three assumptions the recommendation actually depends on, write how you would check each one against data, and say which one being wrong would flip the recommendation rather than merely weaken it.
- Write the four-step structure you used onto a card small enough to hold in working memory when you are nervous.
Deliverable: One recording, three load-bearing assumptions each with a written check, and a four-step structure card.
Day 5 — Your own work, timed
- Write a 90-second version and a four-minute version of your main project, and time both out loud rather than reading them.
- Prepare answers to the two follow-ups that always come: what you would do differently, and how you knew it worked.
- Put one number in the first sentence and be able to say exactly where that number came from and what it excludes.
Deliverable: Two timed narratives with one defensible number in the opening line.
Day 6 — The one full rehearsal, in a longer weekend block
- Run a 60-minute mock covering query work, a case and a behavioural question in a single sitting with no breaks, because sustained attention is the thing evenings have not trained.
- Immediately afterwards, and before hearing any feedback, write the three moments you lost the thread.
- Spend the rest of the block only on those three moments, and on nothing you merely feel shaky about.
Deliverable: Mock notes naming three failure moments with a specific fix written under each.
Day 7 — Taper
- Write the 20-minute warm-up you will actually do on the morning of the interview: one query you can already write from a blank file, one metric you can define out loud, and nothing you have never seen before.
- Re-read only your own notes from this week, and open no new material.
- Write down the logistics: the tool you will be asked to work in, whether lookups are allowed, and the sentence you will use when you do not know something.
Deliverable: A one-page card holding the case structure, the project numbers, and the logistics.
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.
Why do you want to work at American Airlines, and what is your understanding of our current operational challenges?
Medium · behavioural and stakeholder questions
Approach
- State the situation in two sentences and spend the rest on your reasoning.
- Quantify the outcome, including what you would not claim credit for.
- Close with what you would do differently, concretely.
Follow-up
- What would you do differently if you ran that project again?
- How did you know the outcome was caused by your change?
Refuse the denominator that flatters a launch
Medium · integrity · occupancy denominators · supply withdrawal
A launch review is tomorrow. Occupancy computed on sellable nights, SUM(units_sold_to_date + units_available) from fct_rate_availability_snapshot, shows the launch market up 0.4pp. Computed on physical capacity, capacity_units from dim_supply_unit, it shows up 2.1pp, because individual_host suppliers blocked dates during the period and units_blocked is excluded from the first denominator but inside the second. The launch owner asks you to use the second, noting it is a documented convention. Prepare your response and what you put in the review document.
Approach
- Confirm the mechanism before objecting, because the owner is right that both conventions exist. The difference here is not convention, it is that units_blocked grew during the measurement window, so the capacity-based number rises partly because supply was withdrawn rather than because more nights were sold.
- Separate the two movements numerically: hold units_blocked at its pre-period level and recompute the capacity-based figure. Whatever remains of the 2.1pp after that is the real effect, and the difference is the withdrawal.
- Reframe the blocking as a finding rather than an inconvenience. Hosts blocking dates during a launch is a supplier-side signal the launch owner needs, and it may matter more than the occupancy delta.
- Put both numbers in the document with their denominators named in the row labels, plus the blocked-nights level as a separate line, so the reader can see the mechanism without being told which number to prefer.
- Make the ask specific and small: pick one convention for this review, state it in the chart title, and never mix the two inside a single comparison. This is easier to agree to than a debate about which figure is right.
Follow-up
- The owner says the blocking is seasonal and unrelated to the launch. How do you test that?
- Your manager wants you to let it go because the difference is small. What do you do?
- How would you stop this ambiguity reaching a review document next time?
Rank three urgent requests with one analyst-week
Easy · prioritisation · stakeholder management · scoping
You have one week. The pricing team wants a price elasticity for a constrained market to set next quarter's strategy. The supplier team wants a list of suppliers at risk of delisting, for outreach starting Monday. Finance needs a closed stay-month restated after a batch of late cancellations changed platform_net_revenue_usd on fct_stay_night, ahead of a reporting deadline on Thursday. All three escalated to your manager. Produce your order, the reason for each position, and the message you send to whoever is deferred.
Approach
- Sort by deadline irreversibility rather than by who escalated hardest. The finance restatement has an external reporting date, so a miss cannot be recovered later; the other two can start a week late at a cost.
- Check each request for a cheap partial that unblocks the requester without the full job: the supplier team needs a ranked outreach list to start Monday, not a churn model, so a ranked cut on rating_avg, listing_status and recent availability withdrawal may be a few hours rather than days.
- Push back on the elasticity on substance, not capacity. On constrained inventory, price is set from a demand forecast and sold-out unit-dates record capacity rather than demand, so a fast estimate would be biased toward zero and could come out positive; say what you would deliver instead and what a clean estimate would cost.
- Write the deferral message with a date, a reason the requester can verify, and a concrete alternative, because a deferral without a date gets re-escalated within 48 hours.
- Take the ordering to your manager as a decision already made with a named tradeoff, not as a question, and include what you will drop if a fourth request arrives.
Follow-up
- The pricing team says a rough elasticity is better than nothing. What do you give them?
- Two days in, finance's restatement turns out to be twice the size you scoped. What gives?
- How would you stop all three landing in the same week next quarter?