Here are some of the books which we've found useful or interesting.
CodeNotes for C#
, Random House Trade Paperbacks
I needed a book which would tell me enough about C# to know whether it was worth learning more, but didn't treat me as an idiot. This book proved to be it.
This is an introduction to the language (and runtime) designed for a C++, Visual Basic, or Java programmer. It explains the key concepts at a reasonable level of detail (not too high, not too low).
This book isn't a reference. It is not a complete description of the language, not is it intended as one. You'll probably therefore read it once, then refer back to it a few times before moving on to a more comprehensive tome.
The Art of Readable Code: Simple and Practical Techniques for Writing Better Code (Theory in Practice)
Dustin Boswell, Trevor Foucher, O'Reilly Media , 2011.
We all know that we should write readable code, and we've all been cursed when faced with reading somebody else's monstrosity (or even sometimes one of own). However, there are surprisingly few books on the subject.
Towards the end of the book, I thought initially that the book seemed to be delving too far into specific structured programming techniques. But then I remembered that structured programming techniques were the answer invented to deal with unreadable code, and this line of approach didn't seem unreasonable.
It's not a reference book. It's a quick read, and you will probably read this book once or twice and (hopefully) learn something from it rather than retain it as a reference book for future use.
Multicore Application Programming: for Windows, Linux, and Oracle Solaris (Developer's Library)
Darryl Gove, Addison-Wesley Professional , 2010.
It's often tempting to ignore program optimization: modern CPU's are fast enough that for
applications which involve trivial amounts of computation, optimization is rarely necessary.
However, for scientific and technical computing, where computations can take hours or days to
complete, or for applications involving media processing, optimization is essential.
Once an efficient algorithms has been chosen, the next problem is to get that algorithms to
run as fast as possible on a modern computer architecture. This is where this book comes into its own.
The author, Darryl Grove, provides a good overview of of modern multi-core computer architectures,
and in particular the trade-offs associated with multiple cores, multiple threads, and multiple caches.
He then explains how these impact the efficiency of programs, and how simple changes to
program code and data structures can cause a program to run significantly more or less efficiently
on a given architecture.
One thing I particularly liked about this book is that it recognizes the strengths and
weaknesses of current compilers: it is increasingly rare that an assembler programmer can
outdo the performance of compiler produced code, and the maintainability of such code
(as well as its portability) is often suspect. However, optimizing compilers have their
limitations and require hints and language extensions to be able to make effective
use of available parallelism.
A good section of the book therefore covers OpenMP, a widely implemented set of features/pragmas
available in C, C++ and other languages which enable a program to be optionally parallelized for improved
performance while still preserving the ability to revert to single threaded mode.
(OpenMP features are available in Microsoft Visual C++ compilers, as well as in the open source gcc compiler).
Before reading this book, I wasn't aware how easy OpenMP makes parallelizing many common computations.
In particular, there is a good section demonstrating how the addition of a single pragma can distribute
the execution of a for loop across multiple threads and, in the cases considered, provide
near linear speed-ups up to the number of cores available.
The section on locks and synchronization provides some cautionary examples of unintentional race
conditions for create-your-own lock schemes. (Tip: compiler optimization and code re-ordering may and
probably will totally destroy your intended semantics) , and a good overview is provided of
the wide variety of primitives available in Windows, OS X, Solaris, and Linux.
Finally there is a good section on the constraints to application scaling, including the use of
library code, hardware constraints, and operating system constraints.
I would therefore highly recommend this book if you need to write compute-intensive code which will run in
a multi-core environment.
SQL Antipatterns: Avoiding the Pitfalls of Database Programming (Pragmatic Programmers)
Bill Karwin, Pragmatic Bookshelf , 2010.
When writing SQL its quite common to "steal" somebody else's example: but is that example a good example
or a bad example? Is it efficient? Will it scale? Or will it cause problems with the database
structure later on? Without a
reasonable knowledge of SQL in practice, it's quite difficult to tell good examples from bad examples.
Bill Karwin's book examines "antipatterns" for SQL — code that is commonly used but generally shouldn't
be. He outlines cases where the antipattern is a legitimate approach, as well as alternative solutions
which will eliminate some of the problems which the original code creates.
If it's only to learn the best ways to choose a random record from a large data set
(SELECT * FROM table ORDER BY RAND() LIMIT 1 isn't one of them),
then it's worth reading this book.
Effective C++: 50 Specific Ways to Improve Your Programs and Design (2nd Edition) (Addison-Wesley Professional Computing)
Scott Meyers, Addison-Wesley Professional
This is a book all professional C++ programmers should read even if it
does give them the answers to some of my favorite C++ interview questions. Meyers
provides 50 bullet points for writing better C++ programs. This isn't normally
a format I like (too much like 10 ways to start losing weight now), but
these are surprisingly good points. It contains some good material on C usages which
should not be promulgated into C++, as well as the answer to the question
When must you use a virtual destructor? which trips up far
too many interview candidates.
The C++ Standard Library: A Tutorial and Reference
Nicolai M. Josuttis, Addison-Wesley Professional
If you haven't been tracking the evolution of the C++ language closely,
you may have missed out on the development of templates and the introduction
of the Standard Template Library (STL). With these tools you can finally
program at a high level of abstraction, and C++ can finally be
considered a high level language.
Josuttis provides an excellent guide to both the philosophy and usage of the C++
Standard Template Library (STL). I never really understood the full capabilities
of the library (or why it was designed the way it was) until I read this book.
It gives good examples of almost every usage, enough background to understand
the reasoning behind the design of the library, and organizes the material very well
for instant reference. It's my preferred reference for the standard template library: I use it frequently.
How Not to Program in C++: 111 Broken Programs and 3 Working Ones, or Why Does 2+2=5986
Steve Oualline, No Starch Press
Looking for a good present for someone who enjoys debugging? Or just looking to improve
your debugging skills? Oualline's book is a combination of debugging puzzles and computer
anecodotes. Puzzles range from the trivial (missed initialization, missing close comment),
through to the more difficult (race conditions, compiler optimization induced failures). Each
puzzle comes with hints and answers. However, you really have to work through each chapter
in sequence as each puzzle (and each joke) tends to build upon what has gone before.
The problems, of course, have to be a lot simpler than many of those we encounter in
the real world. Think of this as something along the lines of a
Five Minute Mysteries
for programmers rather than a
Warren Commission Report.
An ideal book to read in your smallest room!
The Best Software Writing I: Selected and Introduced by Joel Spolsky
Avram Joel Spolsky, Apress
There's a lot of good writing in blogs on the web. Unfortunately there is a lot of dross and trivia out there too. Who has time to find the good stuff?
The answer, fortunately for us, appears to be Joel Spolsky. This book contains selected essays (mostly taken from blogs) on the human side of software development. There are well-written essays on such topics as management, recruitment, testing, compensation, user interfaces, etc. Included are some excellent insights into why organizations do what they do, and why things are they way that they are.
Joel Spolsky is an excellent writer — indeed, I was surprised not to find one of his own essays in the book. However, if this book has a weakness it is that Spolsky's editorial introductions and footnotes (while very interesting) sometimes overwhelm the essays themselves.
Sometimes it feels that there isn't any intelligent life out there on the web. This book is a useful reminder that there is intelligent life out there: it's just very hard to find.
The C++ Programming Language (3rd Edition)
Bjarne Stroustrup, Addison-Wesley Professional
Stroustrup has a slight advantage over other writers on C++: as the originator
of the language he can not only
tell you what the language is, he can tell you why it is.
In addition he is a good technical writer, with plenty of clear explanations,
and a comprehensive index. This isn't quite as well written as the second edition
(co-authored with Margaret Ellis), but due to changes in the C++ language this is the
edition you need to own.
The coverage of the Standard Template Library (STL) is good, although
nowhere near as good as the coverage in Josuttis. It also omits
Locales, although you can download the missing
covering locales as well as an
Appendix E covering STL exception
handling from the author's web site.
Effective C++ CD: 85 Specific Ways to Improve Your Programs and Designs
Scott Meyers, Addison-Wesley Professional
Normally I'm not in favor of sequels. Nor books of lists. But More Effective C++
contains 35 good additional points. This book is more concerned with useful techniques
than style or coding rules. I find it particularly helpful in designing classes which
prevented naive forms of bad usage. There's good sections here on smart pointers, the
correct usage of multiple inheritance, and general good object-oriented abstraction.
I especially liked the explanation of how to write a class which can distinguish between
its use as an lvalue (left hand side of an assignment) and an rvalue (right hand side
of assignment, etc.)