This interview guide is for educational and informational purposes only. It is designed to help readers prepare, but it does not guarantee any interview result, hiring decision, offer, or outcome. Interview questions, hiring criteria, and preferred answers can vary by employer, interviewer, industry, location, and time. The examples and explanations reflect the authors' research and judgment, are provided without warranties of any kind, and should not be treated as the only correct approach. Diagrams are simplified illustrations intended to highlight the main components and their interactions; actual systems and implementations may be more complex. Alternative approaches may be equally valid or better suited to a particular question, context, or interviewer. To the fullest extent permitted by applicable law, the author, contributors, and publisher are not liable for decisions made, actions taken, or losses incurred based on this guide.
Identity, Image, and Privacy Notice
To respect individual privacy, some names, profile photographs, avatars, biographical details, and other identifying information displayed in this guide may be replaced with pseudonyms, licensed stock images, illustrative avatars, composite images, or representative descriptions. Unless a person is expressly identified as an actual contributor, a displayed name, image, or profile should not be understood as depicting or identifying a specific candidate, interviewer, employee, or other real individual. These representations are provided for editorial and illustrative purposes only and do not imply endorsement, employment, participation, or affiliation with this guide or any company mentioned in it. Any resemblance to an actual person is coincidental.
Company Notice
This guide is an independent educational resource and is not affiliated with, endorsed by, sponsored by, or approved by the company named in this guide. Company names are used only to identify interview experiences commonly reported by candidates. Interview practices can change without notice, and inclusion of company-specific content does not mean these questions are official, complete, or guaranteed to be asked. To the fullest extent permitted by law, the author, contributors, and publisher are not responsible for outcomes related to use of this material.
Questions or comments?
Contact us for general questions, or share feedback, technical corrections, and comments with the community.
11. How would you solve the Word Break II variant?CodingHardMeta
i Question Details
Break a string into dictionary words and return all valid segmentations, including the follow-up variant asked in the interview.
Short Interview Answer (30-60 seconds)
I would use memoized DFS. I start at index 0 and try every dictionary word that can begin at the current index. For each valid word, I recursively solve the remaining suffix and prepend the word to every returned sentence. A HashSet gives average O(1) word checks, and a HashMap caches every suffix result. The runtime is output-sensitive: O(n^2 + total returned sentence size), with worst-case exponential output. Extra space is O(n + memoized and returned sentence size), plus O(n) recursion depth.
The input is a string and a dictionary of valid words. We must insert spaces into the string in every possible valid way. Every piece must be a dictionary word. We must return all complete sentences, not only check whether one solution exists. I use recursion starting from a string index. At each index, I try valid next words. I save the completed sentences for each suffix so the same suffix is not solved again. This matches the two valid results shown for "catsanddog".
Useful Questions to Ask the Interviewer
If there is no valid segmentation, should I return an empty list?
Can the same dictionary word be used more than once if the indices keep moving forward?
Is any valid ordering of the returned sentences acceptable?
How to Explain It in an Interview
1. Understand the input and required output
The input string is "catsanddog". The dictionary is ["cat", "cats", "and", "sand", "dog"]. We need every complete segmentation whose pieces are dictionary words. The result shown in the diagram is ["cat sand dog", "cats and dog"]. The returned order is one valid order. It is not the only order that an implementation could use.
2. Choose memoized DFS and the supporting data structures
I use DFS starting from an index. dfs(start) means: return every valid sentence that can be built from s[start..n). A HashSet stores the dictionary words so membership checks are O(1) on average. A HashMap<Integer, List<String>> stores memoized results. Its key is a start index. Its value is the complete list of valid sentences for that suffix. The central invariant is that memo[i] contains all valid segmentations of s[i..n).
3. Initialize the state and define the base case
The first call is dfs(0). The memo map is initially empty. The dictionary set contains five words. If start equals the string length, the recursion returns a list containing one empty string: [""]. This empty suffix is important. It allows the previous valid word to finish a sentence cleanly without needing a separate special case for the last word.
4. Walk through the exact example
At dfs(0), the first valid word is "cat", so we call dfs(3). At dfs(3), "sand" is valid, so we call dfs(7). At dfs(7), "dog" is valid, so we call dfs(10). dfs(10) reaches the base case and returns [""]. Combining "dog" with the empty suffix produces ["dog"], so memo[7] becomes ["dog"]. Returning to index 3 produces ["sand dog"], so memo[3] becomes ["sand dog"]. Returning to index 0 adds "cat sand dog" to its result.
The next valid first word at index 0 is "cats", so we call dfs(4). At index 4, "and" is valid. The recursion then asks for dfs(7). This time memo[7] already contains ["dog"], so the algorithm reuses it instead of solving that suffix again. Combining the words produces ["and dog"], so memo[4] becomes ["and dog"]. Finally, index 0 adds "cats and dog". memo[0] becomes ["cat sand dog", "cats and dog"]. Non-dictionary substrings are skipped and never expanded.
5. Explain why the result is correct
For every start index, the algorithm tries every possible ending position. It continues only when the substring is a dictionary word. For each such first word, it appends every valid continuation returned by the remaining suffix. Therefore it cannot miss a valid segmentation. It also cannot create an invalid segmentation because every added piece passed the dictionary check. The base case contributes exactly one empty suffix, which correctly closes a complete sentence.
6. Explain the Java implementation, complexity, and edge cases
The Java method builds the HashSet and memo map, then calls dfs(0). Each DFS call first checks the memo. It then tries every possible substring starting at the current index. Invalid words are skipped. Valid words recurse on the next index, and each returned suffix is combined with the current word. There are O(n) memoized start positions and O(n) candidate end positions per start. HashSet lookup is O(1) on average. The runtime is output-sensitive: O(n^2 + total size of returned sentences), with exponentially many answers possible in the worst case. Extra space is O(n + total size of memoized and returned sentences), and recursion depth can reach O(n). Important cases include no valid segmentation, overlapping words such as "cat" and "cats", reused dictionary words, and the internal [""] base case.
Key Insight / Why This Solution Works
The key idea is to solve the problem by suffix. At position start, try every substring s[start..end). If the substring is not in the dictionary HashSet, skip it. If it is valid, recursively get every sentence for the suffix beginning at end. Then prepend the current word to each returned suffix sentence. The HashMap memo stores start index -> all valid sentences for that suffix. The central invariant is: memo[i] is the complete set of valid segmentations for s[i..n). Memoization is important because different branches can reach the same suffix, as both paths in the example reach index 7.
Code
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
publicclassMain {
publicstaticvoidmain(String[] args) {
Strings="catsanddog";
List<String> wordDict = List.of("cat", "cats", "and", "sand", "dog");
// Run the exact example used in the diagram.
List<String> result = wordBreak(s, wordDict);
// Print the returned sentences in the same readable form as the diagram.
System.out.println("[\"" + String.join("\", \"", result) + "\"]");
}
publicstatic List<String> wordBreak(String s, List<String> wordDict) {
// Store dictionary words in a set so candidate-word checks are O(1) on average.
Set<String> dict = newHashSet<>(wordDict);
// memo[start] stores every valid sentence that can be built from s[start..].
Map<Integer, List<String>> memo = newHashMap<>();
// Start solving from the first character of the string.return dfs(0, s, dict, memo);
}
privatestatic List<String> dfs(
int start,
String s,
Set<String> dict,
Map<Integer, List<String>> memo
) {
// Reuse a suffix result if another recursion branch already computed it.if (memo.containsKey(start)) {
return memo.get(start);
}
// Collect every valid sentence that begins at this start index.
List<String> result = newArrayList<>();
// Reaching the end means the previous words formed one complete segmentation.// The empty string lets the caller append its final word without a special branch.if (start == s.length()) {
result.add("");
memo.put(start, result);
return result;
}
// Try every possible next word that starts at the current index.for (intend= start + 1; end <= s.length(); end++) {
Stringword= s.substring(start, end);
// A substring that is not a dictionary word cannot begin a valid branch.if (!dict.contains(word)) {
continue;
}
// Solve the remaining suffix once, then combine this word with every valid result.for (String suffix : dfs(end, s, dict, memo)) {
// Avoid adding an extra trailing space when this is the final word.
result.add(suffix.isEmpty() ? word : word + " " + suffix);
}
}
// Cache the complete result for this suffix so future branches can reuse it.
memo.put(start, result);
return result;
}
}
Time & Space Complexity
Let n be the string length. There are O(n) possible start indices. From each start index, the code can try O(n) ending positions. Dictionary checks with HashSet are O(1) on average. The diagram describes the runtime as O(n^2 + total size of the returned sentences). The number of valid sentences can itself be exponential, so the worst case is exponential because every answer must be created. Extra memory is O(n + total size of memoized and returned sentences). The recursion stack can also be O(n) deep.
Where it is used
This pattern is useful for dictionary-based word segmentation, text tokenization, and parsers that need to enumerate every valid interpretation of an input. Memoized DFS is especially useful when many different choices lead to the same remaining suffix, because the suffix result can be computed once and reused.
Why Interviewers Ask This
This problem tests whether you can move from simple feasibility to generating every valid result. The interviewer is looking for correct recursive state design, a clean base case, and memoization of shared suffixes. It also checks whether you understand why a HashSet helps with dictionary checks, whether your Java code builds sentences correctly, and whether you can explain output-sensitive complexity instead of claiming a simple polynomial bound when the number of valid sentences can be exponential.
Common interview mistakes
A common mistake is solving only Word Break I and returning a boolean instead of every sentence. Another mistake is forgetting memoization, which makes shared suffixes such as index 7 get recomputed. Candidates also sometimes return an empty list at the recursion base case instead of [""], which prevents the final word from being assembled correctly. Another error is treating invalid substrings as recursive branches instead of skipping them. Finally, the complexity should acknowledge that the number and total size of returned sentences can be exponential.
Interview tip
Define dfs(start) clearly before writing code: it returns all valid sentences for s[start..]. Then explain that memo[start] stores exactly that same result. This makes the recursion, memoization, base case, and correctness argument much easier to follow.
Interviewer may ask next
What would change if I only needed to know whether at least one valid segmentation exists?
I would change the memoized state from a list of sentences to a boolean result for each start index. The state would mean whether s[start..] can be segmented. For each dictionary word starting at the current index, I would recurse on the remaining suffix and stop as soon as one continuation succeeds. The same base idea remains correct because a state is true exactly when at least one valid first word leads to a true suffix. Under the same diagram complexity model, this takes O(n^2) expected work with average O(1) HashSet membership checks and O(n) memo plus O(n) recursion-stack space. The tradeoff is that this returns only feasibility and loses the actual sentences.
What happens when the string has a very large number of valid segmentations?
The memoized DFS still avoids recomputing the same suffix state, but it cannot avoid creating every requested answer. If the number of valid sentences is exponential, the runtime and memory used to store those sentences are dominated by that output. The algorithm remains correct because memo[i] still contains every valid segmentation for suffix i. The complexity remains output-sensitive: O(n^2 + total size of the returned sentences), with worst-case exponential output, and extra space is O(n + total size of memoized and returned sentences) plus recursion depth up to O(n). The tradeoff is unavoidable when the contract requires returning all segmentations.
12. How would you design a real-time commenting system for live videos or events in Facebook or Instagram?System DesignMediumMeta
i Question Details
Design a live commenting system with real-time delivery, history, moderation, and scale concerns.
Short Interview Answer (30-60 seconds)
At a high level, this system lets people post comments and see new comments almost immediately during a live video or event. The main challenge is keeping delivery fast while still saving history and supporting moderation. I would explain it in three flows: writing a comment, reading recent history, and pushing live updates. The design uses a Java Comment Service, cache, Durable Comment Store, Event Bus, and Realtime Fanout Service. The trade-off is that moderation can change a comment after users already saw it.
Detailed Explanation
The goal is to let many people comment during a live video or event and see new comments quickly. The system must also keep comment history, control abuse, and allow comments to be hidden later. The difficult part is that several things happen at once. We need a safe write path, a fast history path, and a separate live delivery path. The diagram handles these jobs with a Comment Service for writes and reads, an Event Bus for background delivery, and a Realtime Fanout Service for WebSocket updates.
Useful Questions to Ask the Interviewer
How quickly should a new comment appear to other viewers?
How much recent comment history should the client load at once?
Should moderation happen before delivery, after delivery, or both?
How many viewers may join one live video or event?
How to Explain It in an Interview
1. Explain the goal and main idea
I would separate saving comments from pushing them to every viewer. The Comment Service owns the main write and history flows. The Event Bus and Realtime Fanout Service handle live delivery outside the synchronous request path. This keeps posting and reading simple while still supporting fast live updates.
2. Explain the comment write path
For the write path, the client sends an HTTPS POST comment request to the Edge / API Gateway. The request then goes through Auth + Validation + Rate Limits. This checks the token, permission, input, and abuse limits before the Comment Service receives the validated request.
The Comment Service runs as Java 21/25 JVM replicas. Virtual threads help each JVM handle many concurrent blocking requests. The service writes the comment and its status to the Durable Comment Store. It also updates the Recent Comments Cache. A JSON acknowledgement then returns through the Edge / API Gateway to the client.
3. Explain the recent history path
For history, the client sends HTTPS GET comments with a cursor. The Edge / API Gateway sends the history request to the Comment Service. The service checks the Recent Comments Cache first because recent comments should be quick to read.
On a cache hit, the Comment Service can use the cached comments. If the cache misses, it queries the Durable Comment Store for history. The JSON history response then returns through the gateway to the client. If a client reconnects, it resubscribes and fetches missed comments from its last cursor.
4. Explain live delivery and moderation
After the comment is saved, the Comment Service publishes a comment_created event to the Event Bus. The Realtime Fanout Service consumes the fanout event. It maintains WebSocket subscriptions by live room and uses the Subscription Registry for room membership lookup. It then pushes the comment to connected clients over WebSocket.
The Event Bus also sends moderation input to the Moderation Service. The service can hide, remove, or flag a comment. It refreshes or invalidates the Recent Comments Cache and publishes a moderation_update event. The Event Bus sends hide or delete events to the Realtime Fanout Service, which pushes WebSocket moderation updates to clients. The Moderator Console also supports manual review.
5. Explain scale, operations, and trade-offs
I would partition work by liveVideoId or eventId. This helps spread different live rooms across the system. The Comment Service and Realtime Fanout Service run as separate JVM replicas, so one replica cannot depend on another replica's in-memory state.
Observability collects metrics, logs, traces, and health information from the system. This helps operators find slow or unhealthy parts. The main trade-off is moderation timing. A comment may reach viewers first and then become hidden after moderation.
Engineering Considerations / Design Trade-offs
The benefit is that the main comment request stays simple. The comment is saved through the Comment Service, while live delivery and moderation continue through the Event Bus. The Recent Comments Cache makes recent history faster, but the Durable Comment Store is still needed when the cache misses. Partitioning by liveVideoId or eventId helps spread different live rooms across the system. The downside is that moderation may happen after delivery. A viewer can briefly see a comment that is hidden later. Separate JVM replicas also cannot depend on shared in-memory state across processes.
Why Interviewers Ask This
Interviewers ask this question to see how you split one large real-time problem into clear flows. They want to know whether you can separate writing, history reads, live delivery, and moderation. They also look for good judgment around caching, durable storage, Java JVM replicas, WebSocket delivery, partitioning, and rate limits. Most importantly, they want you to explain the trade-offs clearly instead of only naming technologies.
Interviewer may ask next
What would you change if one live event suddenly became much more popular than the others?
I would keep the same basic design, but I would pay more attention to the liveVideoId or eventId partition for that room. The diagram already uses that key for scaling, so the system can keep related comment work grouped while adding more Java service replicas around the same architecture.
The Comment Service still handles writes and history. The Event Bus still carries comment_created and moderation events. The Realtime Fanout Service still manages WebSocket subscriptions, while the Subscription Registry keeps the room membership lookup outside one JVM's local memory.
The Recent Comments Cache is also important because many viewers may request the same recent history. It keeps repeated reads away from the Durable Comment Store when the data is cached.
The main downside is uneven load. One very popular liveVideoId or eventId can become much busier than other partitions, so capacity must be planned for unusually hot rooms.
What happens if a viewer disconnects for a short time and misses several comments?
I would use the reconnect flow already shown in the diagram. When the client reconnects, it resubscribes to the live room so the Realtime Fanout Service can continue WebSocket delivery. The client also asks for missed history using the last cursor it received successfully.
That history request goes through the Edge / API Gateway to the Comment Service. The service checks the Recent Comments Cache first. On a cache hit, it can use the recent cached comments. If the cache misses, the Comment Service queries the Durable Comment Store for the missing history. The JSON history then returns through the gateway to the client.
This keeps live delivery and recovery as separate paths. WebSocket handles new comments, while the cursor-based history request fills gaps after a disconnect. The downside is extra reconnect work because the client must resubscribe and make another history request.
13. How would you design an Instagram auction system?System DesignMediumMeta
i Question Details
Design an auction system for Instagram with bidding, listing lifecycle, winner selection, and abuse handling.
Short Interview Answer (30-60 seconds)
At a high level, this system lets sellers run auctions and lets bidders place valid bids before the closing time. The main challenge is keeping bids correct when many users may bid at once. I would explain it in three flows: listing and bidding, auction closing and winner selection, and background notifications and abuse review. The Auction DB is the source of truth, while the Distributed Cache makes reads faster. The trade-off is more moving parts in exchange for faster reads and easier horizontal scaling.
Detailed Explanation
The system must let a seller create and manage an auction, let bidders view it and place bids, close it at the correct time, and choose the right winner. It must also reject bad bids and detect suspicious behavior. The difficult part is that many bids may arrive close together near the closing time. The design therefore keeps the Auction DB as the source of truth, uses a Distributed Cache for faster reads, and moves notifications and moderation work into background workers.
Useful Questions to Ask the Interviewer
Can a seller end an active listing early?
How should valid bid increments be defined?
Should suspicious bids be blocked immediately or only flagged for review?
How quickly should outbid and winner notifications be delivered?
How to Explain It in an Interview
1. Explain how requests enter the system
I would start with the seller and bidder applications. Both send requests through the API Gateway / Load Balancer. The next step is AuthN/AuthZ + Rate Limits + Input Validation.
This layer checks the user, permissions, request limits, and input. Valid requests then enter the Auction Platform. Its Java 21/25 services run in replicated JVMs. The HTTP handlers may use virtual threads for many concurrent blocking requests.
2. Explain listing and bidding
The Listing Service manages the listing lifecycle. The diagram shows Draft, Active, Ended, and then Settled or Cancelled. Listing changes are written to the Auction DB.
The Auction Service reads active auction state. The Distributed Cache stores active auction state and the current highest bid to make those reads faster.
For a bid, the Bid Service first checks the current highest bid. It then uses a database transaction to validate the increment and save the bid. The Auction DB returns commit or reject. After a successful commit, the Bid Service refreshes the highest bid in the Distributed Cache.
The place-bid request uses an idempotency key. This lets the service recognize the same request if it is submitted again. The service also rejects bids for ended auctions or invalid increments.
3. Explain auction closing and winner selection
The Auction Close Scheduler finds auctions that are ending now. It tells the Winner Selection Service to close the auction. Server time decides whether the auction has ended.
The Winner Selection Service selects the highest valid bid that arrived before the end time. It marks the winner in the Auction DB. This keeps the final result based on the source-of-truth database instead of the cache.
4. Explain events, notifications, and abuse handling
The Listing Service publishes ListingStateChanged events. The Bid Service publishes BidPlaced events. Winner Selection publishes AuctionClosed and WinnerSelected events through the Message Queue / Event Bus.
The Notification Orchestrator is part of the main Java service layer. The separate outbid / winner notification worker sends seller, outbid, and winner updates to Instagram Notifications. This work runs in the background instead of delaying the main request path.
The Abuse Detection Service checks rate spikes, self-bidding, and possible collusion patterns. Suspicious activity goes to Abuse Rules + Review Queue. The Moderation review worker sends review cases to the Moderator Console.
5. Explain scale, safety, and operations
The services can scale horizontally by auctionId instead of using one global lock. The Auction DB remains the source of truth, while the cache is only a read optimization.
Authentication, authorization, validation, and rate limits protect the request path. Retries use idempotency so repeated bid submissions do not create duplicate bids. Observability tracks logs, metrics, traces, alerts, bid latency, rejection rate, and close-job lag. The benefit is fast reads and background processing. The downside is more cache, queue, and worker behavior to operate correctly.
Engineering Considerations / Design Trade-offs
The benefit is that active auction reads can be fast because the Distributed Cache holds active auction state and the highest bid. The Auction DB still keeps the official result, so the cache does not decide the winner. Background workers also keep auction closing, notifications, and moderation work away from the main request path. The downside is more moving parts. The cache must be refreshed after a successful database commit. The Message Queue / Event Bus and workers must also be monitored. Scaling by auctionId avoids one global lock, but a very popular auction can still create heavy load around one auction.
Why Interviewers Ask This
Interviewers want to see whether you can break a large system into clear flows and protect the parts that must stay correct. This question tests your judgment around concurrent bidding, source-of-truth data, caching, timed winner selection, background work, abuse handling, rate limits, and horizontal scaling. They also want to see whether you can explain those trade-offs clearly instead of adding unnecessary components.
Interviewer may ask next
What would you change if one auction suddenly received a very large burst of bids?
I would keep the same basic architecture and focus on protecting the Bid Service and Auction DB for that auctionId. The API Gateway and rate limits would prevent one client from sending unlimited requests. The Abuse Detection Service would also watch for unusual rate spikes.
The Bid Service would still check the current highest bid and use the database transaction to validate the increment and save the bid. I would not weaken that rule when traffic grows. The idempotency key would still protect against the same place-bid request being submitted again.
The replicated Java services can scale horizontally, and the diagram groups scaling by auctionId instead of using one global lock. That allows unrelated auctions to continue independently.
The main downside is that one extremely popular auction can still create heavy load around the same auction state. I would watch bid latency and rejection rate through Observability instead of sacrificing correctness.
What happens if the Auction Close Scheduler runs late after the auction end time?
I would keep the same design and keep server time as the rule for accepting bids. Once the configured end time has passed, the Bid Service should reject a late bid even if the Auction Close Scheduler has not finished closing that auction yet.
When the scheduler catches up, it finds the auction that should already be closed and tells the Winner Selection Service to close it. Winner Selection then chooses the highest valid bid that arrived before the end time and marks that winner in the Auction DB.
After that, AuctionClosed and WinnerSelected events can go through the Message Queue / Event Bus. The outbid / winner notification worker can then send the final seller and winner updates.
This keeps the winner correct even when background processing is late. The downside is delay. Final status and notifications may arrive later, and Observability should show that problem through close-job lag.
14. How would you design an advertisement delivery system for Meta personalized ads in near real time?System DesignHardMeta
i Question Details
Design an ad delivery system that targets users, serves personalized ads quickly, and handles ranking, storage, and scale.
Short Interview Answer (30-60 seconds)
At a high level, the goal is to choose a useful ad for each user very quickly. The main challenge is doing targeting, policy checks, budget checks, and ranking without slowing the feed request. I would explain the design in three flows: campaign ingestion, real-time ad serving, and background feedback updates. Stateless Java replicas use caches and online stores for fast lookups. Events update features and counters later. The trade-off is that some counters and features can be slightly behind.
Detailed Explanation
The system must choose a personalized advertisement while the user is waiting for a feed or web response. That is difficult because the system needs user context, campaign targeting, policy rules, budgets, and ranking information before choosing an ad. The answer also has two different kinds of work. The ad-serving path must be very fast. Campaign updates and user events can do more work in the background. The diagram organizes the solution into campaign ingestion, a Java serving path, and an event-processing path that keeps features, counters, and reports updated.
Useful Questions to Ask the Interviewer
How fresh do campaign, budget, and user-feature updates need to be?
What should we serve if user features or ranking data are temporarily unavailable?
Which policy and privacy checks must happen before an ad can be selected?
How to Explain It in an Interview
1. Start with campaign ingestion
For the write side, advertisers use the Advertiser / Campaign Manager to upload campaigns and creatives. Campaign Ingestion & Validation checks that input before it enters the serving system.
The Ad Catalog Metadata Store keeps campaign information. Creative Object Store keeps the creative content. Targeting Rules / Inverted Index supports finding campaigns that match a request. Budget & Policy Store holds budget and policy information.
An Index / Cache Updater refreshes serving-side indexes and cached campaign data in the background. This keeps campaign-management work away from the live ad-serving path.
2. Explain how an ad request enters
For the fast path, Meta App / Web Client sends an ad request with user and context information. API Gateway / Ad Request Endpoint performs Auth, Validation, and Rate Limit checks.
The request then enters the Java Ad Serving Cluster. The cluster uses stateless replicas on separate JVMs. The diagram uses Java 21/25 and virtual threads for concurrent I/O lookups, which helps a replica handle many blocking lookups without turning virtual threads into a queue or unlimited resource pool.
3. Walk through targeting and ranking
Request Handler starts the serving flow. User Context & Feature Fetch reads user information from User Profile Store, Online Feature Store, and Hot Cache.
Candidate Generator uses Targeting Index and Campaign Metadata Cache to find possible ads. Eligibility / Policy / Budget Filter removes ads that should not be shown. It checks campaign metadata plus Budget & Policy Store before ranking.
Ranking Service uses Online Feature Store and Ranking Model / Rules to score the remaining ads. Ad Selector chooses the final ad. It works with Creative Cache / Delivery for the selected creative. The selected ad plus creative reference returns through API Gateway / Ad Request Endpoint to Meta App / Web Client, where the creative data is served.
4. Keep feedback work off the main response path
Impression / Click / Conversion Events enter Event Log / Stream after serving. Stream Consumers process those events in the background.
Their asynchronous updates go to Budget & Policy Store, Online Feature Store, and Analytics / Reporting Store. This lets campaign counters, user features, and reporting change without making the current ad request wait.
Observability collects metrics, logs, and traces from the serving path and background processing.
5. Explain failures, scale, and trade-offs
The low-latency path prefers cache-first reads and stateless replicas. Stateless replicas make horizontal scaling easier because a request does not depend on session state inside one JVM replica.
Counters and user features use eventual consistency, which means recent changes may take a little time to appear. If features are unavailable, the diagram falls back to cached or contextual ads. Policy, privacy, and eligibility checks still happen before ranking. The main trade-off is accepting slightly older background data so the user-facing ad path stays fast.
Engineering Considerations / Design Trade-offs
The benefit is that the user-facing path stays fast. Hot Cache, Campaign Metadata Cache, and Targeting Index reduce repeated expensive lookups. Stateless JVM replicas also make it easier to add more serving capacity. The downside is that background updates do not appear everywhere immediately. Budget counters and user features may be a little behind recent events. We accept that small delay because impressions, clicks, conversions, and reporting should not block the current ad response. Another trade-off is the fallback. Cached or contextual ads keep serving available when features fail, but they may be less personalized.
Why Interviewers Ask This
The interviewer wants to see whether you can separate a very fast request path from slower background work. They also want to see how you handle targeting, ranking, policy checks, caching, and user feedback without mixing their responsibilities. A strong answer shows good judgment about latency, scale, failures, and slightly delayed data. It also shows that you can explain a large system in clear steps.
Interviewer may ask next
What would you change if the Online Feature Store became temporarily unavailable during ad serving?
I would keep the same basic design and use the fallback already shown in the diagram. User Context & Feature Fetch would first use any usable information from Hot Cache. If the required online features are still unavailable, the serving path would use cached or contextual ads instead of waiting indefinitely.
Candidate Generator, Eligibility / Policy / Budget Filter, Ranking Service, and Ad Selector would continue with the data that is available. Policy, privacy, eligibility, and budget checks must still happen before the ad is selected. I would not bypass those checks just because personalization data is missing.
The Java Ad Serving Cluster remains stateless, so one JVM replica does not need another replica's local state to continue serving requests. Observability should expose the feature-store problem through metrics, logs, and traces.
The main downside is weaker personalization. The response can remain fast, but the selected advertisement may be less relevant until fresh user features become available again.
How would this design handle a large increase in ad-request traffic without changing the basic architecture?
I would scale the existing Java Ad Serving Cluster horizontally by running more stateless JVM replicas. The request path already supports this because Request Handler, User Context & Feature Fetch, Candidate Generator, Eligibility / Policy / Budget Filter, Ranking Service, and Ad Selector do not depend on per-user session state stored inside one replica.
The hot path would continue using Hot Cache, Campaign Metadata Cache, Targeting Index, and the online stores shown in the diagram. This reduces repeated expensive lookups. Virtual threads can help each JVM replica handle many concurrent blocking I/O operations, but they do not remove capacity limits in caches or downstream stores.
Event Log / Stream and Stream Consumers remain separate from the synchronous serving response. That separation prevents impression, click, and conversion processing from slowing the current request.
The downside is that adding serving replicas only solves part of the scaling problem. The shared caches, stores, ranking data, and background event path must also have enough capacity.
15. How would you design a serverless computation system like Amazon Lambda?System DesignHardMeta
i Question Details
Design a serverless compute platform with job submission, isolation, execution, retries, and scaling.
Short Interview Answer (30-60 seconds)
At a high level, I would separate accepting a function request from safely running that function on isolated workers. The main challenge is handling many concurrent invocations while keeping failures and noisy workloads contained. I would explain the deploy flow, the invocation flow, and the retry and scaling paths. Stateless Java control-plane services manage functions and scheduling, while worker hosts execute them in isolated sandboxes. Warm sandboxes reduce cold starts. The trade-off is that stronger isolation improves security but adds startup overhead.
Detailed Explanation
The goal is to let developers register functions and run them without managing the worker machines themselves. The difficult part is running many invocations safely while keeping one function from affecting another. The platform must also keep invocation state, retry failed work, return synchronous results, and add or remove worker capacity as demand changes. The diagram handles this with a Control Plane for management and scheduling, durable stores and queues for state, and an Execution Fleet / Data Plane where isolated sandboxes run the functions.
Useful Questions to Ask the Interviewer
Should the platform support both synchronous and asynchronous invocations?
How many retries should happen before an invocation reaches the Dead-Letter Queue?
How should concurrency limits and quotas be applied?
How important is reducing cold-start delay for this workload?
How to Explain It in an Interview
1. Explain the deploy and register flow
I would start with how a function enters the platform. A Developer sends a deploy or register request through the HTTPS / API Gateway. AuthN, AuthZ, validation, and rate limits protect the request before it reaches the Control Plane.
The Function Management Service registers, updates, or versions the function. It stores function information in the Function Metadata DB. It uploads the code package or container image to Artifact Storage. The Control Plane uses stateless Java services in replicated JVMs. Separate replicas do not share heap state.
2. Explain the invocation and scheduling flow
For an invocation, a Client App or Event Producer sends an HTTPS request through the same entry path. The Invocation API / Job Submission Service creates or updates the invocation in the Invocation State Store.
The Scheduler / Placement Service handles placement and sends the invocation to the Invocation Queue. The queue provides at-least-once delivery for asynchronous work. From there, the invocation is dispatched to a Worker Host in the Execution Fleet / Data Plane.
3. Explain isolated execution and the response
Each Worker Host has a Node Agent and a Warm Sandbox Pool. Warm sandboxes reduce cold starts because some execution environments are already prepared. On a cold start or update, the worker pulls the code package from Artifact Storage.
Each invocation runs inside an isolated Sandbox, MicroVM, or Container. Separate sandboxes do not share heap state. The Function Handler executes user code with CPU and memory limits and temporary /tmp storage.
The worker reports execution status and results. The Invocation State Store keeps status, result, timestamps, and attempt information. For synchronous invocation, the result returns through the Invocation API and HTTPS / API Gateway to the client.
4. Explain retries and failed work
If execution fails, the worker reports the failure. The Retry Manager schedules another attempt using exponential backoff, which means waiting longer between retries. The invocation is then re-enqueued in the Invocation Queue.
After the maximum retry count, the failed invocation goes to the Dead-Letter Queue. Asynchronous invocations are at-least-once, so the same work may run more than once. Handlers should be idempotent, meaning a repeated invocation should not create an incorrect duplicate effect.
5. Explain scaling and operations
The Autoscaler uses queue depth, concurrency metrics, and worker metrics to scale workers out or in. Logs, metrics, and traces from the Control Plane and workers go to the Observability system.
Concurrency limits and quotas protect the platform from noisy workloads. The main trade-off is isolation. It improves security, but starting a new isolated environment adds cold-start overhead.
Engineering Considerations / Design Trade-offs
The benefit is that the Control Plane and worker fleet can scale separately. Queue depth and concurrency metrics tell the Autoscaler when worker capacity should change. Warm sandboxes reduce cold starts, so many requests can begin faster. The downside is that isolation costs time and resources. Starting a new Sandbox, MicroVM, or Container can delay an invocation. Retries improve reliability, but asynchronous work may run more than once. Handlers must therefore handle repeated work safely. Concurrency limits and quotas protect the platform, but they can throttle a busy function after it reaches its allowed limit.
Why Interviewers Ask This
Interviewers ask this question to see whether you can divide a large platform into clear flows. They want to understand how you separate management from execution, isolate untrusted function code, use queues and retries correctly, scale workers from demand, and handle failures. They also want to see whether you can explain important trade-offs such as cold starts, isolation overhead, repeated asynchronous execution, and concurrency limits.
Interviewer may ask next
How would the design change if cold-start latency became the most important requirement?
I would keep the same architecture, but I would rely more heavily on the Warm Sandbox Pool inside each Worker Host. The goal would be to keep more prepared sandboxes available before invocations arrive.
The Autoscaler would still use queue depth, concurrency metrics, and worker metrics. Cold-start measurements from the workers would also help show when the fleet needs more prepared capacity. When a new sandbox is required, it would still pull the code package from Artifact Storage and run inside the same isolated Sandbox, MicroVM, or Container boundary.
I would not remove isolation to make startup faster. Each invocation should still have CPU and memory limits and remain separate from other sandboxes.
The downside is higher resource use. Keeping more worker capacity and warm sandboxes ready means some resources may stay idle. We get lower startup delay, but the platform becomes less resource-efficient.
What happens if a function keeps failing during asynchronous execution?
I would keep the failure path shown in the diagram. When execution fails, the worker reports the failure and the Retry Manager schedules another attempt using exponential backoff. The invocation is then re-enqueued in the Invocation Queue.
The Invocation State Store keeps the invocation status, timestamps, attempt information, and result details. This lets the platform track the work across repeated attempts. If the invocation reaches the maximum retry count, it goes to the Dead-Letter Queue instead of being retried forever.
The Function Handler should also be idempotent. That means repeating the same invocation should not create an incorrect duplicate effect. This matters because asynchronous invocation uses at-least-once delivery and the same work may execute again.
The downside is extra delay and resource use. Repeated failures consume worker capacity before the invocation finally moves to the Dead-Letter Queue.
16. How would you design a web crawler for a root link?System DesignHardMeta
i Question Details
Design a crawler that starts from a root link, visits each page once, and scales to a very large graph of links.
Short Interview Answer (30-60 seconds)
At a high level, the crawler starts with one root URL and keeps discovering new pages from links. The main challenge is visiting each normalized URL only once while still crawling a very large graph. I would explain three flows: accepting and deduplicating URLs, fetching and parsing pages, and handling retries and scale. The design uses a Seen URL Store, a sharded URL Frontier, polite Java worker replicas, and durable crawl output. The trade-off is extra coordination for deduplication, scheduling, and per-host politeness.
Detailed Explanation
The goal is to start from one root link and keep following links until we have crawled the reachable pages. The challenge is avoiding duplicate work because many pages may point to the same URL. We also need to crawl many websites without sending too many requests to one host. The diagram handles this as a loop. We normalize URLs, claim unseen URLs, schedule them, fetch pages, extract links, and send those links through the same process again.
Useful Questions to Ask the Interviewer
Should the crawler stay on one website, or follow links across domains?
How should we treat a page that changes after it was already crawled?
How many retries should we allow before treating a URL as a permanent failure?
How to Explain It in an Interview
1. Start with the root URL
I would say, "The crawl starts with one root URL, and I first make that URL safe and consistent." The Operator / Crawl Job Request sends it to the Crawl Coordinator API inside a JVM. The coordinator validates the URL, normalizes it, and creates the crawl job. Normalization means equivalent URL forms become one consistent form. The normalized root URL then goes to the Seen URL Store.
2. Claim URLs before adding work
The Seen URL Store is the main correctness step. It performs an atomic check and claim on each normalized URL. Atomic means the check and update happen as one safe operation. If the URL was already claimed, the duplicate is dropped. If it is new, it goes to the URL Frontier. This gives logical visit-once behavior for normalized URLs without claiming every network operation runs exactly once.
3. Schedule work and respect websites
The URL Frontier is a distributed sharded queue. Each shard holds part of the pending URL set. The diagram can shard by URL hash or host for horizontal scale. A next URL candidate is checked by the Politeness + Robots Manager. It enforces robots.txt rules and per-host concurrency, delay, and QPS limits. The Robots Cache stores robots.txt by host. Allowed URLs can be dispatched, while delayed URLs wait.
4. Fetch, parse, and discover links
Java Fetcher Workers run as many JVM replicas. Each worker has a Bounded Input Queue, which provides backpressure by limiting accepted work. Virtual-Thread HTTP Fetchers handle many blocking HTTP requests efficiently. The worker sends an HTTP GET to External Websites and receives HTML. The HTML Parser reads the response body. The Link Extractor finds href and src links. The URL Normalizer canonicalizes those links.
The extracted, normalized URLs return to the Seen URL Store. Newly claimed URLs go back into the URL Frontier, so the crawl continues. Parsed page content and metadata go to the Page Store / Crawl Output.
5. Handle failures, scale, and operations
A transient fetch failure goes to the Retry Queue. Retries use progressive exponential backoff, so repeated failures wait longer. When a retry becomes ready, it returns to the Bounded Input Queue. URLs that exceed the retry limit go to the Dead-Letter Bucket for manual review.
The system scales by adding URL Frontier shards and Java worker JVM replicas. Metrics / Logs / Traces collect operational signals. The main trade-off is extra coordination for deduplication, politeness, retries, and backpressure.
Engineering Considerations / Design Trade-offs
The benefit is that the crawler can grow by adding more URL Frontier shards and more Java worker JVM replicas. The Seen URL Store prevents the same normalized URL from being queued repeatedly. The Bounded Input Queue protects workers when too much work arrives. The Politeness + Robots Manager also protects external websites with per-host limits. The downside is extra coordination. Every discovered URL must be checked before enqueueing. Some URLs may wait because of host politeness rules. Retries add more background work, and permanent failures need the Dead-Letter Bucket. We accept this complexity because it reduces duplicate work and avoids sending requests too aggressively.
Why Interviewers Ask This
Interviewers ask this to see whether you can turn a large graph problem into a clear processing loop. They want to see how you prevent duplicate work, divide pending URLs across shards, scale Java workers, respect external websites, and handle failures. They also test whether you understand backpressure and retries. The important skill is not memorizing components. It is explaining why each part exists and what trade-off it creates.
Interviewer may ask next
What would you change if the crawler had to process a much larger graph and the URL Frontier became the main bottleneck?
I would keep the same basic design and scale the URL Frontier more aggressively. The diagram already uses frontier shards, so I would add more shards and spread newly claimed URLs across them. The Seen URL Store would still perform the atomic check and claim before a URL enters the frontier. That keeps duplicate URLs from being added to different shards.
I would also add more Java Fetcher Worker JVM replicas when the frontier has enough ready work. I would keep the Bounded Input Queue in every worker. That backpressure stops the workers from accepting unlimited work. The Politeness + Robots Manager would still apply robots.txt rules and per-host limits, so adding workers would not allow one website to be flooded with requests.
Metrics / Logs / Traces would help show frontier backlog and worker activity. The main downside is more coordination because more shards and worker replicas make scheduling and balancing work harder.
How would the design behave if many websites started returning timeouts or temporary HTTP failures?
I would keep the normal crawl path unchanged and use the existing Retry Queue for temporary failures. When a Java Fetcher Worker gets a transient failure, it sends that URL to the Retry Queue instead of immediately retrying it.
The queue uses progressive exponential backoff. This means each repeated attempt waits longer before becoming ready again. When the retry is ready, it returns to the Bounded Input Queue. The Politeness + Robots Manager still controls per-host request limits, so retry traffic follows the same politeness rules as normal crawl traffic.
If a URL keeps failing and exceeds the retry limit, it moves to the Dead-Letter Bucket for manual review. That prevents one bad URL from retrying forever. Metrics / Logs / Traces record the failures and retries. The downside is slower crawl completion because failing hosts keep work in the system longer.
17. How would you design WhatsApp?System DesignHardMeta
i Question Details
Design a messaging platform with chat delivery, persistence, presence, and reliability.
Short Interview Answer (30-60 seconds)
At a high level, this system must accept messages safely and deliver them quickly to online or offline devices. The main challenge is keeping message delivery reliable while presence and delivery status can change very quickly. I would explain it in three flows: accepting and saving a message, delivering it through online fanout or offline notification, and handling retries in the background. The design scales with stateless JVM replicas, but some presence and delivery state can be slightly delayed.
Detailed Explanation
The goal is to let people send messages, save them safely, and deliver them to the right devices. The hard part is that users may be online, offline, or moving between devices while messages are being sent. A message must not be lost after the sender gets an acknowledgment. The diagram handles this by separating message acceptance, presence tracking, delivery, and background retry work. It also keeps the Java application tier stateless so more JVM replicas can be added when traffic grows.
Useful Questions to Ask the Interviewer
Do we need to support both mobile and web clients?
Should delivery and read status be allowed to appear a little later?
How long should presence information remain valid without a heartbeat?
What failure behavior is expected when delivery keeps failing?
How to Explain It in an Interview
1. Start with the entry and security path
I would say that clients first connect through the API Gateway / Load Balancer using HTTPS or WebSocket. The gateway does request validation, rate limiting, and session or auth token checks. It sends the token to the Auth Service, which uses the User / Auth Store and returns the auth result. Valid sessions are then routed into the Java application tier.
2. Explain how a message is accepted safely
For the send path, the Chat Service receives the message and validates it. It assigns the message ID and saves the message in the Conversation & Message Store. The sender gets an acknowledgment only after this durable write finishes. This ordering matters because the user should not see success before the message is safely stored. The Chat Service also publishes a delivery event to the Delivery Queue / Event Stream.
3. Explain presence and online delivery
The Connection Gateway manages WebSocket connections, session heartbeats, and routing. The Presence Service receives presence heartbeats and writes online or offline state into the Presence Cache. The Delivery / Fanout Service checks that cache before sending. If the recipient is online, it pushes the message over WebSocket to the recipient device. It also updates delivery or read status in the Conversation & Message Store. Presence is allowed to be slightly behind because it is based on heartbeats and TTL expiration.
4. Explain offline delivery and retries
If the recipient is offline, the Delivery / Fanout Service sends work to the Notification Service. That service sends a push notification to the offline device. Delivery events are also consumed by Background Consumers / Retry Workers running as separate JVM consumers. Failed work is retried with backoff, which means waiting longer between repeated attempts. After repeated failure, the work goes to the Dead-letter Queue / Store.
5. Explain scale, reliability, and operations
The Java 21/25 application tier uses multiple stateless JVM replicas behind the load balancer. That lets the service scale horizontally by adding more replicas. Virtual threads can help with many blocking I/O tasks, but they do not replace the external queue or durable storage. The system uses at-least-once delivery, so processing must be idempotent, meaning the same event can run again without creating a wrong duplicate result. Logs, metrics, and traces flow into the Observability Stack. The main trade-off is that presence and delivery status may update a little later across devices.
Engineering Considerations / Design Trade-offs
The benefit is strong reliability because the message is saved before the sender gets an acknowledgment. The queue and retry workers also let failed deliveries be tried again without blocking the main send path. The downside is more moving parts. Presence may be a little out of date because heartbeats and TTL control it. Delivery and read status may also appear later on another device. At-least-once delivery can repeat an event, so handlers must safely process the same work again. Stateless JVM replicas make scaling easier, but durable state still depends on the external stores and queue.
Why Interviewers Ask This
Interviewers ask this to see whether you can split a large messaging problem into clear flows. They want to know if you protect message data before acknowledging success, separate fast request handling from background delivery, handle online and offline users, and plan for retries. They also want to hear how you scale stateless Java services and explain trade-offs without claiming perfect consistency or exactly-once delivery.
Interviewer may ask next
What would you change if the interviewer requires messages to survive temporary delivery failures without delaying the sender acknowledgment?
I would keep the same basic design, because it already separates saving the message from delivering it. The Chat Service would still save the message in the Conversation & Message Store before acknowledging the sender. It would also publish the delivery event to the Delivery Queue / Event Stream.
The important part is that delivery can continue in the background. Background Consumers / Retry Workers consume the event and call the Delivery / Fanout Service. If delivery fails for a temporary reason, the workers retry with backoff. That means they wait before trying again instead of creating a tight retry loop. After repeated failure, the event moves to the Dead-letter Queue / Store for later inspection.
Correctness is kept because the durable message already exists before the sender sees success. At-least-once delivery means the same event may be processed again, so the processing must be idempotent. The downside is that final delivery can be delayed during failures.
How would this design handle a user who moves between online and offline states very quickly?
I would keep the same Presence Service and Presence Cache, but I would treat presence as a recent hint instead of perfect truth. The Presence Service updates the cache from heartbeats, and the Delivery / Fanout Service checks that state before choosing the delivery path.
If the cache says the user is online, the service tries the WebSocket path through the active connection. If that no longer works, the delivery can be retried through the existing background retry flow. If the user is considered offline, the Notification Service can send a push notification. The next heartbeat can then update the cached state again.
This stays correct because the actual message is already stored in the Conversation & Message Store. Presence only affects how delivery is attempted. The downside is that a fast state change can briefly cause an unnecessary push notification or a failed WebSocket attempt before the cache catches up.
18. How would you design YouTube?System DesignHardMeta
i Question Details
Design a video platform with upload, playback, search, recommendations, and scaling tradeoffs.
Short Interview Answer (30-60 seconds)
At a high level, I would design this as a video platform where playback must stay fast while uploads and processing can happen in the background. I would explain three flows: upload and processing, playback and delivery, and search plus recommendations. Clients enter through the API Gateway, video files live in Object Storage and CDN, and Java service replicas handle requests. Background workers process videos and indexes. The main trade-off is fast reads versus slightly delayed search and recommendation updates.
Detailed Explanation
The goal is to let people upload videos, watch them quickly, search for them, and receive useful recommendations. The hard part is that video files are large, playback must feel fast, and some work takes much longer than a normal request. The diagram separates the design into a fast playback path, an upload and processing path, and background work for indexing, recommendations, analytics, and monitoring. Large video data stays outside the Java application servers, while metadata and service requests go through the main service layer.
Useful Questions to Ask the Interviewer
How important is very low playback delay compared with upload processing time?
How fresh must search results and recommendations be after a new upload?
Should we optimize mainly for heavy read traffic and many concurrent viewers?
How to Explain It in an Interview
1. Explain the entry path and Java service layer
I would start with how requests enter the system. The API Gateway handles TLS termination, authentication checks, rate limits, and request validation. It routes requests to the Java 21/25 Service Tier, which runs as multiple JVM replicas.
Each replica is a separate JVM process, so replicas do not share heap memory. More JVM replicas can be added behind the gateway when request traffic grows. The service tier contains Video API, Upload Session Service, Playback Service, Metadata Service, Search Service, and Recommendation Service.
2. Explain the upload and processing path
For an upload, the Creator Upload Client gets an upload session and signed chunk URLs. Signed URLs let the client send large video chunks directly to Object Storage instead of sending the video bytes through the application servers.
Object Storage keeps the raw and encoded video data. A video uploaded event is sent to the Event Queue. Background Worker JVMs consume queued work. Transcoding Workers create encoded renditions, Thumbnail Generator creates thumbnails, and processed video data is written back to Object Storage.
The Upload Session Service also creates the video record in Metadata DB. Metadata DB holds the main metadata used by the service layer.
3. Explain playback and delivery
For playback, the Web / Mobile Client sends a playback request through the API Gateway. Playback Service looks up the manifest and metadata through Cache. If the cache misses, Metadata Service reads Metadata DB.
The client receives JSON metadata plus a signed playback URL or manifest. Video segments are then requested through CDN / Edge. If the CDN misses, it fetches the encoded video from Object Storage. This keeps popular video reads away from the origin storage.
4. Explain search, recommendations, and analytics
Search Service performs keyword lookups against Search Index. Search Index Consumer runs inside the Background Worker JVMs and receives asynchronous work from Event Queue. It updates Search Index in the background, so search can be slightly behind the newest metadata.
Recommendation Service handles home and next-video requests. Watch and click events from the Web / Mobile Client are sent asynchronously to Analytics / Event Log. Recommendation Feature Consumer processes recommendation-related background data and refreshes features used by Recommendation Service. This work stays outside the main request path.
5. Explain failures, operations, and trade-offs
Failed background jobs can be retried. Poison events that keep failing can be moved to a dead-letter queue for later investigation. Observability receives metrics, logs, and traces from the major components.
The design favors fast playback through CDN caching, signed URLs, caching, and horizontally scaled JVM replicas. The trade-off is that Search Index and recommendation data can be slightly behind the newest metadata.
Engineering Considerations / Design Trade-offs
The benefit is that playback stays fast because CDN / Edge serves popular video segments close to users. Signed URLs also keep large video files away from the Java application servers. Cache makes metadata reads faster, but a miss still needs Metadata DB. Search indexing, recommendation updates, and video processing run in the background, so they do not slow the main request path. The downside is that search and recommendation results may be a little behind. More JVM replicas help handle request traffic, but queues and workers still need retries, limits, and monitoring.
Why Interviewers Ask This
Interviewers ask this question to see whether you can break a large system into clear flows. They want to know if you understand large-file storage, fast playback, caching, background processing, and scaling separate JVM replicas. They also look for good judgment around metadata, delayed search or recommendation updates, retries, CDN usage, and explaining trade-offs without claiming perfect consistency or unlimited scale.
Interviewer may ask next
What would you change if playback traffic suddenly became much larger than upload traffic?
I would keep the same basic design, but I would scale the playback path more aggressively. The first focus would be CDN / Edge because video segments create most of the read traffic. Popular encoded segments should stay in the CDN so fewer requests reach Object Storage.
I would also add more JVM replicas behind the API Gateway for the user-facing service tier. Those replicas are separate JVM processes, so adding replicas increases request capacity without relying on shared in-memory state. Cache should continue serving repeated manifest and metadata lookups before Metadata DB is needed.
I would not move video bytes through the Java services. The client should still receive metadata plus a signed playback URL or manifest, then request segments through CDN / Edge.
The downside is cost. More CDN usage, cache capacity, and JVM replicas cost more, but they protect the origin and keep playback responsive.
What happens if background video processing fails after the upload is already accepted?
I would keep the upload data in Object Storage and let the background path handle the failed work. The video uploaded event goes through Event Queue to the Background Worker JVMs, so long-running processing does not need to block the upload request.
If a Transcoding Worker, Thumbnail Generator, Search Index Consumer, or Recommendation Feature Consumer fails while processing its work, the failed job can be retried. If an event keeps failing, the diagram shows a dead-letter queue for poison events. That separates bad work instead of letting it block normal processing.
Observability collects metrics, logs, and traces so the team can investigate the failure. The main request services can continue serving other traffic while the background job is retried.
The downside is delay. Encoded renditions, thumbnails, search updates, or recommendation features may become available later than expected.
19. How would you design a proximity server?System DesignHardMeta
i Question Details
Design a proximity server that finds nearby users or objects efficiently at scale.
Short Interview Answer (30-60 seconds)
At a high level, the goal is to find nearby users or objects quickly as locations keep changing. The main challenge is making nearby reads fast while keeping the latest location safely stored. I would explain two main flows: nearby search and location updates. Stateless Java replicas search the right spatial cells, calculate exact distance, apply privacy rules, and return JSON results. Updates write durable data and update the geo partition. The trade-off is that caches and read-optimized partitions may briefly lag behind changes.
Detailed Explanation
The system must take a location and quickly find users or objects close to it. The difficult part is that locations keep changing, while nearby searches still need fast answers. Checking every stored location would be too slow. The design solves this by dividing locations into spatial cells and searching only the needed cells. It then calculates exact distance before returning results. The diagram separates this work into a nearby-query path and a location-update path. The Latest Location Store keeps durable location data, while geo partitions are optimized for fast reads.
Useful Questions to Ask the Interviewer
What search radius and result limit should nearby queries support?
How quickly must a new location appear in nearby results?
Should blocked or private users always be removed from results?
How long should an inactive user or object remain searchable?
How to Explain It in an Interview
1. Start with the entry and security checks
A nearby query sends latitude, longitude, radius, and a result limit. It first passes through the API Gateway / Load Balancer.
The edge layer handles HTTPS, authentication, authorization and privacy rules, input validation, and rate limiting. These checks protect the Proximity Coordinator from invalid or unauthorized requests.
The Proximity Coordinator runs as stateless Java 21/25 JVM replicas. Stateless means replicas do not depend on private local application state. Virtual threads support many concurrent blocking I/O operations inside each JVM.
2. Explain the nearby-query path
The Spatial Partition Router finds the owning spatial cell and its neighbors. This avoids searching every stored location.
The coordinator uses the Spatial Partition Map to locate those cells. The Nearby Query Aggregator then queries the Geo Partition Cluster for the center cell and neighboring cells. Searching neighbors prevents misses near cell boundaries.
The cluster returns candidate IDs. The Exact Distance Calculator computes the real distance using Haversine distance. The Result Ranker sorts candidates by distance and relevance.
3. Add profiles, privacy, and the response
Next, the service fetches user or object profiles and ACL rules. The cache provides the fast path for hot profiles. The Metadata / ACL Store holds the profile and access-rule data used by this step.
The Privacy / ACL Filter removes results the caller cannot see. The Response Builder creates the nearby-results JSON and returns it through the edge layer to the client.
4. Explain the location-update path
A location update contains latitude, longitude, and a timestamp. The Location Update Handler validates and normalizes it.
It writes the new position to the Latest Location Store. It publishes a location-updates event to the Event Stream. It also upserts the position into the owning Geo Partition Cluster.
Background Update Workers consume events and maintain the read path. They check partitions, rebuild indexes, remove expired entries, and invalidate cache entries. TTL means time-to-live, which removes stale users or objects.
5. Explain scaling, failures, and trade-offs
Spatial partitioning spreads locations across cells or regions. Stateless Proximity Coordinator replicas can scale behind the load balancer.
If a geo partition is unavailable, the system can retry a replica. It can fall back to the Latest Location Store, but that path has higher latency.
The main trade-off is freshness. Geo partitions and caches make reads fast, but updates may take a short time to appear everywhere. Metrics, traces, and structured logs show latency, errors, cache hit rate, and request flow.
Engineering Considerations / Design Trade-offs
The benefit is fast nearby search because the system checks only the needed spatial cells and their neighbors. The Latest Location Store keeps location data durably, while the Geo Partition Cluster is optimized for quick nearby reads. The downside is that caches and geo partitions may briefly show older data after an update. Background workers help refresh indexes, remove stale entries, and clear affected cache data. If a geo partition fails, the service can retry a replica or use the durable location store. That keeps the system useful, but the fallback can be slower.
Why Interviewers Ask This
Interviewers want to see whether you can break a location problem into clear read and write flows. They also want to see how you use spatial partitioning, separate durable data from fast read structures, protect private data, and handle failures. The key skill is explaining why each design choice exists and what trade-off it creates.
Interviewer may ask next
What would you change if location updates became much more frequent than nearby searches?
I would keep the same design, but I would focus more on protecting the location-update path. The Location Update Handler would still validate each update and write it to the Latest Location Store. That keeps the newest location durably stored.
The handler would still publish a location-updates event and upsert the position into the owning Geo Partition Cluster. Background Update Workers would continue rebuilding indexes, removing expired entries, and invalidating cache data. I would watch the busiest spatial cells because rapidly moving users could create much more update work in those partitions.
The nearby-query flow would stay unchanged. It would search the center and neighboring cells, calculate exact distance, rank candidates, and apply privacy rules.
The main downside is freshness. When update volume becomes very high, read-optimized partitions and caches may take longer to reflect every change.
How would the design behave if one Geo Partition Cluster partition became unavailable?
I would use the failure path already shown in the design. The Proximity Coordinator normally queries the Geo Partition Cluster because it is optimized for nearby searches. If the required partition is unavailable, the system can retry a replica.
If that still fails, it can fall back to the Latest Location Store. That store keeps durable location data, so it provides another source for the request. The fallback is slower because the durable store is not optimized like the geo partition for nearby lookups.
The rest of the request still follows the same path. Candidate results are checked for exact distance, ranked, filtered by privacy rules, and returned as JSON.
Metrics, traces, and logs should show the failed partition, retry, and added latency. The main downside is slower nearby searches while the partition is unavailable.
20. How would you design APIs for Facebook live commenting?API DesignMediumMeta
i Question Details
Design API endpoints for posting live comments, reading recent history, and supporting moderation and delivery needs.
Short Interview Answer (30-60 seconds)
At a high level, I would design the API around posting comments, reading recent history, moderation, and live delivery. Clients send HTTPS requests with a JWT through the API Gateway to a Java Spring Boot Live Comment API. The API validates identity and permissions, persists comments, uses a recent-comments cache, and publishes comment events. Moderation controls visibility before approved comments reach viewers through WebSocket or SSE. I would also use idempotency for duplicate protection and cursor-based history processing. The trade-off is more asynchronous complexity for safer moderation and scalable live delivery.
Detailed Explanation
The goal is to let people post comments during a live video and quickly read recent comments. We also need moderators to review, hide, delete, or respond to reported comments. The difficult part is keeping the experience fast while many people are commenting at once. We also must avoid duplicate posts and prevent hidden comments from being delivered to viewers. I would explain the design in the same order as the diagram, starting with the client request and ending with moderation, storage, and live delivery.
Useful Questions to Ask the Interviewer
How many viewers and comments should one live stream support?
Should comments become visible immediately or only after moderation?
How much recent history should one client request at a time?
How to Explain It in an Interview
1. Define the client-facing API
I would put the Live Comment API behind an API Gateway. Web and mobile clients send HTTPS requests with a JWT. The gateway performs JWT authentication and rate limiting, then forwards a validated request to the Java Spring Boot application.
The diagram shows POST /live-streams/{streamId}/comments, GET /live-streams/{streamId}/comments?since=&limit=, POST /comments/{commentId}/report, POST /comments/{commentId}/hide, and DELETE /comments/{commentId}. Responses return through the API Gateway to the requesting client. The shown successful responses include 201 Created, 200 OK, and 202 Accepted.
2. Check identity and prevent duplicate writes
The Live Comment API asks the Auth Service to validate the token and resolve the user. The Auth Service returns the user identity and permissions. This separates identity checking from the comment business logic.
For comment creation, an idempotency key prevents duplicate submissions. If a client repeats the same submission, the design can recognize it instead of creating another comment.
3. Persist comments and serve recent history
For POST /live-streams/{streamId}/comments, the Live Comment API writes the comment to the Comment Store with a status such as pending or visible. The store keeps persisted comments and moderation status. It returns the commentId and persisted record to the API.
The API also updates the Recent Comments Cache. For recent-history reads, the API reads the cache and receives recent comments on a hit. The public GET endpoint uses since and limit. The diagram also shows the internal cache-miss path querying the Comment Store by streamId and cursor, with ordered recent comments returning to the API. Cursor plus limit supports pagination while new comments continue arriving.
4. Publish comment events and moderate them
The Live Comment API publishes events such as CommentPosted, CommentHidden, CommentDeleted, and CommentReported to the Comment Event Bus. This keeps downstream work asynchronous.
The Moderation Service consumes comment events and performs spam, abuse, and policy checks. It works with the Comment Store to obtain the comment record and current status and to update moderation status. It publishes results such as CommentApproved or CommentHidden back through the event bus. Moderator hide, delete, and review actions also enter through the API Gateway, and their response returns to the Moderator Console.
5. Deliver only visible comments
The Delivery / Fan-out Service consumes approved visibility events from the Comment Event Bus. It pushes only approved, visible comments to Live Viewer Sessions using WebSocket or SSE. Viewer sessions can subscribe or reconnect when needed.
This separates real-time fan-out from the original write request. A slow viewer therefore does not need to block comment persistence or moderation.
6. Record operations and explain the trade-off
The diagram sends request logs, latency information, and errors to Audit Log / Metrics. Moderation decisions are also recorded there. Audit logging is operational support and does not own the business response path.
The benefit of this design is that persistence, moderation, caching, and live delivery can scale separately. The downside is more moving parts and eventual timing differences between storage, moderation, cache updates, and live delivery.
Practical Complexity & Trade-offs
The design uses several choices to keep live commenting fast and safe. The Recent Comments Cache makes common history reads faster, but cached data must stay close enough to the Comment Store. The public history API uses since and limit, while the internal store path also shows cursor-based paging for ordered history. An idempotency key reduces duplicate comment creation when clients retry. Rate limiting protects the API from excessive traffic. The event bus lets moderation and delivery happen without blocking the original request, but asynchronous work adds operational complexity. WebSocket or SSE provides fast live updates, while the Comment Store keeps persisted comments and moderation status. We accept the extra complexity because storage, moderation, history reads, and fan-out can scale independently.
Why Interviewers Ask This
Interviewers use this question to test whether a candidate can turn product requirements into clear API boundaries and flows. They look for correct HTTP methods, request and response direction, authentication, rate limiting, idempotency, pagination, persistence, moderation, caching, and real-time delivery. They also want good judgment about synchronous versus asynchronous work. A strong answer explains which component owns each responsibility and discusses practical scalability and consistency trade-offs instead of only naming technologies.
Interviewer may ask next
How would this design handle a very large live stream with a sudden spike in comments?
I would keep the same external API and scale the existing components independently. POST /live-streams/{streamId}/comments would still enter through the API Gateway and reach the Live Comment API. Gateway rate limiting would protect the service from excessive traffic, while the idempotency key would continue preventing duplicate submissions during client retries. The API would persist comments in the Comment Store and publish comment events through the Comment Event Bus.
The largest pressure would usually be live fan-out because one approved comment may need to reach many viewer sessions. I would scale the Delivery / Fan-out Service separately while keeping WebSocket or SSE connections there. Recent history would continue using the Recent Comments Cache so repeated reads do not always hit the Comment Store. Moderation also remains asynchronous through the event bus.
The main downside is operational complexity. More API, storage, cache, moderation, event, and delivery capacity must stay coordinated, but the client-facing API contract can remain unchanged.
What happens when a comment is reported or hidden after it has been created?
I would keep the same moderation flow shown in the diagram. A report uses POST /comments/{commentId}/report, while a moderator can use POST /comments/{commentId}/hide or DELETE /comments/{commentId}. These requests still pass through the API Gateway to the Live Comment API, with identity and permissions checked through the Auth Service.
The Live Comment API publishes the related comment event to the Comment Event Bus. The Moderation Service consumes comment events, checks spam, abuse, and policy rules, and works with the Comment Store using the comment record and current moderation status. It then publishes an outcome such as CommentApproved or CommentHidden through the event bus. The Delivery / Fan-out Service consumes approved visibility events and sends only approved, visible comments to viewer sessions.
The Recent Comments Cache is updated so later history reads reflect the latest visible comment list. The downside is a small timing gap because moderation, cache updates, and delivery are asynchronous.
More questions load as you scroll
Disclaimer: This interview guide is for educational and informational purposes only. It is designed to help readers prepare, but it does not guarantee any interview result, hiring decision, offer, or outcome. Interview questions, hiring criteria, and preferred answers can vary by employer, interviewer, industry, location, and time. The examples and explanations reflect the authors' research and judgment, are provided without warranties of any kind, and should not be treated as the only correct approach. Diagrams are simplified illustrations intended to highlight the main components and their interactions; actual systems and implementations may be more complex. Alternative approaches may be equally valid or better suited to a particular question, context, or interviewer. To the fullest extent permitted by applicable law, the author, contributors, and publisher are not liable for decisions made, actions taken, or losses incurred based on this guide.
Company Notice: This guide is an independent educational resource and is not affiliated with, endorsed by, sponsored by, or approved by the company named in this guide. Company names are used only to identify interview experiences commonly reported by candidates. Interview practices can change without notice, and inclusion of company-specific content does not mean these questions are official, complete, or guaranteed to be asked. To the fullest extent permitted by law, the author, contributors, and publisher are not responsible for outcomes related to use of this material.