Practical C++ Programming Answers
by Curtis Krauskopf
Some of the practical programming questions require experience
and the answers to some of them can be learned by reading
the right books. A core set of books that every professional
C++ programmer should read are:
- The C++ Programming Language (Stroustrup)
- Effective C++ (Meyers)
- Design Patterns (Gamma)
- The Annotated Reference Manual (Stroustrup & Elis)
- C++ Primer (Lippman)
- C++ Standard Library (Josuttis)
- STL Tutorial (Musser)
- C++ Templates (Nico)
- Advanced C++ (Coplien)
Q1) What language feature is available when a function
returns a reference?
A1) The C++
FAQ-lite at parashift.com answers this question:
The function call can appear on the left
hand side of an assignment operator. This ability may
seem strange at first. For example, no one thinks the
expression f() = 7 makes sense. Yet, if a is an object
of class Array, most people think that a[i] = 7 makes
sense even though a[i] is really just a function call
in disguise (it calls Array::operator[](int),
which is the subscript operator for class Array).
class Array {
public:
int size() const;
float& operator[] (int index);
...
};
int main() {
Array a;
for (int i = 0; i < a.size(); ++i)
a[i] = 7; // invoke Array::operator[](int)
...
}
Q2) What is name mangling in C++?
A2) Name mangling encodes the type of the function's
parameters into the name in order to create a unique
name that is distinguished from identical function names
with different parameter types. For example, the parameter
int *p might be mangled to "intPtr". A function prototype
defined as:
doit(int *p);
could name mangle the doit function into doit_intPtr.
Name mangling is compiler specific. The primary reason
why object libraries from one compiler can not be linked
with object libraries from another compiler is because
each compiler vendor uses a slightly different name
mangling scheme.
Q3) What is overriding?
A3) Overriding only occurs in a class hierarchy. An
overridden method is one that is hidden from the normal
method call hierarchy by a derived class that has a
method with the same name, return type and parameter
list. When a method is overridden by a subclass's method,
the subclass's method is called instead of the parent
class's method.
Q4) Can you assign to a reference?
A4) Yes, you can. Here's an example:
int i;
int &j = i;
j = 5; // changes i to 5
Q5) What happens if you assign to a reference?
A5) From parasoft.com:
You change the state of the referent
(the referent is the object to which the reference refers).
Remember: the reference is the referent, so changing
the reference changes the state of the referent. In
compiler writer lingo, a reference is an "lvalue"
(something that can appear on the left hand side of
an assignment operator).
Q6) What is a static_cast
and when should it be used?
A6) A static_cast<> is
the general replacement for the old-style (cast). A
static_cast<> is safer
than a (cast) because static_cast<>
verifies at compile-time that the conversion makes sense.
Q7) What are the names of the other cast operators?
A7) const_cast, reinterpret_cast
and dynamic_cast.
Q8) How do you trap an exception without knowing what
exception might be thrown?
A8) Use the ... wildcard in the exception handler.
Q9) Describe how you design a program.
A9) Any reasonable answer that you can justify will
work for this question. The better answers will include
the phrases "top-down", and "bottom-up". Other phrases
that could be used are "divide and conquer", "requirements
gathering", budgeting, planning, and testing.
A poor answer is along the lines of, "I just sit down
and start coding because I get something done right
away". Most employers want to know that you spend time
designing the program, that you sit at a blank piece
of paper or a whiteboard and sketch out even a rough
skeleton of how the program will work.
Programmers that design programs using extensive unit
testing get extra credit points. If you're an advocate
of extreme programming (XP) (www.extremeprogramming.org/),
this would be a good time to talk about your experiences
with XP and how it makes you a more efficient and better
software engineer.
Q10) Most programming projects involve modifying existing
code. What things do you look for when you're tasked
with modifying an existing program?
A10) The first thing I do when I take over a legacy
project is to attempt to compile the project in an isolated
environment. I record the compile-time warnings I receive
and I pay particular attention to any modules that compile
with errors because that's an indication that I have
an incomplete or inaccurate development environment.
Next, I make a binary comparison between the legacy
executable and the newly compiled executable. My goal
is to create an executable that is identical to the
legacy executable -- at that point I know I have the
same environment and settings that the previous developers
used.
The next thing I usually look at is any existing documentation.
Although many C and C++ programming projects are notorious
for having little or no documentation (or even inaccurate
documentation!), I have seen projects that had extensive,
amazing and accurate documentation -- even to the point
where the number of lines of useful comments exceeded
the number of lines of code.
Q11) There is a memory leak in a program. What tools
and techniques would you use to isolate, find and fix
it?
A11) I would first determine how big the memory leak
is and look for patterns of when it appears and how
quickly it grows. If the memory leak is small or grows
slowly and the program terminates soon anyway, then
I would say that the problem isn't worth fixing. This
isn't out of laziness -- it's a prudent decision that
recognizes that some things are too expensive to fix.
If a leak was determined to be worthy of fixing, I
would next look for the smallest set of code that reproduces
the problem. Can the problem be reproduced by launching
and then immediately exiting the program? What's the
simplest thing I can do that causes the biggest memory
leak quickly?
I would also realize that there may be multiple memory
leaks in the program and they might be interacting with
each other in strange ways. An example would be a hash
table that leaks whenever the hash table's contents
are rehashed.
On a Windows system, the primary tool I use to monitor
memory usage is the Windows Task Manager. A more aggressive
approach is to instrument the malloc/free and new/delete
methods to provide a log of memory consumption and releases.
Commercial tools are also available to assist in the
detection and eradication of memory leaks. If you've
used one before that you've liked, mention it in the
interview to earn extra points.
Q12) What's the difference between a linked list and
an array?
A12) An array allows random access to the array's elements.
A linked list's elements can accessed by dereferencing
the head (or tail) pointer and then dereferencing the
next (or previous) pointers.
Inserting an element into an array is more difficult
than inserting an element into a list. Deleting is similarly
more difficult in an array than in a list.
Data is stored sequentially in an array but that is
not a requirement for a list. Lists' data can be stored
either sequentially or randomly.
Q13) What is the difference between a vector, a list
and a map?
A13) All three of them are containers in the STL.
Maps use key/value pairs for the elements. The keys
are sorted within the map to allow quick random access.
Insertion and deletion are both very quick. Access to
any particular element is also quick but each element
requires a unique key.
STL vectors and STL lists behave the same as arrays
and lists (see Q12).
|