Table of Contents
Coding interviews can feel unfair to freshers. You have learned a language and built a few projects, and then an interviewer asks you to solve an unfamiliar problem in 30 minutes while explaining your thinking. The good news is that the skills being tested are specific and learnable, and a focused plan beats months of random practice.
This guide covers what the usual rounds test, a 12-week preparation plan, and the part most students never practise: thinking out loud. It includes a real interview-style problem solved two ways, with both solutions tested and timed, so you can see exactly what "optimise your solution" means in practice.
What the rounds usually test
- Online assessment. Timed coding problems, often with aptitude or multiple-choice questions. Speed and accuracy on standard problems matter most here.
- Technical interview. One or two problems solved live, usually in a shared editor. The interviewer watches how you think as much as what you produce.
- Projects and computer science basics. Expect questions about the projects on your CV, plus object-oriented programming, databases and SQL, and sometimes operating systems and networks.
- HR round. Communication, motivation and whether you would work well in the team.
Processes vary a lot between companies, so always read what a company says about its own rounds. But the preparation below covers the common core.
A 12-week preparation plan
This assumes you can already write basic programs in one language and can give 8 to 10 hours a week. It follows the same order as our data structures and algorithms roadmap, compressed for interview preparation.
| Weeks | Focus | Aim by the end |
|---|---|---|
| 1-2 | Your chosen language, Big O | Write clean functions quickly; state the complexity of any loop |
| 3-4 | Arrays, strings, hash maps | Solve two-pointer and counting problems in O(n) |
| 5-6 | Stacks, queues, binary search | Recognise when order or halving is the key |
| 7-8 | Recursion, sorting, linked lists | Trace recursive calls; reverse and merge lists |
| 9-10 | Trees, graphs, basic dynamic programming | BFS, DFS and simple memoisation |
| 11-12 | Mixed problems, mock interviews | Solve unseen problems out loud in 30 to 40 minutes |
Python, Java or C++?
Use the language you are most fluent in. Most companies accept any mainstream language for coding rounds. Python is fastest to write, Java and C++ are common in many technical interviews. Our Python vs Java comparison covers the trade-offs.
A worked example: the problem, then the conversation
Problem. Given a string, return the position of the first character that appears exactly once, or -1 if there is none.
Here is how the conversation should go. First, clarify: "Is the string lowercase letters only? What should I return for an empty string?" Then say the obvious solution out loud: "For each character, I could count how often it appears in the whole string. That works, but counting is O(n) and I do it for each of n characters, so it is O(n²)."
def first_unique_slow(text):
for i, ch in enumerate(text):
# count this character by scanning the whole string again
if text.count(ch) == 1:
return i
return -1
Then improve it by spotting the repeated work: "I am counting the same characters again and again. If I count every character once first, in a dictionary, each check becomes O(1), and the whole thing is O(n)."
from collections import Counter
def first_unique_fast(text):
counts = Counter(text) # one pass to count every character
for i, ch in enumerate(text): # one pass to find the first with count 1
if counts[ch] == 1:
return i
return -1
Finally, test it, including edge cases. We ran both versions against the same tests, and against each other:
def first_unique_slow(text):
for i, ch in enumerate(text):
# count this character by scanning the whole string again
if text.count(ch) == 1:
return i
return -1
from collections import Counter
def first_unique_fast(text):
counts = Counter(text) # one pass to count every character
for i, ch in enumerate(text): # one pass to find the first with count 1
if counts[ch] == 1:
return i
return -1
tests = {"leetcode": 0, "loveleetcode": 2, "aabb": -1, "": -1, "z": 0}
for text, expected in tests.items():
slow, fast = first_unique_slow(text), first_unique_fast(text)
assert slow == fast == expected
print(f"{text!r:>16} -> {fast:>2} (expected {expected})")
'leetcode' -> 0 (expected 0)
'loveleetcode' -> 2 (expected 2)
'aabb' -> -1 (expected -1)
'' -> -1 (expected -1)
'z' -> 0 (expected 0)
And the reason the improvement matters, measured on a long string:
def first_unique_slow(text):
for i, ch in enumerate(text):
# count this character by scanning the whole string again
if text.count(ch) == 1:
return i
return -1
from collections import Counter
def first_unique_fast(text):
counts = Counter(text) # one pass to count every character
for i, ch in enumerate(text): # one pass to find the first with count 1
if counts[ch] == 1:
return i
return -1
import random, string
from time import perf_counter
random.seed(4)
# a long string where the only unique character is near the end
text = "".join(random.choice(string.ascii_lowercase[:25]) * 2 for _ in range(20_000)) + "z"
for name, fn in (("slow, scan per character", first_unique_slow), ("fast, count once", first_unique_fast)):
start = perf_counter()
answer = fn(text)
print(f"{name:<26} answer {answer} {perf_counter() - start:.4f} s")
slow, scan per character answer 40000 1.3293 s
fast, count once answer 40000 0.0058 s
Both return the same answer. The slow one took 1.33 seconds and the fast one 0.006. In an online assessment with a time limit, that is the difference between passing and failing the test cases. Our guide to Big O notation explains how to predict this before running anything.
How to think out loud
- Clarify. Restate the problem in your own words and ask about input size, edge cases and anything ambiguous. It shows care and often reveals the intended solution.
- State a brute force first, with its complexity. A working slow idea beats a silent search for a perfect one.
- Improve out loud. Ask yourself where work is repeated, and whether sorting, a hash map or two pointers would remove it.
- Code while narrating. Short comments like "now I build the counts" keep the interviewer with you.
- Test by hand. Walk through a small example and at least one edge case: empty input, one element, all the same.
Practise speaking, not just solving
Most students only ever practise problems silently. Then, in the interview, explaining while coding feels impossible. Practise at least a few problems a week out loud, ideally with a friend or a teacher playing interviewer.
Projects and fundamentals
For freshers, one project you can discuss in depth is worth more than five you barely remember. Be ready to explain what it does, why you chose its design, what went wrong, and what you would change. A clean GitHub history helps. Our post on Git vs GitHub covers the basics, and how college students build real-world projects has ideas.
Also revise the fundamentals that come up again and again: object-oriented concepts such as classes, inheritance and polymorphism; SQL queries with joins and grouping; and, for some roles, the basics of operating systems and networks.
Common mistakes
- Solving hundreds of problems without reviewing them. Fewer problems, understood and re-solved later, build more skill.
- Jumping into code. Two minutes of clarifying and planning saves ten minutes of rewriting.
- Never stating complexity. Always say the time and space complexity of your solution before being asked.
- Ignoring edge cases. Empty inputs and single elements break many otherwise correct solutions.
- Freezing when stuck. Say what you are thinking. Interviewers can only give hints if they know where you are.
An interview is not a test of whether you know the answer. It is a test of how you behave when you do not, yet.
How we teach it
Interview preparation with us centres on solving problems out loud with a teacher playing interviewer, and on tracing code line by line until you can predict every step, one of the principles on our how we teach page. See our data structures and algorithms course and C++ for placement preparation, taught live, one to one or in small groups of 5 to 10.
Frequently asked questions
Get fluent in one language, learn Big O, then work through arrays and strings, hash maps, stacks and queues, binary search, recursion, trees, graphs and basic dynamic programming. Practise solving problems out loud, prepare one project in depth, and revise OOP and SQL basics.
For a student who already codes, about 12 weeks at 8 to 10 hours a week is a realistic plan. Beginners who are still learning a language should allow longer and focus on fluency first.
The one you know best. Most companies accept Python, Java, C++ and other mainstream languages. Python is quickest to write; Java and C++ are also widely used. Fluency matters more than the choice.
There is no magic number. Understanding and re-solving around 150 to 250 well-chosen problems across all major topics is enough for most fresher interviews. Reviewing matters more than raw volume.
Keep talking. State a brute force solution, explain its complexity, and describe what you would try next. Interviewers often give hints, and a clear partial solution with good reasoning can still pass.
Yes, at least one or two you can explain in depth. Interviewers use projects to judge whether you can build real software and discuss design decisions, not just solve puzzles.
Yes. Online assessments are timed and often automatically graded against hidden test cases, so efficient solutions and handling edge cases matter most. Live interviews also weigh your communication and reasoning.