After 280 LeetCode problems, I realised “feeling ready” wasn’t a metric. A diagnostic was.
I'd solved around 280 problems by the time the FAANG readiness question got serious, and the answer changed every week. Some weeks felt close after a clean batch of trees. Most weeks the next unfamiliar medium would freeze cold and the confidence would evaporate by Tuesday. The pattern repeated for months without resolving.
It took longer than it should have to notice the question itself was the issue.
"Do I feel ready" wasn't a question with a stable answer.
The threshold was real. The measurement of it was a mood read on a moving session.
- Self assessed readiness drifts every session. A clean morning of trees and a frozen afternoon of graphs both produced wrong answers.
- The interview wasn't testing the same skill that practice on familiar problems trains. It was testing what holds up on shapes you haven't seen.
- Problem count flatlined as a useful signal somewhere around 100 problems. Past that, more volume on familiar shapes added count without moving the threshold.
- The fix was a measurable test, not more prep. An unseen medium, a hidden title, a real timer, repeated across three different families.
- The diagnostic was more useful than the score. "Two passed, one failed on graphs" was an action plan. "Feeling 70 percent ready" was anxiety.
Quick disclosure before I get into this: I built Codeintuition, a structured learning platform for coding interviews. This post is the retrospective on what someone should have handed me earlier, not a pitch for the product.
Where the approach was breaking
The first thing that broke was the belief that the count was the metric.
The tracker said 280, on its way to 350. The tracker also didn't predict any individual interview performance. Open a medium you haven't seen, freeze for ten minutes, and the count number sits there grinning at you, useless.
The second thing that broke was the topic completion checkmark.
Sliding window finished in February. By June the recall on a sliding window medium you hadn't seen was unreliable. The completion checkmark didn't decay.
Recall did.
The third thing that broke was speed on familiar problems.
Two Sum in two minutes feels like fluency. It's actually retrieval of a stored solution. The first time you hit a problem that looks like Two Sum but has a different constraint structure, the speed disappears and you're back to staring.
The fourth thing was peer comparison, which broke quietly because it had never worked in the first place.
Someone else got into Google in six months. That said nothing about your readiness. Background, family coverage, how they'd practised, the level they interviewed for, none of it generalises.
What was actually happening is that all four signals were measuring the wrong thing.
The interview gives you a problem you haven't seen. The four signals all measured behaviour on problems you had seen.
They were diagnostically useless for the question they were being asked to answer.
The diagnostic that ended up working
The version that worked was small and strict.
Two hours. Three problems. Three different families. Real interview conditions.
The shape:
- Pick a pattern family genuinely studied (sliding window, tree traversal, graph BFS, DP subsequence)
- Find a medium difficulty problem in that family that has never been solved, hinted, or read about
- Cover the problem name so the title can't reveal the family
- Twenty minute timer, hard cap on failed code execution attempts, no peeking
- Identify the family from the constraints, build the solution from the family's invariant, trace it before running
A pass was:
- solved within the timer
- fewer than two failed runs
- family identified from the constraints
Anything else was data.
Three passes across three families was a strong readiness signal. Recognition was firing on shapes you hadn't seen, the construction was following the family's invariant rather than recall, and the conditions were close enough to a real round that the result generalised.
Two passes and one failure told you precisely which family to work on. No need for more random volume.
Depth in one specific place.
All three failed was the most useful diagnostic of the three.
It said the prep method had been building near transfer without far transfer, which is the gap described in the idea of Transfer of Learning.
Method gap, not talent gap.
The fix was correspondingly narrower than:
“Grind more problems.”
What that looked like on the third pass
The pass that taught the most was a DP subsequence problem run cold.
The family had been studied. The canonical examples had been worked through. It hadn't been ground the way sliding window or trees had been ground, so it was a fair test of recognition rather than recall.
The constraints described a longest increasing subsequence variant.
With the title hidden, the recognition still happened in the first three minutes because the constraints fit the DP subsequence shape:
- A one dimensional input, not two.
- An output asking for the longest sub structure satisfying a condition.
- The absence of two pointer or sliding window triggers that would have applied if the answer had been contiguous.
The skeleton came from the family's invariant, not from a remembered problem:
dp[i] is the length of the longest valid subsequence ending at index i.
def length_of_lis(nums):
if not nums:
return 0
dp = [1] * len(nums)
for i in range(1, len(nums)):
for j in range(i):
if nums[j] < nums[i]:
dp[i] = max(dp[i], dp[j] + 1)
return max(dp)
Trace on a five element array by hand. Verify the recurrence on the trace. Then run.
It passed.
Five minutes still on the timer.
The check that mattered wasn't getting it right.
It was how:
- Family identified from the constraints inside three minutes
- Skeleton written from the invariant rather than retrieval
- Verified by tracing
That's what pattern recognition holding under pressure looks like in practice.
If any of those three steps had broken, the pass would have been a memory pass, not a recognition pass, and the family wouldn't actually have been ready yet.
The protocol the earlier version of me needed
The change that mattered most was switching what practice was for.
Up to about month four practice was for a problem set. After running the diagnostic for the first time, practice changed shape to feed the diagnostic.
| Before the diagnostic | After |
| Solve next problem on the list | Pick a family, work through three problems with the title hidden |
| Read editorial when stuck | Read the foundational material on the family's invariant when stuck |
| Track problem count | Track families where the diagnostic passes cleanly |
| Do problems in order of difficulty | Do problems in order of how shallow recognition was on the family |
| Speed up by recognising problems | Speed up by recognising the family from constraints with the title hidden |
| "How many problems before I'm ready" | "How many families pass the diagnostic before I'm ready" |
Three rules ended up doing most of the work in the after column.
1. One unseen medium per family per week
Title hidden.
Timer running.
Not as a substitute for the rest of practice.
As the diagnostic that anchored what to practise next.
2. Foundational material on the family's invariant before more volume
When a family failed the diagnostic, the next thing to read wasn't a new problem.
It was the page on what made the family applicable.
Volume came after.
That distinction between solving a problem and recognising a family from constraints is exactly what eventually shaped how I built Codeintuition.
3. Don't retest with the same problem
A retest on a problem already seen, even one that was failed, measured recall instead of reasoning.
The whole point of the diagnostic was novel problem performance.
What the failure modes told me
Most engineers running a version of this diagnostic don't pass three for three on the first attempt.
The first attempt for me wasn't clean either.
The diagnoses to read off the result:
One family failed
The pattern was understood at a surface level but the identification triggers and the construction skeleton hadn't been internalised.
Fix:
- revisit foundational material
- retest with a different unseen problem
Two families failed
Usually:
One strong area with over practised volume, shallow gaps everywhere else.
Common for engineers who spent months on one topic because the work felt productive.
Fix:
- broaden coverage
- spend focused time on the families where the depth is thin
All three failed
Method gap, not talent gap.
Too much:
- solving familiar problems
- repetition
- memorisation
Not enough:
- recognition
- transfer
- unseen problems
- interview shaped conditions
The fix is narrower than:
"Work harder."
What I wish someone had handed me earlier
The difference between the score and the diagnostic was the difference between an opaque feeling and an action plan.
"Maybe 70 percent ready" was anxiety.
"Two passed, the DP subsequence family failed because the invariant for non contiguous selections wasn't internalised yet" was what to do on Wednesday.
If family coverage is the bottleneck rather than conditions, the algorithms learning path on Codeintuition is one place to fill the gap before retesting.
The diagnostic itself doesn't depend on it.
The point is the test, not the source of the problems.
I originally wrote a longer version on my own blog that includes the per family signal breakdowns and diagnosis trees for the most common failure modes.
What was the moment that made the readiness question itself feel like the wrong question, and what did you start measuring instead?