## Overview
The key to a successful system design interview is to use a repeatable approach that allows for hitting on all key points within the tight time restrictions of the interview. Using an established framework will ensure that you can move from topic to topic in a clean manner and provide you a reference point on next steps in case you get stuck.
![[_Approach 2024-09-10 13.14.48.excalidraw.svg]]
## Requirements
### [[Functional Requirements]]
From the start, the candidate must establish the functional scope of the system in questions. Ideally, 3 core functions can be established to include in the high-level design. There must be a collaborative conversation between the interviewer and candidate to determine the priority requirements. It is key to ask questions to the interviewer to understand the purpose, users, and goals of the system.
It is also worthwhile to mention any out-of-scope requirements to the interviewer to demonstrate a comprehensive understanding of the product. Typically, omission is assumed to be ignorance.
---
Items to consider for **Functional Requirements** in System Design #flashcard
- 3-4 core functions
- Any "below the line" functionalities to prove strong understanding of the product
<!--ID: 1751507777845-->
---
### [[Nonfunctional Requirements]]
The nonfunctional requirements capture the qualities of the system itself. For example, the system should be able to scale to 100+ Daily Active Users (DAU) or the system shall have strong consistency to ensure data is never out of sync. While these are generic statements, in an actual interview these requirements **must be put into the context of the system**.
Similar to the functional requirements, a conversation with questions between the candidate and the interviewer are key to aligning on the proper nonfunctional requirements. The goal is to identify the 3-5 nonfunctional requirements most important to the problem.
The following a general areas to consider when thinking through what non-function requirements may be most important to the system.
- [[CAP Theorem]] - Should the system prioritize [[Consistency]] or [[Availability]]?
- Environment Constraints- is there anything unique to the system's environment, such as:
- Required to run on mobile?
- Limits in memory or bandwidth?
- [[Scalability]]
- What type of traffic does the system anticipate? Burst at certain times, uniform, large peak holidays?
- What is the expected read-write ratio?
- [[latency]]
- [[Durability]]
- [[Security]]
- [[Fault Tolerance]]
- [[Compliance]]
> [!info]
> Some interviewees always do estimations at this point, but I am going to wait. **CONFIRM THIS IS OKAY WITH INTERVIEWER**. Throughout the interview, there may be a need to calculate things such as size of data or number of API calls. To do so, use [[Back of the Envelope Estimation]] to support your decisions with real numbers.
---
Items to consider for **Nonfunctional Requirements** in System Design #flashcard
- Identify 3-5 NFR and into the *context* of the system
- Quantify certain items like scalability and latency
- Confirm if the interviewer is okay with holding off on BOTE calculations
<!--ID: 1751507777847-->
---
## Core Entities
These are the primary data entities of your system, which will eventually make up your data model. Hello Interview recommends only listing the core entities at this time and waiting to expand on the data model once it becomes relevant to your design.
This only requires a few simple bullets, and they should be listed as plurals.
---
Items to consider for **Core Entities** in System Design #flashcard
- Let the interviewer know we will start with simple list, and build out the data model during high-level design
<!--ID: 1751507777850-->
---
## API or Interface
The APIs represent the contract between a system and its users. In this context, the contract is an agreement of "if you send me this command and data, then I will complete this action and (potentially) return this data".
There are several different types of [[APIs]] that can be used for a given problem. The most common is a RESTful API, but others are shown below along with their general use cases.
> [!warning]
> Never include a UserID in the endpoint of an API. This poses a security risk and should rather be included in the request header.
| Protocol | Description | Pros | Cons | Use Cases |
| ------------------------------------------ | --------------------- | ----------------- | ----------------- | ---------------------- |
| REpresentational State Transfer ([[REST]]) | ![[REST#Overview]] | ![[REST#Pros]] | ![[REST#Cons]] | ![[REST#Use Cases]] |
| [[GraphQL]] | ![[GraphQL#Overview]] | ![[GraphQL#Pros]] | ![[GraphQL#Cons]] | ![[GraphQL#Use Cases]] |
| Remote Procedure Call ([[gRPC]]) | ![[gRPC#Overview]] | ![[gRPC#Pros]] | ![[gRPC#Cons]] | ![[gRPC#Use Cases]] |
| [[SOAP]] | ![[SOAP#Overview]] | ![[SOAP#Pros]] | ![[SOAP#Cons]] | ![[SOAP#Use Cases]] |
| [[WebSockets]] | | | | |
## \[Optional] Data Flow
For backend systems, you may want to capture the data flow.
## High-level Design
Using the previously identified information, create a system that meets the functional requirements. At this point, keep things **simple**. Do not introduce unnecessary complexity. These intricacies can be handled in the deep-dive.
Once decision during this design is when to decide when you'd like to create separate services. Some factors to consider for this decision include:
1. Whether the functionality is closely related
2. Whether the services need to scale independently due to vastly different read/write patterns.
## Deep-dives
Here is where you tweak your system to meet the non-functional requirements. It is key to engage with the interviewer throughout this process. You won't be able to waltz into showing them *exactly* what they need to hear.
When you are discussing various ways to meet the non-functional requirements, do not just say "I will use X." and move on. Discuss *why* that particular approach will address the needs of the system. Some examples of what that next level of thinking may look like:
- Scalability
- How does the technology enable horizontal scaling?
- Is the logic computationally efficient, thus allowing for high throughput?
- Performance
- If you're adding an [[Database Index]], what type of index? On what data attribute(s)?
- What is the [[Big O - Time Complexity]] for that type of index?
- Consistency
- Is the database [[ACID]] or [[BASE]]?
- Reliability
- Handing Concurrency
- Are there any race conditions introduced? Or are they avoided in the solution (i.e., by having a single threaded process)?
- If they are introduced, how are race conditions handled? Last write wins, user feedback, etc.)
- Maintainability
- Does the solution offer some sort of simplicity that makes it beneficial over alternatives?
#### References
- [System Design Delivery Framework](https://www.hellointerview.com/learn/system-design/in-a-hurry/delivery)