It’s not magic!
Interviewing job-seeking candidates is probably the most impactful thing that I do at Microsoft as far as our business is concerned. Sure, the day-to-day work of implementing the compiler is of course what I am specifically there to do. But ultimately nothing impacts the bottom line of our division more than preventing bad hires and encouraging good hires. The dozens of people that I’ve interviewed who got hired will collectively deliver much more value (or do much more damage!) than I can alone. So I think about it a lot.
I find it interesting to notice the common threads that show up in the surprisingly disparate group that is Microsoft interview candidates. A big red flag for me that I see fairly often I jokingly characterize as a form of magical thinking . Now, as someone who values diversity and cherishes the inalienable human right to believe in any old crazy thing you want, I of course do not care at all if candidates engage in magical thinking on their own time. But magical thinking about software concerns me greatly. For example, I should never be allowed anywhere near network drivers, as my beliefs about routing are clearly magical in nature.
The trouble is that I occasionally see this sort of thing in people who are not making silly jokes about it.
The technical interview question I usually ask is a deliberately vague and abstract version of a real problem that I had to solve back when I was working on the VBScript engine. The details aren’t germane to this particular discussion, but suffice to say that every candidate quickly figures out that a necessary step in solving the problem is the automatic generation of a guaranteed-to-be-unique “cookie” value of some sort. The “cookie” is used to track and control the progress of a “task” being performed by a “server”.
You can learn a lot about a candidate from their approach to this sub-problem. Candidates, sensibly enough, always try to solve the unique cookie problem by using an off-the-shelf tool that they are familiar with, like:
- a GUID
- a timestamp
- a global threadsafe counter
- a random number
- an auto-generated primary key field of a database table
There are pros and cons to all of these approaches; none of them is necessarily “right” or “wrong”. (And we explore the pros and cons as the interview continues.) Where I start to see magical thinking though is when I ask the candidate to assume that their chosen solution is simply not yet implemented on their platform. Rather, they are the developer who needs to implement the tool if they want to use it in the overall solution.
I fondly remember the moment of dawning comprehension when I asked a particular candidate “But suppose you had to write the code in the database implementation that auto-generates the primary key on the table you are using to solve this problem. How would that code work?” The candidate was completely taken aback, and just stared at me for a moment before saying “wow, I never before thought about the fact that someone had to write code that does that.” Apparently in his world creating primary keys is done by the primary key pixies who live in the b-tree forest. :-)
Turns out a lot of people think that GUIDs are generated by the GUID goblins, that random numbers are created by the RNG ogres, and so on.
In reality, all of these tools I mentioned were implemented by writing code. And therefore someone had to analyze the problem space, weigh the costs and benefits of possible approaches, design a solution, implement a solution, test it, document it and ship it to customers. No magic involved!
Of course this is not to say that we shouldn’t treat abstractions as abstractions. You don’t want to be relying upon the implementation details of an abstraction, and you don’t want to waste mental cycles understanding precisely how every tool does its job right down to the movement of the electrons. Moreover, there’s nothing wrong at all with being a developer who takes existing tools and strings them together to make something new; we all do that. But what I want to know is can the candidate make their own tools? Because that’s the business my team is in: making tools.
Comments
Anonymous
March 20, 2009
I thought it was obvious that guids were created by goblins. Afterall, the acronym is Goblin Unique Identifier. My understanding is that they come from Gringotts.Anonymous
March 20, 2009
The comment has been removedAnonymous
March 20, 2009
The comment has been removedAnonymous
March 20, 2009
> a global threadsafe counter If that's not implemented on the platform in question, then what is? Maybe the thread safe part might not already exist, but it can't be to hard to devise one with locks or Interlocked.CompareExchange. You might be surprised by the number of candidates who have never heard of such things. If the candidate chooses a counter then the tack I'd take would be to see if the candidate can describe the problems inherent with counters (they wrap around, for example) and find ways to mitigate them. This alone can be made a fairly complex problem -- Eric I'm also not sure I get the point of your followup question. You can always delve somewhat deeper by assuming whatever you want to use doesn't exist, but you're eventually going to have to assume something, so why not just start at the assumptions you're used to? A reasonable assumption for most people is that the compiler works according to spec. That's not a reasonable assumption for the people who are implementing new compiler features! The point of the exercise is to push the problem down to the same low level of abstraction that we frequently are immersed in when implementing compiler features. -- EricAnonymous
March 20, 2009
"But magical thinking about software concerns me greatly. " This bothers me as well. Software is not magic. I had a C# instructor tell the class the .csprog and .sln files were magic and we didn't need to know about them!Anonymous
March 20, 2009
The comment has been removedAnonymous
March 21, 2009
The comment has been removedAnonymous
March 21, 2009
Generating random numbers really is probably best explained as magic. Just about everything that you could explain would only give you pseudorandom numbers (i.e. running the same program from the same initial state with the same inputs will give the same answer).Anonymous
March 21, 2009
> I had a C# instructor tell the class the .csprog and .sln files were magic and we didn't need to know about them! I tell that "lie" in my C# sharp class, but I think what I say is: For purposes of this class, we'll treat them as magical. When you're first learning something, you have to start somewhere.Anonymous
March 21, 2009
Dude, I am glad you think the Aha questions are not good interview questions. I hope, someday, you will also come to the realization that the current style of interviews is equally valid as randomly hiring people of at some guaranteed skill level. If you believe that the problem you solved with the luxury of normal work environment is also solvable by the interview candidate suffering from anxiety, well, you might be passing over a lot of good people. The standard response to this is avoiding bad hires but please think about how many hires you have made who didn't measure up to your expectation in the end. I really believe it is very hard to test programmers. The 45 to 60 minutes is too short and artificial to be anything but select superficially smart people. In my experience, the correlation between people who go rave interview feedback and really productive people who got things done, was never great. So, I have dispensed with my list of technical questions and just try to evaluate people for some minimal expertise. GDAnonymous
March 21, 2009
The comment has been removedAnonymous
March 21, 2009
I was once in a university algorithms class and we had the same cycle detector function as a question. Since class was over, I had a whole week to think about it. I didn't have anything else to do that week, so I sat down and thought about the problem for a few hours. I had the solution that night. I'd never manage to find that solution in an interview. This is the kind of problem that you must take home to think about. Asking that in an interview is just wrong. That said, it's an interesting problem with an equally interesting solution.Anonymous
March 21, 2009
One of the interesting things about not being a real programmer is that over my time in this business, I have now and then attempted to do things like what you describe out of a) ignorance that tools for this already exist and b) ignorance of the problems that I will encounter. ("How hard could it be?") Thus I have, for example, rassled with code to assign the next available primary key. Soon enough my initial optimism about how easy the task "should" be crumbles, of course. But it's always a learning experience; there's nothing like actually trying it to know where-all you're going to run into difficulties.Anonymous
March 22, 2009
you can take a person out of the kindergarten but the nonsense just waits to come out of the mind of senior developers :) one of the best posts ever:)Anonymous
March 22, 2009
"we had a OS data structure with an unused field that we were using to stash away a 32 bit pointer that was meaningful only to us" -- so, in other words, you were already living in sin. Some sort of magical exorcism was clearly the right answer.Anonymous
March 23, 2009
Don't forget the old axiom: "Any sufficiently advanced technology is indistinguishable from magic." That's why I want to hire magicians, because they obviously can create sufficiently advanced technology. Ah, but don't forget the slightly less old axiom "Any sufficiently arcane magic is indistinguishable from technology." -- EricAnonymous
March 23, 2009
The comment has been removedAnonymous
March 25, 2009
The comment has been removedAnonymous
March 27, 2009
There was a stackoverflow question similar to this that I asked a few months ago: http://stackoverflow.com/questions/190701/creating-your-own-tinyurl-style-uid I embarrassed myself with my limited knowledge of probability, but got a moment of dawning comprehension with finding out about base 62.Anonymous
March 29, 2009
I think that every computer science student should be required to write a script interpreter that supports recursion. I have written several ove the years just for lack of anything beter to do and each time I decide to write one i really learn alot more about how code really works and therefore gain insight for general coding. If you are going to code, it is very good to have a real understanding of how your code runs so that you can write your code to run more efficiently. Creating 'virtual memory stacks' managing pointers to functions and passing of values. I would like to see more people that are capable of 'understanding the magic' as well. We need more wizards!Anonymous
March 31, 2009
The comment has been removedAnonymous
April 01, 2009
Gregory, You make a very good point about the complex algorithms involved in cryptography and why in many cases it is best to use a proven algorithm. I think that everyone here would agree with you that you dont have to know how a known algorithm you are using works. But even when using a proven algorithm implementation or something in the framework it is not good to think of it as "Magical." Its not that you have to know how the algorithm works. I think the point here is that it is good to know that something works because someone else made it work. It is good to recognize that the api or algorithm you are using is subject to the same computational constraints as your code, and is not simply "Magic."Anonymous
April 05, 2009
Ah... the light dawns. Yes, I agree that people need to know that software is pretty much written by people, and that someone wrote the code, or implemented the algorithm. The OP as much says so, and that part of it I quibble with not in the least. It's just that I see in the example provided two algorithms I would not want to implement on the spot, as it were - the GUID and random number. I don't recall which factors go into calculating random numbers offhand, you see, and I certainly couldn't tell you which pseudo-random number generating algorithm is the best for any given circumstance. Alas, I was suckered by the example and not the greater principle. Mea culpa.