- Compare and contrast C++ with some other language you know (e.g.,
Python). Describe pros/cons of each -- at least two things that you
feel C++ does better, and at least two things that you feel C++ doesn't
do as well as the other language.[5]
Static typing vs. dynamic typing: ease of fast prototyping in Python
vs. more structure in C++. OO purity -- OO in C++ is mostly just an
add-on. Inconsistency of libraries, e.g., sockets, threads -- too many
choices, little standardization. Multiple inheritance -- good or bad?
Overloading operators -- good or bad? Java has interfaces; C++ doesn't
explicitly.
- Describe and contrast: source code (*.cpp), headers (*.h),
object files (*.o), and executable (*.exe (on Windows)).
[3]
- *.cpp:
- C++ source code, what you as the programmer write.
- *.h:
- C++ headers/includes, put class declarations in here.
#include'd into other C++ files via the preprocessor.
- *.o:
- Compiled object file: produced by the compiler for each
compilation unit. Generally each *.cpp file produces one *.o file.
- *.exe:
- Executable: produced by linker, combines all *.o files
and any needed libraries into one program that you can run.
- What do public, private, and protected mean as
C++ access modifiers? [3]
- private
- only methods in this class can access
- protected
- also subclasses can access
- public
- anyone can access
- (SEP) Write a simple but complete C++ program that outputs
different responses to the console depending on typed user input, using a
switch statement. (This is a warm-up programming question; it's not
supposed to be too complex.) [5]
Many possible solutions; here's a simple one:
#include <iostream>
using namespace std;
int main() {
int choice;
cout << "Do you like pie? [1 for yes, 0 for no] ";
cin >> choice;
switch (choice) {
case 1: cout << "Me too!" << endl; break;
case 0: cout << "Sorry!" << endl; break;
default: cout << "Please enter 0 or 1" << endl;
}
}
- There are at least three meanings of the keyword static
in C++. Describe two of them. [4]
- persistent storage:
- a local variable inside a function that
is declared static preserves its value across calls to that function.
If an initial value is given, that initialization is done only once.
- file scope:
- global variables marked static are limited in
scope to only that file; otherwise, they are accessible everywhere in the
program.
- class member:
- attributes/methods of a class which are marked
static belong to the class as a whole, rather than to individual instances
of that class. Class methods may only reference other class methods or
class attributes.
- Tell me everything you know about namespaces in C++. [4]
Namespaces are containers for names like classes, variables, and functions.
You can create a namespace just like you would a class:
namespace MyNameSpace { } creates a namespace called MyNameSpace,
and everything declared inside the block belongs to that namespace. Items
inside a namespace may be accessed by prepending the namespace and '::'.
Items may also be brought into the current scope by using the
item. The whole namespace may be brought into the current scope by
using namespace.
Every file has a default, anonymous/unnamed namespace. Items declared in
this namespace are accessible only within that file.
- A typical overloaded plus operator for a class MyClass might
look like:
const MyClass& operator+( const MyClass& o );
What is a const reference and why would we use it here? [4]
A reference is like an alias -- another variable name that refers to the
same location in memory. A const ref cannot be changed to point to another
location in memory, and also indicates that the memory pointed to may not
be changed. We declare the parameter to operator+ to be const ref to indicate
to our callers that the plus operator will not change its operand: e.g.,
evaluating the expression 'x + y' won't change the value of y.
- (SEP) Design and draw a UML diagram for a class hierarchy
at least two deep (i.e., there should be at least a "grand-parent" class) and
with at least two sibling classes (i.e., classes that inherit from the same
parent). Here's the important part: the class hierarchy ought to be
meaningful! Include some virtual methods and inherited attributes.
C++ code is not required! But: the classes, their relationships,
and their methods/attributes ought to make sense and be meaningful!
[8]
Many good examples; e.g., Student inherits from Person; Faculty inherits
from Employee, which inherits from Person. Inherited attributes could
include name, phone, address (for Person); GPA (for Student). Virtual
methods could include call() (for Person), or gradAudit() (for Student).
- (SEP) Say we are writing a class, and we wish to print debugging messages
whenever an instance of our class gets created or destroyed.
How would we do that? Write complete C++ code declaring such a class, as
well as a testbed (in main()) that demonstrates the debugging
messages. [6]
#include
class Gadget {
private:
int secret;
public:
Gadget(int s=0) : secret(s) {
std::cout << "Creating a Gadget with secret="
<< secret << std::endl;
}
~Gadget() {
std::cout << "Destroying a Gadget (secret="
<< secret << ")" << std::endl;
}
}
(It's better not to put 'using namespace std' in a header file because other
files may #include it and be affected by the 'using' command.)
- What is an abstract superclass? Describe a situation where it
might make sense to use one. Also describe at least two concrete subclasses.
[5]
An abstract superclass is a class that may not be instantiated; it is used
to categorize other concrete subclasses and hold common attributes+methods.
A simple example might be an abstract superclass 'Person', with two concrete
subclasses 'Man' and 'Woman' -- every Person is either a Man or a Woman, so
it wouldn't make sense to have an instance of the superclass Person.
The Person superclass could contain common attributes like Head, Heart,
Arms, etc. that both Men and Women have -- but the "gender-specific" organs
would be attributes of the subclasses!
- (SEP) Now, write complete C++ definitions for the three classes you
described in the previous question (they need not be terribly complex).
As a reminder, you do need to have at least one abstract (pure virtual) method.
[6]
class Person {
void dealWithStress() = 0;
}
class Woman : Person {
void dealWithStress() { talkWithGirlfriends(); }
}
class Man : Person {
void dealWithStress() { playGames(); }
}
- (SEP) Show the steps to solve the 3-disk
Towers of Hanoi problem in the fewest
number of steps. [3]
- In general, what is the minimum number of steps required
to solve an n-disk Towers of Hanoi problem? [2]
For 1 disk: 1 move. For 2 disks: 3 moves. For 3 disks: 7 moves.
For n disks: 2^n - 1 moves.
- Label three corners 'R', 'G', and 'B', and run the
chaos game with the following sequence.
(The sequence may not be long enough to see the Sierpinski pattern.)
Initialization is up to you.
You may use the edge of a paper as a ruler.
Sequence: R G R B B G R B
[4]
- (SEP) OK, you knew this problem was coming!
Describe the seven layers of the OSI model of networks.
For each layer, give (1) the name of the layer,
(2) a short description of what it does, and (3) an example of a protocol
that fits at that layer. [10]
- Application:
- top-most layer, interfaces with the program.
HTTP, SMTP (email), etc.
- Presentation:
- complex data representation, encryption. SSL.
- Session:
- authentication, suspend/resume session
(save/restore state). SSH, sockets.
- Transport:
- setup of connection, guarantees of reliability.
TCP, UDP.
- Network:
- addressing and routing on the Internet. IP.
- Data link:
- addressing the network interface, MAC addresses.
Ethernet.
- Physical:
- physical medium of sending signals: photos,
electrons. Cat5 cables, Fiber optics, wireless radio.
- The world is running out of IP addresses! Why?
Describe in detail two solutions we covered in class. [6]
IPv4 has only 32-bit addresses, large chunks of which have already been given
out to corporations.
- NAT:
- network address translation. Local network sends all
traffic through a gateway. Only the gateway gets a real public IPv4 address.
All local interfaces get private IPv4 addresses (e.g., within the block
192.168.* or 10.*). Connections get mapped to ports on the gateway machine.
- IPv6:
- new revision of IP uses 128-bit addresses: not likely
to run out! Last 64 bits use the hardware MAC address of the network
interface and so should be globally unique, no matter which network the
machine is plugged into.
- Describe the socket commands needed to setup and run a TCP server.
Also, do the same for a TCP client. Don't just name the commands,
describe what they do. [6]
- Server: socket():
-
Creates a new socket object; akin to buying a phone.
- bind():
-
Connects socket to a port for it to listen on;
akin to getting a phone number.
- listen():
-
Enables socket for listening and sets incoming connection queue length;
akin to setting call-waiting.
- accept():
-
Blocks (waits) for a client to connect, and returns "Caller ID" info
on connecting client. Akin to waiting for someone to call.
- send/recv():
- Communicate with client.
- shutdown():
-
disable sending and/or receiving; akin to mute.
- close():
- Hangs up and closes socket.
- Client: socket():
-
Creates a new socket object; akin to buying a phone.
- connect():
-
Tries to connect to specified server on specified port;
akin to dialing the phone.
- send/recv():
- Communicate with server.
- shutdown():
-
disable sending and/or receiving; akin to mute.
- close():
- Hangs up and closes socket.
- What is a program thread? Why are they cool? What are some
limitations or difficulties in working with threads? [6]
A thread is a "mini-process", another execution context within the same program.
A single processor may execute several threads by switching between them
(e.g., when one thread is waiting for user input, the processor can give time
to another thread), or parallel systems may execute multiple threads on
multiple processors in parallel. Threads share memory and communicate with
each other via this shared memory. This is fast on systems that reflect
this architecture, but synchronization is required to ensure multiple threads
do not simultaneously try to write to the same location in memory.
The shared memory model also does not scale well to large parallel systems
where the memory is actually distributed across a network.
- One of the advantages of FLTK's 'complex' drawing shapes over its
'fast' drawing shapes is the use of transform matrices via
fl_push_matrix() and fl_pop_matrix(). What are
transform matrices, and what do these two functions do? Describe how
you would use transform matrices. [4]
Transform matrices take geometric entities like points, lines, and other
drawing primitives and apply transforms like translation, rotation, and
scaling. The transform commands like fl_rotate(), fl_translate(), etc.
append to the current transform matrix. When a complex drawing command is
encountered, FLTK applies the current transform matrix to the object.
The matrix stack stores several transform matrices; only the topmost matrix
is active. fl_push_matrix() saves the current matrix on the stack and
creates a new matrix on the top of the stack. You may then modify the
current transform matrix freely, and restore the old matrix by calling
fl_pop_matrix().
- (SEP) Say you want to design a system for a church to store
lyrics for their Sunday morning worship songs -- storage, editing,
displaying on the projector, etc. Sketch a UML use case diagram
for this system. Who are the actors in this system? How do they
interact? [6]
Many possible solutions. Actors may include: worship leader, song editor,
PowerPoint jockey, accompanist, database. Worship leader needs to
choose songs and assemble song list; song editor needs to add/edit songs,
PowerPoint jockey needs to integrate lyrics with background images and
switch slides in realtime on Sunday morning; accompanist needs not just
lyrics but chords and/or sheet music.
- (SEP) Choose one use case from the previous question and
describe it in detail: name, actors involved, goals for each actor,
pre/post-conditions, basic flow, and at least one alternate flow. Try to
think of as many alternate flows as you can. [8]
Many possible solutions. For the 'edit songs' use case: actors involved
are just the song editor person and the database. Goal is to have a song
with updated content (lyrics, perhaps chords+sheet music). Pre-conditions:
song exists in the database; person has permissions to edit songs.
Post condition: song has correct info.
Basic flow: person logs in, chooses song from list of all songs, song info
is displayed read-only, with an "Edit" button. User selects "Edit" button;
all song info becomes an editable text box. "Edit" button turns into a
"Save Changes" button; when user selects it, the changes get sent to the
database, and the fields return to read-only; the button reverts to "Edit".
Alternate flows: If desired song does not exist in database, user needs to
use "Add Song" function instead. If user does not have permissions to edit
songs, the "Edit" button will not be displayed, and the song info will be
read-only. If user makes changes and wishes to discard them, a "Discard
Changes" button should be provided. If user makes no changes and still
selects "Save Changes", we may want to detect this and not send any update
to the server.
- (SEP) The "Gang of Four" book describes three categories of
design patterns: creational, structural, and behavioural.
Describe at least three patterns from each category (we covered 5 creational,
7 structural, and 5 behavioural patterns). For each pattern, give its name and
describe how it works. Analogies are fine, but describe clearly how the analogy
applies. [12]
Vince Huston's site has a nice table of mnemonics.