Rubrik Coding Interview Questions: OA, Technical Interview & Systems Round
Rubrik is a cloud data management and cybersecurity company headquartered in Palo Alto with a large engineering center in Bengaluru. Its interview process stands out from most product companies in one specific way, it leans heavily on concurrency, multithreading, and operating system resource allocation concepts, alongside standard DSA, rather than testing DSA alone.
This guide is organized by interview stage, online assessment, technical interview, and the systems and concurrency focused rounds, based on questions actually reported by candidates. Every problem includes the exact question, a worked example, the right approach, and time or space complexity where applicable.
Rubrik's Hiring Process for Fresher Roles
1. Application and Eligibility
- B.E./B.Tech, hired through campus and off campus drives. Eligibility CGPA cutoffs vary noticeably by campus and year, with reports ranging from around 8.0 to 9.0 CPI, so check your specific drive's requirements rather than assuming a fixed number.
2. Online Assessment (HackerRank) around 90 minutes
- Four coding problems in most reported drives, medium to medium hard difficulty, occasionally hard. Some internship specific drives report only two problems instead.
- Some drives are webcam proctored.
3. Technical Interview Rounds 1 to 3 rounds
- Conducted over a shared live coding pad. Typically one core DSA or design problem per round with deep follow-up questions, rather than several quick problems, so be ready to extend and optimise your first solution live.
4. Systems and Concurrency Round
- A distinguishing round at Rubrik, covering multithreading, mutexes, locks, and operating system resource allocation concepts, sometimes combined with a low level design task such as a cache system or messaging queue.
5. Hiring Manager and HR Round
- A conversation about your projects, software development lifecycle practices, testing methodology, and why you want to join Rubrik.
Preparation Resources
Part 1 Rubrik Online Assessment (OA) Questions
The OA runs on HackerRank, around 90 minutes, typically four problems. Problems lean medium to medium hard, occasionally hard.
1. Minimum Operations to Transform Array B Into Array A Medium
Given two arrays A and B containing the same elements in different orders, find the minimum number of operations to turn B into A, where each operation removes one element from B and reinserts it at either the front or the back of B.
Input: A = [3, 1, 2], B = [1, 2, 3]
Output: 1
Why: move 3 from the back of B to the front, giving [3, 1, 2]
Approach: Find the longest contiguous run of elements in B that already appear in the same relative order as in A. Every element outside that run needs exactly one move, so the answer is the total length minus the length of that longest matching run.
Complexity: Time O(n) · Space O(n)
Follow-up: How would you also output the actual sequence of moves, not just the count?
2. Minimum Stabs to Reduce a King's Health to Zero Medium
A king has a starting health value. Each stab either reduces the health by exactly 1, or, if the health can be factored as h1 times h2 with both greater than 1, replaces the health with either factor. Find the minimum number of stabs needed to reduce the health to zero.
Input: health = 12
Output: 5
Approach: Use dynamic programming or memoised recursion. For each health value, the best move is either subtracting 1, or picking the factorisation that minimises the combined cost of reducing each factor to zero, whichever gives the smaller total.
Complexity: Time depends on the factorisation cost per value, roughly O(h * sqrt(h)) in the worst case · Space O(h) for memoisation
Follow-up: How would you handle extremely large health values where full memoisation is not feasible?
3. Tree Color Ball Collection Hard
Given a tree where each node has a colored ball, starting from a source node you collect one ball per second as you move toward a destination node. Determine whether you can reach the destination having collected an equal, non zero number of balls of every color.
Input: a colored tree, source node, destination node
Output: true or false, whether a path exists where all collected color counts are equal and non zero
Approach: Since every valid path is a simple path in a tree, first find the unique path from source to destination, then check the color counts along that path. Multi source BFS or a straightforward tree path extraction both work, since the tree structure guarantees exactly one path between any two nodes.
Complexity: Time O(n) · Space O(n)
Follow-up: How would this change if the graph were not a tree and multiple paths could exist between source and destination?
4. Arithmetic Progressions With Bounded Common Difference Medium
Given an unsorted array and a value d, find all arithmetic progressions of length at least 3 within the array whose common difference is at most d.
Input: arr = [0, 2, 98, 102, 3, 6, 100, 104, 10], d = 4
Output: progressions such as [0, 2] extended pairs and [98, 100, 102, 104]
Approach: Sort the array first, then for each starting element, try extending a progression using nearby values within the allowed difference, using a hash set or sorted structure to check whether the next expected value exists efficiently.
Complexity: Time O(n log n) for the sort plus the search cost · Space O(n)
Follow-up: How would you count only the maximal progressions, avoiding reporting shorter progressions that are subsets of longer ones?
Part 2 Rubrik Technical Interview Questions
The technical interview typically centers on one core problem per round with deep follow-ups, conducted on a shared live coding pad.
5. Array Supporting Add and XOR Queries Medium
Design a data structure supporting two operations, Add, which appends a new element, and Xor, which XORs every element currently in the structure with a given value. A common follow-up asks you to also support a Min query, returning the minimum element, all in O(1) amortised time overall.
Input: add(5), add(3), xor(2), add(1), min()
Output: after xor(2), stored values conceptually become 7 and 1, plus the newly
added 1, and min() should return the smallest current value
Approach: Instead of applying XOR to every stored element immediately, maintain a running XOR mask applied lazily at read time. For the Min query extension, maintain values in a structure like a trie over bits so that XOR with a mask can be interpreted as flipping traversal direction, letting you find the minimum without touching every element.
Complexity: Time O(1) amortised for Add and Xor, O(log(max value)) for Min with a bit trie · Space O(n)
Follow-up: How would you additionally support a Max query alongside Min, using the same structure?
6. Scramble String Hard
Given two strings of the same length, determine whether the second is a scrambled version of the first, produced by recursively splitting the string into two non empty substrings and optionally swapping them at each level.
Input: s1 = "great", s2 = "rgeat"
Output: true
Approach: Use memoised recursion over substring pairs. For each pair, first check that both substrings contain the same character counts, then try every split point, checking both the non swapped and swapped recursive cases, caching results by the substring boundaries to avoid recomputation.
Complexity: Time O(n^4) · Space O(n^3) for memoisation
Follow-up: How would you optimise the character count check to avoid recomputation at every split point?
7. Design a Web Crawler Hard
Given a starting URL, design and implement a web crawler that visits all reachable pages under the same host, avoiding revisiting pages, and be ready to justify your data structure and algorithm choices with complexity analysis.
Discussion points: how visited pages are tracked, how new links are queued for
crawling, and how you would parallelise the crawl safely
Approach: Use a queue or worker pool for pages to visit and a hash set to track visited URLs, normalising URLs before checking membership. Discuss extending this to a breadth first crawl using multiple worker threads, with the visited set protected by a lock or replaced with a concurrent data structure to avoid duplicate work across threads.
Complexity: Time O(V + E) over the reachable page graph · Space O(V) for the visited set
Follow-up: How would you rate limit requests to avoid overwhelming any single host during the crawl?
8. Generate Non-Repeating Random Numbers in a Range Medium
Design a data structure that generates random numbers between 1 and N without repetition, and once all N numbers have been produced, cycles and starts generating the full range again.
Input: N = 5, then call next() repeatedly
Output: a random permutation of 1 to 5, then a new random permutation once exhausted
Approach: Maintain an array of the numbers 1 to N. To pick the next number, generate a random index within the remaining unused portion of the array, swap that element to the end of the active region, and shrink the active region by one. Once the active region is empty, reset it to the full range and repeat.
Complexity: Time O(1) per call · Space O(n)
Follow-up: Why is a hash set based approach less suitable here than the array swap approach?
9. Design a Text Editor Medium
Design a text editor class supporting insert, given an offset and text to insert, delete, given an offset and a length to remove, and getContents, returning the current full text.
Input: insert(0, "hello"), insert(5, " world"), delete(0, 6), getContents()
Output: "world"
Approach: A simple approach uses a mutable string buffer or dynamic array of characters, performing insert and delete as in place shifts. Discuss the trade-off with a more advanced structure like a rope or gap buffer if the interviewer pushes on performance for very large documents with frequent edits far from the end.
Complexity: Time O(n) per operation with a simple buffer, better with a rope · Space O(n)
Follow-up: How would you support undo and redo on top of this design?
10. Minimum Difference in a Sliding Window of the Last K Integers Medium
Given a stream of integers, at each point find the minimum absolute difference between any two values considering only the most recent K integers seen.
Input: stream = [4, 9, 1, 32, 13], k = 3
Output: the minimum pairwise difference within each window of the last 3 values, updated as the stream progresses
Approach: Maintain a sliding window of the last K values in a sorted structure, such as a balanced BST or sorted list, so that the minimum difference is always between two adjacent values in sorted order. Update the structure as the window slides, removing the oldest element and inserting the newest.
Complexity: Time O(log k) per update · Space O(k)
Follow-up: How would you adapt this if K could change dynamically at runtime?
11. Identify Nodes Not Pinged in the Last K Seconds Medium
Given a cluster of nodes and a stream of ping timestamps per node, identify which nodes have not been pinged within the last K seconds.
Input: pings = {(nodeA, t=1), (nodeB, t=2), (nodeA, t=10)}, k = 5, currentTime = 12
Output: nodeB, since its last ping at t=2 is older than currentTime - k = 7
Approach: Maintain the last seen timestamp per node in a hash map, updated on every ping. To find stale nodes, iterate the map comparing each node's last timestamp against the current time minus K, or maintain a time ordered structure like a queue of (node, timestamp) pairs to efficiently expire old entries without scanning the whole map each time.
Complexity: Time O(1) per ping update, O(n) to scan for stale nodes or O(log n) with a time ordered structure · Space O(n)
Follow-up: How would you design this to scale to millions of nodes with pings arriving continuously?
Part 3 Rubrik Systems, Concurrency, and Design Questions
This is where Rubrik differs most from other product companies. Expect genuine depth on concurrency primitives and resource allocation, not just a passing mention.
12. Two Queues Sharing One Buffer Medium
Given a single fixed size buffer of memory, implement two independent queues that share this buffer as their combined storage space.
Discussion points: how you divide the shared space between the two queues, what
happens when one queue needs more space while the other has room to spare, and how
you detect when the combined buffer is truly full
Approach: Rather than statically splitting the buffer in half, grow each queue's region dynamically from opposite ends of the buffer toward the middle, so one queue can use more space than the other as long as their combined usage fits. Track each queue's start, end, and count separately, checking for overlap to detect a full condition.
Complexity: Time O(1) per enqueue and dequeue · Space O(1) beyond the shared buffer itself
Follow-up: How would this design change if the two queues needed to be accessed by different threads concurrently?
13. Job Scheduler Based on Finished Dependencies Medium
Given a set of jobs with dependencies on other jobs, implement get_next_jobs(finished_jobs), which returns every job whose dependencies are all present in the finished_jobs set and which has not already been returned.
Input: jobs with dependencies {A: [], B: [A], C: [A], D: [B, C]}, finished_jobs = {A}
Output: [B, C]
Approach: Model the jobs and dependencies as a directed graph, and maintain an in degree count per job representing how many unfinished dependencies remain. On each call, check which jobs have all dependencies satisfied by the finished set and have not yet been dispatched, similar to Kahn's algorithm for topological sorting but driven by external completion signals instead of a single pass.
Complexity: Time O(V + E) overall across all calls · Space O(V + E)
Follow-up: How would you handle a cyclic dependency being introduced by mistake?
14. Multithreaded Completion of a Task Hierarchy Hard
Given a hierarchy of tasks with dependencies between them, implement a multithreaded program that completes all tasks as quickly as possible, respecting the dependency constraints.
Discussion points: how independent tasks are identified and dispatched to worker
threads, how you signal a thread pool when a task's dependencies are satisfied, and
how you avoid race conditions when multiple threads update shared task state
Approach: Use a thread pool combined with the same dependency tracking idea as a job scheduler, protecting the shared state, such as in degree counts and the ready queue, with a mutex or using a concurrent queue. When a task completes, its thread decrements the in degree of dependent tasks under the lock, and any task reaching zero in degree is pushed onto the ready queue for another worker to pick up.
Complexity: Time O((V + E) / p) with p worker threads in the ideal case · Space O(V + E)
Follow-up: How would you handle a worker thread crashing partway through a task?
15. OS Resource Allocation Policy Design Medium
A single shared resource, framed by one interviewer as a single bathroom, must be allocated fairly between two groups of competing requesters. Design and implement a resource allocation policy, discussing its trade-offs.
Discussion points: fairness between the two groups, starvation risk if one group
requests far more often than the other, and how you would implement your chosen
policy using OS level primitives
Approach: A simple FIFO queue across both groups guarantees fairness in request order and avoids starvation, at the cost of not distinguishing priority between groups. Implement it using a mutex to protect the queue and a condition variable to wake the next waiting requester when the resource is released, explicitly comparing this against alternative policies like strict alternation between groups.
Complexity: Time O(1) per request and release with a queue based implementation · Space O(n) for waiting requesters
Follow-up: How would you modify this policy if one group needed guaranteed priority access under high load?
16. Design a Messaging Queue System Hard
Design a messaging queue system supporting publishers and subscribers, covering the high level architecture and the API surface publishers and subscribers would use.
Discussion points: how messages are durably stored, how multiple subscribers to the
same topic are handled, delivery guarantees, and how you would scale the system
horizontally
Approach: Sketch a topic based architecture where publishers write messages to a durable, append only log per topic, and subscribers track their own read offset into that log, allowing multiple independent consumers to read at their own pace. Discuss partitioning topics across multiple nodes for horizontal scale, and the trade-off between at least once and exactly once delivery guarantees.
Complexity: Not applicable, evaluated on architecture clarity and awareness of trade-offs
Follow-up: How would you handle a subscriber that falls significantly behind and risks losing messages that get purged from the log?
17. Design a Pluggable Cache System Medium
Design and implement a cache system in the language of your choice, then extend it so that the eviction strategy, such as least recently used or least frequently used, can be swapped out without changing the rest of the cache's code.
Input: a cache with a fixed capacity and a pluggable eviction strategy
Output: a working get and put interface that evicts entries according to the
currently configured strategy once capacity is exceeded
Approach: Define an eviction strategy interface with methods like recordAccess and evict, then implement the core cache to call into whatever strategy object it is configured with, using inheritance or composition so new strategies can be added without modifying the cache class itself.
Complexity: Time O(1) for get and put with an LRU strategy implemented via a hash map and doubly linked list · Space O(capacity)
Follow-up: How would you make the cache thread safe without serialising every access behind a single global lock?
Preparation Tips
- Take concurrency seriously, not just as a side topic. Rubrik tests multithreading, mutexes, and resource allocation policies with real depth, more so than most product companies at the fresher level. Practice implementing thread safe data structures, not just reciting definitions.
- Expect one deep problem per round, not several shallow ones. Interviewers push hard on follow-ups and optimisations to your first working solution, so practice extending a solution live rather than moving on once it works.
- Practice explaining trade-offs out loud. Several rounds are evaluated on your reasoning and design choices as much as on a single correct answer, especially in the systems round.
- Do not neglect standard DSA. The OA and several technical rounds still lean on solid array, string, tree, and graph fundamentals, so concurrency prep should be additive, not a replacement.
Join our Telegram group to discuss more Rubrik interview questions and prep strategies!