Programmers, both new and experienced, have a hard time getting away from technical interviews: the “large-company” style of interview where you’re asked to work through an ambiguously-stated programming question with an interviewer who already knows a wide-range of solutions to the problem. There are pros and cons to this interview style; I personally don’t like it at all. However, preparing for technical interviews can teach you a a lot about yourself. I’d like to share my own findings, in case it helps a programmer with similar problems.
Note: this post has been sitting in my drafts section for weeks. I’ve feared publishing it – worried about a possible career-suicide by talking about my faults as a programmer. However, I feel strongly that this type of self-analysis is healthy and essential for us to improve at our craft.
I’m not a fan of technical interviews for many reasons: the unfamiliar stress of solving a problem with someone who already knows the most optimal solution; the assessment’s focus on rarely-used, college textbook material; and the dehumanizing aspect of being assessed solely for your technical ability – not for differentiating, intangible skills.
Despite the unfortunate byproducts of that style/standard of interviewing, there are positive aspects to (preparing for) a technical interview. You become aware of both your problem-solving faults and your knowledge gaps. The preparation solidifies your understanding of “foundational” computer science – possibly opening up new solutions to problems you encounter in your personal projects and at work.
Identifying your problem-solving faults
I tend to jump right into the first solution that comes to mind and rely on my problem-solving ability to get me through it. This rarely ever works well. The end result is typically a working, but poorly-thought out solution that always needs refactoring. Sometimes, by diving in carelessly, I fail to see significantly simpler solutions that are right in front of me.
I thought about why this habit formed and realized that it stems from my early days of building games. I used to over-engineer projects and made very little progress towards actually completing them. I also suffered from a bit of analysis paralysis – where I’d mentally explore a number of solutions at the same time, both getting flustered and shooting down solutions before seeing them through. To counter these problems, I decided to just make progress and worry about problems or improvements when they became important. In my mind, finishing something outweighed poor design.
On one hand, you can think of such an approach as laying down a first draft to explore the problem-space and then fine-tuning/refactoring the solution once you fully understand the problem. However, the important realization is that I didn’t understand the problem that I was solving from the very beginning. How can you realistically solve that which you don’t understand?
This is one benefit to the technical interview: you need to ask questions to clarify the ambiguously-stated problem. You need to know more about the data provided to the function/program you’re writing as it could save you from exploring more complicated (or incorrect) solutions.
Even when you craft a solution, it will have implicit assumptions that should be clarified/confirmed as suitable for the given problem. Perhaps you’ve assumed the string input is only ASCII when it should support UTF8. Perhaps you’ve assumed that the solution should be case-insensitive when the opposite is necessary. Maybe you’ve incorrectly assumed a certain behavior for null or out-of-bounds inputs. The point is, you will always make assumptions about the problem that need to be identified and voiced to fully understand the problem.
Looking back, there have been many times when I’ve failed to voice my assumptions and/or ask questions about edge cases to understand the proper behavior of the system (or interview question). It’s irritating and I’ve beaten myself up over it. However, now aware of some of my faults, I can try to prevent this from happening in the future.
Holes in the foundation – knowledge gaps
It’s amazing and surprising how far we can get as a (web) programmers without a solid foundation in data structures and algorithms. This goes for both self-taught and formally taught programmers.
One could argue that the above point shows a possible divergence in the constructs taught in school and the constructs needed to build (web) applications. There’s some truth to that. On the other hand, there’s more to programming than web apps and knowledge of fundamental algorithms and data structures allows a programmer to write efficient programs across problem-domains.
Back in school, I was enamored by arrays and I used them for every problem. Why should I care about these other data structures when an array gets the job done? Well, an array is one of many tools that can be employed to solve a problem and it’s important to not lose sight of that. When you only solve problems where arrays shine, it’s hard to see its faults. Without spending time digging into linked lists, trees, and hashmaps, I may have missed out on more performant/appropriate/simpler solutions.
So, prep for that technical interview
It’s scary and daunting to prepare for an upcoming technical interview – especially (hopefully) aware of our problem-solving faults and how much we don’t know or have forgotten. However, I firmly believe that the first step to improving is realizing where you’re weak.
We might not pass that interview. That’s fine. At the end of this process, we’ll be much better programmers and problem-solvers. I’d say that’s a win.
Embrace that technical interview as a chance to improve yourself along the way. Cheers to getting better!
Thoughts or comments? Tweet at me.