Note: This post started as an exploration of interview questions; however,
the problem space is much bigger than that. I'm trying to really understand
what software engineering is and why some people are much better at
it than others.
As far as my experience goes, there seem to be four kinds of hiring strategies
employed by various companies. They often come in combinations, with different
values attached to different parts.
- First comes the classic HR questionnaire that you have to fill out and/or
answer in person. It's about personal values, why you want to work for a company (hint: "because I have no money" is not the right answer), etc.. This can
essentially be replaced by a single question: "are you happy being
a replaceable gear?". Tends to be mostly absent these days in pure-tech
companies, but is still employed by large corps with IT departments, e.g.
banks or defence contractors.
- Second comes the "I know you already" kind. Very popular among startups
and companies entrenched in Open Source - they essentially view your
work on GitHub and/or know you already from conferences and it all boils
down to an informal chat to establish whether you are the right match. If there is
a technical interview, it's very informal and mostly revolves around
technology choices and the rationale behind them. These companies also
tend to have a decent way of exploring the common ground in the first
month or week, so the decision to hire is not permanent.
- Third is the classic knowledge-based questionnaire. They'll ask you
unusual tips & tricks in the technology that you know (or you don't),
like handling of **args in Python or whether can you do some magic JOIN
in SQL. Usually these answers can easily be googled, and while the rationale
is "if you know all these quirks you have spent a lot of time on this platform",
it heavily favours people like me with a photographic memory for obscure details.
This photographic memory usually brings no value whatsoever - I know a lot
of crazy details about all kinds of platforms that are completely useless.
If you want to impress the potential interviewer, put the BUGS section
from a random manual into your fortune cookie each time you start a terminal.
- Last, but not least, is the classic "Google-style" interview. It involves
asking you questions like this one. You have a well-defined problem and
you have to find the right solution. There are a few good solutions, but only
one that's really correct. The problem space is very finite. Repeat for the
whole day in stressful conditions, until you're tired (and way after that).
So once we have categorized these groups, let's have some opinions. First I would
like to dismiss the classic HR one as not applicable to the software
development I know. I can't imagine a good project where people are treated
as replaceable gears. The third kind, and to some extent the fourth kind
have some sort of correlation to real
knowledge, but there is definitely no causation -- the only thing you can say
is that a person who does not know a platform at all will not be able
to answer questions about its quirks. We have something to work with, but the problem with it is that your company does not exist in
a perfectly uniform vacuum.
If everyone does these kinds of interviews, the candidates who know
these quirks will have a lot more job offers than those who don't.
At the end of the day, if you're the only company who does not do that,
you can hire all the good people who don't have photographic memory and you win.
Now, let's sidestep a bit and talk about how software development
really works in my opinion. The sequence looks vaguely like this:
- step 0 - customer problem "I want to send messages to my peers"
- step 1 - technical problem "we need to send messages between computers with browsers"
- step 2 - technology and architecture choice "AJAX program, JS logic, Python in the backend, HTTP"
- step 3 - implementation overview "this is the backend API, JS has to respond to this..."
- step 4 - actual implementation (bunch of code, usually a lot)
Where each step corresponds to moving from the previous state to the next.
Eg. step 1 means "understand what customer wants and explain it in technical
terms".
Now, as a person working for a company as a software engineer, especially
a large company you might not participate in steps 1 or 2. Working for
a startup or a small company will require you to deal with it much more,
so the interview style where you just chat makes a lot of sense. After all,
this will be your primary skill.
The problem with the rest is that step 3 is the hard step these days,
since we don't code on punch cards in assembler. However, most interviews will focus on step 4 -- which is not quite, but almost, purely mechanical. In my opinion, the difference is as follows:
- step 4 covers a problem space within constraints that make it finite and
explorable.
An interview concentrating on this will cover how quickly you can navigate
a finite space. I believe this step can be solved completely by better
programming languages.
- step 3 covers a space which can be considered infinite - the number of
possible combinations is just too large. Most of actual software engineering
revolves around "I need to find a simple solution for this formal, but
vague problem. How do I constraint my infinite space so that it's possible?".
Note that even in a completely formal environment -- like implementing
PyPy, which is a Python interpreter -- step 3 is far more important than
step 4. You're presented with a piece of code to be optimized. You need
to find an optimizer model that's simple enough and correct to optimize this
piece of code. While the problem is formal, the potential space is infinite,
so you need to constrain it in various ways first, before making any real
progress. Once you have done that, the actual task of e.g. writing a tree-walking
algorithm correctly is trivial.
Now, to summarize, I don't really know how to conduct technical interviews
that cover the most important parts of software engineering. I think
a lot of interviews focus on the wrong things and only vaguely resemble what is
actually happening. That's why we generally go with "let's have a chat
and we'll see as we go along", but maybe there are better ways. I don't
think enough research has been done on the human ability to explore complex
systems, but on the other hand I might just be highly ignorant of that
topic. Please mail me interesting papers if you know some.
On a sidenote - we're hiring. If you want to work with smart people on
challenging problems, get in touch. Contact info findable courtesy
of google ;-)
Cheers,
Maciej Fijalkowski