Be honest: how many of the problems in your “Solved” list could you solve right now, from a blank editor, with someone watching?
When I asked myself that, the answer was uncomfortable.
I had solved 300+ problems. On paper, I thought I was ready.
But in actual interviews, I would sometimes recognize the pattern and still freeze halfway through the implementation. Or I’d open a problem I had “solved” a few weeks earlier and struggle to work it out again.
Looking back, I realized there were three gaps in the way I was preparing.
When practicing on LeetCode, my goal was simple: get Accepted.
Once I saw the green checkmark, I considered the problem done and moved on.
But an actual interview evaluates much more than whether your final code eventually works.
Can you recognize the pattern without a hint?
Can you explain your approach clearly before you start coding?
Can you derive and justify the time and space complexity?
Can you think of edge cases yourself?
Can you dry-run your code and catch bugs before someone else points them out?
Can you implement the solution cleanly under pressure?
Two people can both get AC on the same problem, but have very different levels of proficiency across these dimensions.
That was the first gap for me: I was practicing for AC, while interviews were evaluating a much broader set of skills.
So after each problem, I started evaluating myself on those dimensions instead of treating AC as the finish line.
This was the second gap.
I used to solve a problem, understand the solution, get AC, and think: Okay, I know this now.
But solving something once isn’t the same as mastering it.
To me, mastery means more than being able to recognize a problem you’ve seen before. It means understanding the underlying idea well enough that you can reconstruct the solution later, explain why it works, and recognize when the same idea applies to a problem you’ve never seen before.
In other words, the goal isn’t to remember the solution. It’s to internalize the pattern well enough to transfer it.
And that doesn’t automatically happen after one AC.
A few weeks after solving a problem, I would sometimes open it again and realize that I remembered seeing it, but couldn’t derive the solution from scratch.
My old version of “reviewing” didn’t help much either:
Open an old problem → look at my solution → “Oh right, two pointers” → close it.
Everything looked familiar, so I assumed I had mastered it.
But recognition can create a false sense of mastery.
In an interview, nobody shows you your old solution. And often, the problem won’t even look exactly like one you’ve seen before. You have to recognize the underlying structure, retrieve the right idea, and adapt it to a new setting — all while under pressure.
So I changed how I review:
Basically, spaced repetition — but the thing I’m trying to reinforce isn’t the code itself. It’s the reasoning pattern behind the problem and my ability to retrieve and apply it.
That’s also why I think periodically revisiting old problems matters. Without retrieval and reuse, something you understood perfectly on the day you solved it can still fail to become something you can reliably use later.
This was probably the most expensive mistake.
I used to look at my solved count as evidence that I was ready:
100 problems.
200 problems.
300 problems.
The number kept going up, so naturally I felt like I was getting closer to being “ready.”
Eventually I started interviewing.
And then I realized that 300 solved problems didn’t necessarily mean I could reliably solve interview problems under interview conditions.
Some patterns I hadn’t truly mastered.
Some I understood when I first learned them but couldn’t retrieve weeks later.
Sometimes I recognized the right algorithm but couldn’t implement it smoothly.
Other times I could write the code but struggled to clearly explain the reasoning, complexity, or edge cases.
The frustrating part was that I didn’t discover those gaps until I was already in an actual interview.
And interview opportunities aren’t unlimited.
Failing because you genuinely haven’t learned something yet is one thing. Failing because the metric you were using told you that you were ready when you actually weren’t is especially frustrating.
So I stopped asking:
“How many problems have I solved?”
and started asking:
“How many of these could I solve again, cold, under interview conditions — and how well?”
That turned out to be a much more useful question.
Of course, identifying these gaps is one thing. Actually tracking and improving them consistently is another.
I initially tried using a spreadsheet, notes, and calendar reminders to track my performance and schedule reviews.
It worked, but maintaining the system itself created a surprising amount of friction.
After every problem, I had to update my spreadsheet, organize my notes, figure out when to review it again, and keep track of what was due each day.
None of these tasks was particularly difficult, but together they added a lot of overhead to something that was already hard to stay consistent with.
And that’s the problem with friction: every extra step makes it a little easier to say, “I’ll do it tomorrow.”
LeetCode prep already requires a lot of discipline. I didn’t want maintaining my prep system to require another layer of willpower on top of actually solving problems.
So I started trying to keep the process as lightweight as possible:
I’m still refining this process, but one thing has become clear to me: a review system is only useful if you can actually stick with it.
And ultimately, the biggest change in my preparation was realizing that:
Solved count measures how many problems I’ve passed before. It doesn’t necessarily measure how many patterns I’ve mastered or how ready I am to solve a new problem tomorrow, under pressure.
I’m curious how other people measure interview readiness.
Do you have a point where you decide, “Okay, I’m ready to start interviewing”?
And how do you tell whether you’ve actually mastered a pattern versus just recognizing problems you’ve seen before?