{"id":78,"date":"2008-01-01T00:04:38","date_gmt":"2008-01-01T07:04:38","guid":{"rendered":"http:\/\/thesmithfam.org\/blog\/2008\/02\/01\/how-to-conduct-a-good-c-phone-interview\/"},"modified":"2019-08-12T07:16:12","modified_gmt":"2019-08-12T13:16:12","slug":"how-to-conduct-a-good-c-phone-interview","status":"publish","type":"post","link":"https:\/\/thesmithfam.org\/blog\/2008\/01\/01\/how-to-conduct-a-good-c-phone-interview\/","title":{"rendered":"How to Conduct a Good C++ Phone Interview"},"content":{"rendered":"<p>\nI&#8217;ve interviewed dozens of software engineers, mostly to fill positions involving C++. I&#8217;ve also interviewed <b>for<\/b> about a dozen positions involving C++ and lots of other technologies and languages. I thought I&#8217;d share some good on-the-phone interviewing techniques for the <b>interviewer<\/b> for C++ positions.\n<\/p>\n<p>\nBefore you read this, you shoud know that my interviewing technique is mostly inspired by Joel Spolsky&#8217;s <a href=\"http:\/\/www.joelonsoftware.com\/articles\/fog0000000073.html\">Guerilla Guide to Interviewing<\/a>, which is a great read, though a little extreme for hiring programmers.\n<\/p>\n<p>\nI also very much enjoy Steve Y&#8217;s writing on hiring and interviewing, particularly his article on <a href=\"http:\/\/steve.yegge.googlepages.com\/five-essential-phone-screen-questions\">phone interviews<\/a>.\n<\/p>\n<p>\nThese questions usually take between 30 and 45 minutes to ask. A great candidate will answer all these and more in less than 30 minutes. A poor candidate will only get through half of them in 45 minutes. I&#8217;ve divided each question into sections. Some questions are not a single question per se, but more of a discussion topic. Enjoy!\n<\/p>\n<p>\n<b>Removing Duplicates from a List<\/b>\n<\/p>\n<p>\nThe first thing I ask candidates is how to remove duplicates from a list. There are basically three answers to this question, and I want the candidate to give me all three, with the advantages and trade-offs of each. If they can only get two of them, I might hint them along to the third. If they still can&#8217;t get the third answer, I almost never hire them.\n<\/p>\n<p>\nThe great candidate will ask me lots of questions up front, like what my data structure is. Is it a linked list or an array? What&#8217;s the penalty for removing an item from the structure? Does it have random access of elements? These are all great quesions. I usually let the candidate assume that indexing is O(1), and so is removing items from the list. Good candidates will ask if the list is sorted first or not. Are the elements hashable? Are the elements easy to compare to eachother? If the candidate dives right into the answer without asking any of these questions, I usually don&#8217;t hire them. Here are the three answers I want to get from the candidate:\n<\/p>\n<p>\n<b>Answer 1: The dumb way (N<sup>2<\/sup>)<\/b>\n<\/p>\n<p>\nFor each element in the list, scan the rest of the entire list and remove matching elements.\n<\/p>\n<p>\nAdvantages: Easy to implement. No extra memory required.\n<\/p>\n<p>\nDisadvantages: It&#8217;s O(N<sup>2<\/sup>) slow, and on large lists it&#8217;ll take a <b>long<\/b> time.\n<\/p>\n<p>\nIf they skip this one, and go straight to answer #2, that&#8217;s just fine (even preferable).\n<\/p>\n<p>\n<b>Answer 2: The adequate way (N log(N))<\/b>\n<\/p>\n<p>\nSort the list first. For each element in the list, look for duplicate <b>neighbors only<\/b> and remove them.\n<\/p>\n<p>\nAdvantages: Faster than Answer 1 because you don&#8217;t have to iterate over the entire list for each element. No extra memory required. Pretty easy to implement.\n<\/p>\n<p>\nDisadvantages: It&#8217;s pretty good in most cases, but still not the (theoretical) fastest way.\n<\/p>\n<p>\n<b>Answer 3: Hash the elements<\/b>\n<\/p>\n<p>\nFor each element in the list, insert it into a set structure that uses a hashing algorithm. When done, just pull out the values, and that&#8217;s your unique list.\n<\/p>\n<p>\nAdvantages: Very fast (theoretically), on the order of O(N).\n<\/p>\n<p>\nDisadvantages: You may choose a poor hashing algorithm and end up with a much worse speed. Implementing a reliable hashing algorithm can be hard, so you&#8217;ll have to <b>find<\/b> one (like the non-standard hash_set class). It also uses much more memory than the other two answers (bonus: What is the memory complexity of this implementation).\n<\/p>\n<p>\nAs you can see, this question is not about &#8220;right or wrong&#8221;, it&#8217;s about how <b>many<\/b> solutions they can come up with, and whether they are able to adequately weigh their chosen solutions. This tells you a lot about a candidate. Note also that this is not strictly a C++ question.\n<\/p>\n<p>\n<b>Counting the Bits in a Byte that are One<\/b>\n<\/p>\n<p>\nIn this question we want to see if they understand the C\/C++ bit-wise operators. This may not be important if your position doesn&#8217;t do a lot of bit twiddling, but it is for my job, so I always ask it. There are several ways to answer this question, again, so I&#8217;m seeing how far they&#8217;ll take it. Again, I want good questions, like how much memory is available to them and whether performance is important.\n<\/p>\n<p>\n<b>Answer 1: Mask, compare, shift, mask, compare, shift, <i>repeat<\/i><\/b>\n<\/p>\n<p>\nIn this answer, you &#8220;and&#8221; the byte with one, and compare the result with one, then shift right by one bit, and repeat it seven more times, like this:<\/p>\n<pre>\r\n    unsigned char input = (some value);\r\n    int count = 0;\r\n    if (input &amp; 1) count++;\r\n    input &gt;&gt;= 1;\r\n    if (input &amp; 1) count++;\r\n    input &gt;&gt;= 1;\r\n    if (input &amp; 1) count++;\r\n    input &gt;&gt;= 1;\r\n    ...\r\n<\/pre>\n<p>Of course, they could just use a loop like this:<\/p>\n<pre>\r\n    unsigned char input = (some value);\r\n    int count = 0;\r\n    for (int i=0; i&lt;8; i++) {\r\n        if (input &amp; 1) count++;\r\n        input &gt;&gt;= 1;\r\n    }\r\n<\/pre>\n<p>I&#8217;ve seen some fun variations on this, like using the modulus operator (%) and the divide operator (\/) instead of shifting and masking. Basically, in this case you are checking for &#8220;oddness&#8221; of the input byte and dividing by 2 each time (which is the same as right-shifting), like this:<\/p>\n<pre>\r\n    unsigned char input = (some value);\r\n    int count = 0;\r\n    for (int i=0; i&lt;8; i++) {\r\n        if (input % 2 == 1) count++;\r\n        input \/= 2;\r\n    }\r\n<\/pre>\n<p>That&#8217;s a fun one, and shows that, even though the candidate may not know the bit-wise operators well, at least he can improvise. We hired a candidate who gave this answer about a year ago. He told me on the phone that he didn&#8217;t know the bit-wise operators, so I thought for sure that he wouldn&#8217;t get the right answer, but he did! He turned out to be an awesome employee too (yes, Chris, I&#8217;m talking about you). :)\n<\/p>\n<p>\n<b>Answer 2: Short-circuited version of the above<\/b>\n<\/p>\n<p>\nYou can modify the above to not iterate all 8 times, if not necessary, by changing the &#8220;for&#8221; loop to a &#8220;while&#8221; loop, like this:<\/p>\n<pre>\r\n    while (input) {\r\n        ...\r\n<\/pre>\n<p>That way, it&#8217;ll bail out as soon as the input hits 0 (which it will eventually), and it may happen sooner than 8 iterations. Actually, it&#8217;ll happen that way more than half of the time. Ask the candidate in what cases would this save you a step (answer: it&#8217;ll iterate at most 7 times for inputs less than 128, 6 times for inputs less than 64, 5 times for inputs less than 32, and so on).\n<\/p>\n<p>\n<b>Answer 3: Lookup Table<\/b>\n<\/p>\n<p>\nThis is the fastest implementation to count bits, but it requires a pre-initialized array with 256 entries in it. It goes like this:<\/p>\n<pre>\r\nunsigned char input = (some value);\r\nstatic int table[256] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, ..., 6, 6, 7, 7, 8 };\r\nint count = table[(int)input];\r\n<\/pre>\n<p>The table takes byte values as inputs and returns the number of bits that are set in the byte. It must be pre-computed and statically-initialized to be fast. This works well because a byte can only have one of 256 values. If they can&#8217;t get this answer, I will often hint them to it by asking, first, &#8220;Can you think of a faster solution if you have some memory available to you?&#8221; If they can&#8217;t get it with that hint, I&#8217;ll ask, &#8220;Can you think of a table-driven approach?&#8221;. If they can&#8217;t get it with those hints, I usually don&#8217;t hire them. If they do really well on the rest of the questions, I may still hire them.\n<\/p>\n<p>\nAfter they give this answer, you&#8217;ll want to ask them about statically initialized data. They should understand that it&#8217;s basically free to initialize. They should also know that if they don&#8217;t statically declare that table, there will be a significant performance penalty.\n<\/p>\n<p>\n<b>Object Oriented<\/b>\n<\/p>\n<p>\nTo get a feel for the candidate&#8217;s understanding of object oriented programming, I like to ask them what polymorphism is. They usually come up with an example (the zoo, shapes, or cars usually). They talk about how having a common &#8220;Animal&#8221; base class is good because all Animal-derived classes can share data. This is a good answer, but the better answer is that a common ZooManager could treat all Animal-derived classes exactly the same, without having to know about each individual child class (Monkey, Elephant, etc).\n<\/p>\n<p>\nI follow this question up with a question about C++&#8217;s &#8220;virtual&#8221; keyword, and what it means when a class member function is declared as virtual in, say, the Animal class previously mentioned. Candidates tend to get this one right about 50% of the time.\n<\/p>\n<p>\nWhen a candidate is <b>really<\/b> good, we can get into a discussion about C++ multiple inheritance and the &#8220;unfavorable diamond&#8221; problem, and how to solve it with virtual inheritance.  I&#8217;ve only had three candidates get that far with this question, and in all three cases, we hired them.\n<\/p>\n<p>\n<b>Understanding Networking<\/b>\n<\/p>\n<p>\nFirst I ask the candidate if they have any network programming experience. Bare in mind that most of our candidates have less than 5 years of experience. If they do have networking experience, I ask them the difference between TCP and UDP. I also ask them the difference between blocking and non-blocking network I\/O.\n<\/p>\n<p>\n<b>Threading<\/b>\n<\/p>\n<p>\nFirst let me just say that I am astounded how <b>few<\/b> candidates have any multi-threaded programming experience. I am blown away by it. If the candidate has any threading experience, I ask them what a mutex is, what a semaphore is, and what deadlock is. I then ask them to give an example of a producer\/consumer problem.\n<\/p>\n<p>\nI also ask what the difference is between a thread and a process. If they come up short, I ask them follow-on questions like whether processes share memory, and whether threads share memory. Then I take it further, and ask if processes share heap or stack and if threads share heap or stack.\n<\/p>\n<p>\n<b>GUIs<\/b>\n<\/p>\n<p>\nIf the candidate has any GUI-programming experience, I ask them why polymorphism is useful to GUIs. Usually they say something about how widgets (a.k.a. controls) can share common data like size and position. That is about 25% of the answer. That&#8217;s just data sharing. The real answer is that the GUI&#8217;s layout and event-dispatching code can treat all widgets identically. This means that widgets can re-implement specific functionality and the event-dispatcher (a.k.a, the event loop) can treat them all the same, even user-invented widgets. Widget-specific code, like painting, can be delegated to each widget without the rest of the toolkit having to know about it. The way Qt does this for example, is that there is a common QObject base-class, and a common QWidget class that inherits from it. QObjects can emit signals that can be connected to other QObject slots. QWidgets have an API for painting, sizing, etc., and can be sub-classed by users. Qt can treat these custom classes just like it does all the built-in QWidgets.\n<\/p>\n<p>\nIf they seem to have any significant GUI experience, I will ask them to send me screenshots of their work. I don&#8217;t require anything spectacular (we&#8217;ll teach them <b>that<\/b> on the job), but I <b>do<\/b> want to know if they have done anything beyond your basic <a href=\"http:\/\/en.wikipedia.org\/wiki\/CRUD_(acronym)\">CRUD<\/a> application. I seriously don&#8217;t care if someone has developed GUIs that even a <a href=\"http:\/\/jguigen.sourceforge.net\/\">computer could create<\/a>. Show me something cool!\n<\/p>\n<p>\nI also ask them what an event loop is, and what it does. I have yet to get a good answer to this one. If they do have a good answer, that usually means they are a great GUI programmer. If they don&#8217;t, that just means they aren&#8217;t great yet. :)\n<\/p>\n<p>\n<b>Embedded<\/b>\n<\/p>\n<p>\nIf the candidate has any embedded programming experience, I ask them what an interrupt is and what the &#8220;volatile&#8221; keyword does in C. If they have any idea about either of them, it usually means that they actually <b>did<\/b> some embedded programming.\n<\/p>\n<p>\nWell, that&#8217;s pretty much it. Not too tricky and not too long. I can usually figure out whether to bring in a candidate for in-person interviews based on these questions alone. In some cases, I need to do some more work to get a better feel. For really excellent candidates, I can tell after their answer to the first question. About 90% of the time, when I bring in a candidate after passing this phone interview, they end up passing the rest of the in-person interviews.\n<\/p>\n<p>\nI hope you find this information useful!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve interviewed dozens of software engineers, mostly to fill positions involving C++. I&#8217;ve also interviewed for about a dozen positions involving C++ and lots of other technologies and languages. I thought I&#8217;d share some good on-the-phone interviewing techniques for the interviewer for C++ positions. Before you read this, you shoud know that my interviewing technique [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-78","post","type-post","status-publish","format-standard","hentry","category-code-and-cruft"],"_links":{"self":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/78","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/comments?post=78"}],"version-history":[{"count":3,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/78\/revisions"}],"predecessor-version":[{"id":1573,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/posts\/78\/revisions\/1573"}],"wp:attachment":[{"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/media?parent=78"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/categories?post=78"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thesmithfam.org\/blog\/wp-json\/wp\/v2\/tags?post=78"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}