// reverse in place
void str_reverse(char *str)
{
if(!str)
{
ERRNO = EINVAL;
return;
}
else
{
// new scope for autos
char *begin = str;
// swap begin and end until we meet in the middle
for( char *end = (str + strlen(str))-1; end > begin; --end, ++begin; )
{
// using a temporary is probably faster now days but I like this method
*end ^= *begin;
*begin ^= *end;
*end ^= *begin;
}
}
}
Complexity
Hash tables/containers are O(1) -> lookup complexity is not dependant on size of container
Trees are O(log n) -> lookup complexity is logarithmically related to depth of tree
// Design patterns
The observer pattern is fancy name for a list of callbacks, something that is "observable" provides a mechinism for interested parties to register a callback (e.g function pointer in C).
When something happens, the observable object iterates over its list of interested parties calling the callback.
You might use that in an application by using the observer to update the view in response to changes in the model, in a traditional MVC application.
For what it's worth these question are a bit rubbish, anyone with any STL knowledge will know the complexity ratings of the various containers.
Secondly GOF is probably the most overrated book in the literature, some of the patterns are useful and some are widely overused outside of the problem they actually solve, e.g. the singleton solves the static initialization problem in C++ but almost everywhere else is just disguised global.
How about some questions which assess useful knowledge.
// knowledge of testing and refactoring
1) how would you refactor a piece of code which is atrocious in implementation but correct in behavior to a more maintainable design while preserving behavior.
2) how would you prove the behavior was the same.
// knowledge of existing methods
3) implement an efficient hash function for strings
4) explain why you chose that implementation and any tradeoffs in the design.
// Recursion -> Iteration
5) implement a recursive pre-order tree traveral i.e. visit(*node)
6) implement the iterative equivalent.
// IPC
7) name three methods of IPC
8) explain when you would prefer one method over another and why.
// Memory Managment
9) Explain how you would determine the maximal memory usage of a process
10) is there a way to impose a hard limit on the usage of your application (e.g allocators)
// Sorting
11) describe the behaviour of a quicksort
12) describe the behaviour of bubblesort
13) describe when is a bubblesort preferable to a quicksort
// STL knowledge
14) name three sequence containers
15) when should you prefer a pair of sorted std::vector<K> over a std::map<K,K>
// CI & build systems
16) what is the function of Continuous integration
17) name two CI systems
18) name three build systems e.g. Make/Ant/CMake
// Copy correctness
19) what properties are needed to make an object "trivally" copyable
// Estimation and planning
20) How do you estimate how long it will take to complete a piece of work
21) What safety factors do you build into your estimate.
// Low level knowlege
22) what is an atomic operation
23) how would you implement atomic increment and decrement on an x86 processor
24) how would you implement a mutex given the following primitives atomic_increment() and atomic_compare_and_swap();
BTW, left school at fifteen, been a paid programmer since seventeen, been training graduates and post-graduates since the age of twenty-three, now the highest paid person on the team (the only one without a phd).
Do I regret not taking a degree? Sometimes, but not so I could spend three years, reading textbooks that I could read at anytime, but more for the esoteric parts of the discipline, compiler construction - access to different architectures other than the x86 and mips.
I learned a lot on the job, working with really good programmers, I'm still learning all these years later. It's not about code - it's about design and architecture. You can learn these things yourself overtime, but the idea that three years trying to get your end away and killing braincells in the student union, confers some advantage to three years at the coal face learning your craft is a joke.
The main advantage of the really good course are the additional elements of the industry, but for your developer as opposed to your quant, a degree doesn't confer much except a whole bunch of bad habits which must be shaken out of the incoming member of staff.
As for getting your foot in the door, here what you do..
Setup a github account,
Start writing code, make sure that code has tests.
Go to the agile conferences, meet people around the industry.
Learn new technologies, for example teach yourself erlang.
Buy a copy of sedgwick`s algorithms - implement them, understand them.
Install Linux on a old pc, any old piece of junk will do.
Write some code, disassemble it, try and understand the relationship between the high level code you have written and the assembly it generated.
Learn a scripting language - like ruby or python - learn how to interface them to native languages.
Write simple network applications and use a packet sniffer (Tcdump or wireshark) to examine the packets and understand whats going on when you send something across the wire.
Use distributed source control (git or mercurial )
Keep your chin up and your resolve strong and you will do it, keep applying and don't let the bar-stewards grind you down.
Qualifications don't mean anything, ability and experience are everything.
You can't teach ability and remember experience is a fancy way of saying "I made that mistake already so I won't do it again" no more - no less.