How does the average person hire a top-notch tailor? They ask the candidates to show them what they’ve stitched so far, maybe even ask them to sew something fast. Then they’ll observe the results, noting how well they operate the sewing machine, the organization of the workplace, and assess the tailor’s attention to detail. Are they wasting too much fabric or simply not doing a very good job?
How do software developers hire top-notch tailors? Well, it would probably go a little something like this; “This is a whiteboard. Please draw the difference between Ghiordes and Senneh knot. Derive the length of thread as a function of fabric’s surface area”.
Honestly, I believe that a top-notch tailor should know the difference, but what are we really verifying here? Do you want an elegant jacket or an elegant equation on a whiteboard?
My experience with a Search Company and an Investment Bank
Let me share some experiences I had while being an interviewee in two large companies. One sells ads occasionally interlaced with actual organic search results. The other was a Large Enterprise Bank. In the former, I spent several hours coming up with solutions to non-trivial algorithmic tasks. The latter was similar, but I described my algorithms over the phone to a person sitting on the other side of The Atlantic…and it gets even weirder than that.
At the Search Company, I was looking for the longest suffix of a linked list that… something. Frankly, I don’t remember much. Just like I don’t remember the last time I used a linked list. Yes, I understand how it’s different from an array – performance implications, different use cases, etc. I also happen to know that because that question is asked in every bloody interview! But in real work, I simply never had the chance to take advantage of these. There was also a question related to balancing or traversing a tree in some bizarre fashion. Honestly, not a very memorable experience. Actually, I thought it’d be honest of me to say I knew this exercise beforehand. Not from a book about algorithms, but a guide on how to get hired at this particular company. More on that later.
At Investment Bank I was first asked to generate all possible permutations of a list of elements. Keep in mind this all happened over a transcontinental phone call. OK just for fun, I’ll imagine asking myself this type of question. Here are the possible answers I expected, from worst to best:
- Search for a solution on the internet, claim it’s yours and think that I don’t hear the keyboard tapping
- Recite a solution from memory, line by line, because you prepared like crazy, and luckily you happened to know the solution off the top of your head. And not much more than that.
- Imperative, convoluted code that iterates over the input. Preferably using variables like i, j, k
- Clean, recursive solution, because the candidate realized this problem can be decomposed.
- Be disgusted by hand-written code, search a little bit longer and find a library that does exactly that (e.g. Collections2 from Guava)
Seriously, you’re probably looking for a new teammate. Would you rather see a pull-request with elegant, recursive code or a single library call? A library battle-tested by millions of developers, based on Donald Knuth’s “The Art of Computer Programming“? Also, it took me a while to find a library, whereas hand-crafted, nested loops are all over the place on the Internet. What kind of attitude are you looking for? Memorizing and blindly copying code from the Internet, or actually doing the research to find battle-proven solutions?
Another exercise that I was given required randomly shuffling an array having only a random coin toss at my disposal. This is an interesting problem in its own right, however entirely unrelated to the working conditions. I somehow came up with an algorithm (and it was rather enjoyable), but, after a few months, all I was doing was passing a piece of XML from one side of the bank to the other. Hundreds of mundane transformations per second and by the way, every major language has shuffle support: , , , , or a package .
Algorithmic test interview questions: the bane of recruiting
Having a degree in Computer Science, I don’t find algorithmic tests intimidating or pointless. It’s actually quite the opposite, they are great for exercising your brain, like solving sudoku or playing bridge. I attended multiple algorithmic competitions (e.g. Advent of Code) and always found them enjoyable. But that’s just my hobby, you might prefer studying DDD or advanced SQL. And I’m not sure pure algorithms and data structures are a particularly good fit for the majority of job interviews. They do verify a candidate’s abstract analytical skills, as well as solid CS and Math background which are both important traits in software engineering. But they fail to capture other important traits or are too convoluted to be conclusive.
These days, most of the work in IT requires stitching together APIs and frameworks. We are more like tailors than fabric producers. Algorithmic proficiency is helpful when scaling a single feature of your system, but more focused experience in distributed systems will probably get you further. For example, knowing graph theory or discrete functions is valuable. However, hands-on experience with a large network of replicated databases or understanding why some hash functions are compromised has a much larger impact on your daily work.
Indeed, understanding what is recursion is essential. Just like knowing why HashMap is so fast in Java. But understanding why Dictionary is even faster in C# is the next level. Hint: memory layout, something unrelated to theoretical computational complexity. However, many believe that asking purely algorithmic questions is the simplest way to find exceptional, well-trained developers. Such a belief is very romantic, but often extremely naive. Just see how many books are helping you to succeed specifically in (famously algorithmic) Google interviews. They are not teaching the fundamentals of CS, they barely explain how to solve specific classes of Google-style problems.
Sorting is one of the most commonly (ab)used algorithmic interview questions. Knowing how Quicksort works is valuable, even though, for example, Java hasn’t used it for almost a decade. Understanding what O(nlogn) is, may also come in handy. But much more often it wasn’t algorithmic complexity that caused my system to grind to a halt. Instead, it was an N+1 problem – something that I kept encountering the hard way but was barely touched on during my CS education. If you can’t resist the urge to ask about sorting, at least discuss what it means for an algorithm to be stable. You will most likely use a readymade, fast algorithm. Stable vs. unstable is most likely your only concern. Hint: sorting in Java is stable, in C# it is not.
Keep in mind that algorithmic questions are great if that’s really what you need on a daily basis. Machine learning experts need to understand what gradient descent is, and that requires a substantial Math background. Also, statistics, research, computer graphics, and game development tend to require a certain amount of CS background. Otherwise, use your recruiting time slot wisely and ask the right questions.
A better approach to an algorithmic test: design and work together
I interviewed tons of people during my career, I consider this to be part of my job, especially in more senior positions. Many of the interviews were forgettable, but occasionally candidates were extremely satisfied, even though they didn’t get the job. This builds a great relationship and a brand for your company. How did I create such a great experience?
- Prefer real-life problem-solving. Design Twitter-like architecture or Scale out Instagram-like website – exercises like that are way more enjoyable than finding the shortest path or longest palindrome.
- Prefer pair-programming over whiteboard sketching. Seeing how a candidate works, how he or she navigates code, searches for answers, approaches obstacles – this should tell you a lot. Also working together reduces stress and makes the process more humane.
- Prefer existing codebase over an empty editor. We love greenfield projects, but modifying an existing codebase is much closer to real work.
- Prefer testing over pure production code. Coding is great, but does a candidate look for or develop tests alongside the implementation? That aspect is almost universally overlooked during an algorithmic test.
Remember that working together doesn’t require meeting on-site. Screen sharing and real-time collaboration are quite seamless these days, also with DevSkiller.
There is nothing wrong with algorithmic questions during a job interview. This is an important part of our field. However, given how little time you have for recruiting, there are wiser ways to choose your next best engineer. By exercising real skills you make sure a candidate is great at what you really need. Also, this reduces stress and improves a candidate’s perception of your company.