Fog Creek Software
Discussion Board




Are these reasonable C++ questions?

I need a sanity check.

Here are the first five questions from my C++ test.  I've been giving this test for a while now, and I'm getting fewer and fewer people that can answer more than half of them convincingly.

Some information about my motives may help.  My assumption is that these questions are easy for anyone with five or more years of C++ experience to answer.  I am not saying that if you can answer these questions, you know C++.  I am not looking for C++ experts with this test, and I don't expect the answers to be more than one or two coherent sentences.  What I'm trying to do is discriminate between people who have actually programmed in C++ for a while, and those who have not (regardless of what their resume says).


1. What is the difference between a class and an object? 

2. What is the difference between "private" and "protected" access? 

3. Describe inheritance in your own words; give a simple example. 

4. What is a virtual function; why are they used? 

5. Where is the best place to initialize a class's member variables? 


I'd appreciate any feedback, opinions, better questions, flames, remarks about my mother, reasons why C# is better, etc.    ;)

Grumpy Old-Timer
Tuesday, July 29, 2003

These should be very simple questions for anyone who says they know C++.  The most C++ coding I've done was in College 5+ years ago and I could easily answer all these questions (most are not really C++ specific questions, but OOP questions).

Anyone who has a CS degree or worked with an OOP language should be able to answer these questions easily.  In my opinion this would serve to filter out the people who are not at all familiar with basic OOP concepts.

chris
Tuesday, July 29, 2003

The first four questions seem quite reasonable.  The wording of the fifth question could be a bit clearer.  Try "Where is the best place to initialize an object's member variables?" or "Where is the best place to initialize a class's static member variables?" depending on your intention.

Rob Mayoff
Tuesday, July 29, 2003

Easy for anyone with five or more *years* of experience?

I shudder to think that there are people with more than five weeks of experience that don't get perfect.

You may get fewer and fewer that don't get near-perfect scores. That just means more people are lying through their teeth on their resume.

Mike Swieton
Tuesday, July 29, 2003

Yes .. I believe that anyone out of university should hopefully know the answers to those questions.

jedidjab79
Tuesday, July 29, 2003

Those are questions that a freshmen in college that has taken his first C++ question should be handle to handle.

Those are basic, basic questions...

Mark Hoffman
Tuesday, July 29, 2003

er, make that course. Not question.

Mark Hoffman
Tuesday, July 29, 2003

I haven't even programmed C++ (though I've gleaned through Stroustrup's books, and once used C++ as C) and even I can answer them.  The only problem is if "protected" means something different than in Java.

anon
Tuesday, July 29, 2003

sounds like a pop quiz i had as a freshman in intro to C++...

nathan
Tuesday, July 29, 2003

Even with my very limited knowledge of C++ I could handle all these questions. I think you are aiming too low.

Just me (Sir to you)
Tuesday, July 29, 2003

I've only taken freshman c++ and I can answer them all except maybe the last, which I could probably make a good guess at.

Lee
Tuesday, July 29, 2003

Interesting that whenever these questions come up, everyone pipes up about the ease of answering them all, but no one provides their intrepretation of the answers. I suspect that the justified reason is "it's so trivial, why bother?", yet one often finds in these circumstances that someone is looking for a magic word/magic phrase, and different vocabularies means that you may believe that you're correct, but another would think that you're wrong.

Dennis Forbes
Tuesday, July 29, 2003

I don't like interview quizzes like this. I much prefer an actual programming question, like the ones Joel has suggested in his interview article. My favorite interview question is to ask them to implement atoi(). Surprisingly few people actually get it right. This function lets you quickly see whether they understand the difference between a string, a pointer, ASCII representations of numbers, and integer representation of numbers. I've had a few interview candidates that have BS and MS degrees in Computer Science, but do not understand the difference!!

runtime
Tuesday, July 29, 2003

"Implement atoi" is good if you're checking whether the candidate has good attention to detail, etc.  I ask questions like that of just-out-of-college candidates. 

But for industry candidates, or candidates with advanced degrees, I'm more interested in their OO design skills.  I wouldn't give them a pop quiz; I'd come up with a simple coding problem which requires OO design skills.  I far prefer to ask questions about things I've actually had to do in this job. 

"How would you write a hash table?" for example.  Good candidates will ask what the hash table is going to be used for, how generalized it has to be, does it need to be subclassable, what the pattern of adds and removes is going to be, the likelihood of collisions, etc, before diving in. 

Once they clarify the problem and starts writing code, it is pretty easy to see whether the candidate understands OO design!  Are the right things made public vs protected? Are the right methods virtualized? Do they nest the bucket struct?  Do they understand parametrized templates? etc, etc, etc.

 

Eric

Eric Lippert
Tuesday, July 29, 2003

Q: What is the difference between a class and an object? 

A:  A class is the definition of the object.  An object is the instantiation of a class.

Q: What is the difference between "private" and "protected" access? 

A: Crap.  I never use "protected" and it's been too long since I read the intro material.  I believe that makes the variable/function in question only visible to derived or friend classes.

Q: Describe inheritance in your own words; give a simple example. 

A: The mechanism in which a class can take-on or inherit another class's behavior.  Insert trivial example here (vehicle/car, animal/human, etc...).

Q: What is a virtual function; why are they used? 
A:  A function that can be overridden in derived classes.  Used to alter behavior at run-time.

Q: Where is the best place to initialize a class's member variables? 

A:  I always put it in the constructor, but I had a professor tell me that they should all go in an init() function and let the init() function get called by the client _after_ construction.  Something about incompletely constructed objects and exceptions. 


How'd I do?  I've been programming C++ for 5 years or so.

Johnny Simmson
Tuesday, July 29, 2003

Johnny, if I were giving the test I might knock you for your vitual function answer.  The key thing that I would be looking for is that calling a virtual function calls the function defined by the *actual* type of the object.  Calling a non-virtual function calls the function defined by the *declared* type of the object.  You may have intended this, but it wasn't clear to me ("overridden" could have this meaning, but it could also have a more general meaning)

The last question is a bit ambiguous IMO.  It depends on the situation, and what the variables are.  I'm guessing you're looking for "in the constructor" but I'm not sure

Mike McNertney
Tuesday, July 29, 2003

Maybe, "in the initializer list of the constructor", since with objects (as opposed to primitives) that can be more efficient.

I use that as a rule, if I put it some place else I have to think of a good reason.  By default initialization goes there.

Andy
Tuesday, July 29, 2003

Johnny, I don't know about the last answer.  The problem is that constructors can't throw exceptions.  So the answer is to move everything that could cause an exception to a member function.  These are operations like opening a file or a DB connection or a socket, so it makes sense to have an Open( ) function for that ...

However, most constructors you'd write don't throw exceptions.  In those cases, having a separate Init( ) function is a bug waiting to happen.  Someday, someone's going to forget to call it, and you'll be working with an object with completely random state.

Alyosha`
Tuesday, July 29, 2003

These answers are (or should be) too easy for someone with five years of C++ experience.

(In the spirit of Dennis Forbes' suggestion, here are my answers... all from memory)

1) A class can be looked at as the "definition" or "template" if you will, that the object will use and fill in once it is instantiated.  Multiple objects may be instantiated for each class "definition".

2) Private restricts access to only the base class, while protected offers access to the base class and any derived classes of that class.  (That is unless of course you introduce the 'friend' keyword, but that is outside the scope of your question.)

3) Inheritance allows the programmer to create reusable base classes (not necessarily virtual base classes) that may be extended by child classes.  When a child class inherits from a base class, it has all the properties and methods of that base class, and has the ability to add new properties and methods as well.  The classic example is using base class Shape that has a SurfaceArea property (for example) and the child class Rectangle that inherits from Shape.  Class Rectangle will also intrinsically have the SurfaceArea property, and may also add Length and Width properties to facilitate the extra requirements.

4) Virtual functions must be defined in the class in which they are declared (unless they are pure virtual, which is out of the scope of this question).  The use of virtual functions allows multiple versions of the function to exist across the inheritance model, and ensures that the correct version of the function will be evoked when called from an inherited class.

5) The best place to initialize them would be in the constructor.  Furthermore, using the class ‘initializer’ syntax (versus using a plain assignment) is often more efficient due to less overhead.

Edward Livingston
Tuesday, July 29, 2003

Alyosha` - of COURSE constructors can throw exceptions.

I question this particular tool - what I think Grumpy Old-Timer wants is a demonstration that candidate knows C++.  Instead of a quiz, why not ask for that?  As in "Tell me something that demonstrates how well you know C++".
The pop quiz format seems more appropriate to a phone screen - issued by someone who cannot judge the answers.

Danil
Tuesday, July 29, 2003

Forgot to mention, anybody who thinks that C# is better than Grumpy Old-Mother is kidding themselves - she's goooood.

Danil
Tuesday, July 29, 2003

Danil: What kind of answers would you expect?

I mean, the quiz and other well-written questions can easily tell you if they know C++ feature XYZ. If you asked me that question, you'd probably have me generate a problem that might suggest a particular list of features.

This shows nothing about my ability to know *when* to use those features.

I personally think it would be more effective to question them on the specifics (pop-quiz) and seperately pose something more intended to check OO ability. Damned if I know what, though.

Mike Swieton
Tuesday, July 29, 2003

Thanks everyone; this has been very helpful.  I've already changed some of the questions based on your feedback.

chris said: "In my opinion this would serve to filter out the people who are not at all familiar with basic OOP concepts."

Exactly so.  Of five people I've given this test to, the average number correct was three!  No one got all five completely correct (although two came close).  These people all claimed at *least* five years of C++ experience on their resume.

Rob Mayoff - Re the fifth question, good point; I'll clarify that.  Another problem with that question is that 10% of the people give the technically correct answer "In the constructor".  What I'd really consider a more correct answer is "In the constructor initializer list".  Maybe I'll try rewording this to, "Where in the constructor is the best place to initialize (non-static) members?"

Mike Swieton said - "I shudder to think that there are people with more than five weeks of experience that don't get perfect... people are lying through their teeth on their resume."

I hear ya.  And these are the easy questions.  You should see the hash they make of the medium-difficulty questions!  The lying problem is really the whole motivation for this test: if you can't answer the first five halfway decently, I know you're a faker.

Just me (Sir to you) said: "I think you are aiming too low."

Boy, you'd think so, wouldn't you?  I mean, some of these questions are borderline insulting to someone with five years of C++ experience.  "Give an example of inheritance"?  Actually, you're right - I'm aiming as low as I can - and I'm still not hitting anything!

Dennis Forbes said: "... someone is looking for a magic word/magic phrase..." 

That's a valid concern, and it's happened to me in tech interviews.  All I can do is try to be as liberal as I can in interpreting the answers.  For example, for the question about 'inheritance', I give full credit for any answer that contains the words 'specialization', 'derive', 'parent', 'child', 'vary', 'subclass', 'behavior', 'different' (and a few dozen others that you'll just have to have faith that I would recognize).  It doesn't even have to be a sentence - if you just toss out the words, that's good enough for me at this point!

rntime said: "I much prefer an actual programming question..."

Me, too, very much so.  But I assumed that would be even harder than these five questions.  Am I wrong?

Eric Lippert's idea of using a simple coding problem is something I'd do on a "second round" of testing, I think.  Assuming I can get anyone past the first round, and could get company buy-in for two rounds of interviews... I like the idea, though.

Johnny Simmson has a good point about "protected"... I'm going to delete that question in favor of something more frequently used.  (Any ideas?)  And compared to the people I've been getting, he did very well.

Edward Livingston - How long have you been using C++?

Danil - Good one!

Grumpy Old-Timer
Tuesday, July 29, 2003

I could easily answer these questions, but if they were much trickier or C++ specific than this, I'd probably fail because I haven't used C++ much the last 7 years.

However I have many years of experience developing real computer systems in a variety of business areas. So even if some lousy candidates would pass your test, if it was any harder you'd probably lose some good ones too (yeah, like myself...)

As far as evaluating technical merit, I really like asking candidates to provide some code they've written and just study it and discuss whatever issues I find with them.

Big B
Tuesday, July 29, 2003

Actually, a design patterns guy might say the constructor's a bad place to initialize, a factory is better. ;)

anon (the same as earlier in the thread)
Tuesday, July 29, 2003

Grumpy Old-Timer said: "Edward Livingston - How long have you been using C++?"

Using C++ = Three years.
Learning/Using C++ = Five years.

Did you agree with most of my answers?

Edward Livingston
Tuesday, July 29, 2003

Grumpy old-timer... is there any particular reason you're specifically looking for "in the constructor initializer list" rather than just "in the constructor"?  I'm curious, because I usually avoid that particular idiom for style reasons, so if you were looking specifically for that I'd probably miss the question

Edward, as with my previous post, I'm not sure I would take your answer about virtual functions without further talking to you to make sure you really got it.  "Allowing multiple versions of the method in the inheritance tree" is pretty vague, and is not specific to virtual functions, as is "making sure the correct version is called when calling from an inherited class."  When reading that, two things come to mind: what, exactly, do you mean by "correct" (correct could mean the function of the actual type, or that of the declared type)?  And by "from an inherited class," you mean from a *base* class right?  When I first read that I thought you meant from a subclass, which doesn't quite make sense.

I get the feeling you know what virtual functions are about, but without making the specific distinctions that virtual functions call the method of the *actual* type while non-virtual functions call the method of the *declared* type, it is hard to say

Mike McNertney
Tuesday, July 29, 2003

As pointed above, the problem is:
"programming" in C++ in real world
!=
real programming in C++ (learned and studied too, *of course*)

Some people "just are in C++", not "performing in C++"

My opinion:
I'll mantain your basic 5 questions (they are good as a very basic filter!) and add 5 more sophisticated ones: so having 2 groups of questions.

My 11th question would be: "Where did you learn C++", "tell me your favourite/handy C++ book/s", etc.

PS: chg "C++" any-comp-lang /all

Ross
Tuesday, July 29, 2003

1. A class is what I write, an object is what I call it to keep my manager understanding what i do.

2. Protected - The code is in the repository.
Private - The code is on my hard disk, and that is where it is staying.

3. Grandad dies, and I can quit this crap job once and for all.

4. The ones I will write to finish the app in SR1.

5. First time someone asks for them - Why waste those precious cycles?

LuftWaffle
Tuesday, July 29, 2003

My $.02 (0.0174567 EUR)

-- Of the people who answered the question here, even they did not agree.
-- As I mentioned in a similar question yesterday,  you are looking for a key phrase,  in the absence of which, you consider the answer wrong (i.e. "in the constructor _initializer list_" emphasis mine)
  -- Asking the question of an experienced person will get you a different type of answer than an answer by a college grad.  A college grad tends to the text book answer.  Experience lends itself more to an explaination than a definition. (Usually because we spend years explaining it in the real world)

As for runtime's atoi example, I find these problamatic.  A person either remembers it from a textbook example or doesn't.  Surprisingly few people get it right because the example is abstract and you are looking to see specifics in the code. 

BigRoy
Tuesday, July 29, 2003

uh... I don't think atoi is something you "either remember from a textbook or don't".  Writing it shows that you know how the bases work (i.e. base 10), how to use char* strings in C, how to use int types, how to write a loop, etc.  If you know the algorithm, and you know C, you should be able to write it.  I have never written it but I know I could do it in an interview.

As for the initializer list, if someone just says "constructor", that shows they know what a constructor is, and that it is used for initializing member data and such.  If you say "can you be more specific", then they will say "the initializer list" if they know, and say that it can be more efficient than doing assignment in the constructor, which myself and someone else already pointed out.  If they don't know what an initializer list is, then that's a minus.

Andy
Tuesday, July 29, 2003

Edward Livingston - Yup, I think your answers are great - especially compared to what I've been getting… Since we're C++ programmers, after all, I have to nit-pick  :)  I would argue that using the constructor initializer list is *always* more efficient than not.  (How's that for being picky?  And if there's an exception - built-in types? - you can be sure we'll hear about it, and thus learn something new!  In real life, if I got answers like yours to my five questions, I'd sprint to my manager's office and put him in a headlock until he called you in for another interview…)

Mike McNertney said: "Is there any particular reason you're specifically looking for "in the constructor initializer list" rather than just "in the constructor"?  I'm curious, because I usually avoid that particular idiom for style reasons…"

The only way to explicitly (*explicitly*) call a member object's constructor is on the initializer list.  Let's say we have a class like this:

class Foo {
    // … stuff …
   
    CString  m_sName;
};

The only way to explicitly call m_sName's constructor is:

Foo::Foo()
    : m_sName("Grumpy")
{
}

This has two advantages that I can think of.  First (and, IMHO, usually less importantly) it's more efficient than:

Foo::Foo()
{
    m_sName = "Grumpy";
}

Why?  Because the first way calls just a constructor; the second way calls a constructor, then an operator= method.  Trivial beyond words for a CString, but what if it was a "Grumble" object instead?  Who knows what kind of overhead it would entail then?  Now, I take a back seat to no one when it comes to being a complete anal jerk about style, but avoiding the initializer list is not a good habit to get into: if you have two ways to do something, and one way is occasionally better, everything else being equal, do it that way.  As least that the way I *try* to do things.

The other advantage is that some idiot (including myself) can't come along later and do this:

Foo::Foo()
{
    if (0 == m_sName.Compare("Grumpy" )) {
          DoSomethingSpecial( );
    }

    //  800 lines of someone else's code, which you
    // and I know is a terrible thing to do, but - sigh…

    m_sName = "Grumpy";
}

If I had used the initializer list instead, no one could insert that code before m_sName was properly initialized.  (Hey - that's the purpose of constructors, isn't it!)

There's a good discussion of this in Eckel's "Thinking in C++"…

Grumpy Old-Timer
Tuesday, July 29, 2003

Grumpy, I believe I learned answers to all those in my first C++ textbook. To me therefore they seem like such basic questions that if someone knows C++ but cannot answer those questions at all, then it it must be because they don't speak English. As you said, each person will use different wordings in their answers (I might use the word "isa" as contrasted with "hasa" in explaining inheritance as opposed to containment), which makes it important that the test answers be evaluated by someone who know the subject. On the other hand, perhaps some people who "know C++" know it as "a better C" or as "a Java with extra complications that I avoid". Also, beware my agreeing with you because my first C++ textbook was _Thinking in C++_.

Mike McNertney, 3 reasons for prefering to use the initializer list: 1) member data objects which have an explicit constructor but no default constructor, i.e. which require a parameter passed to their constructor, MUST be constructed in the initializer list ... ditto member data that are references, or that are const (if you never use references and const data, perhaps you should); 2) objects which have a default constructor WILL be constructed (by the compiler) using their default constructor, if you don't construct them explicitly in the initializer list ... initializing them in the body of your constructor then results in two function calls (default constructor, then assignment/initialiser) instead of one. 3) The compiler initializes member data in the order in which the data is declared ... your initializing in the body might imply you think you have some control over the sequence.

All that said, there are times when you might prefer to initialize in the body: for example if you have 2 constructors you might like to avoid code duplication by having them both call a common init() function; or for example, you want some complex calculation before you init the data, and it's inconvenient to put the complex calculation in a single expression of the initializer list.

Johnny, the only reason I can think of for having a separate init() function which is called explicitly by the client after construction is if the init() function is virtual, or calls virtual functions in its implementation; routinely forcing the client to call init() explicitly is too error-prone in my opinion: I would sooner do without exceptions than do without the "creation is initialization" idiom.

Quoting from Item 10, "Prevent resource leaks in constructors" from Meyers' _More Effective C++_ (I haven't verified whether my compiler implements this properly)onstructors can throw exceptions, but the compiler won't call the object's destructor if that happens (the compiler doesn't call the destructor of incompletely-constructed objects), and therefore it's better if member data which are constructed clean up after themselves automatically, for example prefer to use auto_ptr<> objects as member data instead of explicit delete of a dumb pointer.

Christopher Wells
Tuesday, July 29, 2003

BigRoy, I'll give you the benefit of the doubt that you're confusing atoi with something else.  Someone who can't implement a reasonable atoi in a few minutes probably should seek employment in a different line of work : ) 

SomeBody
Tuesday, July 29, 2003

Well Mike, that's why it's good to ask follow up questions, that way you'd know I knew what a virtual function was!

I really can't remember why my professor said that about the init() function.  Don't really care. 

Everytime I read Meyer's I'm reminded of how many pitfalls the language has and how much time is spent wrestling with the language compared to wrestling with the business problem.  2 books full of traps and gotchas.

If I had my own shop, I think I'd follow Joel's advice and adopt VB.

Johnny Simmson
Tuesday, July 29, 2003

Yeah Johnny, if I had been interviewing you I definitely would have asked about it (whereas with a more in depth answer I probably wouldn't have bothered)

About initialization: I understand that some things (as others have mentioned) require being initialized in the initialization list, and some things are much more efficient to do that way.  I guess I just wouldn't come up with that as the "best way to initialize member data" because I prefer not to do it unless necessary for style reasons (even if it is slightly less efficient)

Mike McNertney
Tuesday, July 29, 2003

I'd also ask the interviewee to describe which test cases they'd write for their atoi() function to verify it works.

Andrew Reid
Tuesday, July 29, 2003

atoi would be a great question if it weren't for the fact that it gets asked so often.

I've been asked to write atoi so many times for interviews that I have inadvertently memorized it.

Alyosha`
Tuesday, July 29, 2003

Is this topic still live?

A question for the panel - is "What is an initializer-list?" a more effective version of question #5? 

Effective depends on your objective, of course, which may not match someone else's - but if I wanted to know if candidate had learned about them, that's what I would ask; in this case, I don't worry that the nature of the question gives away the answer.

However, the original form of the question gives you two grades of right answer "in the constructor" versus "in the initializer list", which may prove useful.

"What kind of answers would you expect?"

Not very good ones - I've seen the candidates out there too.

What answers might I give?  I would talk about implementing an assignment operator: implications of different return types, implications of different argument types [including discussion of auto_ptr], techniques for avoiding code duplication with the various constructors, exception safety and the swap idiom....

For a digest version, I'd probably just use the sentence above - is it convincing on it's own?

Danil
Tuesday, July 29, 2003

I also have a questionnaire for job candidates - 8 questions as follows.  Note that these questions are give to the candidate at least a week in advance of the interview.  They have every resource on the internet and their own text books available to undertake research if they need to.  They can even type in the code and execute it if they want to.

Most candidates get about 3 out of 8 questions right.  Very sad.  No one has yet found all the temporaries in question 4.

The issue from my perspective is not what people know - but do they know how to find out if they don't know.  Most candidates do not know how to research, which makes them unemployable in my book.


1.    What do you consider to be the major weaknesses of C++?

2.    Implement a Singleton in C++.

3.    What is the difference, if any, between the following variable declarations and initialisations  ?

    SomeType t = u;
    SomeType t(u);
    SomeType t();
    SomeType t;

4.    You are doing a code review.  A programmer has written the following function which uses a number of unnecessary temporary objects.  How many can you find, and how should the programmer fix them?

string FindAddr( list<Employee> l, string name )
{
        for (list<Employee>::iterator i = l.begin();
i != l.end(); i++)
  {
        if ( *i == name )
    {
return i->addr;
    }
      }
      return “”;
    }

5.    What is the difference in the behaviour of dynamic_cast for the following
    1.    A* a = dynamic_cast<A*>( pb );
    2.    A& a = dynamic_cast<A&>(*pb);


6.    As per the example below, the standard string has no automatic conversion to a const char*. 
    
    string s1( “hello” ), s2( “world” );
    strcmp( s1, s2 );                    // 1. error
    strcmp( s1.c_str(), s2.c_str() )        // 2. ok

    It would be far more convenient to write #1.  Given that writing a conversion to const char* operator is trivial why has it not been done?

7.    What is wrong with the following code?  How would you fix it?

template<class T>
void f( size_t n )
{
  auto_ptr<T> p1( new T );
  auto_ptr<T> p2( new T[n] );
}


8.    What is the value of the variable token at the end of the following function for inputs of  data: “1,3,4,6,9” and index: 3?


string f( string& data, int index )
{
  char* token = 0;
  char* s = const_cast<char*>(( data + ",0" ).c_str());
  do {
    token = strtok( ( token == 0 ) ? s : 0, "," );
  } while (( --index >= 0 ) && ( token ));
  return string( token );
}

James Thorpe
Tuesday, July 29, 2003

The following is my perhaps excessively grumpy response to James' quiz. It's been a hard day.

1. The major weakness of C++ is that it is so insanely complicated that it lends itself perfectly to tests like this.

2. No. If I only want one instance of a class then I’m perfectly capable of only declaring one, thank you very much.

3. As regards the difference between 1&2 and between 3&4, I don’t know and I don’t really care enough to go through the pain of reading Stroustrup’s prose to find out.

4. Apart from passing the list by value, I’ve no intention of even looking for them. And I’m certainly not going to start writing ++i instead of i++ after all these years just to save a few nanoseconds and be politically correct.  I’d recommend the programmer get rid of the ugly redundant braces, though.

5. Beats me. I’ve never used a dynamic cast, and I’m not about to start now.

6. Trivial, you say?

7. I’d rewite it as follows with no loss of functionality:

void f()
{
}

8. This code is intended as a joke, isn’t it?

Even Grumpier Old-Timer
Wednesday, July 30, 2003

1. It is an insecure language. It it up to the programmer to ensure that buffers aren't overrun and that no other programmers go, "But aren't arrays one-based?".

2. As the old-timer said, if you can't declare the darn class once and just use that one instance, you ain't trying enough.

3.  SomeType t = u; //creating an instance of sometype called 't' and assigning it a value assuming that u has been declared and has a value
    SomeType t(u); //see above
    SomeType t(); //creating and instance of sometype called 't' and relying on the default constructor's values
    SomeType t; //see directly above

4.
string FindAddr( list<Employee>& Emp_list, const string& name )
{
        for (list<Employee>::iterator itor = Emp_list.begin();
i != Emp_list.end(); itor++)
  {
      if ( *itor == name )
      {
        return itor->addr;
      }
  }
      return “”;
}
The comments are: pass by reference to save memory, descriptive names are our friends, line up your braces or ELSE!!, and indent for God's sake. Oh and I found that the # of temp objects were the passed value of the string name and how many objects could be in the list.

5. There's a reason why I stick to C style casting and this is one of those reasons.

6. A string to char conversion would not be called by the funtion strcmp. strcmp would still see two strings and not the data type it was made to work with: char values. strcmp doesn't support templates and over-riding that function with a function of my own would be confusing to anyone else having to deal with my code. And it would just make my code harder to read and messy. For an example, please see the source code of X-Windows.

7. You are creating two pointers that do nothing while in the scope of that function. That's like me going into the Playboy Mansion with a camera and not taking any pictures of the lovely scenery. Re-writing it to do nothing would be the best thing to do.
8. 1,3,4,6,9,0,000

Sho_Asylumn
Wednesday, July 30, 2003

1. How can there be a "right" answer to this? It's a matter of opinion, not fact.

2. I agree, the right answer is to ask "Why does it need to be a singleton?"

3. Sho is almost correct, except that:
SomeType t();
Is actually declaring a function prototype, not invoking the default constructor. It's a stupid question because unless you know to look for the trick, you wont see it. If you put it in a compiler, the problem would be pretty immediately obvious.

4. Without the definition of Employee, we don't know how many temporary objects there are. operator== could be creating some, for example.

5. The first one returns null on failure, the second throws an exception, if I recall correctly. dynamic_cast is rarely used in C++ anyway, most compilers don't even enable the RTTI required to use it by default. For that reason I'm not sure it's a good question either.

6. Again, a matter of opinion, not fact, so I don't see that there can be a right answer here. I think you're looking for the answer that it can cause problems with overloaded function resolution, but there are alternates.

7. auto_ptr doesn't work with arrays. Use a vector is one possible alternative. But like other people said, it also apparently does nothing.

8. I think it's undefined, because you're calling .c_str() on a temporary object. One could argue that you can't get this one wrong, because any result you answer with could happen. ;)

This is in the most part a trivia quiz, not a test of how well you can program.

And the horse you rode in on
Wednesday, July 30, 2003

The answer to 3 is a bit more complicated than some of you are letting on. The = u and (u) call different operators (assignment and copy constructor respectively). The results may differ depending on how you've implemented them (or failed to impleemnt them).


Wednesday, July 30, 2003

Which all goes to show that I prefer fixing C++ code to writing it.

Simon Lucy
Wednesday, July 30, 2003

The original 5 questions looked fine to me. However the later set of eight just confused the crap out of me. I can write perfectly good MFC apps without knowing any of this stuff. I hate the new cast syntax and think it looks uglier than sin so never use it. Item 8 on that new quiz must be a joke since it uses strtok, quite plausibly the nastiest least thread safe item in the C library cannon (I'm not even sure the code works:
what does c.str() return on a temporary string? I assume this will either do one of three things, leak memory, let s point to some now free memory that may be overwritten at some point in the future, do what the programmer hoped would happen and keep the temporary result around for the lifetime of the function. I think the point to undefined memory is the correct answer here but my C++ is rusty.
I just checked with VC7 the answer is that I'm right the code doesn't work (The string destructor gets called). and eventually it falls over since string(NULL) gives an exception as it tries to compute the length.
Please tell me this was the sort of answer you wanted and this was a deliberate bad code question.

Peter Ibbotson
Wednesday, July 30, 2003

"I hate the new cast syntax and think it looks uglier than sin so never use it."

Just because you think it's ugly doesn't mean that it isn't useful...

The 3 main reasons I prefer the new style over the old are:
1. you can search on the new style casts to find them.
2. it shows the intent of the original programmer (easier to figure out why they put the cast in).
3. it prevents subtle bugs by limiting the casting to only do what you intended.

I agree that dynamic_cast is rarely used - I don't think I've ever had a use for it in my code.

BTW - singletons are really useful when you only want one instance, but don't want to create it until needed. If you're using them instead of declarign a global variable, you aren't using it right.

RocketJeff
Wednesday, July 30, 2003

dynamic_cast is useful for cross casting - a key idea in the acyclic visitor pattern.

Danil
Wednesday, July 30, 2003

*relaxes in the bliss of knowing C++ is a distant memory*

By the way, in nearly every case, I'm sure I'd answer the 8 questions differently than you intented. For instance, my answer to #4 would be "there's nothing wrong with this code until you've run a profiler on the system and shown it to be the bottleneck for performance".

Seriously, performance problems in modern applications generally come about because of two things: (1) waiting for I/O from something really slow, like a disk or a network; (2) writing inefficient algorithsm. Pre-optimizing stuff like "i++" vs. "++i" is code-based masturbation (my answer to that, too, would be "get a better compiler that elides unused temporaries").

Brad Wilson (dotnetguy.techieswithcats.com)
Wednesday, July 30, 2003

aargh!  I used to work for a company that had the uber-macho c++ programmer types there.  There was more of a focus on arguing the finer points of Bjarne and Meyer's than in getting real work done. 

I guess that's just required when dealing with a language as complex as c++?


Wednesday, July 30, 2003

> there's nothing wrong with this code until you've run a profiler

I think there is: because l is passed by value instead of by reference, returning i->addr returns an element of a list item in a list which no longer exists after the function returns.

Christopher Wells
Wednesday, July 30, 2003

Many people have pointed out that some of the questions have room for interpretation and that the answers are not necessarily clear cut.

Perhaps these are the *worst* questions for an automated test or multiple choice test where the candidate has to answer exactly what you want.

But these might be the *best* questions for an interview, where a candidate can show their depth by arguing the validity/interpretation of the question.

Reginald Braithwaite-Lee
Wednesday, July 30, 2003

"I think there is: because l is passed by value instead of by reference, returning i->addr returns an element of a list item in a list which no longer exists after the function returns."

I would agree, if you were returning a pointer to something that no longer exists, but you're returning a COPY of something that no longer exists. That's an entirely different animal (with its own set of bugs).

But also consider the question. The question wasn't "where's the bug?" it's "how do you minimize the number of temporaries?". My answer to THAT question is: I don't, until you prove to me that I have to.

Brad Wilson (dotnetguy.techieswithcats.com)
Wednesday, July 30, 2003

> 4.    You are doing a code review.  A programmer has
> written the following function which uses a number of
> unnecessary temporary objects.  How many can you find,
> and how should the programmer fix them?

Ah, a trick question!  The first part of the question is technical, but the second part is MORAL.  How, morally speaking, SHOULD the programmer "fix" them?

Note that the question implies that unnecessary temporary storage is something that requires fixing.  The expression "if it ain't broke, don't fix it" comes to mind.  I would answer this question with a question -- "does the code work?  If so, why would you risk introducing bugs by changing it?"

Often when I ask coding questions I end up with a godawful mess on my whiteboard.  Once we've determined that the code is semantically correct I often ask the candidate to rewrite it "better". 

Good candidates come back with "Define 'better'.  Is 'better' faster? more portable? more readable? more maintainable? more robust? more debugging spew? terser? less terse? smaller object size? ..." 

Each of these spawns its own series of questions.  Suppose I say better is faster.  Good candidates ask more questions: Faster for typical scenarios or edge cases or amortized cases?  Is scalability a concern? What kind of hardware are we using? ...

That's what I'm looking for -- candidates who know that good design always involves decisions and tradeoffs.  I want candidates who can clarify ambiguity _before_ they dive in to write code. If you can't do that, then you're going to write perfectly correct code that doesn't solve the problem at hand.

I quite literally couldn't care less whether the candidate knows the semantics of a copy constructor or not.  Heck, I design compilers for a living and I doubt that _I_ could give you a cogent explanation of the exact C++ initialization semantics.  I look that stuff up in Stroustrup when I need it!

Eric

Eric Lippert
Wednesday, July 30, 2003

"I look that stuff up in Stroustrup when I need it!"

I consider that answer in an interview worth full credit.

Danil
Wednesday, July 30, 2003

"The answer to 3 is a bit more complicated than some of you are letting on. The = u and (u) call different operators (assignment and copy constructor respectively). The results may differ depending on how you've implemented them (or failed to impleemnt them). "


No, in a declaration, using = calls a constructor, not an assignment operator. You can't call the assignment operator on an uninitialized object, that would be a disaster, so to get around that, they defined that assignment at declaration time should be like calling a constructor with a single argument.

And the horse you rode in on
Wednesday, July 30, 2003

The point of these questions is not to find the uber-geek, but to see if people can do some research and can talk intellegently about the issues.

Some of the code (ie. the temporaries question) is deliberately vague.  I expect people to be able to say "assuming x then ... ", or at least tell me it is vague.

Contrary to popular belief it is possible to get question 1 wrong even if it is asking for an opinion.  I have had a least 6 candidates in the last 2 years say something like "the documentation is not very good".  Buzzt - no score.  And the number of candidates who do not know what a singleton is is astounding.  A 2 second search on Google is all that is required to answer this.  I expect OO developers who supposedly have 5+ years experience to know the most basic of design patterns.

Don't forget candidates had at least one week prior to the interview to consider these questions - and any resources they can imagine at their disposal.  This is not an on-the-spot quiz.

There seems to be an widespread problem with the knowledge of current programmers.  I did a straw poll of VB developers in our organisation (a large financial institution) and less than 5% knew what a hash table was.  What is worse is that most didn't care that they didn't know.

James Thorpe
Wednesday, July 30, 2003

Actually, yes, the answer to three is more complicated than we are letting on, but that's because of how copy-initializers work, not how copy-assignment works.

See ISO/IEC 14882 - 8.5 p14

And for those of you playing the home game - yes, you can go five years without NEEDING to know this sort of esoterica.

Danil
Wednesday, July 30, 2003

A couple people mentioned that they thought finding out if the applicant understands OO is important to determining if the applicant is an expert in C++. 

I think it would be best to address the issue of combining OO with new "generic" or template driven mechanisms in the language as that is what really seperates C++ from other languages like Java and C#....

I would, and have asked, something like this:

Explain how to create a heterogenous collection of policy based string objects which implement the same "concept."  Examples of policies would be copy on write and copy on creation.  Assume the string class and policies have already been implemented. 

If an insightful conversation on the paradigm clashes that occur between OO and generic programming erupted, I'd hire the person on the spot, if an language expert is what I wanted.  But I'd keep keep in mind that a well rounded developer and not a language expert might be what I really want.

http://www.baus.net/

christopher baus
Wednesday, July 30, 2003

Danil,

True, but like you said, you'll likely run into such things so rarely it's not worth considering them. Code that depends on the difference is most likely broken anyway.

For practical purposes, I say they're the same. Language lawyers can bite me. :p

And the horse you rode in on
Thursday, July 31, 2003

VB programmers shouldn't need to care what a hash table is, let the database / collection class take care of it. I haven't used a hash table in the last seven years, it's only needed for high performance dictionaries (Which in my case was looking up MAC addresses)

Talking about a singleton design pattern to me in an interview would probably induce me asking what exactly you mean by that.  I think I know what that means, but I've never used "patterns" in anger, and I think unless your current employer buys into the agile/XP design philosphy you may never have heard of what a singleton IS. Doesn't make you a bad programmer, the VB solution to a singleton class is described in the coffee pot activeX.exe section of the VB6 manual, but the word singleton isn't mentioned. The first edition of the gang of four is 1995, the VB manual dates to 1997 so it ain't surprising.
If you ask me about the singleton pattern I will ask back what do you mean? You asked the question so it means you have an answer in mind.

Peter Ibbotson
Thursday, July 31, 2003

"VB programmers shouldn't need to care what a hash table is, let the database / collection class take care of it"

Hmmm.  I get the feeling that a lot people (even on this notice board) don't care that they don't know.  Clearly you guys have nice stable long terms jobs without problems that require complex data processing.  Good for you.

My organisation had this exact problem 12 months ago during a data migration to a new financial system.  Using stored procedures and COBOL on a high end (but aging) RDB system it took 166 hours to restructure the data to be uploaded to the new system.  We only had a 24 hour window to upload and test.

Eventually we just dumped the data to flat files and used a C++ application and (you guessed it) hash tables to cross reference and convert the data.  The data dump took 4 hours the conversion took 16 minutes.

Knowing what a hash table was meant the difference between success and failure on this project.  You don't need to do things like this often but you need a bigger bag of tricks than VB, arrays and SQL.

That old saying comes to mind "if you only have a hammer, everything looks like a nail"

James Thorpe
Thursday, July 31, 2003

This has been a rather interesting discussion.  James, you note that only 5% of VB developers at your organization even know what a hash table is and most don't care.  I take it you think this is a bad thing.

I am a techie nerd type myself and like to learn about that sort of thing even if I don't have an immediate need on the job.  But let's apply some economic thinking to the VB developers.  They probably have some idea that they would like to advance their career.  What kind of knowledge would be more valuable to them.  I would hypothesize that in a financial institution they get more long term benefit from learning business rules than from knowing what a hash table is and how to implement one.  In the case where you needed a hash table you only needed one person to know it and only needed it once.

mackinac
Thursday, July 31, 2003

"VB programmers shouldn't need to care what a hash table is..."

That sentence alone shows why people are leery to hire VB programmers. Look, in my mind, it's not important to know how a hash table is implemented (nor a linked list, nor a stack, etc.). You do, though, need to know what's available, and how it performs with specific data requirements, so that you can pick the right thing when you need to.

Brad Wilson (dotnetguy.techieswithcats.com)
Thursday, July 31, 2003

>>>  I think unless your current employer buys into the agile/XP design philosphy you may never have heard of what a singleton IS. <<<

You are confusing concepts here.  The singleton is an OO design pattern, not necessarily related to either a specific language (such as C++) nor a specific development methodology (e.g., XP).  In any case, the set of 8 questions were assigned as a one week project.  I expect a lot of experienced C++ programmers have never heard of it, but it's a trivial pattern and would take only on the order of an hour to look up and learn what it is and how to implement it.  James, the set of 8 poster, did say he was looking for people who could research problems and come up with a solution, not people who have encyclopedic knowledge.

mackinac
Thursday, July 31, 2003

> James, the set of 8 poster, did say he was looking for people who could research problems and come up with a solution, not people who have encyclopedic knowledge.

In that case, perhaps he should have set questions which couln't be answered by someone who just has encyclopedic knowledge...

Christopher Wells
Thursday, July 31, 2003

"Explain how to create a heterogenous collection of policy based string objects which implement the same "concept."  Examples of policies would be copy on write and copy on creation.  Assume the string class and policies have already been implemented.  "


You've got to be f*cking kidding me!

What does this mean and what does it have to do with Getting The Job Done?

This thread has gone a long way in educating me about what is wrong with software development.

std::vector<OverArchitected> project
Thursday, July 31, 2003

"Look, in my mind, it's not important to know how a hash table is implemented (nor a linked list, nor a stack, etc.). You do, though, need to know what's available, and how it performs with specific data requirements, so that you can pick the right thing when you need to. "

Preach it brother!.  These data structures are part of the STL library that ships with every C++ compiler.  While VB developers may not have any exposure, C++ developers must know what these things are about - they are part of the tool.  I would also expect any university software development course to cover these things in detail.

The coding questions are based on mistakes that I have either made or picked up in code reviews.  Since they are based on code written for day-to-day systems I do not regard them as "esoteric".  They may seem esoteric to a VB programmer, but they are bread-and-butter stuff in my problem domain.

There is a certain amount of truth to the statement that VB programmers do not need to know this kind of thing.  Most companies (well mine at least) operate on the assumption that they do not know, and therefore problems that require this level of knowledge are not given to VB programmers.  Sort of self fulfilling prophecy.  As a result we reserve VB for small "personal productivity" type applications, reports, or for "glueing" Microsoft office products together.  We have no mission critical systems written in VB.

This is not to disparage VB developers - we need people operating in this space.  It is amazing how may "personal productivity" systems and reporting system we have.

Anyway good discussion - I'll go back and lurk now.

James Thorpe
Thursday, July 31, 2003

It has been interesting to hear what might be important to interviewers.  As a recently laidoff C++ developer I am looking for all the job getting ideas I can find.

mackinac
Thursday, July 31, 2003

Irrelevant side note: Ironically, a hash table is not part of STL.  The map is actually a red-black tree (balanced tree), though it can be substituted for a hash table in most cases.  Many implementations have a hash_map; it's just not standard.

Andy
Friday, August 01, 2003

But it's not irrelevant!

Doing a search on a balanced tree is an O(log n) operation; doing a search on a hash table is an O(1) operation; doing a search on a queue (unsorted) is an O(n) operation.

Doing a traversal of a balanced tree yields sorted elements; doing a traversal of a hash table yields randomly placed elements; doing a traversal of a queue yields items in insertion order.

Doing an insertion... okay, you get my point. This is precisely the kind of stuff I was talking about. :)

Brad Wilson (dotnetguy.techieswithcats.com)
Friday, August 01, 2003

Oh, and to be pedantic to the pedant: :-p STL does include hash tables. The standard C++ library does not (yet? they were talking about folding them in). The standard C++ library took the STL as it was at a point in time, and included it. The STL has continued to grow since that time.

Brad Wilson (dotnetguy.techieswithcats.com)
Friday, August 01, 2003

mackinac: i do wish you luck in finding a good job.  I have programmed C++ for the most of the past 8 years, and last year I was out of work for months.  I'm not sure if you love C++.  For me, it was my world, i never thought I would get out of it.  But through learning PHP/MySQL for a non-profit (volunteer) project, I now have a career writing dynamic web apps for universities.

I still do a little C++ on the side occassionally.  I've becomed disillusioned with it lately.  The amount you need to know and learn to keep up-to-date with it is ENORMOUS.  I figure: if I am going to spend my life learning a language, it may as well be a really well-designed one.  Until I find that (and it might not be another programming language, it could turn out to be Sanskrit), I'm skimming languages to get just what i need from them.

SunSwallower
Monday, August 11, 2003

The answers of these questions depends upon the knowledge and the level of the person who has asked these questions. You can treat these questions as 0-level and quiet good also if you are going in the intrinsic details of the C++ modelling.

Praveen Bhushan
Wednesday, January 28, 2004

*  Recent Topics

*  Fog Creek Home