Discord Software Engineer Interview Questions
6+ questions from real Discord Software Engineer interviews, reported by candidates.
Round Types
Top Topics
Questions
## Problem Implement a content moderation function that detects bad words in user-submitted text. Matching must handle: 1. Exact match (case-insensitive). 2. Leet-speak substitutions: `3->e`, `@->a`, `0->o`, `1->i`. 3. Repeated characters: `haaaate` matches `hate`. Return the sanitized string with each bad word replaced by `***`. ```python def censor(text: str, blocklist: list[str]) -> str: pass ``` **Example:** ``` blocklist = ["hate", "spam"] text = "I h@t3 sp@@m and haaaate it!" output -> "I *** *** and *** it!" ``` ## Follow-ups 1. Leet-speak normalization should happen before deduplication or after? Why does the order matter? 2. How would you build a Trie over the normalized blocklist for fast multi-pattern matching (Aho-Corasick)? 3. False positives: `"assassination"` contains `"ass"`. How do you reduce them without a huge allowlist? 4. The system processes 100,000 messages per second. What architecture would you use for real-time filtering?
Chat Server: Design a Real-Time Messaging System with Rooms, Message History, and User Presence
## Problem Design a `ChatServer` class that manages chat rooms: - `create_room(room_id)` -- create a new room. - `join_room(user_id, room_id)` -- add user to room. - `leave_room(user_id, room_id)` -- remove user from room. - `send_message(user_id, room_id, text) -> Message` -- broadcast message; return message object with timestamp. - `get_history(room_id, limit=50) -> list[Message]` -- return the `limit` most recent messages. - `online_users(room_id) -> list[str]` -- return currently joined users. ```python from dataclasses import dataclass from datetime import datetime @dataclass class Message: id: int user_id: str room_id: str text: str timestamp: datetime class ChatServer: ... ``` **Example:** ``` server.create_room("general") server.join_room("alice", "general") server.send_message("alice", "general", "hello") server.get_history("general") -> [Message(...)] ``` ## Follow-ups 1. `get_history` must be fast even with millions of messages. What storage structure and index would you use? 2. A user disconnects without calling `leave_room`. How do you detect and clean up stale presence? 3. How would you fan out a message to 10,000 users in the same room with low latency? 4. Add read receipts: track which users have seen each message up to which message id.
## Round 1 - Coding ## Problem Design a `LeaderFollower` system where one node acts as the leader and all others are followers. The leader accepts writes; followers replicate state and can serve reads. ```python class Node: def __init__(self, node_id: str): ... class LeaderFollowerCluster: def __init__(self, nodes: list[str]): ... def elect_leader(self) -> str: ... def write(self, key: str, value: str) -> bool: ... def read(self, node_id: str, key: str) -> str: ... def fail_node(self, node_id: str) -> str: # returns new leader if applicable ... ``` ## Example ``` cluster = LeaderFollowerCluster(["A", "B", "C"]) cluster.elect_leader() -> "A" cluster.write("x", "10") -> True cluster.read("B", "x") -> "10" # replicated cluster.fail_node("A") -> "B" # B becomes new leader cluster.write("x", "20") -> True cluster.read("C", "x") -> "20" ``` ## Follow-ups 1. How do you handle a write that arrives while a leader election is in progress? 2. What consistency guarantees does a follower read provide? How would you support read-your-writes? 3. How do you detect a leader failure — heartbeat timeout, explicit signal, or quorum-based? 4. How does your design change if the cluster has 100 nodes?
## Round 1 - Coding ## Problem Implement a message reaction feature for a chat app. Users can add or remove emoji reactions on any message. Each reaction type shows a count and the list of users who reacted. ```python class ReactionStore: def add_reaction(self, message_id: int, user_id: int, emoji: str) -> None: ... def remove_reaction(self, message_id: int, user_id: int, emoji: str) -> None: ... def get_reactions(self, message_id: int) -> dict: # returns {emoji: {"count": int, "users": list[int]}} ... def top_reaction(self, message_id: int) -> str: ... ``` ## Example ``` store = ReactionStore() store.add_reaction(1, 101, ":thumbsup:") store.add_reaction(1, 102, ":thumbsup:") store.add_reaction(1, 103, ":heart:") store.get_reactions(1) # -> {":thumbsup:": {"count": 2, "users": [101, 102]}, # ":heart:": {"count": 1, "users": [103]}} store.top_reaction(1) -> ":thumbsup:" store.remove_reaction(1, 101, ":thumbsup:") store.get_reactions(1) # -> {":thumbsup:": {"count": 1, "users": [102]}, ...} ``` ## Follow-ups 1. How would you persist reactions to a database? What schema would you use? 2. A user tries to add a reaction they already added — what should happen? 3. How would you extend this to support animated reactions with a display order? 4. At scale (millions of messages), how do you keep `get_reactions` fast?
## Problem Parse and organize log events by timestamp or category, possibly merging overlapping or deduplicating events. ## Likely LeetCode equivalent No direct match with high confidence. ## Tags sorting, arrays, hash_table
## Round 1 - Frontend/Coding ## Problem Build a simplified spreadsheet engine. Cells hold integer literals or formulas referencing other cells. When a cell changes, all dependent cells must recompute. ```javascript class Spreadsheet { constructor() {} set(cell, value) {} // value: integer or formula string like "=A1+B2" get(cell) {} // returns computed integer value } ``` ## Example ``` sheet = new Spreadsheet() sheet.set("A1", 5) sheet.set("B1", 10) sheet.set("C1", "=A1+B1") sheet.get("C1") // -> 15 sheet.set("A1", 20) sheet.get("C1") // -> 30 (auto-updated) sheet.set("D1", "=C1*2") sheet.get("D1") // -> 60 ``` ## Approach (optional) Build a dependency graph. On `set`, parse the formula, update the graph, then topologically sort affected cells and recompute them in order. ## Follow-ups 1. How do you detect and handle circular references like `A1 = "=B1"` and `B1 = "=A1"`? 2. Can you support built-in functions like `SUM(A1:A5)` or `MAX(B1,B3,B5)`? 3. If the spreadsheet has 1M cells and 100K are updated at once, how do you batch recomputation efficiently? 4. How would you persist and restore the sheet state?
What Discord Looks for in Software Engineer Interviews
Discord Software Engineer interviews are calibrated against the level and scope expected of the role. Across 6+ verified candidate reports on LeakCode, the consistent signals interviewers look for: clear problem decomposition before coding, explicit complexity reasoning, structured handling of edge cases, and the ability to articulate trade-offs between two reasonable approaches.
The discriminator between candidates who advance and candidates who do not is rarely the final correctness of the solution. It is the path to the solution: did you ask clarifying questions, did you state your approach before coding, did you handle edge cases without prompting, and did you communicate your reasoning throughout. Reports tagged "no hire" frequently cite a working solution with poor communication; reports tagged "strong hire" cite clear thinking even when the final solution was incomplete.
How To Use This Question Set
Real interview reports are a calibration tool, not a memorization target. Companies update their question pools every 2-4 months; memorizing exact problems risks misleading you when the interviewer uses a variant. The high-leverage use: identify the patterns that appear repeatedly in Discord Software Engineer reports, practice those patterns on similar (not identical) problems, and use the reports to understand the interviewer's typical follow-up depth.
Filter the questions below by round type, difficulty, and recency. Focus first on reports from the past 6-12 months; older reports may reference questions that have since rotated out of Discord's pool. Reports tagged with quantified difficulty (e.g., "medium-hard") are higher-signal than reports without difficulty tags.
Round-by-Round Expectations
Discord Software Engineer loops typically span 4-6 rounds across phone screens and on-site or virtual on-site interviews. The structure varies by company: some run 1 recruiter screen + 1 technical phone + 3-4 on-site rounds; others run 1 recruiter screen + 1 OA + 4-5 on-site rounds. The recruiter screen is logistics and culture-light; the technical phone screen is medium-difficulty coding; the on-site loop covers coding, system design (at L4+ levels), and behavioral rounds.
Each round is designed to surface a specific signal. Coding rounds: correctness, code quality, complexity reasoning, communication. System design rounds: requirements clarification, design judgment, operational thinking. Behavioral rounds: ownership scope, leadership, ambiguity tolerance, conflict navigation. Strong candidates explicitly hit each signal dimension out loud during the round; weak candidates focus only on solving the prompt.
Common Interview Mistakes At This Combination
Reports tagged "no hire" at Discord Software Engineer commonly cite: jumping into code without clarifying requirements, coding silently for 10+ minutes without verbalizing approach, missing edge cases (empty input, single element, very large input, overflow), and producing a working solution that the candidate cannot explain or refactor when probed. Strong candidates avoid these patterns by following a consistent template: clarify, verbalize approach, code with narration, test with examples.
Behavioral and design rounds have their own failure modes. Behavioral: stories that use "we" instead of "I" diluting individual signal, stories with no quantified outcome, defensiveness when probed about failure. Design: not asking clarifying questions, not stating requirements out loud, designing for a single server when the prompt clearly implies scale, ignoring operational concerns (deployment, monitoring, rollback). These show up in roughly half of Discord Software Engineer interview retrospectives on LeakCode.
See All 6 Discord Software Engineer Questions
Full question text, answer context, and frequency data for subscribers.
Get Access