While knowing the standards makes you a better programmer, it's still bad programming practice to write non-excplicit, cryptic code.
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.
Good point, but I think this is probably more true for a higher-level language (C#, Java, Ruby, etc.) in a domain that is probably more focused on feature delivery than performance.
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.
I agree on the "I would never write code like this" point. I have never read the C standard and don't know off the top of my head what happens when you fail to initialise a static vs auto variable, but I don't really care because I would never write code which relies on whatever the implicit behaviour is. If I found code which did that on a project I'm involved with, I'd search for what is supposed to happen and then fix the code to make it explicit.
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.
I disagree. I feel that knowing what might happen demonstrates that the individual has considered the design of C carefully and taken the time to find out how it is, and why it is the way it is. I think that sort of knowledge always leads to better code in the language.
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.
I agree - the girl's knowledge might be a net win, provided she doesn't go out of her way to use it.
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."
I think there is a point of expected knowledge though, as somethings really won't matter in the long run. It's been a long long time since I've touched C, but if I remember right a big issue with int main() & int main(void) is that if you don't have the void to tell the compiler that main takes no argument then you can cause lots of micro-controllers running your code to crash. This fact makes the void knowledge more important for micro-controller programmers then it does for Windows programmers (although it's very simple knowledge that a lot of people state).
Sure, but would you really care whether someone knew off the top of their head that %zu is the escape sequence for size_t? Some of the stuff she shows off is pretty arcane, though pieces of it are actually useful.
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.
I have to work with folks who confuse size_t with int, and as a result they have overflow bugs depending on whether O_LARGEFILE is in use. So yes, I care. Not because printf format strings are terribly important, but because understanding and adhering to the type system is essential to write bug-free software.
Of course. You and I know they're doing it wrong, however sirclueless suggested above that type correctness is "arcane" and asks if "we would really care" when it comes to type issues in printf format strings.
Yes, I would care. Someone who didn't know might notice the sizeof() and note that it returns size_t, but not know what to do about it, and end up saying "screw it" and just using "%d", which is not portable, and the program might crash when compiled for a different system. It might even run on his sytem today, but not tomorow, or run in the debug image but fail in production. I've seen this and similar things happen many-a-time.
Pet peeve alert: sizeof is not a function. It's a unary operator.
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.
> I agree - the girl's knowledge might be a net win, provided she doesn't go out of her way to use it.
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...).
I agree. It's a little like a Java programmer knowing JVM bytecode: definitely not _needed_ but you'll be much better at understanding why (for example) some code structs are more efficient than others.
Knowing what happens when you fail to initialize a static variable may be useful for debugging when you (or someone else) accidentally fails to initialize a static variable.
Well, knowing the dark corners of the language is not useful "per se", but it allows you to say "I wouldn't write code like this" more often. And, consequently, it makes you NOT write "code like that".
Indeed. The first is blindly following a dogma, the second is true knowledge.
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.
Actually, with enough experience with a given vehicle, it is quite possible to smoothly shift it without the clutch. When the engine reaches the appropriate RPM, you let off the gas as you take the car out of gear, smoothly and firmly shift to the next gear at the right time (a super-narrow window), and ease into the gas again. Unfortunately, if you get any of that wrong, you get an unpleasant (and somewhat damaging) grinding.
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.
IANACM, but I think car mechanics have a model in their head about the gears and rods that make up the shifter, but they certainly don't know off the top of their head which exact gear will break or bend when you try shifting from 2nd to 3rd in a 1990 Ford Focus.
I also ANACM, however I can guarantee you that it is impossible for any gear to break or bend under those conditions (the first model year for the Ford Focus was 1998).
Regarding such 'trivia that might come in handy one day', it is possible on some cars to shift gears without using the clutch, but you have to get the timing exactly right.
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'm worried that the girl will leave a loaded shotgun for someone else to shoot themselves in the leg by writing code that relies on order of evaluation rather than by using parantheses.
The girl clearly knew her stuff, but I'd be much happier if she prefaced this example by also saying "it's dangerous to write code like this because...". I wouldn't want to work with someone who writes code that relies on all the features discussed in the C examples.
How would one write code that depends on order of evalution, instead of using parentheses? Where can you use parentheses that lets you write code that doesn't depend on order of evaluation? I think you missed something here because nothing about the example at hand has anything to do with the use of parentheses.
I'm actually worried the girl's going to shoot herself in the leg.
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.
Indeed. Rather than exploring the obscure standard corners, with a boring code snippet, one should better test that the candidate masters pointers, the pitfalls of implicit type casts, and that s/he can spot the most common traps of the language, etc.
While it's tremendously fun to go through and learn, I question whether she would be a better programmer.
For the first half, the boy is making all the right decisions. He's not taking changes and using little compiler tricks to do things. He's not being clever. (For the second half, they appear to deliberately make him stupid. I'm not sure why.)
She, on the other hand, has a lot more tools in her toolbox. At the very least, she'll be tempted to use them. And if anyone else is working on the code, they'd better know those tools as well as she does. That's a dangerous situation.
Of course, it depends on what they're working on. If they're working with Carmack on his new 3D engine, she's the obvious choice. He would never keep up to Carmack.
Having a deep understanding of the environment in which your program runs (be it the language runtime, or the machine itself) is always an advantage.
It doesn't necessarily follow that you will use that knowledge to be "clever". It helps you avoid pitfalls and debug strange behavior more easily. It helps you know when to use them, and when NOT to use them.
Someone who only knows how to program in practice is ignorant, and someone who only knows the "deep stuff" and can't program effectively and cleanly is just a "language lawyer".
You're essentially saying since you're doing simple things you'd prefer to hire an ignorant programmer who doesn't understand anything more than what you think the job requires.
Well heaven help you if your application gets more complicated and you need to figure out something more difficult.
A truly good programmer knows all the tricks and knows when to not use them.
And pay will scale accordingly. Software development is a balancing act.
If all pay were equal, yes, I'd want her, with the ability to keep her code simple and never be tempted to use complicated things where they don't belong. I'd also want her to understand everything down to the logic gates, and be able to write her own operating system and VM from scratch. If she could also make the perfect waffle, that would be desirable, too.
But pay isn't equal, and I'd be a fool to pay for more than I really need. (Assuming I'm paying fairly.) If the project gets more complicated, I'll educate or hire accordingly. In fact, by that time, he may have educated himself up to the level I need.
The level of the inequality in pay is at most a factor of 2. I am so, so confident that the woman in those slides will be more than twice as productive, on a range of metrics, than the man. There's a big difference between being competent and being an expert. (In addition, her knowledge about the details of C is good evidence that she's probably going to be more knowledgeable about other things related to the job, too.)
Actually, I believe the oft-quoted factor is 10x productivity when dealing with someone at this skill level (and from what I've seen in the field, I'd believe it). But that implies good architectural sense, which I'd test for before making a final decision.
Barring any serious deficiencies, she'd be a steal at 2x pay.
I think the 10x number is inflated, but one thing I realized more recently is it doesn't matter! If you can get a programmer that is 50% (1.5x) as productive for 2x as much, it's almost certainly worth it, since you are unlikely to get even 50% more productivity by hiring twice as many people (which is the alternative).
Meta comment: it's funny that a pink haired girl in ponytails is correcting a boy on hardcore C details. Sure, a few of these women exist in real life. But we really need to resist these Orwellian psyops as the depiction is not really reflective of reality.
tl;dr: Nerdy guys don't have much in life. Let them have C.
Offhand, I would trust that all of the women that graduated from my CS program would trounce me in low-level C programming.
But that's because there were only a handful of them of them, and if you want to make it as a woman in CS, you have to want it bad, or you won't put up with being the one woman in a class of 20.
Oh, I'm sure it was done on purpose. There's no legit reason it can't be a girl, but all too often it's a guy. And if they'd put the girl in the 'dumb' position, the PC people would have jumped up and down on it for furthering a stereotype.
So I don't mind a bit that they chose the roles as they did.
I know it was a tongue in cheek comment but imagine if the roles were reversed in this presentation.. It's an easier life to put the male in any sort of negative or dumb role, for sure. Though I'd prefer robots.
This seems like a false dichotomy to me. The "shallow" character seems completely uninformed about the basics of computer science, maybe having worked through a C tutorial or two, while the "deep" character seems to have an encyclopedic knowledge of every C spec and compiler implementation that's ever been written. How many interview candidates really fall into one of those camps?
I don't really know C that well -- certainly nothing spec- or compiler-specific -- but I got "deep" answers for most of the questions just because I know that generally C compiles straight to machine instructions, and I know how computers work. (I got 5/5 on the little quiz, and the tutorial on sequence points was completely new to me.)
C isn't hard. Thinking like a computer, in any language, is hard. The ability to predict what code will do, while important, is less crucial than the ability to figure out what's really going on when you get one wrong. I feel like calling that ability "deep knowledge" is putting the cart before the horse.
To put it another way, "I don't know the answer to that question, but here's a guess" and "I know the answer to that question, here it is" are both less impressive answers than "I don't know the answer, but give me a second and I'll figure it out for you."
I noticed that too, i'm glad you mentioned it. Q6600 running Chrome 15, everything was perfectly snappy until somewhere around then.
Maybe slideshare has some sort of architectural problem? Is it seeking through the slides linearly for every request? Maybe slides after a certain point get read from disk in multiple segments? Maybe at that exact point in time, the load on the server increased?
I think this slideshow would be better titled 'Standards Compliant C'.
At least for the first printf example, I would employ the boy rather than the girl. The boy gave a correct answer - what was missing, what would happen. The girl spouted a bunch of standards that added no value (with the exception of the 'return 3' which does indeed demonstrate deep knowledge).
In particular, the 'you should add a blank line at the end of your code' comment would immediately make me suspect her to be a finicky letter-of-the-law PITA who would be a nightmare to work with.
Standards are all well and good, but if your code compiles with no warnings and runs without errors according to the spec you were given, nobody of any consequence is going to give a damn.
"Standards are all well and good, but if your code compiles with no warnings and runs without errors according to the spec you were given, nobody of any consequence is going to give a damn."
Wait, what?! The whole point of this slideshow is that without a deeper understanding of your language you can end up with errors that you don't anticipate or understand.
Your code compiles and runs today. But then you rebuild on a different machine, or with different compiler optimization level, add a seemingly innocuous piece of code here or there and then it starts acting differently.
Or you deploy it to your customer and they start seeing intermittent problems with it because you failed to understand when to initialize auto variables.
You can never have too much knowledge about the language (and tools) that you are using to build your code. I would even go further and say the same thing about the hardware you or your users are running your code on.
While I do agree that you can never have too much knowledge, there is a huge dropoff in value.
Your code compiles and runs today. But then you rebuild on a different machine, or with different compiler optimization level, add a seemingly innocuous piece of code here or there and then it starts acting differently.
IMO this is the problem with the deck. The "problematic" code is code that ppl who don't know the corners of C/C++ aren't likely to write. If you're tempting sequence points in your code, you're asking for trouble, even if you know the standard well because now you're tempting fate you don't make a mistake and you're assuming every compiler implements the standard perfectly (and we all know this isn't the case).
And the smart girl makes at least one potential error. She says that, "You said that your runtime is 64bit so that means your pointers are probably 8 bytes".
First he never says the runtime is 64bit. He says its a 64bit system running in 32bit compatibility mode. What does 32bit compatibility mode mean? Potentially a lot of things. For example, on Windows it means you have 4 byte pointers. Rather than conjecturing -- this is something she could have just said, "How long are your pointers?" But her character was one that had to have an answer -- even if it meant making a potentially wrong assumption.
we actually got bit in game development by the "last line must be blank" standard. along game a compiler that actually complained and we had to write a script to fix up the code.
It's not a commentary on interview questions. It's a tutorial on C language rules, with a silly little story to make it more interesting.
What everyone is missing is how interesting the tutorial is, despite it being about a really dreary topic. I'm reading a book called "Why Don't Students Like School", which goes into some detail about this kind of thing. It's quite good (and really should be, given that it's about how to make education interesting).
Here, have an upvote. So many people in this thread are missing the forest for the trees here and turning this slide deck into a referendum on interview styles, programming personas, and style. I guess it certainly makes for a nice bike shed, but the point of this is to help you appreciate some of the finer details of writing good C code. I like it.
Not sure why there are so many negative comments, the exact detail of the questions and answers aren't as important as the overall message and the guy and girl are archetypes.
We're interviewing some candidates for embedded C programming right now and these are the types of questions (although generally easier) I ask to find out the level of C expertise. For embedded systems with a focus on stability I want candidates who have a very good grasp of the fundamentals like the difference between normal globals, statics, volatile, etc. Also I'd like people who understand enough about the linker to know about data segments, zero init and stuff like that. For embedded you generally have to be able to implement interrupt handlers so the exact translation of a line of C code to assembly is important, as is knowing what's atomic and what isn't.
I'm continually surprised how many programmers have worked on embedded systems in C without being able to answer almost any of my questions. Many seem exactly like the guy in the examples, none like the girl.
Unless I asked for more information I would have been turned off by the girl because she was pedantic. The last thing a team needs is someone who gives a never ending answer to a simple question. If I prodded for more and she delivered it and the guy didn't then she wins hands down. Otherwise I want a simple answer to a simple question and move on to the next thing.
Edit: I only went through the first twenty or so slides. After disagreeing with the initial premise I didn't think the author earned any more of my time.
The first is to remedy the misconception that "C is a really simple language". It's not.
The second is because while you'll never write any code like this, you'll probably have to debug code written by someone who did. That means that in order to use your time efficiently, you need to know what matters and what doesn't. Writing a regex to replace all "static int foo" with "static int foo = 0" is going to waste your time and not expose the cause of the bug. If you didn't know that, your time would be wasted.
The title reminded me of Expert C Programming: Deep C Secrets bu Peter van der Linden. If you don't have this book buy it today. It's one of the best C books I've read and AFAIK the only book that combines C and humor! His description of how to make Oobleck is alone worth the price (for those who are curious, it's a non-Newtonian fluid, http://en.wikipedia.org/wiki/Non-newtonian_fluid#Oobleck, and also a Dr. Seuss character).
this book is recommended on one of the last slides (although i don't remember it talking about sequence points, or i forgot, since that was one of the things i just learnt...; i think they may only have been named in the iso standard which was probably after that book was published)
Would it be useful if most of your colleagues have a deep understanding of the programming language they are using?
Not if by "deep understanding" he means "knowing trivia about underspecified corners of the language that have nothing to do with getting the job done".
No, by "deep understanding," he means "knowing how your code will run on a given system," which can have a lot to do with "getting the job done," especially if your code must be fast and stable.
I don't care what the standards say, please just type the initialization value you need. It's inconsistent to pick a special case, 0, out of 4,294,967,296 possible values, and type something different in the special case.
Initialization of static data is more problematic than you think; it's particularly susceptible to races.
On the other hand, there are very important pragmatic reasons for using 0 to initialize data; the OS loader can give you zero pages (corresponding to bss segment or equivalent) for "free"; free to the point that they don't need to be stored in the image, and allocated lazily as needed.
It is also guaranteed in C++11. GCC has been implementing thread-safe initialization since version 4, I believe, but I'm not sure whether they use this algorithm.
That doesn't solve anything relevant; I quote, "the initialization of an object is indeterminately sequenced with respect to the initialization of an object defined in a different translation unit"; if you have two pieces of initialization code in different translation units, each referring to the other's data-to-be-initialized, you have a race; one is going to get initialized first (whether the order is determined by the standard, by the link order, by the arbitration of dragons, it doesn't matter) and the other is going to be uninitialized when accessed.
I personally think it's better, where possible, to define the relevant types such that a zeroed structure as a valid state, or else use trivial initialization (where "trivial" might be defined as literals or constant expressions). Where this is not possible, explicit initialization (e.g. called directly or indirectly from main()) ought to be used.
Wait, I think we are talking about two different things: the spec I pointed to refers to static local variables, and solves pretty much all the cases I can think of. (Initialization is delayed until first function call).
You are talking about global static variables, and yes, that's a tricky matter.
Well, being local doesn't protect you from indirect access; it's the lifetime that makes statics troublesome, not the scope. The function wrapping the local may be called by the initialization.
I don't think it's super-important to know eg. what value an uninitialized static variable will have. If you use it, you should initialize it explicitly, end of story. If you write code that counts on such detailed minutiae of the standard, you make your code harder to read for no good reason.
I really hate this attitude. Static variable initialization is not "detailed minutiae of the standard" (nor is operator precedence--I know you didn't mention that but others in the discussion have). If you don't know those then you don't know C! It doesn't make your code harder to read if you understand the language. And if you don't understand the language, then why, oh why are you trying to read or write it?
It's like encouraging people to speak in baby talk because the people listening shouldn't have to understand all the detailed minutiae of the English language.
Not many people can have an almost complete and thorough understanding on how each compiler/linker/platform will behave on the various C standards, to suggest such a thing is silly and to enforce it is borderline insanity.
And if you don't understand the language, then why, oh why are you trying to read or write it?
a) To get things done.
b) To attempt to understand the language.
Not everyone can learn the complete work of C standards and quirks just by reading, some need to read and write it.
You haven't given any reason why implicit initialization of variables is better than explicit. Explicit initialization is already required for any initial value except 0 and it conveys intention. It's not onerous -- it's 3 extra characters, and it makes it clear that you meant it to be zero (and you didn't just forget to initialize it).
I think the case for omitting "= 0" is weak at best. If you encourage this style some novice/intermediate programmer could do the same thing for a stack variable, which will bite him/her. Given all these costs/downsides, what is the benefit of not typing those three characters?
Anyone who writes ambiguous code, such as not initializing variables and then incrementing them, deserves to have nobody else understand it. Such a person should work alone.
I'm a bit surprised by the suggestion that optimisation somehow makes the compiler work harder (e.g. catching uninitialised variables), isn't that what -W flags are for? I'm not sure that optimiser flags will catch anything with gcc that -Wall and -Wextra would miss.
There are warning flags that aren't even usable unless you're compiling with optimization on, such as -Wuninitialized.
As the gcc man page says, "These warnings are possible only in optimizing compilation, because they require data flow information that is computed only when optimizing." (emphasis mine)
That only applies to warnings in conjunction with optimisations though, just turning optimisations on (as shown in the example slide) won't necessarily pick up uninitialised variables. For example, if I compile the example given in the slides with -O, -O1, -O2 or -O3 with gcc, I don't get an error/warning, but I do if I use -Wall.
Also, you can use -Wuninitialized without optimisations and it picks up the problem, at least in my version of gcc (4.5.2).
The example in the slide uses `-Wall -O`, and `-Wall` includes `-Wuninitialized`.
Recent versions of GCC have a revamped syntax tree analyzer, which was needed for the new tree-vectorize features. It does more work from the outset these days, so I'm not surprised if it throws the warning earlier.
Ah, I'm using a newer version of gcc, which seems to catch the warning regardless of the optimisation level (including none at all). The text of the man page also seems to be different.
It's articles such as this that scare developers away from C. You honestly do not have to mind meld with the C compiler to be a safe and productive C developer. If you're not sure what's going to happen if you don't initialize a variable then that's OK, because most developers realize that being explicit is better than allowing the implicit case to occur in every language.
Sure, but I don't think this slideshow was targeted towards the developer who does not already know C. Instead, it seems to be targeted towards the semi-experienced C developer who lacks a deep understanding of the standard. Whether or not that kind of understanding is necessary for everyday coding is a different topic altogether, but the main point of the article is sound: take every opportunity to learn.
Didn't get very deep into this slide deck, but I did notice that both of those candidates neglected to complain about using smart-quotes in source code. Sloppy, wouldn't hire either.
Most code is buggy. Usually its author isn't nearby, and even if they are, hitting them rarely helps. Knowing the symptoms of buggy code, however, will help you debug it.
I took something different to many of the comments here. I found the most important takeaway was hidden in the later part of the slideshow, and referred to the difference in the attitudes and approaches to learning for two. Clearly the girl understood that in coding, there's usually a correct way to do things, and was always in search of that answer.
That correctness has varying levels of importance depending on the industry/application, but for a sufficiently large and complex project, the benefits to writing correct code is extremely valuable.
For instance, if it were a team environment and I had to write some functionality using the code supplied by the girl, I could simply assume standard conventions and immediately attempt to use her classes in my code. If written correctly, that code might work without further effort my on end.
If the code were supplied by the guy, I would likely have to go in to the implementation and ensure that the behavior conformed my expectations. And having to go through and read the code could require a significant time investment.
And of course, reading code often takes significantly (10x++) more time than writing it, so minimizing the necessity for it is essential in maximizing productivity. I would suspect that in most programming teams that reading other people's code is what eats up the most time, yet this time can be significantly reduced by following such a standard.
When the slideshow begins to refer to C++ conventions and the "rule of three," the guy shows that he doesn't take into account that others may need to work with his code. This can be dangerous as this single new team member can actually cause the total productivity of the team to decrease.
While this guy is just a made-up character, I wouldn't be surprised if most programmers think/act like him. At the very least, the majority of the ones that I've worked with, do.
On another note, the minutia details of C do come up if you work with and read enough source code. Being able to understand it is the more important issue at hand. Also, in response to many comments stating that writing code that works based on such minutia is poor practice, I think the girl would likely agree.
I really appreciated the slides, and they have a direct impact on my current C++ side project. I breezed through the bits that were not about C or C++, but here's what I took away:
1) Add "-Wall -Wextra -Weffc++" and fix the problems found
2) Have some insights into the various C/C99/C++ language contracts, including what sequence points are, how data is packed, and how expressions are evaluated.
3) Learn when to use delete or delete[], when to declare a destructor virtual.
If anything in this summary piques your interest, you may want to check out the full presentation.
this is great, but also embarrassing. not only am i a worse c programmer than i thought (i thought i was pretty good), but i burnt lunch because i forgot what was on the stove while reading it :o)
C is an incredibly sharp industrial-strength tool. There is absolutely nothing about C that can't trip you up and break your program if you don't know it by heart. But if you do know it by heart, forwards and backwards, it has no equal.
Or, if you prefer: It is a crazy girlfriend: serving your whim one second, burning your clothes the next. Pay it close attention or be ready to buy a new wardrobe regularly.
This is brilliant. It contains simple and direct explanations of C's (and C-based languages) rough edges that many programmers encountered or been bitten by but few have taken the time and effort understand.
I appreciate the presentation style too. The characters clearly represent the difference between deep understanding and casual knowledge of the subject. Good stuff.
These slides makes it look like you have to be one type or the other. I'd suggest that the boy is an excellent candidate for the job and that you could help provide him the lower level understanding that you would like your programmers to have.
The key to me is how the candidates gain the understanding of whatever languages they use. Meaning, is programming something that they really enjoy and are learning on their own time and solving some of their own problems. Or, are they simply picking up programming to try to get a better paying career (aka the types of people that are often drawn to those 6 week learn to program type of schools). Therefore, for me and the interviews I have done in the past asking candidates about books they've read or programs they've worked on (for themselves or others outside of their employment) are often times much more enlightening.
Ironically, the examples provided for illustrating your 'deep C' knowledge, are in fact superficial.
I don't really care if <stdio.h> has a printf definition, or whether C99 behaves differently. You might care more if you are an app programmer.
What I care about is the universal properties of the language that applies everywhere. Also that's where the strength of C comes out. For example, what is a function? What does it compile into? Why are there arguments, return values? How do they get represented? These are far more important questions than how C99 dictates entering the program from int main(). That's least of my worries. Programs I write usually enter a C program from _start
Someone mentioned Expert C Programming: Deep C Secrets as a good book to learn the C standards. Are there any other books that or resources one would recommend to learn this sort of material?
no, it's not a good book to learn the standards! :o) for that you are better with harbison & steele or similar (although that's more a reference - maybe this http://publications.gbdirect.co.uk/c_book/ which i just found?). deeper c is more like a collection of essays that explore interesting corners - it doesn't attempt to cover everything (i enjoyed it, i'm just saying it's not what you described...)
ps you say standards (plural) - all the above is c only.
You must be a language lawyer in order to do anything moderately complex and then be met with "the standard doesn't say anything about that!" when you realized the standard library doesn't include the most basic of things (yeah comp.lang.c, I'm looking at you...).
Yeah, I know. C++0x will be the grand unifying standard to rule them all...sure.
Is this articles note about needing to place a newline at the end of a standards compliant C program actually accurate?
When I write out a file containing "aaaaa" with nano (to avoid any unusual tricks vim might use), and then hexdump it, I get "6161 6161 0a61". In other words, nano slapped on an ending newline when I saved. It is my impression that everything does this.
It has long been unix convention that every line of text is followed by a terminating character. It used to be that many command-line tools relied on this, I suspect most tools are more forgiving nowadays. Nearly all linux/unix text editors perform little normalizations to be as compatible as possible. I bet if you opened a file in vim's binary editing mode (vim -b) you could write it without the final line ending (does nano also have a binary mode? might be worth trying).
Edit: Apparently nano has a -L option that skips the last-line normalization.
I recommend students to take OS development course at university. Many concepts of C are discussed and viewed in practice in this class: the relation of the static storage class in C and the .bss section of the object/executable file, the stack and calling conventions of different processor architectures, and so on.
Let me brag first: I could be that girl in the interview. Yay me. But am I the only one to think these are obsolete skills? Isn't there more to software than knowing C++ at this level? Would I want to spend 10 years on learning it as well as I know it now, today in 2011?
Don't be so sure. I'm currently writing C code that has run on Linux (Intel, both 32 and 64 bit systems), Solaris (Intel 64 bit, 32 adn 64 bit SPARC) and Mac OS-x (not sure, since we don't actually deply on Macs, but we have several developers that use them), and most of this code deals with binary files and some custom network protocols, so alignment issues are important.
It was also neat to see my code run flawlessly under Valgrind (we were attempting to debug an issue with the 32 bit Intel Solaris build---it may be a compiler issue since that's the only platform (out of the ones listed above) the code broke on, but I haven't investigated the issue enough to say for sure).
This is the most mind-tickling thing I have seen/read/watched in a long while! I am going through all the slides and now I know how to interview other coders. Thanks for sharing this!
In C, at least, it helps to think of regions of memory independently of any meaning overlaid on top. For instance, there is plenty of code that depends on behavior like this:
struct list_node {
struct list_node * next;
struct list_node * prev;
}
struct useful {
/* This struct should be part of a list, so include the list header first */
struct list_node;
/* That data that this struct is storing follows */
in_addr_t sip;
in_port_t sport;
in_addr_t dip;
in_addr_t dport;
}
Then, you can write a generic list walker by casting the a "struct useful * " to a "struct list_node * " since the first fields will match up.
This is just one example, another would be parsing and unwrapping ip headers and data sections. As I'm sure you've noticed, C prefers explicit to implicit, and this applies to the layout of memory as well.
The first named element of a structure is required to be located at the same address as the structure, yes; but I'm not aware of any requirement beyond that.
Elements are required to be "sequentially allocated":
This is from the draft N1256 document as I don't have access to the official standard. From 6.2.5 - Types:
"A structure type describes a sequentially allocated nonempty set of member objects (and, in certain circumstances, an incomplete array), each of which has an optionally specified name and possibly distinct type"
I can say that a lot of device drivers in the Linux kernel depend on this ...
Hmm, I understood "sequentially allocated" to mean "this structure gets a block of memory and no other variables will be allocated space within that block". Your interpretation would make sense, though.
As for Linux device drivers... it wouldn't be the first time that the Linux kernel (and especially device drivers) assumed a certain compiler behaviour which wasn't guaranteed, with hilarious results on later compilers.
Long time C coder here. Knowing this stuff just shows you've had more interaction with your C compiler(s) than with humans, which is fine (I knew quite a few of the details except for some of the C++ differences because, well, I code C, not C++).
That said, relying on obscure stuff is where the problem lies. Long time C hackers almost always agree on one thing (if maintainable code is their goal and they're not engaging in some silly contest on how to squeeze a certain program into a ridiculous number of bytes or on how to write a program that you can't understand on purpuse): If you want your code to be maintainable in the long run try to be as transparent as possible about what the code does, don't rely on obscure or implementation dependent features.
So the 'girl' probably has huge experience, but the 'boy's answer is equally valid from a novice's point of view, because it (probably) gets the job done with a minimum of fuss (at least wrt to the initial set of questions). At some point he'll have to expand his knowledge.
If you had to sit through an exposition like that for every silly simple question the days wouldn't be long enough to get any work done. Literal answers like the girl gives are rarely productive, but it is good to have the knowledge that allows you to give those answers. It isn't a must for every position though, and even 'lesser' programmers have to learn somewhere (but when you're hiring you want to hire the best you can at the right price).
Oh, and please, do initialize your local variables before first use ;) Even if you are compiling with the debug options on, not initializing your locals before first use is a really bad idea, no matter how much you know about your compiler.
Later on in the series the differences get more interesting, keep clicking :)
What is probably frightening off many people from C is that there is a lot of arcane knowledge that the 'girl' is exposing that can actually be helpful during the debugging stage of writing a program, and that there isn't really a manual that you can read that will tell you all that stuff.
The only way that I know to come by it is to write code for many years and to run into those issues. I've had a couple of all-night debugging sessions that are still pretty vivid after many years and it is interesting that those bugs taught me lots about how compilers optimize, possibly more than I learned from reading books on the subject.
C bugs can be pretty subtle. The 'girls' knowledge can be helpful while doing hardcore stuff.
Given the choice between the two candidates I'd probably pick the girl (assuming she wants the same salary, which is very unlikely) and put a daily time limit on exposition ;), the 'boy' simply doesn't have that much experience yet.
Oh, and you can declare your 'main' fuction to be int main(void) all you want, argc and argv and envp will still be passed to it.
Keeping your globals 'static' in the file they are declared in (instead of (gasp!) having a bunch of globals that are declared 'extern', try to avoid that if you can) is good practice.
And so on. In short, there is a lot to know about any programming language, you can use questions like these to gage experience levels, don't rely on obscure stuff, explicit is better than implicit, don't expose more than you have to and so on.
It doesn't matter, because in the professional world people don't use tricks in their code; rather, they keep it simple and understandable for the next person to come along. For example where I work it's common in code reviews to see comments like "that's confusing, put more parenthesis there", etc.
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.