5 ms·
I love this type of analysis / retrospective. Ive done 100s of technical interviews and so far there are a handful of questions that stand out as highlighting g
by thinkingkong 7y ago
I love this type of analysis / retrospective. Ive done 100s of technical interviews and so far there are a handful of questions that stand out as highlighting great candidates.
- the interviewer writes a simple c program that compiles and asks the candidate what it does. The best example is an app that dereferences null. Good developers see it right away and answer “segfault”.
- ask someone to do something requiring managing delays, recursion, and error handling. Its wild how few people can handle this who have been developing for 5+ years.
- RcouF1uZ4gsC 7y ago> The best example is an app that dereferences null. Good developers see it right away and answer “segfault”. And more pedantic developers state that it is "undefined behavior" and anything can happen.
- umanwizard 7y agoThis sort of standards-purism goes too far, IMHO. The map is not the territory: C compilers are real, concrete things that have real behavior regardless of whether that behavior is defined by an international treaty. "What does the C standard require of an implementation when given this program" and "based on your experience, how might you expect a typical implementation to react to this?" are different questions, but both are interesting. None of this implies, of course, that I think it's a good idea to write UB! But I think an ideal candidate would both know what UB is and also some of the ways it manifests in practice. If you don't know that code often segfaults on null dereference, you are going to have a very hard time debugging segfaults that you see in the real world.
- Gibbon1 7y agoFar as I've seen on systems with MMU's generally you get page fault. And then the OS handles that and issues a seqfault. Which is what happens usually when you start trying to poke at random addresses. On an ARM Cortex, if you try and read a null pointer you get the top of stack address. Least on my machine/compiler. If you try and write, then you get a bus fault. Beacuse flash memory is mapped to that address. On an AVR, I think reading gives you the reset vector. And write to address 0 is useally a nop. I think with some magic though you can write to that page of flash. So yeah. Kinda depends.
- gravypod 7y agoThe only correct answer would be "you dereference a null pointer". That is the only part of this equation the c language interacts with. That's the entire reason SIGSEGV is a signal to your process. Page faults or access violations are manifested as interrupts in most systems. In some systems there are no such restrictions. Even in C & x86 within RING 0 you should be able to access ((char )0). I've even made an example branch on an old kernel I was making when I was in highschool to test this and it does work [0]. What is unfortunate is that everyone is looking for a different kind of person. If I'm applying to a job, saying "segfault" might be the right answer OR it will be the wrong answer and the interviewer will leave thinking I don't know how this fundamental functionality (in some industries) works. I could also give the more correct answer and look like a know-it-all which, when I'm trying to sell myself based on what I know, is somehow a bad thing. It's a loss no matter which way I play it. I distinctly remember one interview where someone asked me to define a RESTful API for a chat service. So I naturally defined the different objects (ChatRoom, Message, User) and defined what CREATE, LIST, DELETE on them all did. The interviewer was confused because CREATE&LIST are not HTTP methods and I explained that RESTful design isn't really coupled to HTTP and these objects and the operations we can perform with them could be implemented over an RPC or HTTP/json and I listed the steps for both of these approaches. He cut the interview short and I never heard from that company again. [0] - https://github.com/gravypod/Simple-OS/commit/b7a608500b2e70dc0cc2b939ba1bd6381e555bd8#diff-cdd8f39dc4ace4d761440f54b310f2f6R23 https://github.com/gravypod/Simple-OS/commit/b7a608500b2e70d...
- umanwizard 7y agoYou make it sound like there is no right answer, but why couldn't you just explain to the interviewer everything you wrote in this post? "Well, according to the C standard it is undefined behavior. In context X it performs like Y" and so on.
- amluto 7y agoHow about “are you aware that this ‘segfault’ may be turned into RCE by a clever compiler plus a clever attacker”? This may not be such a good interview question but, in most industries, C programmers should internalize this.
- gizmo686 7y agoAn ideal candidate would have been bitten by bugs where the segfualt never happens because the offending code got optimized away. Once you've been bitten by that once, it become hard to answer with just "segfault".
- umanwizard 7y agoI am not suggesting someone should answer with "segfault" and in fact I think that might be a worse answer than just "UB". A good answer would be something like "UB according to the standard, but often segfault in real-world code on x86"...
- deathanatos 7y agoI'm not sure it even has to get optimized away. Stuff like, Foo *ptr = NULL; ptr->member... isn't going to access address 0, even w/o optimizations, despite the only pointer here being null. (It depends on the offset of "member", and if that offset is large enough, it might not be in the first page anymore. What's mapped at 0x1000 and later?)
- kabdib 7y agoYou can define this behavior if you want to. I did that on an embedded system where location zero was mapped and it was a complete pain in the fundament to arrange things so it would generate a fault. So I put on my wizard hat, intoned "Indirecting through NULL yields the value <some-reset-vector-or-something>, so mote it be!" and sure enough, a few weeks later one of the Q/A folks wrote a test that indirected through zero and filed a bug when it didn't explode. "But it's supposed to generate an exception!" "Says who?" "Uh... it just does, right? It's in the CPU or something." "Really? How do you think that works?" I took the opportunity to explain the mechanisms that were in play on various platforms, including ours, because the engineer in question had always treated indirection through zero as something just universally and magically fatal somehow, and there is no magic, just details. It's still a darned good idea to keep the first 64K or 1MB or whatever of your address space unmapped (as well as similar guards at the top of your address space) because it catches interesting mistakes, but it's not like this stuff was handed down to us on stone tablets.
- gizmo686 7y agoThe issue is that it is a C program, and according to the C standard, dereferencing (void * )0 is undefined behaviour. If you actually want to get at memory address 0 in a C program, you need to use some other mechanism or use a compiler that explicitly defines dereferencing NULL. I believe the other mechanism could be as simple as pointer arithmetic, and not involve any compiler specific construct, but I would want to check the spec carefully before assuming that. Also, I would yell at whoever thought it was a good idea to store data at 0.
- dearrifling 7y agoThis doesn't remove UB though. Your compiler still can assume that null-dereference never happens and generates code with this assumption.
- minikomi 7y agoInteresting go to response! "So what does this code do?" "Undefined behavior" "Well, actually, it just prints out 'Hello World'" "How can you be sure? Will the universe exist at that point? Will your computer not spontaneously combust? Will not a cosmic ray strike and flip the bits just-so, to make it print out 'Hello Girls'?"
- keithnz 7y agoI think its potentially bad the common thinking I've seen where an interviewer ( and I've fallen into this trap ) thinks "whoa! X years of development and they can't do that! shakes head slowly". It's more a failure of the interviewer to find out what the X years of experience entailed. They could be insanely good at something really useful and just haven't coded many things like your random coding problem.
- thinkingkong 7y agoAgreed! Its super important to make sure the job, job description, candidates, and interview questions are aligned.
- deleted 7y ago[deleted]
- duxup 7y agoAt a technical but non programming job someone once told me "Man he doesn't know what X is!" My response, "The only reason I know that is because of that bug of ours that keeps coming up..." Some things just happen more some places and other things don't.
- Jach 7y agoIt can also just be nerves. It sucks, but it happens, and your brain just freezes up and kicks itself later in the evening for looking so stupid. Besides general strategies of trying to lower the adversarial atmosphere I think the only full solution to this problem is to be open for them re-applying after some number of months. That at least codifies a second (or more) chance for candidates who really want to work for your company specifically.
- reallydontask 7y agoit really depends on the that although I get the intention that you are trying to convey. It's also worth bearing in mind the old refrain about X*Y years of experience vs X years of experience repeated Y times.
- gravy 7y agoSo here's something I've been thinking about recently. I'm 2.5 years into my first job out of college and I think I'm starting to pick up on things like "oh let me guard against something that could return null" or "let me guard against calling .at() out of bounds". I'm starting to feel really thankful that my work has me thinking like this, because I can actually see it as a sign of getting better as a developer. So -- instead of wondering what kinds of problems will get me through interviews, do you think some way I can train myself to be able to see things like that more often? "Defensive programming" or something?
- umanwizard 7y agoRun your code in as many sanitizers and UB detectors as you can (ubsan, ASAN, valgrind, ...). Send code reviews to smart and detail-oriented people on your team.
- Jach 7y agoI'm not that far ahead of you years-wise (5 years post graduation though I had a combined 3.5 or so years of paid work during/before that) and while I think defensive programming is great and keep it in mind I also have recently been thinking we need more champions of pure reason. Instead of "let me guard against this possibly being null", go and actually look: can it really ever be null? Or, can you make it not ever be null? Or "do I even care if it's null?" In many cases, the guarding is just paranoia or a band-aid against spending a little effort to go look and maybe change. In the worst cases the guarding becomes itself a failed guard. One piece of advice is know your programming language pretty well. e.g. in Java I've caught a few people "guarding" against null by wrapping the thing in Optional.of(), except that throws if the thing is null. They need Optional.ofNullable(). Similarly while I think unit tests (and other tests) are great, there's a notion of "I can't refactor without tests" that I don't agree with. You can use pure reason! And other tools. Michael Feathers has a whole book showing how to refactor legacy code without tests in order to make it possible to get it covered by tests at all. Try starting or joining a book club at work (and even better if you can get the company to pay for copies, and maybe lunches for weekly or every-other-week meetings :)) since working with other coworkers (might not even be on your team!) who want to improve will be pretty stimulating and you can learn things from each other. There are lots of great technical books written by programmers with many years of industry experience. Don't take books dogmatically, but many usually have something worthwhile in them. Writing good code from the software engineering standpoint is something that seems largely missing from the interviewing processes, but it's pretty important for lots of jobs...