16 April 2023

Writing Algorithms Under Pressure

I’ve passed and failed a few live technical interviews so thought I’d share what I think the important points are.

Talk

You won’t be in your usual environment for writing algorithms, which I assume, unless you do a lot of pair programming, is a quiet space in which you can sit back and contemplate the problem for a few minutes before writing code.

In a tech interview, especially if it’s remote, silence gets awkward fast. This adds to your stress levels, which inhibits clear thinking.

A trick I’ve found to alleviate some of this is to talk in an almost stream-of-consciousness fashion and not be too bothered about whether what you’re saying makes sense. You will interrupt yourself multiple times in succession as you find the edges of the problem. Don’t try to give a coherent lecture on what your thought processes are, just blab them out.

I find being deliberate about adding some emphasis around key concepts or realisations – “ah, yes, we can stop searching as soon as we’ve found a node that’s in both lists, because […]” – helps to prevent this from becoming a very monotone, droning speech, and shows that you’re paying at least some attention to the communication aspect of it.

When you get stuck, this practice of filling the silence with a thought-process monologue can also act as a rubber duck and actually help you solve the problem. Try articulating exactly what you’re not getting in a way that the interviewer can understand, and then follow on from there with logical steps for testing any hypotheses or underlying assumptions that you’ve identified. In any case, it’s better than sitting in mounting silence and being paralysed by confusion and panic, and shows that you can do at least the beginning part of problem-solving.

Start Writing Code Immediately

Along with being talkative, I find this acts as a kind of foothold and provides solid ground for the thinking process to grab onto.

Even if the first code you write is absolute nonsense, it’s concrete nonsense that you can look at, talk about, and change into not-nonsense. Fixing things is easier than writing things, so just write anything and then fix it.

This also might not be how you usually do things – if you’re an experienced developer, you probably do a bit of upfront thinking so that the first code you write represents at least a coherent or reasonable possible approach to the problem. But in tech interviews, I find that the balance goes in favour of just writing code, for the reasons mentioned.

Zoom Out

If focusing on details is what’s helping you avoid some of the stress of the larger situation, you might occasionally get stuck on something like a single line of code that you’re sure should work but for some reason seems like it isn’t, inducing a kind of panicked questioning of whether you can actually program at all or have just been faking it somehow until now.

One technique I’ve found useful for this is to deliberately pause, take a breath, and re-state the problem – out loud – along with a high-level description of your intended approach. Then break it down, explaining how each smaller part fits (or should fit) into the whole, until you reach the detail you’re stuck on. This again shows that you can problem-solve methodically, and might help you see a silly mistake that’s causing the part to fail.

Check Assumptions

This is part of regular programming, of course, but it’s worth emphasising that if the code isn’t working, methodically checking that each individual part works is a good approach to fixing it.

In live coding interviews in particular, you might find that mistakes you wouldn’t usually make get in, and you won’t be used to looking for them – so try to be extra receptive to whether each expression is actually what it should be.

When typing out code under pressure, it’s very easy to do things like completely missing out sub-expressions or mixing up variable names because you’re trying to do an interview, solve a problem, and write code all in parallel and your thought processes are trampling each other. Writing code while saying what you’re writing out loud at the same time is a surprisingly error-prone process! Check the whole program for errors like this.

Write Functions and Classes (?)

This isn’t something I’ve done enough to verify its effectiveness, but I suspect that isolating the ancillary parts of the problem like conversions and repeated calculations into reasonably well-named functions will help with the problem-solving process.

For some reason I’ve had the idea that live-coding algorithm code should be very technical and procedural-looking, and that classes in particular would be somehow out of place, but this is of course nonsense and I’ve looked back on at least one example and thought that writing classes for the main entities would have been a good idea.

A possible reason to avoid this would be the risk of getting stuck in bike-shedding mode and not being able to decide on good names or organisations for things. But in general, code where the organisation and names more accurately reflect how you’re thinking about the problem will be easier to reason about and debug, so I think it’s possible that including at least a bit of these activities into the process is a good idea.