← Figma Interview Insights

Figma·Machine Learning Engineer·Technical Phone Screen·Senior

Senior
Apr 2026

Summary

Figma ML engineer interview with a coding problem centered on undo/redo behavior in a layer editor. The problem was deceptively tricky once batched operations entered the picture.

Questions Asked (1)

Q1

You're building a layer/document editor (think Figma-like) that supports mutating operations and an Undo command. Implement Redo such that it re-applies the most recently undone operation, handles batched operations as atomic units, and invalidates the redo stack whenever a new mutation occurs after an Undo.

Algorithms & Data StructuresSystem DesignTechnical Trade-offs
Author's notes

The basic redo stack wasn't bad, two stacks, push to redo on undo, pop from redo on redo, clear redo on new mutation.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying the requirements and constraints, then propose a two-stack (undo and redo) architecture where each stack stores operations or batches. Explain how Redo pops from the redo stack, re-applies the operation(s) atomically, and pushes back onto the undo stack, while any new mutation clears the redo stack.

Pro tip: Emphasize that batching should be handled at the operation level, not by storing individual sub-operations, to ensure atomicity and simplify undo/redo logic. Also, mention that in a collaborative editor like Figma, you'd need to consider conflict resolution and operation transforms, but for this question, focus on the single-user case.

1. Clarify Requirements and Constraints

Ask about the nature of operations (e.g., are they reversible? do they have side effects?), the expected size of batches, and whether concurrency or collaboration is in scope. Confirm that Redo should only re-apply the most recently undone operation and that new mutations invalidate the redo stack.

2. Design Data Structures

Propose using two stacks: one for undo (history) and one for redo. Each element can be a single operation or a batch (list of operations) treated as an atomic unit. Alternatively, use a single list with a pointer, but two stacks are simpler for this requirement.

3. Define Operation and Batch Representation

Specify that each operation should have an apply and revert method (or equivalent). For batches, wrap multiple operations into a composite operation that applies/reverts all sub-operations in order (or reverse order for revert) to maintain atomicity.

4. Implement Undo and Redo Logic

Undo: pop from undo stack, revert the operation(s), push onto redo stack. Redo: pop from redo stack, re-apply the operation(s), push onto undo stack. Ensure that redo is only possible if the redo stack is non-empty.

5. Handle New Mutations and Edge Cases

When a new mutation occurs (not via redo), clear the redo stack to invalidate it. Discuss edge cases: empty stacks, redo after multiple undos, and potential memory optimizations (e.g., limiting history size).

Key Points to Mention

  • Two-stack approach: undo stack and redo stack for O(1) undo/redo operations.
  • Batched operations as atomic units: treat a batch as a single operation in the stacks.
  • Redo stack invalidation: clear redo stack on any new mutation after undo.
  • Operation interface: apply() and revert() methods for each operation.
  • Memory considerations: potential to limit history size or use command pattern.
  • Collaboration context: mention that in a multi-user scenario, operational transforms or CRDTs would be needed, but not required for this question.

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.