You're reading for free via Omar Sharaki's Friend Link. Become a member to access the best of Medium.
Member-only story
How (and Why) Software Developers Should Always Be Interview-Ready
Interview prep starts long before the interview
Alice and Bob are each planning their beach holidays. This year, they’ve both taken it upon themselves to be in the best possible shape they can. Thinking ahead, Alice started hitting the gym and got her diet in check months in advance. Bob, on the other hand, only recalled his resolution while shopping for swim shorts a few weeks before his planned flight.
Write a function that determines who’s posing for pictures beachside this year.
The answer is no one — since we’re all in lockdown, but the moral of the story is that it’s easier to stay in shape than get in shape. This statement applies to software developers just as much as it does to vacationers. Gaining and maintaining a certain level of proficiency at handling technical interviews is crucial if you think you will apply for software development jobs.
This is not an argument for or against technical interviews in and of themselves, plenty has been said on the matter on both sides of the aisle, but until the status quo changes, it pays to be prepared — literally.
There’s more than one way a prospective employer may put your technical prowess to the test. While you may be asked to showcase your system design know-how or demonstrate your skills in some specific area relevant to the position in question, it’s usually the dreaded coding task, which aims to test your algorithmic and problem-solving skills, that is most famously bemoaned by interviewees. And it’s this last part that we’ll be talking about here.
So with the why out of the way, let’s talk about the how.
Pick a Platform, Any Platform
Let’s face it, you didn’t need a Medium article to tell you this, but for what it’s worth, you’ll only get better at solving coding problems by solving coding problems. And just as with gyms, there is no shortage of programming platforms where you can hone your skills. Which one you use to practice doesn’t really matter — so long as you practice. In my case, HackerRank and LeetCode are two that I tend to use, and there are things that I like and dislike about both. A quick online search will yield many alternatives, so don’t feel obliged to use a particular platform just because it’s the one everybody seems to be using: try a few, find one that suits your style, and get coding.
Pace Yourself
Problems typically come in three levels of difficulty: easy, medium, and hard. My advice here is, don’t bite off more than you can chew. Start simple and gauge your level. If you’re stuck tearing your hair out trying to solve a problem, that might be a sign to bring down the difficulty a notch. There’s no shame in it. As it happens, Bob started lifting weights from the heavier end of the rack and ended up hurting himself in the process. Alice, on the other hand, left her pride at the door and started slow, gradually working her way up to the heavier weights. Be like Alice, leave your pride at the door — or rather, the log-in screen.
Seek, and Ye Shall Find
But what if you’re already in the shallow end and still struggling? Well, that’s where the discussion section, editorials, and a neat tool called the World Wide Web come in handy. You would be hard-pressed to find a problem that hasn’t been covered either on the platform itself or in some forum or YouTube video.
Again, a quick search will go a long way here. Rather than spending too much time on a problem, it’s often better to look up how others have solved it, understand their approach, and implement it yourself. This has the added benefit that you’ll often need to read other people’s code, sometimes written in other languages, which is a valuable skill in and of itself.
Be Selective
While solving problems is already great, not all problems are created equal. To get the most bang for your buck, consider filtering problems by popularity if supported by the platform. Other useful filtering options include filtering by topic (e.g., dynamic programming). However, unless you're actively targeting a specific area, I’d suggest leaving that unchecked so as to be exposed to a good mix. For more practice tips and tricks check out this LeetCode post.
Unfortunately, many problem statements are formulated in convoluted, roundabout ways that don’t get straight to the point of what is actually being asked. As you progress and become a more fluent problem solver, however, you’ll start being able to see through the frill and directly tell what the task is. Often, I also find that I’m able to grasp the problem much quicker by skimming the description and jumping to the examples as soon as possible.
Take Notes
Although there are myriad ways of approaching a given problem, some are much better suited than others. Many problems are designed such that only solutions that adopt a certain strategy are able to pass all tests within the time limits. With more practice, you’ll start picking up on cues and similarities to past problems that give away which strategy to adopt and when. This also shows the importance of being methodical with your practice.
This means documenting your progress and taking notes. That way, when a problem seems similar to something you’ve done before, you can consult your notes and see how you solved it then. Notes have the added benefit of serving as a kind of journal so that, even when some time has passed, your old solutions don’t seem cryptic.
This also helps train your mind to recognize these patterns, as mentioned before. I find Obsidian to be a great tool for this, as it allows me to tag notes (e.g., by problem type) and cross-reference them later. LeetCode also has note-taking functionality built into their code editor.
Talk the Talk
While there is no substitute for actually improving your ability to solve programming problems, demonstrating this ability is no less important. After all, you’re being scrutinized by other human beings who aren’t just interested in the final solution, but how you got to it. And you do that through communication. That’s why the behavioral aspect cannot be neglected.
The thing about solving coding problems, though, is that it’s very much like using the restroom — it’s hard to go with someone watching. But, that being kind of the point of a live coding interview, there’s no getting around it. Interviewers will expect you to walk them through your thought process as you come up with and implement your solution. All this is to say, it’s time to get a duck.
Say hello to your new sparring partner. Contrary to popular belief, ducks are not only good for debugging, but the duck gives you someone to talk to as you’re solving. Granted, this is pretty unnatural as most of us are used to thinking inside our own heads — not narrating it to someone else — least of all a rubber duck.
However, the sooner you get better at thinking out loud, the better. The fastest way to do so is by tying this exercise into your practice routine. It’s OK to occasionally stumble and hum and haw. The duck won’t judge. And the more you mess up in front of the duck, the less your chances of freezing and going radio silent in the actual interview.
Structure Your Solutions
Many guides will provide suggestions on how to structure your approach to solve a problem. For example, Gayle Laakmann McDowell, author of Cracking the Coding Interview: 189 Programming Questions and Solutions recommends a 7-step approach that starts with a naive solution before iteratively optimizing it. In general, adding structure to the way you approach problems not only allows your method to come across clearly to the other side, but also allows you to warm up and get in the zone as you work your way toward more performant solutions.
Go Above and Beyond
As an old professor of mine used to say, “In mathematics, you’re never too far from a difficult question.” Meaning that it doesn’t take much to tweak a seemingly trivial scenario into a vastly more complex one. For example, with just four colors you can color a graph’s nodes such that no two adjacent nodes share the same color. But good luck doing that with three colors.
The same logic applies when solving a coding problem. Don’t rest on your laurels as soon as your solution passes all tests, but rather think critically about your code. Consider any questions that might be posed to you, like the following:
- “Can you identify any bottlenecks?”
- “How could you make it faster?”
- “What are the time and space complexities of your implemented solution?”
- “Can you make the code more concise?”
- “Can you tweak your solution to use more space in exchange for a shorter runtime?”
Often, it isn’t necessarily about coming up with the “right” answers to these questions (the interviewers may not even have them), but rather how you argue and reason your responses.
It helps to know the complexities of your programming language’s implementation of commonly used operations, like sorting or searching in different data structures. This is not only to be able to answer some of the questions above — but also to be able to make conscious design decisions or improvements.
Whether you love technical interviews or hate them, for now at least, there’s usually no getting around them. So while Bob may spend his days lamenting the current state of the software industry, Alice understands that if you want peace, you better be ready for war.