← Headway Interview Insights

Headway·Software Engineer·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
Jun 2026Remote

Summary

Coding round at Headway for a software engineering role. The problem looked like a stats/probability question dressed up as a racing leaderboard, which threw me off at first. Mostly about finding bugs in starter code and writing tests, not greenfield design.

Questions Asked (3)

Q1

Given a list of racers each with a list of completion times, implement a function that returns the smallest personal-best time across all racers, where each racer's personal best is their minimum time.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Pretty mechanical once you see it.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the input format and edge cases, then propose a two-level reduction: for each racer, find their minimum time, and then find the minimum across those personal bests. Discuss time and space complexity, and consider trade-offs between readability and performance.

Pro tip: Mention that you can solve this in a single pass without storing all personal bests, which shows you think about memory efficiency. Also, proactively discuss how to handle empty lists or missing data, demonstrating attention to robustness.

1. Clarify the problem

Ask about input constraints: Are racers guaranteed to have at least one time? Can times be negative or zero? What should be returned if the list is empty? This ensures you handle edge cases correctly.

2. Outline the approach

Explain that you'll iterate through each racer, compute their minimum time, and keep track of the global minimum. Alternatively, you can flatten the list and find the overall minimum, but that may be less efficient.

3. Analyze complexity

State that the time complexity is O(N) where N is the total number of times, since each time is visited once. Space complexity is O(1) if you compute on the fly, or O(R) if you store personal bests (R = number of racers).

4. Discuss trade-offs

Compare approaches: using built-in min functions for readability vs. manual loops for performance. Mention that a single pass avoids extra space and is optimal.

5. Handle edge cases

Propose returning null, -1, or throwing an exception for empty input, depending on requirements. Also consider racers with empty time lists.

Key Points to Mention

  • Time complexity: O(N) where N is total number of times
  • Space complexity: O(1) with single-pass approach
  • Edge cases: empty input, racers with no times, negative times
  • Readability vs. performance trade-offs
  • Use of built-in functions like min() for clarity
  • Single-pass vs. two-step reduction

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q2

Implement a function that estimates the probability that a given candidate time would be a new personal best for a racer, based on their history. The model assumes times are drawn from a normal distribution fit to the history, and returns the probability that a fresh draw falls below the current minimum.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

This is where I spent most of my time.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem: we need to estimate P(new time < current minimum) given a normal distribution fitted to historical times. Then outline the steps: compute sample mean and standard deviation, use the normal CDF to find the probability that a new draw is below the current minimum, and discuss edge cases and assumptions. Finally, mention potential improvements like handling non-normal data or using Bayesian methods.

Pro tip: Acknowledge that the normal distribution may not be ideal for race times (which are often skewed and bounded below), and suggest validating the fit or considering a log-normal or truncated normal distribution. This shows you think critically about model assumptions.

1. Clarify the problem and inputs

Confirm that we have a list of historical times and the current personal best (minimum). The goal is to compute the probability that a new time is less than the current minimum.

2. Fit a normal distribution

Calculate the sample mean and sample standard deviation (with Bessel's correction) from the historical times. These are the parameters of the normal distribution.

3. Compute the probability

Use the normal CDF: P(X < min) = Φ((min - μ) / σ). This gives the probability that a new draw is below the current minimum.

4. Handle edge cases and assumptions

Discuss what happens with small sample sizes, zero variance, or if the minimum is far in the tail. Also mention that the normal assumption may not hold for race times.

5. Suggest improvements or alternatives

Propose using a log-normal distribution, truncated normal, or Bayesian estimation to better model race times and incorporate uncertainty in the parameters.

Key Points to Mention

  • Sample mean and standard deviation as estimators for μ and σ
  • Using the normal CDF to compute P(X < min)
  • Bessel's correction for sample standard deviation
  • Assumption of independence and identical distribution (i.i.d.) for historical times
  • Limitations of the normal distribution for race times (skewness, lower bound)
  • Potential use of log-normal or truncated normal distributions
  • Handling small sample sizes and parameter uncertainty (e.g., Bayesian approach)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.

Q3

Identify the bugs in the provided starter code for both functions, fix them, and add unit tests covering the corrected behavior.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Writing the tests was fine but I defaulted to happy-path cases first.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, read the starter code carefully and trace through it with sample inputs to identify logical errors, edge cases, and off-by-one mistakes. Then, fix each bug with minimal changes, explaining your reasoning, and finally write unit tests that cover normal cases, edge cases, and the specific bugs you fixed.

Pro tip: Before diving into fixes, clarify the expected behavior and constraints with the interviewer—this shows you think before coding and helps avoid solving the wrong problem. Also, write tests that would fail on the original buggy code to prove your fixes are correct.

1. Understand the code and expected behavior

Read the starter code and identify what each function is supposed to do. Ask clarifying questions about input/output types, edge cases, and constraints.

2. Trace and identify bugs

Walk through the code with simple examples, including edge cases like empty inputs, single elements, or negative numbers. Note any incorrect logic, off-by-one errors, or missing handling.

3. Fix bugs and explain reasoning

Make minimal, correct changes to fix each bug. Explain why the original was wrong and how your fix addresses it, considering time/space complexity.

4. Write unit tests

Create tests for normal cases, edge cases, and the specific bugs you fixed. Ensure tests are clear and would fail on the original code.

5. Review and discuss trade-offs

Summarize your fixes, run through tests mentally, and discuss any alternative approaches or trade-offs (e.g., readability vs. performance).

Key Points to Mention

  • Edge cases such as empty inputs, null values, single-element arrays, and boundary conditions
  • Time and space complexity of the original and fixed code
  • The importance of writing tests that specifically target the bugs found
  • Clear communication of your debugging process and reasoning
  • Potential trade-offs between different fixes (e.g., simplicity vs. efficiency)
  • How you would verify the fixes beyond unit tests (e.g., integration tests, manual testing)

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.