The Best C++ Interview Question – Ever
blogs.windwardreports.com
blogs.windwardreports.com
My old Sonicity C++ code, which was built on ACE, is littered with "delete this" calls for Reactor callbacks. Obviously, "delete this" is OK if you're on the heap and you can guarantee that the code isn't going to touch the object again. But what I remember most about that ACE Reactor code was how fragile the event handling was; "delete this" is a recipe for horrible memory corruption flaws.
This is what you get when your C++ interviewers decide that interviews are more about proving how smart they are than about qualifying candidates.
If you add up all the time it takes to write a particular system, I think you'll find debugging and fixing bugs to be one of the largest chunks of time, probably beating out the time it actually took you to write and possibly design the system. Obviously a design more suited to maintainability will decrease this somewhat.
Given this, I'd say this is an excellent question. Especially if the interviewee can tell you why it's a bad idea, or what the gotchas are with using 'delete this;'. It might not find developers with other positive characteristics like what makes for simple and elegant designs. But if you have a mix of questions to cover the many aspects of development in the interview, you should be good to go.
Is the not asshole answer to be stopping right before the malloc and taking note of memory consumption and determining how much malloc is trying to allocate?
When you start asking about how much memory malloc is asking for, that's a tip-off in the wrong direction for me too; malloc handles "out of memory" pretty gracefully.
Then you can either litter break points and start stepping or load the core file in gdb, and start looking closer.
A) Running the code on another system to double check that the systems memory / OS has not been corrupted. I once wasted ~6 hours on a corrupted production box, so now the new rule is when system call fail double check it's not just the machine.
B) Double check that none of the memory allocation / book keeping memory had been over written, memory had not been freed twice etc.
Honestly, I usually try to do that type of stuff by direct code inspection. If it's failed once I am probably going to need to debug related code in the not to distant future so really understanding what's going on is important, but hack and slash debugging can be fun.
I agree that doesn't tell you if the candidate is good at solving problems using C++, but there is potential to discover how deep their understanding is.
PS: I worked with code from the 1984 Macintosh days that was still in use in 2005. You could see where people had updated from Motorola 68020 to PPC and if it had not been stripped out some poor coder might have updated the remaining ASM to x86.
I just figured a good language lawyer, like a good real lawyer, would be able to both interpret the law (spec), but also tell you what would happen in reality if you violated it a certain way.
But as long as the alloca'd memory is only accessed from within the same thread, it is -- AFAIK -- safe to call alloca() simultaneously from multiple threads, the same as malloc(). I think that qualifies as thread-safety by the usual definition: i.e. the function doesn't access statics or globals.
(Of course this will vary depending on the CRT. I don't think any UNIXes nowadays ship without threading support in the CRT, but Microsoft Visual C++ used to have separate thread-safe and non-thread-safe C libraries.)
As the author says, he doesn't expect anyone to get it on their first try. It's more a test of if the candidate can figure the answer out or not. Would you rather have someone who can figure questions like this out on their own or someone who will dismiss this as "trivia"?
FTFY
1. Must it work according to the standard?
2. Is there a reason why it can't work?
3. Are you aware of it working or not working in any particular implementation?
4. Reasoning about how the relevant features might be implemented, can you guess whether it would work?
At some point candidates should express any doubts they feel about the advisability of actually using the technique, or about the conditions under which they would use it, and of course they should explain what further research they would do if the question came up in practice.
In my mind, a candidate can get full marks without actually knowing the answer to the question. I would actually prefer them not knowing, because then I'll learn more about how they think and how well they understand C++.
C++ the language is an extremely leaky abstraction. There are so many places where you really do need to think about what the compiler is doing and what is happening behind the scenes rather than thinking at a consistent abstract level.
Is that a bad thing? I suspect that C++ programmers would say no. But then again, there would be a lot of bias in that answer...
Perhaps C++ has some extraordinary benefits that I don't understand, which makes deleting the v-table before the method returns the stack to the heap worth the trouble [1]?
[1] I might have mixed up some of the terminology a little here. Feel free to correct me vigorously.
"Yeah, this one time I double allocated a vtable on the stack of a doubly-linked binary hash."
And by the way, thanks so much for your work on OpenBSD (assuming you are the Ted Unangst of legend). I've been using it for years, and I appreciate the dedication of the folks who created it.
Also, with respect, it's fairly clear from your second paragraph that you don't understand the terminology being used at all. Which is okay, it's not your field. But, it makes your assessment of how complex this discussion is somewhat suspect.
I'd just be wary of using an extremely complex tool. From what I can tell, this "C++" looks like it could self-destruct at any minute, unless handled by an expert. Perhaps that makes the case even more strongly that you ought to filter your hires most strictly, but I wonder whether there might exist a simpler tool that could do the job with fewer risks.
Once you develop a language, teach it to all your developers and establish a policy to punish deviations you can write very efficient programs - at near or exceeding asm performance (modern compilers are smarter than developers when it comes to CPU-specific optimizations).
Programming in raw C++ using all its features is probably not productive - the code will not be readable by anyone except Stroustroup himself.
Other languages such as Lisp also allow you to create your own language for specific problems, however they are focusing on expressive power and not on performance.
However, I found I could pretty much weed the good C++ programmers from the mediocre/just read about C++ before the interview by asking one question:
"What is a virtual function?"
If they have trouble starting to answer it, give them a hint with "What would cause you to type the keyword 'virtual' in your code?"
You would be amazed how many C++ coders don't really know the answer to this, or what is going on (vtables etc, or even just the behaviour).
One candidate answered "I'd make a function virtual if there were any other virtual functions in the class." It seems like there is no shortage of bad answers to this question. All the people who ever gave me a correct answer (hit rate was <10% of candidates) were good C++ developers.
It's a good question :-).
The key to using C++ successfully, like it or not, is not to understand what happens in every possible circumstance (this is pretty much impossible). The key is to carve out a subset of the language (and some usage patterns) that you know how to use and stick with it. I wouldn't use delete this without consulting the documentation first, even if I suspect it's legal (hell, I use "idiomatic" delete maybe once in 5000 LOC)
The point here is not whether this is good practice, or whether the candidate knows the answer, or whether they would write it themselves, or whether they get the right answer immediately, or whether they automatically know the darkest corners of the C++ spec (of which this isn't one).
The point is whether they can reason through, with the interviewer, and then potentially change their mind if they find that they're wrong.
Part of being a good programmer is finding the good ideas among the dross, finding the right implementation technique among the many at their fingertips, and finding the right design among the myriad plausible constructions.
If you can't find the good ideas in these sorts of interview questions, if you can't read carefully enough to see that the whole point was to uncover whether of not the candidate can reason through then potentially change their mind, or if you think that to do so isn't an important characteristic to test for, then that tells me something.
Yes, it's important to see why things don't work, or are broken, or are a bad idea, but the ability to find good ideas is infinitely more important.
I like this interview question, and if you don't, then we're not a good fit. It doesn't mean you're a bad programmer, it doesn't mean (necessarily (I hope)) that I'm a bad employer/manager/programmer/interviewer - but it doesn mean we probably won't work well together.
But I could change my mind if you provide better arguments than the ones I've seen so far.
deleting "this" releases memory held by the instance data of the object. The programmer can't be sure that any subsequent references to that data will return valid data (although the compiler will allow it). Static data and type-level methods should be fine to call -- although every time the program counter ticks you can't be sure that you're continuing to walk through uncontaminated memory.
I think that's it.
Sounds like a BS question to me because you're going way, way under the hood with exactly how the compiler runs the code. It's like those coding questions where you have to start byte-counting to get the answer. Neat trivia perhaps, but I'd much rather have somebody who delivered clean, organized, easily-maintainable code and got the answer wrong.
EDIT: Seems like I've seen delete this on several occasions (although I can't remember where), but hell if I'd use it unless I had no choice. Even then, it'd be the last statement in the method.
Most all of the time, yes. But the function could have been dynamically allocated to an instance of the object. You don't know from the definition of the question. A dynamic function, presumably, would be picked up by the dtor.
Mismatches between new[] and delete will generally just fail to call dtors or potentially call dtors twice, but the behavior's undefined. Ick.
I know nothing about C++, but I know that this is bullshit. I also think that it's pretty ironic if you think about it for a minute.
If you want to thin out a hundred otherwise-equivalent candidates - knock yourself out. But at that point you might as well be flipping coins.
To add to the discussion, however, I knew the answer because I had a run in with doing this sort of thing. I had built a simple game with OpenGL - stuff moved around on the screen and you could shoot it. Due to the way I constructed the objects, it was trivial to "Delete this" when the object should disappear - a bullet collides with an enemy, perhaps. I did it, it worked exactly as expected.
The follow up question - "What can you do after delete this; ?" - also reared it's head, and that's when I found the other edge to the sword and shied away from it's usage.
It felt so much more elegant as "delete this;" :(