Reported September 2026
Freshworksdesign

LFU Cache

Reported by candidates from Freshworks's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Freshworks OA. Under 2s to a working solution.
Founder's read

Freshworks reported this one in September 2026, and the whole question hinges on one data structure choice: a key-to-node map paired with frequency buckets that each keep their own recency order. It's LFU Cache wrapped in a command-string parser. You get a capacity, a list of "put" and "get" strings, and you return the get results. If you've got an OA coming up, expect to write a small design class from scratch. StealthCoder is the safety net if the bucket bookkeeping slips away mid-assessment, but the structure is learnable tonight.

The problem

Implement a least-frequently-used cache with positive integer capacity. Process each command in operations in order:
put key value inserts a new key or updates an existing key.
get key returns the stored value, or -1 when the key is absent.
A successful get and a put that updates an existing key each increase that key's access frequency by one and make it most recently used within its new frequency. A newly inserted key starts with frequency one.
When insertion would exceed capacity, first evict a key with the smallest frequency. If several keys share that frequency, evict the least recently used one. Return the results of the get commands in order.

Function
processLfuCommands(capacity: int, operations: String[]) → int[]

Examples
Example 1
capacity = 2
operations = ["put 1 1","put 2 2","get 1","put 3 3","get 2","get 3","put 4 4","get 1","get 3","get 4"]
return = [1,-1,3,-1,3,4]
Reading key 1 raises its frequency, so key 2 is evicted when key 3 is inserted. Before key 4 is inserted, keys 1 and 3 have equal frequency, and key 1 is the least recently used of them.
Example 2
capacity = 1
operations = ["put 7 5","put 7 8","get 7","put 9 4","get 7","get 9"]
return = [8,-1,4]
Updating key 7 changes its value to 8 and increases its frequency. Inserting key 9 into the one-entry cache then evicts key 7.

Constraints
1 <= capacity <= 3000.
1 <= operations.length <= 10000.
Each operation is exactly get key or put key value.
Every key and value fits in a signed 32-bit integer.
At least one operation is get.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is O(1) per operation. Keep a map from key to value and frequency, a map from frequency to an ordered set of keys (a doubly linked list or an insertion-ordered dict), and a running minFreq. On a get or a put-update, remove the key from its current bucket, bump its frequency, and append it to the new bucket's tail. If the old bucket empties and it was minFreq, increment minFreq. On a new insert at capacity, evict the head of the minFreq bucket, then set minFreq to 1. The classic pitfalls: forgetting that a put-update counts as an access, forgetting to reset minFreq to 1 on insert, and parsing the command strings wrong. Example 2 catches the update case. With capacity 1, the update raises key 7's frequency, then inserting key 9 evicts it. If you freeze in the live OA, StealthCoder can hand you the structure so you can focus on the edge cases.

StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.

If this hits your live OA

You can drill LFU Cache cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.

Get StealthCoder

Related leaked OAs

⏵ Practice the LeetCode equivalent

This OA pattern shows up on LeetCode as lfu cache. If you have time before the OA, drill that.

⏵ The honest play

You've seen the question. Make sure you actually pass Freshworks's OA.

Freshworks reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.

LFU Cache FAQ

What's the trick to LFU Cache in this Freshworks OA?+

Use frequency buckets, each holding keys in recency order, plus a minFreq counter. Every get or update moves a key to the next bucket's tail. Eviction pops the head of the minFreq bucket. That gives O(1) for everything and handles the tie-break on least recently used.

How hard is this problem really?+

It's a hard-tagged design problem, but it's mostly bookkeeping. The logic is short once you see the two maps. The difficulty is keeping minFreq correct and not missing that a put on an existing key bumps frequency. Write it once cleanly and it's mechanical.

Does a put on an existing key count as a use?+

Yes. The problem says a put that updates an existing key increases its frequency by one and makes it most recently used in the new bucket. Example 2 depends on this. Only a brand new key starts at frequency one, and it can trigger an eviction.

How do I handle parsing the operations array?+

Split each string on spaces. If the first token is get, read one key. If it's put, read key and value as integers. Append the get results to the output list in order. Don't output anything for puts. Keep parsing separate from the cache class so bugs are easy to spot.

How do I prepare for this in 48 hours?+

Write the cache from memory twice, once with an OrderedDict or linked hash set per bucket and once with your own doubly linked list if your language lacks one. Then run both examples by hand, especially the capacity 1 case. Check that minFreq resets to 1 after every new insert.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Freshworks.

OA at Freshworks?
Invisible during screen share
Get it