← Early-stage Startup Interview Insights

Early-stage Startup·Data Scientist·Technical Phone Screen·Senior

Senior
Apr 2026

Summary

Technical screen for a data scientist role, heavy on Python internals and pandas. Four questions back to back, no small talk, felt more like a written exam than a conversation.

Questions Asked (4)

Q1

What are the memory and evaluation differences between list comprehensions and generators in Python? Write a generator that yields rolling windows of size k over a list.

Technical Trade-offsAlgorithms & Data Structures
Author's notes

The conceptual part was fine, eager vs lazy evaluation, one materializes everything into memory and the other doesn't.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by contrasting list comprehensions and generators in terms of memory usage and evaluation strategy, emphasizing that list comprehensions build the entire list in memory while generators produce items lazily. Then, demonstrate your understanding by writing a generator function that yields rolling windows of size k, ensuring it handles edge cases like k > len(list) or k <= 0. Conclude by discussing when to use each approach in data science workflows.

Pro tip: Mention that generators can handle infinite streams and large datasets that don't fit in memory, which is crucial for data science pipelines. Also, note that list comprehensions are faster for small datasets due to optimized C implementation, but generators save memory for large data.

1. Define list comprehensions and generators

Briefly explain that list comprehensions create a new list by evaluating an expression for each item in an iterable, while generators produce items one at a time using yield, pausing and resuming execution.

2. Compare memory usage

Highlight that list comprehensions store all results in memory, leading to O(n) memory usage, whereas generators use O(1) memory as they generate items on the fly.

3. Compare evaluation strategy

Explain that list comprehensions are eagerly evaluated (all at once), while generators are lazily evaluated (on demand), which affects performance and suitability for large or infinite data.

4. Write the rolling window generator

Implement a generator function that takes a list and window size k, and yields tuples of consecutive elements. Use a loop with slicing or deque for efficiency, and handle edge cases.

5. Discuss trade-offs and use cases

Summarize when to use each: list comprehensions for small, repeated access; generators for large data, streaming, or memory-constrained environments. Relate to data science tasks like batch processing.

Key Points to Mention

  • Memory efficiency: generators use constant memory, list comprehensions use linear memory.
  • Lazy evaluation: generators compute values on demand, enabling infinite sequences.
  • Performance: list comprehensions are often faster for small datasets due to optimized C loops.
  • Use cases: generators for large datasets, streaming data, or pipelines; list comprehensions for small, reusable collections.
  • Implementation details: using yield, handling edge cases like k > len(list) or k <= 0.
  • Data science relevance: processing large datasets without loading into memory, feature engineering with sliding windows.

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

Q2

In CPython 3.x, what is the maximum integer value and why?

Technical Trade-offs
Author's notes

There isn't one, CPython integers are arbitrary precision.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying that in CPython 3.x, integers are arbitrary-precision, so there is no fixed maximum value. Then explain that the limit is only constrained by available memory and system resources, and mention that Python 3 removed the distinction between int and long. Finally, relate this to practical data science scenarios where large integers might appear.

Pro tip: Mention that while Python integers are unbounded, operations on very large integers can be slow and memory-intensive, so for performance-critical tasks, consider using NumPy's fixed-width integers or other optimized libraries.

1. Clarify the premise

State that CPython 3.x does not have a maximum integer value; integers are arbitrary-precision. This corrects the assumption in the question.

2. Explain the implementation

Describe how Python 3 unified int and long, and that integers are stored as arrays of digits, growing as needed. The only limit is available memory.

3. Discuss practical implications

Mention that while you can compute with huge integers, performance and memory usage degrade. For data science, this matters when handling large IDs or cryptographic operations.

4. Contrast with other languages

Briefly note that languages like C or Java have fixed-size integers (e.g., 32-bit or 64-bit), which can overflow. Python avoids this at the cost of speed.

5. Relate to the role

Connect to data science: e.g., when dealing with large factorial calculations, big integers in pandas may be object dtype, or using Python ints for exact arithmetic in algorithms.

Key Points to Mention

  • Python 3 integers are arbitrary-precision (no max value).
  • The limit is determined by available memory (RAM) and system architecture.
  • Python 3 removed the int/long distinction; all integers are of type int.
  • Operations on very large integers are slower and more memory-intensive.
  • For performance, consider fixed-width types from NumPy or other libraries.
  • In data science, large integers may appear in IDs, cryptography, or exact computations.

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

Q3

Show a bug that arises from Python's pass-by-object-reference when a function mutates a list argument, then fix it.

Technical Trade-offsAlgorithms & Data Structures
Author's notes

Classic gotcha and I've seen it before, but I fumbled the explanation of why it happens.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clearly explaining Python's pass-by-object-reference semantics: arguments are references to objects, and mutating a mutable object inside a function affects the caller's object. Then demonstrate a concrete bug where a function unexpectedly modifies a list argument, and show a fix by either copying the list or returning a new list instead of mutating in place.

Pro tip: Emphasize that this behavior is not a bug in Python but a common source of bugs in code; showing awareness of when mutation is intentional versus accidental demonstrates maturity. Also mention that in data science, such bugs can silently corrupt datasets, so defensive copying or using immutable structures is often wise.

1. Explain Python's argument passing

Clarify that Python passes references to objects by value, meaning the function receives a reference to the same object. For mutable objects like lists, modifications inside the function affect the original object.

2. Demonstrate the bug

Write a short function that takes a list and mutates it (e.g., appends an element or sorts it) without the caller expecting it. Show how the original list is changed after the function call.

3. Identify the root cause

Point out that the bug arises because the function modifies the list in place, and the caller's reference points to the same list. This can lead to unintended side effects, especially in larger codebases.

4. Provide a fix

Show two common fixes: (a) make a copy of the list inside the function before mutating (e.g., using list.copy() or slicing), or (b) return a new list instead of mutating the input. Discuss trade-offs like performance and memory.

5. Relate to data science context

Explain how this bug can manifest in data pipelines, e.g., a preprocessing function that modifies a DataFrame or list in place, leading to data leakage or incorrect results. Suggest best practices like using pure functions or documenting mutation.

Key Points to Mention

  • Python's pass-by-object-reference (also called pass-by-assignment) semantics
  • Difference between mutable and immutable objects in Python
  • In-place mutation vs. creating a copy (shallow vs. deep copy)
  • Using list.copy(), slicing [:], or copy.deepcopy() for nested structures
  • Returning new objects instead of mutating arguments (functional style)
  • Potential side effects in data science workflows (e.g., modifying DataFrames in place)

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

Q4

Given a pandas DataFrame with columns for user ID, event date, event type, and revenue, compute per-country 7-day conversion rate for a specific date and total revenue using groupby and boolean indexing. No row-wise apply allowed.

Product Analytics & MetricsData Modeling
Author's notes

This was the hardest one.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

First, clarify the data schema and define the 7-day conversion window (e.g., users who converted within 7 days of their first event). Then, use boolean indexing to filter events within the relevant date range, and groupby with aggregation to compute per-country conversion rates and total revenue. Avoid row-wise apply by leveraging vectorized operations like groupby, transform, and merge.

Pro tip: Always validate your conversion definition with the interviewer—whether it's based on first-touch or last-touch attribution—as this can drastically change the metric. Also, mention that you'd handle time zones and missing data explicitly to avoid silent errors.

1. Clarify requirements and define conversion

Ask clarifying questions about the conversion event, the 7-day window (e.g., from first event or from a specific date), and how to handle multiple conversions. Confirm the target date and whether revenue should be summed for converters only or all users.

2. Filter and prepare data

Use boolean indexing to select events within the relevant time frame (e.g., 7 days before and after the target date). Ensure date columns are datetime objects and handle any missing or invalid entries.

3. Identify converters per country

Group by user ID and country to find users who performed the conversion event within 7 days of their first event (or the specified window). Use groupby with transform or agg to flag converters without row-wise apply.

4. Compute conversion rate and revenue

Group by country to calculate the conversion rate (number of converters divided by total users) and total revenue (sum of revenue for converters or all users, as defined). Use vectorized operations like groupby.agg with custom functions or named aggregations.

5. Validate and present results

Sanity-check the numbers (e.g., conversion rate between 0 and 1, revenue non-negative) and be prepared to explain the logic. Optionally, discuss how to handle edge cases like users with no events.

Key Points to Mention

  • Definition of conversion: which event type counts and the 7-day window (e.g., from first event or from a specific date).
  • Use of boolean indexing to filter events by date range and event type.
  • Groupby operations: grouping by user ID and country to identify converters, then grouping by country for aggregation.
  • Avoiding row-wise apply by using vectorized methods like groupby.transform, merge, and boolean masks.
  • Handling of time zones and date normalization to ensure accurate 7-day windows.
  • Validation of results: checking for missing data, ensuring conversion rate bounds, and cross-verifying with a sample.

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