← Snapchat Interview Insights

Snapchat·Data Scientist·Technical Phone Screen·Intermediate

IntermediatePrefer not to say
Oct 2023Remote

Summary

Snapchat data scientist interview with a SQL-heavy technical screen focused on a friend-request abuse monitoring scenario. Three questions, all building on the same two tables, escalating from pure SQL to system design and edge case thinking. Not a brutal round but the third question caught me a bit flat-footed.

Questions Asked (3)

Q1

Write a SQL query that returns each of the last 7 calendar days along with the same-day acceptance rate, defined as the number of approvals where the approval date equals the request date divided by total requests on that date.

Product Analytics & MetricsData Modeling
Author's notes

The DATE(request_ts) = DATE(approval_ts) condition is the actual crux here and I almost forgot to scope it that way.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use a date spine (e.g., generate_series or recursive CTE) to produce the last 7 calendar days, then left join aggregated request and approval counts per day. Compute the acceptance rate as approvals with same-day approval divided by total requests, handling days with zero requests to avoid division by zero.

Pro tip: Always use a date spine to ensure all 7 days appear even if there are no requests; this shows you understand the difference between filtering and joining, and prevents missing days in the output.

1. Generate the date spine

Create a list of the last 7 calendar days using a date generation function (e.g., generate_series in PostgreSQL, recursive CTE in other dialects). Ensure the dates are inclusive of today and the previous 6 days.

2. Aggregate requests per day

From the requests table, count the total number of requests for each request date. Group by date to get daily totals.

3. Aggregate same-day approvals per day

From the approvals table, count approvals where the approval date equals the request date. Group by date to get daily same-day approval counts.

4. Join aggregates to the date spine

Left join the daily request counts and same-day approval counts to the date spine. Use COALESCE to replace NULLs with 0 for days with no activity.

5. Calculate acceptance rate

Compute the acceptance rate as same-day approvals divided by total requests. Use NULLIF or a CASE statement to avoid division by zero, returning 0 or NULL for days with no requests.

Key Points to Mention

  • Use of a date spine to ensure all 7 days are included, even with no data.
  • Definition of same-day approval: approval_date = request_date.
  • Handling division by zero when total requests is 0.
  • Use of LEFT JOIN and COALESCE to fill missing days with zeros.
  • Aggregation before joining to avoid fan-out and incorrect counts.
  • Consideration of time zones if dates are stored with timestamps.

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

Q2

Write a SQL query to find the percentage of friendship requests from last week that did NOT come from accounts flagged as spam.

Product Analytics & MetricsRoot Cause Analysis
Author's notes

Straightforward join question but the Users table being incomplete is the gotcha.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the schema and definitions (e.g., what constitutes a 'friendship request', 'last week', and 'spam flag'). Then write a query that calculates the percentage by dividing the count of non-spam requests by the total requests from last week, using appropriate date filters and joins.

Pro tip: Mention that you would validate the spam flag logic with the trust and safety team, as false positives/negatives could skew the metric. Also, consider if 'last week' should be based on calendar weeks or rolling 7 days, and confirm with stakeholders.

1. Clarify definitions and assumptions

Confirm what 'friendship request' means (e.g., a row in a requests table), how 'spam' is flagged (e.g., a boolean column or a separate table), and the exact time window for 'last week' (e.g., previous calendar week or last 7 days).

2. Identify relevant tables and columns

Locate the table containing friendship requests (e.g., friend_requests) with columns like request_id, sender_id, receiver_id, created_at, and a way to join to account flags (e.g., accounts.is_spam or a spam_flags table).

3. Filter requests from last week

Apply a date filter to select only requests created within the defined last week period, using appropriate date functions (e.g., DATE_TRUNC, BETWEEN).

4. Compute the percentage

Calculate the percentage as (count of non-spam requests / total requests) * 100, using conditional aggregation (e.g., SUM(CASE WHEN is_spam THEN 0 ELSE 1 END)) or subqueries.

5. Validate and present results

Check for edge cases (e.g., zero total requests) and consider adding a sanity check by also computing the raw counts. Present the final query with clear aliases and comments.

Key Points to Mention

  • Definition of 'friendship request' and 'spam' flag—clarify with stakeholders if ambiguous.
  • Time window for 'last week'—specify whether it's calendar week or rolling 7 days, and handle time zones.
  • Use of LEFT JOIN or subquery to ensure all requests are considered, even if sender account is not flagged (treat as non-spam).
  • Conditional aggregation to compute the percentage in a single query.
  • Handling of NULLs or missing spam flags—decide whether to treat as non-spam or exclude.
  • Edge case: if total requests is zero, return 0 or NULL to avoid division by zero.

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

Q3

The Users table may not contain all users. Propose at least one data or query change to make the previous queries more robust, and describe the key hypotheses and edge cases you would validate when interpreting results.

Data ModelingTechnical Trade-offsRoot Cause Analysis
Author's notes

This one tripped me up more than I expected.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by acknowledging that incomplete user data can bias metrics, then propose a concrete data or query change (e.g., left join with a fallback dimension table or use of a more complete event log). Follow with a structured plan to validate key hypotheses and edge cases, emphasizing how you would interpret results and communicate uncertainty.

Pro tip: Mention that you would quantify the coverage gap (e.g., % of events with missing user info) and use that to bound the potential bias, showing you think about impact, not just correctness.

1. Diagnose the gap

Quantify how many users or events are missing from the Users table and identify patterns (e.g., new users, specific platforms, or regions).

2. Propose a data/query change

Suggest a concrete fix such as joining with a more comprehensive user dimension table, using event-level user attributes, or creating a fallback 'unknown' category with flags.

3. Formulate hypotheses

List key hypotheses about why data is missing (e.g., logging delays, privacy settings, bot traffic) and how they might affect the analysis.

4. Validate edge cases

Test edge cases like users with multiple accounts, deleted accounts, or timezone mismatches to ensure the change doesn't introduce new biases.

5. Interpret and communicate

Assess the impact of the change on key metrics, compare before/after, and clearly communicate remaining limitations and uncertainty to stakeholders.

Key Points to Mention

  • Left join vs. inner join and how it affects row counts and metric calculations
  • Using a slowly changing dimension (SCD) or snapshot table to capture historical user attributes
  • Handling missing data with imputation, flags, or separate 'unknown' categories
  • Quantifying coverage bias and its potential impact on conclusions
  • Validating with A/B tests or sensitivity analysis to ensure robustness
  • Documenting assumptions and data lineage for reproducibility

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