Notion logo

Notion Interview Questions

31 practice questions for Notion technical interviews

Notion software engineer interviews cover algorithms, data structures, system design, and coding problems drawn from real interview rounds.

Software Engineer Backend Engineer Frontend Engineer Full Stack Engineer Mobile Engineer Data Engineer Data Scientist ML Engineer DevOps Engineer DevOps Engineer Product Manager SRE Security Engineer Engineering Manager Data Analyst UX/UI Designer QA Engineer

No verified questions yet for Notion.

coding Medium ui #1

1. Coding — Implement an image carousel component

Background: An image carousel is a common UI component used in user-facing applications, such as product galleries in Notion that allow users to view images in a rotating manner.
Problem statement: Your task is to create an ImageCarousel component that displays a list of images and allows users to navigate through them using next and previous buttons. The component should automatically cycle through images every few seconds as well. Implement the following methods:
  • next(): Navigate to the next image.

  • prev(): Navigate to the previous image.

  • display(): Output the currently visible image.


Function/class signature:
  • class ImageCarousel:

- def __init__(self, images: List[str]):
- def next(self) -> None:
- def prev(self) -> None:
- def display(self) -> str:
Example 1:
Input: carousel = ImageCarousel(['image1.jpg', 'image2.jpg', 'image3.jpg'])
carousel.display()
Output: 'image1.jpg'
Explanation: Initially, the first image is displayed.
carousel.next()
carousel.display()
Output: 'image2.jpg'
Explanation: The next image in the sequence is displayed.
Example 2:
Input: carousel.prev()
carousel.display()
Output: 'image1.jpg'
Explanation: Navigating back shows the first image again.
Constraints:
  • Maximum number of images: 100

  • Each image filename is a non-empty string and contains only alphanumeric characters and .

  • The carousel should auto-cycle every 3 seconds while displaying if not interrupted by user actions.

coding Medium api design #2

2. Coding — Build an Image Carousel Component

Background: Notion is known for its sleek user interface that allows users to create visually appealing pages and documents. Building an image carousel enhances user experience by allowing users to showcase images dynamically on their Notion pages.
Problem statement: You need to create an image carousel component for Notion that displays images with transition effects. The carousel should automatically move to the next image after a certain interval but also allow users to navigate manually through the images. Please implement the class ImageCarousel with the following methods.
Function/class signature:
  • def __init__(self, images: List[str]):

  • def next_image(self) -> str:

  • def previous_image(self) -> str:

  • def display(self) -> None:

Example 1:
  • Input: carousel = ImageCarousel(['image1.jpg', 'image2.jpg', 'image3.jpg'])

  • Output: carousel.display() → Displays image1.jpg, then carousel.next_image() displays image2.jpg.

  • Explanation: Initially, the first image is displayed. The next_image() method navigates to the second image.

Example 2:
  • Input: carousel.previous_image()

  • Output: Displays image3.jpg again after going back.

Constraints:
  • The number of images, n, must be greater than 0.

  • Each image URL is a non-empty string.

  • The navigation methods should handle wrapping around (i.e., going back to the last image from the first).

  • The display method should be called to show the current image.
coding Medium array #3

3. CODING — Build an image slider component

Background: Notion allows users to create and manage rich content, including images. An image slider is an interactive component that enhances user experience by displaying images efficiently within documents.
Problem statement: Implement a function that creates an image slider with the ability to move to the next or previous image. The component should accept an array of image URLs and provide navigation methods. The slider should loop through the images, allowing for seamless transitions.
Function/class signature:
  • class ImageSlider:

  • def __init__(self, images: List[str]) -> None:

  • def next_image(self) -> str:

  • def prev_image(self) -> str:

  • def current_image(self) -> str:

Example 1:
  • Input: slider = ImageSlider(['url1', 'url2', 'url3']) followed by slider.next_image()

  • Output: 'url2'

  • Explanation: The slider starts at url1, and calling next_image() moves it to url2.

Example 2:
  • Input: slider.prev_image() after the previous example

  • Output: 'url1'

  • Explanation: It loops back to url1 since the slider can navigate through its images in a loop.

Constraints:
  • The images list will contain at least 1 and at most 100 images.

  • Each image URL is a valid string URL not exceeding 2048 characters.
coding Medium caching #4

4. Caching — Implement an LRU Cache

Background: Notion needs an efficient caching strategy to manage frequently accessed data in a collaborative workspace. The Least Recently Used (LRU) Cache can ensure that frequently used items are quickly accessible while freeing up memory for less-used items.
Problem statement: Implement a data structure that supports the following operations: get(key: int) -> int and put(key: int, value: int). The get method returns the value of the key if present, otherwise returns -1. The put method updates the value of the key if the key exists. If the cache reaches its capacity, it should invalidate the least recently used item before inserting a new item.
Function/class signature:
  • def get(self, key: int) -> int:

  • def put(self, key: int, value: int) -> None:

Example 1:
*Input*:
cache = LRUCache(2)
cache.put(1, 1)
cache.put(2, 2)
print(cache.get(1))  # returns 1
cache.put(3, 3)      # evicts key 2
print(cache.get(2))  # returns -1 (not found)

*Output*:
1, -1
*Explanation*: Key 1 was accessed, key 2 was evicted to make space for key 3.
Example 2:
*Input*:
cache = LRUCache(1)
cache.put(1, 1)
print(cache.get(1))  # returns 1
cache.put(2, 2)      # evicts key 1
print(cache.get(1))  # returns -1 (not found)

*Output*:
1, -1
*Explanation*: Only one element can be kept in this cache, so key 1 is evicted when key 2 is added.
Constraints:
  • 0 < capacity <= 1000

  • 0 <= key, value <= 10^4

  • Cache operations are called at most 2 * 10^5 times.

coding Medium hash map #5

5. [Hash Map] — Find Duplicate in Document

Background: Notion allows users to upload and organize various types of documents. Efficiently identifying duplicate entries within a document can improve user experience and data management.
Problem statement: You are given an array of string representing lines of a document. Write a function that identifies if there are any duplicate lines. Return true if there are duplicates, otherwise return false.
Function/class signature: def has_duplicates(lines: List[str]) -> bool:
Example 1:
Input: ['Line 1', 'Line 2', 'Line 1']
Output: true
Explanation: The line 'Line 1' is duplicated.
Example 2:
Input: ['Hello World', 'Notion Rocks', 'Welcome to Notion']
Output: false
Constraints:
  • 1 <= lines.length <= 10^5

  • line length <= 100 characters

  • Each line is case sensitive.
coding Medium hash map #6

6. CODING — Find the first non-repeating character in a string

1. Background: In Notion, efficient text processing is essential for features like real-time collaboration and comment tracking. Identifying unique characters in user-generated content can help streamline these features.
2. Problem statement: Given a string s, return the first non-repeating character. If all characters are repeating, return None.
3. Function/class signature:
- def first_non_repeating_character(s: str) -> Optional[str]:
4. Example 1:
- Input: s = "engineering"
- Output: "n"
- Explanation: The character 'n' appears just once in the string.
5. Example 2:
- Input: s = "aabbcc"
- Output: None
- Explanation: All characters in the string are repeating.
6. Constraints:
- 1 <= len(s) <= 10^5
- s consists of only lowercase English letters.
coding Hard backtracking #7

7. [OA] Backtracking — Generate Notion-like Markdown from block types

Notion allows users to create various types of blocks that can include textual content, images, and to-do lists. We want to generate all possible Markdown representations from given block types.
The task is to implement a function to produce all combinations of Markdown representations for these blocks using backtracking.
Function Signature:
  • def generateMarkdown(blocks: List[str]) -> List[str]:

where blocks contains strings representing different block types like 'text', 'image', 'todo'.
Example 1:
Input: blocks = ['text', 'image']
Output: ['text', 'image', 'text
image', 'image
text']

Explanation: Each block can occupy a position individually or combined in a sequence.
Example 2:
Input: blocks = ['text', 'todo']
Output: ['text', 'todo', 'text
todo', 'todo
text']
Constraints:
  • 1 <= blocks.length <= 10

  • blocks[i] consists of unique types only.
coding Hard sliding window #8

8. [OA] Sliding Window — Calculate current view state in Notion’s real-time collaboration

In Notion, when many users are editing a shared document, we need to maintain a view of their changes in real time. Using the sliding window technique can help us efficiently track the changes.
The problem is to implement a function that can track the number of changes made within a specific viewing window of time.
Function Signature:
  • def countChanges(changes: List[Tuple[int, int]], window: int) -> int: where changes is a list of tuples representing changes with start and end times.


Example 1:
Input: changes = [(1, 4), (2, 5), (5, 7)], window = 3
Output: 3
Explanation: Changes are made at times 1, 2, 4, 5, 6, 7; within the window [1, 4], there are 3 changes.
Example 2:
Input: changes = [(1, 2), (2, 6), (5, 10)], window = 5
Output: 3
Explanation: All changes occur within the single 5 unit time frame.
Constraints:
  • 1 <= changes.length <= 10^5

  • 1 <= changes[i][0], changes[i][1] <= 10^9
system design Medium api design #9

9. Design ImageCarousel — A component for displaying images in a rotating carousel


Background: Notion often incorporates rich media elements in its notes and pages. An ImageCarousel component helps users navigate through a collection of images efficiently, enhancing visual storytelling in workspace documents.
Requirements:
1. The carousel should allow addition and removal of images dynamically.
2. Users can navigate through images using next and previous buttons.
3. The carousel should support automatic transitions after a specified interval.
4. A method to pause and resume automatic transitions should be included.
5. Each image should display a caption at the bottom.
Class API:
  • addImage(imageUrl: str, caption: str) -> None - Adds an image with its caption to the carousel.

  • removeImage(imageUrl: str) -> None - Removes an image from the carousel based on its URL.

  • nextImage() -> str - Moves to the next image and returns the current image's URL.

  • previousImage() -> str - Moves to the previous image and returns the current image's URL.

  • startAutoPlay(interval: int) -> None - Begins automatic transitions at the specified interval (in milliseconds).

  • pauseAutoPlay() -> None - Pauses the automatic transitions.

  • resumeAutoPlay() -> None - Resumes the automatic transitions.


Example 1:
  • Input: addImage("https://example.com/image1.jpg", "First image")

  • Output: None (image added successfully)

  • Explanation: The image with URL "https://example.com/image1.jpg" and caption "First image" is added to the carousel.


Example 2:
  • Input: addImage("https://example.com/image2.jpg", "Second image") followed by nextImage()

  • Output: "https://example.com/image1.jpg"

  • Explanation: After adding the second image, calling nextImage() returns the first image's URL and moves the pointer to the second image.


Constraints:
  • Maximum of 10 images can be added to the carousel.

  • Image URLs must be valid and not exceed 255 characters.

  • The interval for automatic transitions should be between 1000ms and 10000ms.
system design Senior api design #10

10. [OA] Twitter Feed — Design a minimal backend for Notion-like collaborative posting

Design a class structure that simulates a collaborative posting system similar to a Twitter feed in Notion. Users should be able to post messages, follow each other, and retrieve feeds from followed users in the correct order.
Class Signature:
  • class TwitterFeed:

  • def __init__(self): Initializes the Twitter feed object.

  • def post(self, userId: int, tweetId: int) -> None: Posts a tweet for a user.

  • def follow(self, followerId: int, followeeId: int) -> None: Allows follower to follow a followee.

  • def unfollow(self, followerId: int, followeeId: int) -> None: Allows follower to unfollow a followee.

  • def getFeed(self, userId: int) -> List[int]: Retrieves the 10 most recent tweet IDs in the order they were posted.


Example 1:
Input: twitter = TwitterFeed() and twitter.post(1, 5) and twitter.follow(1, 2) and twitter.getFeed(1)
Output: [5]
Explanation: User 1 posts a tweet and follows user 2.
Example 2:
Input: twitter.post(2, 6)
Output: [6, 5]
Explanation: User 2 posts a tweet, and user 1 gets the feed with both tweets in the right order.
Constraints:**
  • 1 <= userId, followerId, followeeId <= 10^4

  • 0 <= tweetId <= 10^4

  • The operations' total number does not exceed 1000.
system design Senior caching #11

11. [OA] LRU Cache — Implement caching for Notion's API responses

In Notion, caching is critical for performance, especially for frequent API requests. Implement an LRU (Least Recently Used) Cache to store API responses and efficiently handle eviction of the least recently accessed items.
Class Signature:
  • class LRUCache:

  • def __init__(self, capacity: int): Initializes the LRU Cache with a capacity.

  • def get(self, key: int) -> int: Fetches the value from the cache.

  • def put(self, key: int, value: int) -> None: Updates the cache with a new key-value pair or updates the value if the key exists.


Example 1:
Input: cache = LRUCache(2) and cache.put(1, 1) and cache.put(2, 2) and cache.get(1)
Output: 1
Explanation: Cache contains {1=1, 2=2} and fetching key 1 returns 1.
Example 2:
Input: cache.put(3, 3)
Output: None
Explanation: Previously added key 2 will be evicted due to LRU policy.
Constraints:
  • 1 <= capacity <= 3000

  • 0 <= key, value <= 10^4

Start practicing Notion questions

Sign up for free to access walkthroughs, AI-generated questions, and more.

Get Started Free