← Upstart Interview Insights

Upstart·Data Scientist·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
Jul 2026Remote

Summary

Upstart data scientist interview with two technical sections back to back: a multi-table SQL problem and a pair of Python/Pandas questions. Pretty heads-down stuff, no behavioral fluff, just code.

Questions Asked (3)

Q1

Write a single SQL query to compute click-through rate (CTR) broken out by pin format, but only for US users who signed up within 30 days of the event date. Return impressions, clicks, CTR rounded to 4 decimal places, and distinct new user count per pin format.

Product Analytics & MetricsData Modeling
Author's notes

This one had a lot of moving parts.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by identifying the necessary tables and joins: events (impressions and clicks), users (signup date and country), and pins (format). Filter for US users whose signup date is within 30 days before the event date, then aggregate by pin format to compute impressions, clicks, CTR, and distinct new users. Use conditional aggregation to count impressions and clicks separately, and ensure CTR is calculated as clicks divided by impressions, rounded to 4 decimal places.

Pro tip: Clarify the definition of 'new user'—it could mean users who signed up within 30 days of the event, or users whose first event is within that window. Also, consider whether to use COUNT(DISTINCT user_id) for new users or a separate metric, and handle potential division by zero in CTR.

1. Identify tables and join keys

Determine which tables contain event data (impressions, clicks), user data (signup date, country), and pin data (format). Join them on user_id and pin_id as appropriate.

2. Filter for US users and signup window

Apply a WHERE clause to include only users with country = 'US' and whose signup date is within 30 days before the event date (e.g., event_date BETWEEN signup_date AND signup_date + INTERVAL '30 days').

3. Aggregate metrics by pin format

Use GROUP BY pin_format and compute SUM(CASE WHEN event_type = 'impression' THEN 1 ELSE 0 END) for impressions, similarly for clicks, and COUNT(DISTINCT user_id) for new users.

4. Calculate CTR and round

Compute CTR as clicks divided by impressions, using NULLIF to avoid division by zero, and round to 4 decimal places with ROUND(..., 4).

5. Finalize query and consider edge cases

Ensure the query returns the required columns in the correct order. Consider if there are multiple event types or if clicks and impressions are in separate tables, requiring UNION or JOIN.

Key Points to Mention

  • Use conditional aggregation (CASE WHEN) to count impressions and clicks from a single events table.
  • Filter for US users and ensure signup_date is within 30 days before event_date.
  • Calculate CTR as clicks / impressions, using NULLIF to handle zero impressions.
  • Round CTR to 4 decimal places using ROUND function.
  • Count distinct new users per pin format, ensuring the definition of 'new user' aligns with the signup window.
  • Consider performance implications of COUNT(DISTINCT) and potential need for indexing or subqueries.

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

Q2

Given a DataFrame with pin engagement data and a category ID to name mapping dict, find the category name with the highest average time spent among video pins (case-insensitive match). Break ties by lexicographic order, exclude nulls, and do it without looping over rows.

Algorithms & Data StructuresProduct Analytics & Metrics
Author's notes

The case-insensitive filter tripped me up slightly.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by filtering the DataFrame to video pins and dropping rows with nulls in the relevant columns. Then normalize the category IDs for case-insensitive matching, map them to names, compute the average time spent per category using groupby, and finally select the category with the highest average, breaking ties by lexicographic order.

Pro tip: Mention that you would validate the mapping dictionary for missing or duplicate keys and handle them appropriately, as this shows attention to data quality and edge cases.

1. Filter and clean data

Filter the DataFrame to include only video pins and drop any rows with null values in the category ID or time spent columns.

2. Normalize and map categories

Convert category IDs to a consistent case (e.g., lowercase) and map them to category names using the provided dictionary, handling any unmapped IDs.

3. Compute average time per category

Group the filtered DataFrame by category name and calculate the mean time spent for each category.

4. Select top category with tie-breaking

Sort the resulting averages in descending order and then by category name in ascending lexicographic order, and pick the first category.

Key Points to Mention

  • Vectorized operations using pandas (e.g., boolean indexing, groupby, agg) to avoid row-wise loops.
  • Case-insensitive matching by normalizing both the DataFrame's category IDs and the mapping dictionary keys (e.g., using .str.lower()).
  • Handling nulls by dropping or filling them before aggregation, ensuring they don't affect the average.
  • Tie-breaking logic: when multiple categories have the same highest average, choose the one that comes first lexicographically.
  • Efficiency considerations: avoiding loops, using built-in pandas methods for performance.
  • Validation of the mapping dictionary: checking for missing keys or duplicates that could cause errors or unexpected results.

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

Q3

Given a dict mapping users to lists of pin IDs (with possible duplicates), compute the mean number of unique pins per user. Handle empty lists, very large inputs, and explain time and space complexity.

Algorithms & Data StructuresTechnical Trade-offs
Author's notes

Straightforward conceptually but the complexity discussion is where they actually wanted detail.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the problem and edge cases, then propose an efficient solution that iterates through the dictionary once, using a set to count unique pins per user. Discuss time and space complexity, and mention how to handle very large inputs (e.g., streaming or distributed processing).

Pro tip: Emphasize that the mean should be computed over all users, including those with zero pins, and discuss how to handle division by zero if the dictionary is empty. Also, mention that using a set per user is memory-efficient if lists are small, but for very large lists, consider alternative approaches like sorting and counting.

1. Clarify requirements and edge cases

Ask about input size, whether users with empty lists should be included, and if the mean should be over all users or only those with pins. Confirm that duplicates should be ignored.

2. Design an efficient algorithm

Iterate through each user's list, convert to a set to get unique pins, and count the size. Accumulate the total unique pins and the number of users.

3. Compute the mean and handle edge cases

Divide the total unique pins by the number of users. If there are no users, return 0 or handle appropriately. Ensure empty lists contribute 0 to the total.

4. Analyze time and space complexity

Time complexity is O(N) where N is total number of pin entries across all users. Space complexity is O(U + M) where U is number of users and M is max unique pins per user (for sets).

5. Discuss scalability for very large inputs

For inputs too large for memory, suggest streaming or distributed approaches (e.g., MapReduce) to compute unique counts per user and then aggregate.

Key Points to Mention

  • Use of sets to efficiently deduplicate pin IDs per user.
  • Handling of empty lists: they contribute 0 unique pins but still count as a user in the denominator.
  • Time complexity: O(N) where N is total number of pin entries; space complexity: O(U + M) where U is number of users and M is max unique pins per user.
  • Edge case: empty dictionary (return 0 or handle division by zero).
  • Scalability: for very large inputs, consider streaming or distributed processing (e.g., MapReduce) to avoid loading all data into memory.
  • Clarify whether the mean should be over all users or only those with at least one pin.

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