So, probably the single most important one for me has been the concept of immutable data structures: whether in C, C++, Java, or Javascript, treating my data immutable has made debugging things a lot easier, <i>especially</i> in environments with parallel execution and shared memory.<p>The next one would be abstraction of storage. Whether using an array, linked-list, or something more exotic, I usually want to hide that from the rest of my program if possible. In general, abstraction is a very handy tool--though you are going to screw up and overdo it until you've got some experience (mainly gained by screwing up).<p>Next top one would be recursive functions to operate on tree-based structures--though I hesitate to use them automatically in languages that don't have mandatory TCO unless I know I won't blow the stack. So many things are plain elegant when you write the problem recursively.<p>Those are three general principles of engineering and design that have served me well. Some specific things that are useful are: the general idea behind finite-state machines and when to recognize if they apply to your problem, regular expressions and their use, pitfalls of the floating-point representation of numbers, basic linear algebra for graphics and simulation.