PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates understanding of randomized selection, efficient in-memory data structures, and API/state management for a fixed-capacity load balancer that must support addNode, removeNode, and uniform random routing while handling duplicates, removals, and empty-state behavior.

  • medium
  • Revolut
  • Coding & Algorithms
  • Software Engineer

Implement a random fixed-size load balancer

Company: Revolut

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

## Problem: Build a simple load balancer Implement a minimal in-memory load balancer that routes each incoming request to **one backend node chosen uniformly at random**. ### Requirements - The load balancer maintains a **set of backend nodes** (e.g., strings or IDs). - The number of nodes is bounded by a fixed maximum capacity `K`. - Support these operations: 1. `addNode(nodeId)` - Adds a node if it is not already present. - If the load balancer is at capacity `K`, define and document what happens (e.g., reject the add / throw). 2. `removeNode(nodeId)` - Removes the node if present; otherwise no-op. 3. `route()` (or `getNodeForRequest()`) - Returns a node chosen **uniformly at random** from the currently active nodes. - If there are **no nodes**, define and document what happens (e.g., return null / throw). ### Constraints / Edge cases to handle - Adding duplicates. - Removing a non-existent node. - Routing when empty. - Keeping `route()` efficient (ideally O(1)). ### Deliverable Describe the data structures and implement the API (language-agnostic or Java-style).

Quick Answer: This question evaluates understanding of randomized selection, efficient in-memory data structures, and API/state management for a fixed-capacity load balancer that must support addNode, removeNode, and uniform random routing while handling duplicates, removals, and empty-state behavior.

Implement a minimal in-memory load balancer that routes each incoming request to one backend node chosen uniformly at random, with a fixed maximum capacity. Because `route()` is random, this challenge drives the load balancer through a deterministic, seeded simulation so the behaviour is reproducible. Implement `solution(operations, capacity, seed)`: - `operations` is a list of `[op, arg]` pairs: - `["add", nodeId]` -> `addNode(nodeId)` - `["remove", nodeId]` -> `removeNode(nodeId)` - `["route", null]` -> `route()` - `capacity` (K) is the maximum number of active nodes. - `seed` seeds the random generator used by `route()`. Return a list with one result per operation: - **addNode** -> `True` if the node was added, `False` if it was rejected (already present, or already at capacity K). - **removeNode** -> `True` if the node was removed, `False` if it was not present (no-op). - **route** -> the chosen node id, or `None` if there are currently no active nodes. Design target: keep `addNode`, `removeNode`, and `route()` all O(1). **Edge cases to handle:** adding duplicates, removing a non-existent node, routing when empty, and rejecting adds at capacity. **Hint on the O(1) design:** keep a list of node ids for O(1) random indexing, plus a hash map from node id to its index in the list. To remove in O(1), swap the target with the last element, pop the last, and fix the moved element's index in the map.

Constraints

  • 0 <= number of operations <= 10^5
  • 1 <= capacity (K) <= 10^4
  • Node ids are non-empty strings (or comparable hashable ids).
  • addNode at capacity K is rejected (returns False).
  • removeNode on an absent node is a no-op (returns False).
  • route() on an empty set returns None.
  • Each operation should run in O(1) amortized time.

Examples

Input: ([['add', 'A'], ['add', 'B'], ['add', 'A'], ['route', None], ['remove', 'B'], ['remove', 'B'], ['route', None]], 2, 42)

Expected Output: [True, True, False, 'A', True, False, 'A']

Explanation: Add A and B (capacity 2). Adding A again is a duplicate -> False. route() with seed 42 returns 'A'. Remove B -> True; removing B again is a no-op -> False. With only A left, route() returns 'A'.

Input: ([['route', None]], 3, 1)

Expected Output: [None]

Explanation: Routing when there are no active nodes returns None.

Input: ([['add', 'n1'], ['add', 'n2'], ['add', 'n3'], ['add', 'n4']], 3, 7)

Expected Output: [True, True, True, False]

Explanation: Capacity K is 3. The first three adds succeed; the fourth is rejected because the load balancer is full -> False.

Input: ([], 5, 0)

Expected Output: []

Explanation: No operations -> empty result list.

Input: ([['add', 'x'], ['route', None], ['remove', 'x'], ['route', None]], 1, 99)

Expected Output: [True, 'x', True, None]

Explanation: Add 'x' -> True. With one node, route() returns 'x'. Remove 'x' -> True. Now empty, so route() returns None.

Hints

  1. Maintain a flat list of active node ids so you can pick a random one in O(1) via an index.
  2. Maintain a hash map node_id -> index_in_list for O(1) membership checks and removals.
  3. To remove a node in O(1) without shifting, swap it with the last element, pop the last, and update the swapped element's index in the map.
  4. Guard the three edge cases explicitly: duplicate add, at-capacity add, remove-of-absent, and route-when-empty.
Last updated: Jun 26, 2026

Related Coding Questions

  • Implement a thread-safe money transfer - Revolut (medium)

Loading coding console...

PracHub

Master your tech interviews with 8,000+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.