
What should every programmer know about programming? - spolsky
http://programmers.stackexchange.com/q/1785/30
======
mpk
I don't have an account there, but a few things immediately spring to mind.

\- Caching and cache invalidation are really hard - if you have to go there,
make sure you can disable the cache at any time

\- Using regular expressions for anything but processing lines of text means
you're probably doing it wrong

\- Few programmers can handle concurrency, provide APIs with lots of run-time
checks

\- Have coding guidelines and enforce them in code review

\- Boring code is good code

\- Lack of automated tests make every commit a crap-shoot

\- Use consistent logging (with levels), if this is a major performance hit
scrub the code out for the production build

\- If there is no expert on the team, become the expert. If there is, learn
from the expert and become one as well

\- Always take responsibility for your code

\- Sometimes ugly hacks are necessary. Deploy them, but make it a priority to
factor them out at the start of the next cycle (don't leave this crap around
for 'someone else later')

Oh man, I could go on like this for hours.

~~~
MartinCron
_Lack of automated tests make every commit a crap-shoot_

The last thing I want to do is start another broad TDD flamefest, but I
honestly believe that if a programmer hasn't even tried a test automation
framework ( _xUnit_ or similar) then they are being professionally negligent.
Would you want to work with a surgeon who was too set in his ways to sterilize
instruments?

The last time I was doing developer candidate interviews, I would start the
phone screen with "what test automation frameworks do you enjoy using and
why". If they couldn't answer that, I did my best to make it a very short
phone call.

~~~
keyist
You are misusing the term, and the conflation around definitions of TDD make
up half of every 'TDD flamefest'.

<http://c2.com/cgi/wiki?TestDrivenDevelopment>

TDD specifically calls not only for unit tests, but for writing them first, ie
the test _drives_ the development. You write a test that fails, then write
code to pass the test.

One can be anti-TDD but still believe in unit tests, full coverage, etc.

~~~
silentbicycle
Indeed. I've never seen a TDD debate that has focused _specifically_ on
whether tests upfront are sufficient for designing good APIs, etc., though
(ironically, the most important part of TDD!). Usually, one side is aghast
that the other side _doesn't believe in testing_ (when they usually do, just
not to an eXtreme), and the other isn't convinced that letting tests do all
the design work makes sense. They're usually talking (or firing cannonballs!)
past each other, mistaking disagreement for mutually extremist positions. (And
then the "us vs. them" feelings kick in...)

I'm in very strong agreement that automated testing (unit, regression,
integration, etc.) pays for itself in most sufficiently large projects, but
skeptical of TDD specifically - testing during exploratory programming often
gives good feedback, but it's just one of many tools.

~~~
c00p3r
Writing a test-cases based on business cases (domain knowledge) before any
code is a good practice. It is that simple.

~~~
silentbicycle
I think it's better to have the spec _be_ the code, as much as possible.

------
mixmax
I'm rather new to programming, but sometimes there's good advice to be had
from people that are just starting out - they don't take things for granted.
Anyway, here's my list:

\- How to think. If you can't hold abstract thoughts in your head you should
find something other than programming to do.

\- How to learn. Progrramming is a dynamic and often changing discipline. You
must know how to learn new stuff.

\- How to find information. Programming is such a vast field that no matter
what you do you'll often come across something you don't know. 99% of the time
someone else has had the exact same problem, and the solution is out there if
you know how to find it.

If you know how to think, learn and find information everything else will
follow.

~~~
jacquesm
How to find information is a skill that is no longer just for librarians,
that's rapidly becoming a 'must have' skill for just about every job.

If you don't know how to effectively search for information that is already
available out there then you are probably wasting valuable time re-inventing
various wheels.

If there is one thing I would do if I had a company with employees of any kind
it would be to teach newcomers in a couple of hours the finer points of using
search engines and other online resources.

~~~
silentbicycle
> How to find information is a skill that is no longer just for librarians,
> that's rapidly becoming a 'must have' skill for just about every job.

And don't forget about asking librarians, either. Some research librarians are
so good at finding things, it's scary. They're like meta-meta-search engines,
except they're usually much better at teasing the relevant details out of
vague questions.

~~~
derefr
It would be quite nice if there were a service half-way between Ask Jeeves and
Mechanical Turk, where any query you entered would be passed to a librarian,
who would reply with an optimized search string (with the option of starting a
chat with you to "tease the relevant details out.")

------
johnnygood
So, I encounter a lot of programmers that have read a little and consider
themselves to really know what they're talking about. However, they can't
explain how an index works - not even in simple terms. Like, if I'm looking
for someone with the username 'johnnygood', why would indexing the username
column make that lookup faster? Even a very simplistic answer like, "an index
orders the information so that the database server can jump to that record
binary-search style rather than looking through every row" would be wonderful.

In that light, I think that programmers should know the basics of computer
science: what references are; how a linked list works; a little about tree
data structures; stacks, queues; basic sorting and searching stuff; etc. I'm
not saying that you need to be able to talk about everything off the top of
your head. I just think a familiarity with the theoretical concepts is good.

On the other end, I see a lot of people who know that PHP interprets strings
using single quotes faster than double quotes, but have no idea why NoSQL
might scale better (and might actively think it's because of the SQL
language).

I want someone to say "a lot of the NoSQL technologies work by having you pre-
compute data so that your data structures have the information you want to
display together stored together in a structure that can be read more quickly
like a hash." It isn't magic.

~~~
mixmax
I somewhat disagree with this - it depends entirely on what you're doing. If
you're writing a 3D gaming engine you're absolutely right, but if you're
writing simple webapps, which most people are nowadays, you don't really need
to know what a linked list is. Your programming language of choice will
abstract it away.

These are certainly good things to know, but for most people not really
essential or even important.

~~~
tbrownaw
_if you're writing simple webapps, which most people are nowadays, you don't
really need to know what a linked list is. Your programming language of choice
will abstract it away._

You still need to understand it at least well enough to know that you really
shouldn't try to access random list elements. Just like you need to understand
arrays well enough to not try to insert things into the middle of them.

~~~
rikthevik
I think Yegge was right about compilers. Without understanding low-level
languages and how high-level languages get transformed, a programmer can never
really understand the language he's working with.

------
jacquesm
If there would be only one thing that you would really have to know it would
be divide and conquer, everything else follows from there. It allows you to
tackle any size project and to solve problems that are too complicated at
first glance.

It allows you to debug really tough bugs and keep moving.

The guy that taught me that trick was a long time COBOL programmer, he took
pity on me after not being able to crack a certain problem and it was like
someone handed me an electric drill after puttering about for years with a
pocket knife.

~~~
danilocampos
What would be an example of a successful application of this approach?

~~~
jacquesm
When faced with a problem too large to solve divide it in to two roughly equal
halves.

Pick the first half of the two and see if you can solve it.

If not recurse with the first half, else solve it.

Now look at the other half and see if you can solve it.

if not recurse with the second half, otherwise solve it.

For debugging it mostly relates to chopping up the program in to bits that are
'verified good' and 'unsure', until you are literally staring at the bug.

Some sort/search algorithms are an almost literal implementation of divide-
and-conquer.

edit: the more I think about this the more I realize that this has pervaded in
to just about everything that I do. I'm currently rebuilding a car that has
crashed and I find I use divide and conquer to troubleshoot and to repair.
Tomorrow I'll be puling the engine to replace a cracked gearbox casing and for
sure I'll use it again, both to remove the engine, to remove and replace the
gearbox and to put the whole thing back together again, one small 'obvious'
step at a time.

edit2: see also: <http://news.ycombinator.com/item?id=1695794>

~~~
varjag
> For debugging it mostly relates to chopping up the program in to bits that
> are 'verified good' and 'unsure', until you are literally staring at the
> bug.

It should be noted there's a whole class of bugs where divide and conquer
simply doesn't work. E.g. about anything with race condition.

Good points otherwise.

~~~
jacquesm
True enough, and interrupt driven programs tend to exhibit very nasty ones as
well where that strategy does not work.

It's not a 100% silver bullet but it will get you quite far.

------
danilocampos
With only four years under my belt, I spend a lot of my time feeling like a
woefully ignorant developer. I was hoping for a little more meat, but the
discussion so far seems mostly common sense.

What should a self-taught programmer know that schooling or tragedy would have
otherwise taught me?

For example, I know there are design patterns for data structures. I've
modeled plenty of data and nothing has ever blown up on me, but I suspect I
could have done it even _better_ with a solid grasp of best practices for data
structures. What should I know about these things?

edit: Also, I owe StackOverflow et al a huge chunk of my success but _damn_
the you're not logged in slidey bar is obnoxious as hell.

~~~
arghnoname
I personally think a strong mathematics background is under-rated, and it is
uncommon for self-taughts to have one (speaking as one with that background).
Of course, even a lot of CS grads don't have the kind of mathematics
background I would espouse.

It's not about the specific mathematical techniques, but the general way of
thinking.

~~~
TamDenholm
Personally I absolutely suck at maths, the only maths I use now is basic
mental arithmetic. I'm also completely self taught, but agree with your
concept that it's a "way of thinking", because I am a very logical person.

Caveat emptor, I'm just a web dev, not a crazy 3d modeller or anything.

~~~
NickPollard
I think a really important thing that many people realise is that Maths is not
just numbers. Arguably most of Computer Science is a kind of Maths, really
Maths is just an abstract notation for describing systems.

For Programmers in particularly, I think Mathematical Functions[1] and Set
theory[2] are some important areas that you should look at.

[1] <http://en.wikipedia.org/wiki/Function_(mathematics)> [2]
<http://en.wikipedia.org/wiki/Set_theory>

------
wccrawford
'Disregarding a bunch of things I don't want to talk about, what do you think
a programmer should know?'

Seriously? You're going to take huge swaths of things off the table to try to
force the discussion the way you want it to go?

~~~
xyzzyz
I'm actually more interested in the parts he chose to ignore, because all the
replies are about things that every programmer learns in his firsts 2-3 years
of work -- so nothing especially insightful, just common field knowledge.

~~~
theycallmemorty
It's plenty insightful when you don't have 2-3 years of experience.

~~~
xyzzyz
I guess HN is not the best place for targeting inexperienced programmers.

~~~
jacquesm
I'm inexperienced in any language that I did not write at least a mid-sized
program in, on every system that I haven't used yet and on every program whose
code is not intimately known to me.

There is 'general' experience that applies equally across the board and that
experience you either have or you don't have it, but for the rest we are all
only as experienced as we are familiar with the tools we use to do our work.

Try switching from your 'favorite language' to one that is your least favorite
and making some headway, versus the 'experienced' (but relative newbie) on
that platform. You won't stand a chance.

Programming computers and computer science has become too large to still be
able to be an 'all-rounder', you can't do all of 'embedded systems', 'web
apps', 'operating system kernels', 'algorithm research' and so on. And if you
can then you're either not human or exaggerating ;)

~~~
xyzzyz
But, generally speaking, you are experienced. What you say is of course true,
but that's what makes the linked article even less interesting. If I wanted to
learn more about new language, new system or new tool, I would rather ask
"what should every _foo_ language programmer know about _foo_ ". The question
posed on stack exchange asks about nothing specific. It's like one asked "what
should everyone know about life?" and got replies "always remeber to brush
your teeth and flush the toliet". Meh.

If HN was the mathematics forum, one would read and comment news about
research in number theory and algebraic topology, not high school math, for it
is not particularly insightful and entertaining.

------
TamDenholm
I think its a classic 80/20 rule. You'll learn 80% of what you need in the
first 20% of your career, the rest is what makes you really really good.

The thing is, the 20% isnt the technical stuff, its everything else.

------
statictype
Learn to simplify. If your code is long, hairy and convoluted, there's
probably a better way to do it.

If the problem itself is long, hairy and convoluted, then redefine the problem
in a different way. ie, come up with a different paradigm for achieving the
same result.

If you find yourself writing a lot of special edge case handlers, then try to
redefine the model to implicitly take care of those edge cases.

None of this is easy, but being aware of it goes a long way towards becoming
better at it.

~~~
arghnoname
I've had this experience. It took me a while before I realized that a decent
chunk of hairy tricky code could be avoided if I just started out with an
appropriate data structure in the first place. Starting with a good data
structure in the first place is almost like starting with the solution for a
surprisingly large amount of problems.

Now, whenever I find myself getting confused I try to think really hard about
where I went wrong. Good code is like good prose. If you have to read it six
times to understand what is happening, the writing sucks.

~~~
eru
Have a look at the data structures in "How to roll your own Window manager"
([http://donsbot.wordpress.com/2007/05/17/roll-your-own-
window...](http://donsbot.wordpress.com/2007/05/17/roll-your-own-window-
manager-tracking-focus-with-a-zipper/)) for a nice example.

------
billswift
Voted up, not because I thought the SO page was interesting or very useful,
but it did have a link to this page,
<http://docs.sun.com/source/806-3568/ncg_goldberg.html> , _What Every Computer
Scientist Should Know About Floating-Point Arithmetic_ , that is well worth
reading.

------
kloc
Found nothing interesting. Its submitted by spolsky, is he looking for traffic
to his website ;) Nothing bad about it though :D

~~~
InclinedPlane
I think he's looking for traffic _and_ for participation. Have a better
suggestion? Post it, you don't even need an account.

~~~
kloc
I was just kidding. I guess was not obvious from couple of smileys. I have a
huge respect the SO folks and blogs they write. Have learned great deal by
just reading there blog. Thanks for downvoting though!!.

~~~
InclinedPlane
'twasn't me, I rarely downvote.

~~~
Locke1689
I think HN may be getting a little more reactionary -- both more quick to
upvote and more quick to downvote. I've noticed that some of my comments get
far more upvotes then they're worth and also some unexplainable downvotes.

This comment(<http://news.ycombinator.com/item?id=1695010>), for example,
seems on-topic but was downvoted pretty quickly.

~~~
InclinedPlane
I've noticed something like that recently, although I hesitate to call it a
trend from just a few observations. I suspect some people upvote/downvote
based on personal feelings alone, or whether they agree/disagree with a post.
I prefer to be a little more disciplined with my voting. I like the way
stackexchange et al works in this regard, where negative votes have a cost to
the voter and voting is rate limited (everyone has a maximum number of votes
per day), this ensures that most voting is taken seriously.

------
bluesnowmonkey
Questions like this degrade the professionalism of the field. Better
programmers than any of us have to tried to cover the topic so generally, and
they still came up with whole books that barely scratched the surface. If you
want to know how to be a programmer, do some tutorials, then go to college for
a few years, then work underneath an experienced professional for a few more
years.

Can you imagine how silly it would sound applied to other fields?

"Hey guys, I decided to be a nuclear engineer/attorney/pilot/paramedic. What
are the main things I need to know? I'll figure out the rest as I go along."

------
eoin_murphy
I was going to reply with a comment. But one of the most Important things to
realise as a programmer is that your program is not unique and most likely
someone smarter has spent longer on crafting a much better solution _. Here's
a full post with a comprehensive answer.

<http://samizdat.mines.edu/howto/HowToBeAProgrammer.html>

_ An even more important requirement is realising when your solution is better
and being able to explain exactly why.

------
amalcon
You didn't get it right the first time. You aren't getting it right this time.
You won't get it right the last time.

Learn when to fix it, when to move on to something else, and when to come
back. This is the hardest part.

Likewise, nobody else ever gets it right. Know when to build, when to borrow
and tweak, and when to steal.

~~~
rikthevik
That sounds like a good statement about life in general.

I keep looking forward to the time I have it all "figured out". As I get
older, I've started to think this never happens.

------
angusgr
What lexing and parsing are, just a vague overview is fine. Better yet,
passing familiarity with at least one parser generator framework.

Most of the most horrid WTFs I've seen is people's custom parsing routines.
Horrible to initially code, worse to maintain.

------
terryjsmith
Understand how computers handle different data types and what their min/max
values are. Someone sent me the following code today (in Javascript):

ord=Math.random()*10000000000000000;

A) It's unnecessary and will get "trimmed" down to 2147483647 on 32-bit
systems. B) Clearly the programmer that wrote this has absolutely no idea that
his number is going to require a 64-bit long int (on applicable systems) just
to generate a random number to make their URL non-cached. What a waste.

</minor rant>

~~~
Erwin
The result of this is a 64-bit double (there are no other numeric data types
in JS and this is the data type regardless of the underlying CPU
architecture). That has just under 16 digits of precision so the above code
will not lose much by multiplying by 10^16 and rounding.

Why would you think this this calculation would get clamped to the range of a
signed 32-bit integer?

------
Locke1689
I wrote this comment
([http://programmers.stackexchange.com/questions/1785/what-
sho...](http://programmers.stackexchange.com/questions/1785/what-should-every-
programmer-know-about-programming/4079#4079)).

I have a lot more advice for systems developers (which can basically be
summarized as "you're never as smart as you think you are -- plan for it") but
I don't think they generalize as much to "all programmers."

------
wrs
Joel, didn't you answer this yourself a long time ago? Pointers and recursion.
(Though I'd add concurrency if you intend to be programming much longer.)

------
ataggart
"Code doesn't exist if it is not checked in Version Control System."

What if it's "checked in" to just another part of the same harddrive (e.g.,
git)?

~~~
silentbicycle
git _is_ a version control system.

That point is about people completely unaware of VCSs.

~~~
bitwize
Git is not yet ready for production use in commercial environments. It's got a
long tough battle ahead if it wants to displace p4 and svn.

------
hendler
Use the right tool for the job.

The programmer is the important element, and the language and tools should be
chosen based on the problem. .

------
ddelony
On writing concurrent programs: Why don't we make the interpreters/compilers
do that automatically?

~~~
Dn_Ab
A simple answer is because its hard. A slightly better answer I think, is that
the current crop of more expressive languages (such as not Fortran and
including functional languages) are harder to analyse and even harder (much
more so) to synthesize in a sufficiently coarse grained manner (parallelized
but now less efficient due to overhead say).

The key is a way of providing non-obtrusive (to the programmer) hints to the
compiler - whether by annotation or the type system or whatever.

------
zephyrfalcon
You are _never_ done learning. (But that is probably true for life in general
as well...)

------
greg_holsclaw
I echo a commenter on the article: Code Complete 2. Read it all, use it all.

------
m3mb3r
"Every single line of code you write will probably solve a problem and will
introduce at least one bug"

I believe that sort of extreme skepticism is helpful in writing solid code and
thinking about unintended consequences.

------
dugmartin
Thinking is more important than typing.

------
c00p3r
The difference between a programmer and a coder.

For example, programmers are talking about ideas, algorithms and abstraction
layers, while coders talking about tools - which one is the right tool (Java,
of course) which one is the best for so-called web-development (PHP, of
course), and about cool features of C# if they're using that system.

The difference is the same as between, say, GM engineer and a taxi driver.

There are also sysadmins, who know that everything sucks, but some things when
fine-tuned suck less. ^_^

