Part I · Orientation
How You're Actually Being Scored
Section 03 · about 17 minutes
Most candidates prepare for a coding interview as if it were an exam with a single question: did you get the right answer?
It is not. Your interviewer is filling in a scorecard, and correctness is one line on it. I have sat on both sides of that table, and I have watched candidates produce a working optimal solution and still fail, because they spent forty minutes silent and the interviewer had nothing to write down. I have also watched candidates never finish the code and pass comfortably, because everything they did say was the right thing to say.
That is not unfair. It means you are being judged against a rubric no one showed you.
This chapter shows it to you. Eight things are being assessed, and once you can name them you can prepare against them deliberately instead of hoping that raw practice volume covers everything.
Your interviewer is filling in a scorecard, and correctness is one line on it.
One problem runs through the whole chapter. It is deliberately simple:
Write a program that finds the index of a target number in a sorted array.
Simple enough that you already know the answer, which is exactly the point. We are not here to solve it. We are here to watch the same twelve lines get scored eight different ways.
3.1 The Rubric
The eight factors are not a flat list. They fall into four groups, each tied to a question the interviewer is trying to answer about you.
| Group | The question behind it | Factors |
|---|---|---|
| What you know | Do you have the vocabulary? | Algorithms and data structures · Complexity |
| How you think | Can you get from a problem to a plan? | Problem-solving · Attention to detail |
| What you build | Would I want to review your pull requests? | Code efficiency · Modular code · Debugging |
| How you convey it | Can you work with other people? | Communication |
Keep that shape in mind. Almost every published interview rubric I have seen is some rearrangement of those four questions, whatever the company calls them.
3.2 Which Ones Actually Decide It
Presented as a list, the eight factors look equally important. They are not, and treating them that way would waste your preparation time.
Here is the honest ranking, from most to least decisive.
Communication decides more interviews than anything else on this list. It is the only factor that is being assessed continuously, from the first sentence to the last. It is also the only one whose absence cannot be recovered. A wrong complexity estimate can be corrected when the interviewer prompts you. Forty silent minutes cannot be.
Problem-solving comes second, because it is what the interviewer is hired to measure. They are not trying to find out whether you have memorised binary search. They want to know what you do when you meet something you have not memorised.
What you build comes third. Efficiency, structure and debugging matter, but they are recoverable in a way the first two are not. An interviewer will let you fix a bug. They will not let you restart your thought process.
What you know comes last, which surprises people. Knowing more algorithms raises your ceiling, but it is rarely what fails a candidate. Candidates fail because they froze, or went quiet, or started typing before they understood the question.
If your preparation is entirely “learn more algorithms,” you are optimizing the factor that decides the fewest outcomes. That is the single most common mistake I see, and it is why practice volume alone does not work.
What You Know
The first group covers your technical foundation: the concepts and tools you need to recognize before you can choose an approach.
3.3 Algorithms and Data Structures
The interviewer wants to see whether you recognize familiar problem patterns and can choose a suitable technique.
Here is how it gets tested. You will produce a brute-force solution, and then they will wait. What they do with that silence is the assessment.
A beginner reaches for the obvious: walk the array, check each element.
def linear_search(array, target):
for i in range(len(array)):
if array[i] == target:
return i
return -1
This is correct. It is also O(n), and the interviewer is waiting to see whether you notice that you were handed something better.
An experienced candidate notices the word sorted in the problem statement and reaches for binary search instead:
def binary_search(array, target):
left, right = 0, len(array) - 1
while left <= right:
pivot = left + (right - left) // 2
if array[pivot] == target:
return pivot
if target < array[pivot]:
right = pivot - 1
else:
left = pivot + 1
return -1
It is longer. It is also O(log n), and the difference is not a detail.
Suppose looking at one element takes a millisecond. Then:
| Array size | Linear search | Binary search | Comparisons |
|---|---|---|---|
| 1,000 | 1 second | 0.01 seconds | 10 |
| 1,000,000 | 16.7 minutes | 0.02 seconds | 20 |
| 1,000,000,000 | 11.6 days | 0.03 seconds | 30 |
Read the last column again. Multiplying the input by a thousand adds ten comparisons. That is what logarithmic time means, and it is worth being able to say out loud, because saying it is how the interviewer knows you understand it rather than having memorised it.
The halving is where the logarithm comes from. Each pass discards half of what is left, so the question is not “how many elements are there” but “how many times can this be halved before nothing remains.”
Binary search is the technique here, and Section 9 covers it properly, along with when a problem is secretly a binary search even though nothing is sorted. For now the point is narrower: one word in the problem statement changed the entire solution.
3.4 Complexity
You will be asked what your solution costs. Every time. This is the single most predictable moment in a coding interview, and it is the one candidates most often improvise.
Two terms, and they are worth stating precisely:
- Time complexity
- How the running time grows as the input grows.
- Space complexity
- How the memory used grows as the input grows. This includes the call stack, because recursion is not free, and forgetting it is a common way to give an answer that is half right.
Notice that both are about growth, not about seconds or megabytes. “It takes two seconds” is not a complexity. “It doubles when the input doubles” is.
You cannot optimize what you have not measured, so this factor is load-bearing for the next several. Section 5 teaches how to derive a complexity from code you are looking at, how to account for recursion, and how to state one out loud without hedging, which is the part that actually gets scored.
How You Think
These factors reveal how you reason through unfamiliar problems, test your ideas, and respond when your first approach fails.
3.5 Problem-Solving
This is what the interview is for.
The most expensive mistake in a coding interview is starting to type. It feels productive, it relieves the anxiety of the blank screen, and it tells the interviewer that you solve unfamiliar problems by guessing.
Before writing anything, ask. For our sorted-array problem:
How large can the array get?
Can it be empty?
Are the values unique, or can the target appear more than once?
If it repeats, do you want the first match or any match?
Are the values integers? Can they be negative?
That fourth question is not padding. If duplicates are allowed and the interviewer wants the first occurrence, plain binary search is wrong, because it returns whichever match it happens to land on. A candidate who asks discovers this in ten seconds. A candidate who assumes discovers it after writing the whole solution, if at all.
Then write down what goes in and what comes out:
Input: a sorted list of integers, and a target integer
Output: the index of the target, or -1 if it is absent
Example 1: [1, 2, 4], target = 4 -> 2
Example 2: [-1, 2, 5, 6, 7], target = 6 -> 3
Example 3: [], target = 1 -> -1
Three examples, and Section 4 explains why those three: one empty, one ordinary, one awkward. It takes ninety seconds and it is the highest-value ninety seconds of the interview.
3.6 Attention to Detail
Some words in a problem statement change everything. Miss one, and you may solve the wrong problem perfectly.
In ours, the word is sorted. It is doing enormous work, the entire difference between the two solutions above, and it appears exactly once, in passing. The interviewer put it there to find out whether you read carefully.
This is why Section 4 asks you to read the problem more than once. Not as diligence theatre: because the second reading is where you catch the word that changes the answer.
Detail also lives below the algorithm, in the arithmetic. Look again at the midpoint:
pivot = left + (right - left) // 2
The obvious way to write that is (left + right) // 2, and in Python it is perfectly safe, because Python integers grow as large as they need to.
In C, C++, Java or Go it is not safe. With a 32-bit signed integer and a large enough array, left + right can exceed what the type holds and wrap around to a negative number. Your index goes negative and the program fails on an input large enough that you will never see it in testing.
Subtracting first keeps every intermediate value inside the range you started with, so it cannot overflow. It is the same answer, computed in an order that cannot go wrong.
If you are interviewing in Python, you do not need this. Saying it anyway is free, and it is exactly the kind of remark that moves an interviewer’s assessment of you.
What You Build
Here, the interviewer looks at the solution you produce: whether it is efficient, clear, and dependable.
3.7 Code Efficiency
The interviewer watches which data structure you choose, because that decision often determines the complexity before you write the logic.
The common failure is storing things in a list and then repeatedly searching it. Searching a list is O(n). Searching a dictionary is O(1). If your problem involves asking “have I seen this before?” inside a loop, a list turns an O(n) algorithm into an O(n²) one, and the interviewer will notice before you do.
This is not a small preference. It is usually the whole optimization, and Section 10 is built around it.
Corner cases belong here too, because handling them is part of what makes code efficient to review. What should the function above do with an empty array? Work through it: left is 0, right is -1, the loop condition left <= right is immediately false, and it returns -1. Correct, with no special case needed.
That is worth saying out loud. An interviewer cannot tell the difference between code that handles the empty case by design and code that handles it by luck, unless you tell them which it is.
3.8 Modular Code
Interviewers are asking themselves a quiet question throughout: would I want to review this person’s code?
Code written as a string of loose statements is the tell. Compare:
Loose code: no boundary, no name, no contract
n = len(array)
for i in range(n):
if array[i] == target:
return i
That return has nothing to return from. It cannot be tested, reused, or named. It is a fragment.
The same logic, as a function
def linear_search(array, target):
for i in range(len(array)):
if array[i] == target:
return i
return -1
The difference looks cosmetic. It is not. The second version has a name that says what it does, inputs that say what it needs, and a defined result in every case, including when nothing is found, which the first version simply does not address.
That last point matters more than it looks. A function that returns an index on success and nothing at all on failure will fail at the call site, far from the bug. Decide what absence looks like, and return it every time.
3.9 Debugging
Everyone makes mistakes in their code. What matters is not whether you make one, but how you respond.
The real failure is staring at the screen and guessing, or worse, going quiet while you guess.
Two you will actually hit:
Using = where you meant ==
if array[i] = target: # SyntaxError
A single character, and the file will not run. Python catches this immediately, which makes it cheap, but only if you read the error rather than scanning your code hoping to spot it.
Using / where you meant //
pivot = (left + right) / 2 # 2.5, not 2
This one is worse, because it is not a syntax error. It runs, produces a float, and fails later with TypeError: list indices must be integers or slices, not float. The error surfaces on the line that uses the value, not the line that produced it.
That gap, between where a bug is reported and where it lives, is most of what debugging is. When you hit an error, the useful question is not “what is wrong with this line?” but “where did this value come from?”
Say that out loud when it happens. An interviewer watching you read a traceback and reason backwards to the cause is watching the most job-relevant thing that will happen in the whole interview.
How You Convey It
Your reasoning has to be visible to count. These final factors measure how clearly you explain it, especially when you are uncertain.
3.10 Communication
This is the factor that decides the most interviews, and the one candidates prepare for the least.
The mistake is thinking of communication as narrating your typing. It is not. It means making your reasoning clear enough for the interviewer to follow, help when useful, and see how you approach an unfamiliar problem.
The shape is: say what you are about to do and why. Leave the how to the code, which is visible anyway.
Here is the sorted-array problem, from the top.
Confirm what you were asked. Not politeness. It catches misunderstandings while they are still cheap.
Interviewer: Given a sorted array of integers, write a function that searches for a specific integer. Return its index if found, and -1 if not.
You: So a sorted array of integers and a target, and I return the index or -1. Can the array be empty? And if the target appears more than once, do you want the first occurrence or is any match fine?
Interviewer: It can be empty. Assume values are unique.
That exchange took fifteen seconds and removed two ways the solution could have been wrong.
Say your approach before you write it, and say why.
You: Since it is sorted, I do not need to look at every element, so I can use binary search and throw away half the array each comparison. That gets it to O(log n) instead of O(n). I will keep a left and right bound and narrow them until they cross.
Note what happened: the complexity was stated before any code existed. That is the difference between analysis and justification after the fact.
Walk an example out loud. This is where candidates most often stumble, so be concrete and be slow.
Interviewer: Can you walk me through an example?
You: Take [1, 3, 5, 7, 9] and search for 6.
Left is 0, right is 4, so the midpoint is 2. That is 5, which is less than 6, so everything from index 2 down is out. Left becomes 3.
Now left is 3 and right is 4, so the midpoint is 3. That is 7, which is greater than 6, so 7 and everything above it is out. Right becomes 2.
Left is 3 and right is 2, so they have crossed, so the range is empty. 6 is not in the array, and I return -1.
That trace is correct, and it is worth checking your own the same way before you say it. Nothing damages an interviewer’s confidence faster than a walkthrough that arrives at the wrong answer, because it suggests you cannot execute your own algorithm.
Then state the cost, both kinds, unprompted.
You: Time is O(log n), because the range halves each pass. Space is O(1); I am only holding two indices, and there is no recursion, so no stack growth either.
Unprompted matters. Waiting to be asked reads as reciting. Saying it yourself reads as knowing it.
3.11 Score Yourself
Before the next chapter, rate yourself on each factor. Be honest. The goal is to find where your preparation needs attention, and you cannot do that if you score yourself generously.
| Factor | Strong | Shaky | Have not practised |
|---|---|---|---|
| Algorithms and data structures | |||
| Complexity | |||
| Problem-solving | |||
| Attention to detail | |||
| Code efficiency | |||
| Modular code | |||
| Debugging | |||
| Communication |
Now compare that against how you have been spending your preparation time.
If your weakest rows are communication and problem-solving, and your hours have gone to solving more problems alone in silence, you have found the reason practice alone has not been working. Those two factors cannot be trained by solving problems quietly. They are trained by solving problems out loud, in front of someone, or at minimum into a recording you are willing to play back.
The cheapest fix available to you: solve your next five problems narrating every step aloud, as though someone were listening. It feels absurd. It is also the closest thing to the real conditions you can produce on your own, and the gap between silent solving and spoken solving is much wider than anyone expects the first time.
Key Takeaways
- You are scored on eight factors across four groups, not on whether you got the answer.
- Communication decides the most outcomes, and is the one factor whose absence cannot be recovered later.
- Knowing more algorithms decides the fewest. It raises your ceiling; it is rarely what fails you.
- The interviewer’s real question after your brute force is can this person see the bottleneck?, not did they memorise the optimal solution?
- Load-bearing words in a problem statement, like sorted, are placed to see whether you read carefully.
- State your complexity before you write code, and unprompted. Both time and space, and count the call stack.
- Decide what absence looks like, whether
-1or an empty list, and return it in every path. - When you hit a bug, ask where the value came from, not what is wrong with the line.
Practice
- Take the last algorithm problem you solved. Score it against all eight factors. Most people find four they never considered.
- Solve one easy problem entirely out loud, recorded. Play it back. Count how long you were silent.
- Add the duplicate case to the problem in this chapter: if the target appears more than once, return the first occurrence. Plain binary search does not do this. Work out what has to change, and state the new complexity before you write it.
Keep reading. It is free.
The first three sections are open to anyone. The other 16 need an account, which costs nothing and does not expire.