Katkat

Design an in-memory TODO list API

BloombergSoftware Engineer · Technical Screen

Last updated

This problem tests your ability to design a thread-safe, in-memory API for managing tasks, focusing on selecting efficient data structures for retrieval and update operations.

Problem Statement

Design an in-memory TodoList class that supports managing a collection of tasks. Each task has a unique id (integer), a title (string), and a status (enum: PENDING, IN_PROGRESS, COMPLETED).

You need to implement the following interface:

  • addTask(id: int, title: str) -> bool: Adds a new task. Returns False if a task with the given id already exists, otherwise returns True.
  • updateStatus(id: int, status: str) -> bool: Updates the status of an existing task. Returns False if the task does not exist, otherwise True.
  • getTask(id: int) -> dict: Returns the task object as a dictionary if it exists, or None otherwise.
  • deleteTask(id: int) -> bool: Removes the task. Returns False if it does not exist, otherwise True.

Constraints

  • The system must be thread-safe.
  • Operations should ideally run in O(1) time complexity.
  • Assume id is a non-negative integer.

Example

todo = TodoList()
todo.addTask(1, "Finish report")  # Returns True
todo.updateStatus(1, "COMPLETED") # Returns True
print(todo.getTask(1))            # Returns {'id': 1, 'title': 'Finish report', 'status': 'COMPLETED'}
todo.addTask(1, "Duplicate")      # Returns False

Considerations

  • How will you ensure data consistency in a multi-threaded environment?
  • What data structures allow for efficient lookup, insertion, and deletion?

Hints

Hint 1

Use a hash map (dictionary) to store tasks with the ID as the key for constant-time access.

Hint 2

Use a synchronization primitive, such as a reentrant lock (mutex), to ensure that read and write operations are atomic.

Hint 3

Consider defining an Enum class or constant strings to validate the status input and prevent invalid states.

Follow-up questions

  • How would you modify the API to support filtering tasks by status in O(1) or O(N) time?
  • If the number of tasks grew to millions, how might you optimize memory usage beyond a simple dictionary?
  • How would you implement a 'history' feature to track when a status was last changed for each task?