For an embedded systems C coder (which was the stated context of the interview) working in a memory and CPU-constrained environment, seemingly arcane knowledge of the compiler and runtime can be crucial, so in context I think these questions were very appropriate.
I would say rather than exclude low-level exercises like this, in favor of more high-level concerns like GOF, SOLID, etc., why not use both types in order to find out what kind of strengths the coder is bringing to the table?
I've found that a lot of coders who tend to be very design/architecture/strategic focused (for instance, me!) tend to have weak areas in low-level/tactical concerns, and visa-versa. Both kinds of coders can be a great asset to a team, and provide a diversity of expertise while pushing each other to grow in weaker areas.
If you can find a coder that does both strategic and tactical very well, you might have found a team lead.
If I was interviewing, I'd much rather hire someone who said "I'd never write code like that" to someone who reels off what might happen in every possible scenario, unless I was hiring for a compiler writer.
The man in the example might know to "never write code like" a variable incrementing and assigning to itself again, but there might be other, more subtle pitfalls in design and implementation that he succumbs to because he hasn't given much thought to all the different ways that the rules of the language can interact.
Note that it's not all stuff that you can just look up: although you can look it up, it might not be obvious that it needs to be looked up. I had no idea there was a difference between `int f()` and `int f (void)`, and if that ever caused problems for me I doubt I would have been able to track it down easily.
"A gentleman is someone who knows how to play the bagpipes, and doesn't."
Understanding the memory model and execution model is a big plus, because it lets you write correct and efficient code (and if you are using C you care about correctness and efficiency). Recalling arcana about the C99 standard is just overkill and asking someone to pull stuff like that out of a hat in an interview is asking too much IMO.
Suggestion: enable -Wall and treat warnings as errors.
gcc -v shows that it's been configured with --disable-werror
sizeof-test.c: In function ‘main’: sizeof-test.c:5:3: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’
Compilers have warnings so that you don't have to remember archaic bits of C. :)
The parenthesis you usually see after it are part of the argument, which for type names looks like a cast to the type in question. Like any other cast, the syntax is the type name in parenthesis.
Apologies if you already knew this.
It's only a net win if the price is right and the project requires such knowledge (in the case of C, mostly likely the trade-off would be a bad one, experience at that level comes at a steep price, fixing bugs due to a lack of knowledge about what happens 'under the hood' is expensive too...).
An example: I have been taught to never attempt shifting the gear in a car before pressing the clutch. I accept this as a dogma, but I have no idea what would have happened had I tried really hard. When I asked "why", the only answer I got was roughly "the engine would break". Only some car mechanics / engineers have enough understanding to explain in detail what would have happened. They have knowledge, I'm following a dogma.
Your transmission is a series of gears with varying ratios of wheel revolutions to engine revolutions. When you upshift, your engine requires fewer revolutions to drive your wheels. When the no-clutch-shifter lets off the gas, the engine's RPM begin to fall. With the correct timing, the shift is performed during this drop in RPM such that the engine's current RPM matches the RPM necessary to drive the car at this speed in this new gear. This obviates the need for a clutch, since the engine and the rest of the drivetrain (for which the transmission is the link) are being manually synchronized: the shift is performed with a technique that keeps everything spinning at the same relative speed.
When you depress the clutch pedal, the transmission disengages from the engine, allowing you to freely shift without regard to the engine's machinations. When you let out the clutch, what typically occurs is that a carbon disk slips a bit before fully reëngaging, allowing the engine and the rest of the drivetrain to gradually synchronize. This is the "catch" that you feel when you let out the clutch.
To illustrate explicitly, let's say we're shifting from 3rd gear to 4th gear at about 30 MPH, and for this car at 30 MPH the engine must spin at 5000 RPM in 3rd gear and 3000 RPM in 4th. Without the clutch, you left off the gas and pull the car out of gear (taking it out of gear is a split-second after letting off the gas), the engine's speed (RPM) begins to fall as you pull the shifter into 4th, and just as the engine hits 3000 RPM (on its way down to 1000, the idling rate), you shift the transmission fully into 4th gear. With the clutch, you jam the clutch and shift, and the engine could be anywhere from 1000-4500 RPM when you let the clutch back out. The clutch slips a bit, allowing the engine to reach the appropriate 3000 RPM before it is fully engaged. Without the clutch, you have very little room for error.
If you time it right the shift will happen from say to 2nd to neutral at one rpm (to neutral is always possible without the clutch), then you reduce the rpm until you know it will match 3rd gear for that speed (good hearing helps here) and then you can make the shift from neutral to 3rd without any force at all. The more 'sloppy' a gearbox the easier this goes.
As long as you don't force things you'll be fine, if you do force it you'll likely be greeted by expensive grinding noises.
On the classic 'beetle' and 'mini' engines I can do this without fail or any chance of damage.
Modern cars (read more expensive) I haven't tried.
Of course this is not what you're supposed to do but it's interesting when you have a 'junker' to play around with it until you can do it right.
I think in real life the boy will shoot himself in the leg without knowing the order of evaluation in C.
void foo(void)
{
int a = 41;
a = a++;
printf("%d\n", a);
}
She says 'a gets an undefined value' but that's not true at all. There are compilers that will look at that undefined function and omit the entire body, including the print.It is extremely important to understand that undefined behavior can and will break everything, even if it appears to be behaving whenever you look.
I think the boy's initial "I would never write code like this" response is spot on. I also agree with the boy's implied annoyance and "who cares what this badly written program actually does" stance.
These are fairly terrible interview questions. They test knowledge of standards and various obscure behaviour, but it's far more important what kind of code (readable, explicit, maintainable, simple, architected, commented, performant, bug-free, etc.) the person writes. In real life, the boy may actually be a better programmer than the girl. It's just not a good, comprehensive test.
Nevertheless the examples are fun, but I would never ask them in an interview. Interview time is precious and not to be wasted on stuff like this, unless you're interviewing for a compiler job...
EDIT: Most of the above applies to the first, C part of the interview. In the second, C++ part, the stuff the girl says is mostly basic knowledge that is useful on a daily basis.