Katabench
Start free
← All posts

Coding interviews are broken, but the skills they fumble are real

The standard objection to coding interviews is that they're a memorization game with no relationship to the job. Reverse a binary tree on a whiteboard, recite the time complexity, get hired, then spend your first month wiring up a CRUD endpoint and arguing about pagination. The ritual measures one narrow, heavily-gamed skill and pretends it predicts everything else.

That objection is correct, and it's also where most people stop, which is a shame, because they throw out something true on the way. The interview is broken. The underlying thing it keeps groping at, "can this person write good code," is the most real thing there is. We just picked an absurd proxy for it.

What the whiteboard actually measures

A live algorithmic interview measures your ability to recall a known pattern, code it on a surface with no compiler and no execution, while a stranger watches and your adrenaline spikes. That is a skill. It is the skill of doing algorithmic interviews. It correlates with the job roughly as well as parallel parking under a spotlight correlates with being a good road-tripper.

What it conspicuously does not measure:

  • Whether your "working" solution survives a realistic input instead of the three cases on the board.
  • Whether you'd notice your innocent LINQ query firing forty times where one would do.
  • Whether your code is structured so the next person can change it without fear.
  • Whether it falls over the instant someone sends it hostile input.

These aren't soft skills or culture fit. They are the literal substance of the job, and the whiteboard is blind to every one of them. So the problem isn't that we test technical ability. It's that we test a cartoon of it.

The real disciplines, and why they're testable

Strip away the theater and "good at writing code" decomposes into a handful of disciplines that are concrete, learnable, and, crucially, measurable if you bother to measure them.

The disciplines, and how each is measured

Algorithms

time + memory against a budget

Database

every query your code fires + the plan

Refactoring

cyclomatic complexity, nesting depth

Secure coding

an adversarial suite probing for the exploit

Architecture

dependencies pointing the right way

Every one of them is measurable. The whiteboard measures none of them.

Correctness under real constraints. Not "passes the three examples" but "still correct when n is two hundred thousand." The gap between those is where most production incidents live. Take the interview chestnut, Two Sum. The nested-loop answer is correct and gets a nod on a whiteboard:

public int[] TwoSum(int[] nums, int target)
{
    for (var i = 0; i < nums.Length; i++)
        for (var j = i + 1; j < nums.Length; j++)
            if (nums[i] + nums[j] == target)
                return [i, j];
    return [];
}

It's also O(n²), which a whiteboard rewards you for saying and never makes you feel. Give it a large input under a wall-clock budget and it times out. The dictionary version doesn't:

public int[] TwoSum(int[] nums, int target)
{
    var seen = new Dictionary<int, int>();
    for (var i = 0; i < nums.Length; i++)
    {
        if (seen.TryGetValue(target - nums[i], out var j))
            return [j, i];
        seen[nums[i]] = i;
    }
    return [];
}

Roughly 1,500 ms grinding to a timeout versus 4 ms. Reciting "O(n)" is trivia. Watching the slow one die against a clock is the lesson that actually sticks.

Efficient data access. Half of real .NET work is talking to a database, and the interview universe pretends databases don't exist. The N+1 query is the single most common performance bug I've seen ship, and you can write it in your sleep:

var orders = await dbContext.Orders.ToListAsync();
foreach (var order in orders)
{
    // one query per order: 1 + N round trips
    var customer = await dbContext.Customers.FindAsync(order.CustomerId);
    Console.WriteLine($"{order.Id}: {customer!.Name}");
}
// One query, the relationship loaded with the orders
var orders = await dbContext.Orders
    .Include(o => o.Customer)
    .ToListAsync();

Forty queries collapse to one. No whiteboard in the world catches this, because the broken version works perfectly on a dev machine with ten rows. It only reveals itself when you can see the SQL your code generates.

Structure that survives contact. Can you keep a method's complexity and nesting low enough that the next person can change it safely? Can you keep dependencies pointing the right way so a feature doesn't leak across every layer? These are gradeable, with cyclomatic complexity, nesting depth, and dependency-direction checks, but only if your feedback loop measures structure and not just output.

Security. The whiteboard never once asks whether your code refuses hostile input. Production asks constantly. Functionally-correct-but-vulnerable is the default state of working code, and noticing it is a trainable instinct that no algorithm puzzle exercises.

The trap of practicing the proxy

Here's the part that bothers me most. Because the industry settled on algorithmic interviews, the entire practice ecosystem optimized for passing them. Grind a few hundred problems, pattern-match the prompt to a memorized template, get the green checkmark. The green checkmark is the disease, not the cure: it tells you the three sample cases passed and nothing else. It can't tell you the solution is slow, allocates a gigabyte, fans out into forty queries, or hands an attacker your database.

You get good at exactly what your feedback loop measures. Train against "is it correct," and correct is all you'll build, which is precisely the cartoon version of skill the interview was already testing. To get good at the real thing, you need a loop that grades the real thing: time against a budget, the actual SQL your LINQ produces, the structural metrics of your code, an adversarial suite probing for the exploit.

The fix for a bad proxy isn't a better whiteboard. It's practicing the underlying skill directly, measured objectively, where you can't fake it.

That's the entire premise of Katabench. The tracks map onto the disciplines above on purpose: algorithms graded on performance against a real time and memory budget; a database track that runs your LINQ against actual PostgreSQL and shows you every query (and sometimes grades the query plan); refactoring graded on structure with Roslyn-measured quality gates; architecture graded on fitness functions; and secure coding where you have to block an adversarial exploit suite without breaking the feature. Server-side in a sandbox, so the numbers are clean and the leaderboard is honest, none of it gameable by reciting a complexity class.

I'm not going to tell you this fixes hiring. It probably doesn't, on its own. But it inverts the incentive that broke us: instead of grinding a proxy so you can pass an interview, you practice the work so you're actually good at it, and the interview becomes a formality you happen to be ready for.

The algorithms track is free, performance grading and all, so you can feel the difference between "correct" and "good" before you decide anything. The other four tracks live on Pro. If you're tired of practicing the wrong thing, start with the real one and let the clock be the judge.

Get new puzzles and .NET tips in your inbox

A short note when fresh kata land, plus the C# and performance tricks behind the grading. No spam, unsubscribe anytime.