On this page
- The signals interviewers typically score
- Coding interview tips for a 45-minute round
- A worked example: Longest Substring Without Repeating Characters
- Step 1: Clarify
- Step 2: Start with brute force
- Step 3: Find the bottleneck
- Step 4: Code the sliding window
- Step 5: Dry run on "abba"
- Step 6: State the complexity
- Red flags interviewers notice
- What to do when you're stuck
- How to practice effectively
- Learn patterns, not answers
- Do timed mock interviews
- Explain out loud
- Review your mistakes
- Key takeaways
Many candidates prepare for coding rounds by solving more problems, then find in the interview that working code is only part of what's evaluated. This post collects the coding interview tips I'd give from the other side of the table: the signals interviewers typically score, a minute-by-minute plan for a 45-minute round, a fully worked example, and a practice routine that builds the right habits.
As part of the hiring loop at BigLeap, I take technical interviews covering data structures and algorithms, system design and problem solving. What follows isn't any company's official rubric. It's the set of signals widely used across the industry, and the ones I listen for when I'm interviewing.
The signals interviewers typically score
A correct solution matters. But "solved it" is one data point, and interview feedback usually covers how you got there.
| Signal | What good looks like | Common miss |
|---|---|---|
| Clarifying the problem | Restates it; asks about input size, types, duplicates, empty input and expected output | Solves an assumed version of the problem |
| Communicating an approach | Explains the plan and gets agreement before coding | Types in silence, so the interviewer can't follow or help |
| Brute force, then improve | States a simple correct solution and its cost, then finds the bottleneck | Freezes hunting for the optimal answer, or never offers a baseline |
| Complexity reasoning | Gives time and space complexity and explains why | Guesses "O(n)" without tying it to the code |
| Clean, readable code | Clear names, small helpers, edge cases handled explicitly | Single-letter variables, copy-pasted blocks |
| Testing | Traces an example by hand, then edge cases, and fixes what it finds | Says "I think it works" and stops |
| Responding to hints | Pauses, considers the hint and builds on it | Ignores it or treats it as an interruption |
| Coachability | Takes feedback and new constraints calmly and adapts | Gets defensive about the original approach |
The common thread is visibility. An interviewer can only score what they see or hear, and a candidate thinking brilliantly in silence looks the same as one who is stuck.
Coding interview tips for a 45-minute round
Rounds vary, so treat this as a rough budget, not a script.
| Minutes | What to do |
|---|---|
| 0–5 | Restate the problem. Ask about constraints, input size and edge cases. Agree on one or two examples. |
| 5–12 | Describe a brute-force solution and its complexity. Propose a better approach and check the interviewer is happy for you to code it. |
| 12–30 | Write the code, narrating key decisions. If a detail blocks you, say so and leave a note to return to it. |
| 30–37 | Trace one normal example line by line, then edge cases. Fix bugs out loud. |
| 37–42 | State final complexity. Discuss trade-offs and likely follow-ups. |
| 42–45 | Ask your questions. |
The blocks easiest to skip under pressure are the first five minutes and the testing window. Both are cheap, and both are scored.
A worked example: Longest Substring Without Repeating Characters
Let's run the framework on a classic, Longest Substring Without Repeating Characters: given a string s, return the length of the longest substring with no repeated characters.
Step 1: Clarify
- Substring or subsequence? Substring, so characters must be contiguous. For
"pwwkew"the answer is 3 ("wke"), not 4, because"pwke"is a subsequence. - Which characters? Letters, digits, symbols and spaces. This bounds how large a hash map can grow.
- Empty string? Return 0.
Examples to agree on: "abcabcbb" → 3, "bbbbb" → 1, "pwwkew" → 3, "" → 0.
Step 2: Start with brute force
Checking every substring for duplicates is O(n^3): O(n^2) substrings, O(n) to check each. You can drop a factor of n quickly by fixing a start index, extending right with a set, and stopping at the first repeat.
def length_of_longest_substring_brute(s: str) -> int:
best = 0
for i in range(len(s)):
seen = set()
for j in range(i, len(s)):
if s[j] in seen:
break
seen.add(s[j])
best = max(best, j - i + 1)
return bestThat's O(n^2) time in the worst case and O(min(n, k)) space, where k is the size of the character set. Saying this out loud takes a minute and gives you a correct fallback.
Step 3: Find the bottleneck
The waste is in restarting. On "abcabcbb", when the window "abc" meets a second a, the brute force rescans from b, even though we already know "bc" has no repeats. We only need to move the window's start past the previous a.
That's a sliding window: right grows the window one character at a time, and left only moves forward. A hash map from each character to its last-seen index tells us where to move left.
Step 4: Code the sliding window
Python:
def length_of_longest_substring(s: str) -> int:
last_seen = {} # character -> index where we last saw it
left = 0 # start of the current window
best = 0
for right, ch in enumerate(s):
# Only jump if the repeat is inside the current window.
if ch in last_seen and last_seen[ch] >= left:
left = last_seen[ch] + 1
last_seen[ch] = right
best = max(best, right - left + 1)
return bestTypeScript:
function lengthOfLongestSubstring(s: string): number {
const lastSeen = new Map<string, number>(); // character -> last index
let left = 0; // start of the current window
let best = 0;
for (let right = 0; right < s.length; right++) {
const ch = s.charAt(right);
const prev = lastSeen.get(ch);
// Only jump if the repeat is inside the current window.
if (prev !== undefined && prev >= left) {
left = prev + 1;
}
lastSeen.set(ch, right);
best = Math.max(best, right - left + 1);
}
return best;
}charAt works on UTF-16 code units, which is fine for this problem's character set; for emoji you'd iterate by code point instead.
Step 5: Dry run on "abba"
"abba" is the case I'd trace first, because it catches the most common bug in this solution.
right ch last_seen before left after window best
0 a {} 0 "a" 1
1 b {a:0} 0 "ab" 2
2 b {a:0, b:1} 2 "b" 2
3 a {a:0, b:2} 2 "ba" 2At right = 3, a was last seen at index 0, which is outside the current window. That entry is stale. Without the >= left check, left would jump back to 1, the window would become "bba", and the function would wrongly return 3. The check (or left = max(left, last_seen[ch] + 1)) keeps left moving forward only.
"" never enters the loop and returns 0. "bbbbb" moves left to right on every repeat, so the window never exceeds 1. "pwwkew" shrinks to "w", grows to "wke", then slides to "kew", returning 3.
Step 6: State the complexity
- Time: O(n).
rightvisits each index once with constant average-time map work, andleftnever moves backwards. - Space: O(min(n, k)). The map holds at most one entry per distinct character.
If asked "what if the input is only lowercase letters?", a fixed array of 26 indices can replace the map: a constant-factor gain, not a change in complexity class.
Red flags interviewers notice
These are habits, not a lack of ability, and habits respond to practice.
- Silent coding. Long stretches of typing leave the interviewer guessing. Narrate decisions, not keystrokes.
- Jumping straight to code. Skipping clarification risks solving the wrong problem.
- Ignoring hints. "What if the input were sorted?" is rarely idle curiosity. Stop and engage with it.
- Not testing. Finding and fixing your own bug is a positive signal; leaving it for the interviewer to spot is not.
- Arguing. Disagreeing with reasons is fine. Defending an approach after a clear counterexample isn't. Treat the interviewer as a collaborator.
What to do when you're stuck
Getting stuck is normal, and how you handle it is part of what's evaluated.
- Say it. "I'm stuck on how to avoid rescanning the window" tells the interviewer where to aim a hint.
- Work a small example by hand. Solve a five-element input on paper and watch what you do. That's often the algorithm.
- Fall back to brute force. A correct slow solution beats an unfinished fast one, and improving something concrete is easier than inventing from nothing.
- Ask what a data structure would buy you. Repeated lookups suggest a hash map; repeatedly needing the smallest item suggests a heap; sorted input suggests binary search or two pointers.
- Simplify. Solve a smaller version first (no duplicates, a single row), then generalize.
- Use hints visibly. Restate the hint in your own words and show how it changes your approach.
How to practice effectively
Solving problems at random mostly builds recall of specific answers. Interviews reward recognizing which tool fits a problem you haven't seen, so practice for that.
Learn patterns, not answers
A large share of coding-round problems are variations on a handful of patterns:
| Pattern | Reach for it when |
|---|---|
| Two pointers | Sorted arrays, pairs meeting a target, in-place partitioning |
| Sliding window | Longest or shortest contiguous range meeting a condition |
| Hashing | Membership checks, counting, grouping |
| BFS / DFS | Graphs, grids and trees; BFS for shortest paths in unweighted graphs |
| Binary search | Sorted data, or searching on the answer when "is x feasible?" is monotonic |
| Heaps | Top k, k-th largest, merging sorted lists, scheduling |
| Intervals | Merging or counting overlapping ranges, usually after sorting by start |
| Dynamic programming | Counting ways or optimizing over choices when subproblems overlap |
Binary search on the answer is easy to miss. "Find the minimum ship capacity to deliver all packages within d days" doesn't look like a search problem. But if you can check one capacity in O(n), and every capacity above a feasible one is also feasible, you can binary search over the possible answers. The same narrowing of a sorted range is what makes B-tree indexes fast, which I cover in my PostgreSQL indexing guide.
After each problem, note which pattern it was and what in the statement should have pointed you there.
Do timed mock interviews
Solve problems against a 45-minute timer with a peer playing interviewer. Time pressure and an audience change how you think, and only repetition gets you used to them.
Explain out loud
Even alone, talk through your approach as if someone were listening. It's the fastest way to discover that an idea you "understood" has a gap.
Review your mistakes
Log the problem, the pattern, where you got stuck and any bug you wrote. Re-solve failed problems from scratch a week later. Mistakes that repeat in the log tell you what to drill next.
Many loops also include a system design round. If you're preparing for one, my walkthrough on designing a real-time collaborative task board shows how I approach that kind of problem end to end.
Key takeaways
- Interviewers score the process, not only the answer: clarifying, communicating, improving from brute force, complexity, clean code, testing and taking hints.
- Spend the first five minutes clarifying and agreeing on examples.
- State a brute-force solution and its complexity before optimizing.
- Trace examples and edge cases, like
"abba", before saying you're done. - When stuck, say so, work a small example and use hints visibly.
- Practice patterns over memorized answers, do timed mocks, explain out loud and review every mistake.
