views:

791

answers:

19

Should all decent programmers be expected to know at least something about low-level stuff such as the following:

  1. The gist of how garbage collection is implemented, how memory management works without GC, and exactly what the difference is between the heap, the stack and the static data segment?
  2. At least be able to read assembly language and have some idea what's going on (I'm not talking about a high level of proficiency here, just familiarity.)
  3. Understand some basic computer architecture concepts such as caching, out-of-order execution, pipelining, etc.
  4. Understand pointer semantics well and be able to write at least small, toy programs in straight C.

My arguments as to why these are essential skills for any decent programmer are as follows:

  1. All abstractions are leaky. If you don't understand at all how the layer beneath you works, you'll usually get burned sooner or later.
  2. IMHO, caring about performance breaks all abstraction/encapsulation. You may be able to get away with not caring how something is implemented if you just want the layer on top of it to be correct, but the minute you need it to be fast, you need to care about the implementation.
  3. Understanding how stuff works at a low level can provide a level of intuition about what is and isn't feasible, therefore making problems at a higher level easier to reason about. For example, if garbage collection is just magic to you, you may have no clue why all that data you've kept references to, but never access again causes memory leaks. However, if you understand that garbage collection works by tracing, not by semantic code analysis, it becomes immediately obvious why keeping references to stuff you don't need would cause memory leaks.

Do you believe that learning low-level stuff is important to all programmers? If so, what and why?

+8  A: 

I think there are a great many fields of programming where ignorance of that low level stuff is not a hinderance.

You can stand on the shoulders of giants, and write an very polished web application with adequate performance in a modern scripting language, without knowing one jot about GC, ASM, pointer arithmetic, pipelining.

If you want super-duper scalability or speed, then you need to be cleverer. But many projects don't.

slim
+6  A: 

Many decent programmers write only web programs, where most items on your list don't apply.

Many decent programmers work on teams of specialists, where responsibility in one area can be passed to someone else.

Many decent programmers program in Excel spreadsheets, where none apply.

Many decent programmers only write administrative scripts.

Many decent programmers spend almost all their time in Oracle or SQL Server or DB2.

This might be written in praise of your classic "Code Cowboy" (and I don't mean that as a put-down.) Maybe if you were referring to "well-rounded general-purpose programmers who program by themselves ..."

There are too many legitimate exceptions for your statement to hold as a generality.

le dorfier
A: 

it is not essential to all programmers (but some people on the team need to know some of it). the trend for most programming today is at the "glue" or "use this api" level. this trend will probably continue.

Ray Tayek
A: 

"Should all decent programmers be expected to know at least something about low-level stuff such as the following:"

No.

All decent programmers should know the business model they are implementing. They should know who their users are, and be intimate with the use cases.

An architect, or senior-level programmer should know technology internals.

IMHO, caring about performance makes abstraction/encapsulation absolutely the single most important thing. If you break the encapsulation boundaries you make optimization nearly impossible.

The principle benefit of encapsulation is that it permits you to replace a version that's slow but uses minimal memory with a version that's fast but uses a lot of memory.

The question of caring about implementation varies with what your programmer is working on.

Programmers that solve real problems can't care about implementations. Architects, on the other hand, must care about implementations. Both are decent programmers.

S.Lott
+11  A: 

It depends if you just want to be a common programmer, or a great programmer. The guys you will look up to will be those who know a lot about how things work, not just how to make them work.

At first glance it would seem that you don't need to know any of this stuff to make great applications, until you find yours goes slow, or doesn't scale, or use all the memory- as you suggested in your question.

As an example: why do you need to lock for as short a time as possible? surely getting a lock, doing some work, unlocking.. then lock+work+unlock again would be really inefficient, far better to get the lock, do all the work, then unlock and your app would go faster and be just as threadsafe.... of course a great programmer would tell you that your app will not scale too well, but you would not know why and you'll make the same mistakes again (or worse - go the opposite and lock every single statement!)

The same applies to everything, what that computer does under the object model you're given is important, you can hide from it, but it won't do you any good in the long run, you might as well become a manager!

gbjbaanb
OP was asking specifically about "all decent programmers".
le dorfier
define decent. I'd say decent ones know their tools but not how they work under the covers.
gbjbaanb
Oh. I didn't realize we get to create our own definitions for "decent". :D Or that SQL programmers, for instance, shouldn't count.
le dorfier
lol, I was thinking of web programmers really, decent lads but they should learn proper programming disciplines :)
gbjbaanb
+3  A: 

Depends whom you ask. According to Ulrich Drepper, here is What every programmer should know about memory

He does not even say "decent", but "every" :)

Nemanja Trifunovic
Should every programmer know how static RAM is implemented in CMOS? Really?
Federico Ramponi
I have to assume Drepper was being tongue in cheek. A decent programmer shouldn't assume anything about the underlying hardware.
slim
Just shows you can find somebody to quote to defend any point of view.
le dorfier
+1  A: 

I know all that stuff and it really hasn't been of benefit to me for numerous years (or maybe it has but not in obvious ways). I write better, more correct software than I ever have and I really haven't had to worry about any of that - when in the past I had.

billybob
A: 

IMHO, caring about performance breaks all abstraction/encapsulation. You may be able to get away with not caring how something is implemented if you just want the layer on top of it to be correct, but the minute you need it to be fast, you need to care about the implementation.

If you mean the data structures and algorithms behind the implementation, I agree with you. If you mean hardware details, I don't fully agree. The more I get involved with Project Euler, the more I understand that the choice of clever algorithms is far more important, with respect to performance, than knowledge of the details of my machine (I refer to P.E. because I'm not a professional programmer).

For example, there is a particular problem which comes in two versions, one of dimension 16 and one of dimension 100 (if I remember). The problem with n=16 is easily solvable both by brute force and with a clever algorithm, but the n=100 problem needs cleverness (or, all in all, common sense). Now, I'm sure that a thorough knowledge of low-level stuff could speed my solution by a factor of 1:100; but the choice of the "right" algorithm makes the difference between using a fraction of a second or 100 years to solve the n=100 problem.

So, if the optimization you're talking about is not "premature" and if you are sure that you have already chosen the right strategy to solve your problem and if you still want to extract the last nanosecond of computation from your program (as is the case for, say, a library that will be used by thousands of people), I agree that hardware matters. Otherwise, in my opinion there are better things to take care of. (But I must admit to be biased in this respect - I am no low-level expert by any means :)

Federico Ramponi
+5  A: 

Over 40 years in the business, I've never seen anyone hurt by knowing too much. (I have seen an occasional senior techie offended by a junior person knowing more than they do.)

That doesn't mean everyone needs to know all the details of OS internals, device drivers, and so on. But then along will come the odd chance when you can solve a problem because you do.

Some examples I can think of from my own experience:

  • A numerical code in a physiological simulation that worked fine except under very special conditions. No one I worked with -- all numerical analysts -- could solve it. I coud read the actual assembly and so determined it was a compiler bug, exercised by the optimizer.
  • Data corruption caused by a device driver that wasn't always swapping bytes to net-canonical order. Only showed up when I started examining the actual network using ethereal.
  • Bad exception handling caused by a bug in the Sun JVM, discovered by reading the C code.
  • Performance problems in Linux disk I/O caused by the scheduler. Read the sources to find it.

So, must you know these details? No, but then you don't have to be a programmer at all. If you're going to be one, why not be a good one?

Charlie Martin
+3  A: 

There are 10 types of programmers. Those who understand binary (ie low level things) and those who don't.

You can make a decent living being a mort type programmer, being unaware of the magic which manages memory for you. But if you want to be an outstanding programmer, you should learn C, understand modern memory collection (and why certain strategies are used ie deterministic or non deterministic collection), understand pointers, understand graph theory etc.

Bob
+2  A: 

My vote is that yes, it's important that all programmers understand these concepts. To ignore how the computer works is like a race car driver ignoring the internals of their car or chefs ignoring the chemistry behind cooking. You may be able to pull off being an amateur without understanding the tools of your trade, but you'll never be great.

commondream
A race car driver knows more about his car than a typical motorist - but nowhere near as much as his team's engineers. Likewise a programmer can defer detailed knowedge of how their platform is implemented, to that platform's authors.
slim
Agreed. I more meant the analogy in terms of the question asked of whether or not it's important for someone to know something about low level stuff. Is it important for the driver to know some? Yes. Is it important for him to know all? No.
commondream
+1 for the great metaphor :)
Botond Balázs
+3  A: 

It just occurred to me that since we only have finite resources for learning and knowing, whenever you choose to extend your skills down the abstraction chain, you're sacrificing an opportunity to extend your skills up or sideways.

Imagine Alice has some somewhat stale web development skills - she knows C, data structures, Perl, HTML and CSS, she knows her way around a TCP sniffer and can debug HTTP dumps. Perhaps she's been out of Web work for a while, so her comfort zone is mod_perl or CGI.

If it's to be one or the other, which benefits her more:

  • down the abstraction chain: IP packets, ethernet packets, ethernet driver code?
  • up the abstraction chain: JQuery, Spring, RoR, whatever?

The answer depends largely on circumstance. A specific problem might prompt her to start delving into IP. But for most people, going up the abstraction chain is the better choice because it will make them more productive in future.

This works both ways. If your speciality is bit twiddling, going up the abstraction chain is probably not going to benefit you as much as going down. The people striving to write a faster Javascript interpreter probably wouldn't benefit from learning RoR.

slim
I picked the web domain because lots of people here on SO are familiar with it. I think the principle applies to many other kinds of software development. There's always a right level of abstraction for you.
slim
A: 

Knowledge is power and having an intimate understanding of every single abstraction you rely upon would be very valuable. However, it's impractical and has no logical end point.

Many specialized fields involve tools/abstractions that leave the practitioner dead in the water when they fail. Doctors can't debug a faulty heart monitor. Mechanics can't repair the internal mechanisms in a faulty torque wrench.

The world is far too complex to expect anyone - even well paid professionals - to be capable of debugging all the abstractions they rely upon.

Thus developers - like all other professional fields - are expected to have competence in their specialty and a general understanding of their abstraction's boundaries. When the abstraction fails, a developer should do the same thing a doctor or mechanic would do:

  1. Test to determine if the issue is outside his/her realm of control.
  2. Consult a professional on the "leaky" abstraction. For developers, this may mean checking documentation for known bugs, consulting peers, hiring a consultant, etc.

Sure, a doctor or mechanic could theoretically learn how to fix their own equipment, but isn't their time better spent honing the skills required in their niche?

Cory House
A: 

I would not say all programmers, but many. If you work with a modern interpreted language, you'll appreciate features such as loose types and garbage collection much more. Moreover, you'll have some idea of what your code is actually doing to any given computer.

At the least, I recommend learning the basics of memory management as well as studying how your kernel of choice manages virtual memory. This can help you write programs in almost any language (i.e. PHP web apps) more efficiently.

I think anyone heavily into PHP/Perl/Python would be interested at getting a look under the hood and understanding some of the innards anyway. A great place to start is examining how they manage memory .. which gives you a better understanding of just how 'expensive' your code is.

I will say this, when hiring a PHP programmer one of my first question is "Have you ever written an extension?" Those who say yes are considered much more than those who say no.

Tim Post
+1  A: 

I think the answer to the question here really depends upon what kind of programmer are we talking about here. Requirements for an programmer in embedded systems are very different from a programmer writing web applications.

I have written assembly programming as well, wherein there are data segments, code segments etc, but does a web application programmer care about it may be not and it is good that he does not know it.

Whereas a programmer for embedded systems cares a lot about memory restrictions. I generally believe in knowing what is important for the project at your hand.

kal
+4  A: 

Keep in mind that someday web programming will be totally different than it is today, Java will be obsolete, PHP will be but a memory, and Ruby will have vanished.

But computers will still use binary, memory management will still be important, threading and contested resources will still be an issue, and on and on... The low-level issues are simply more stable than the high-level issues. Therefore, for longevity in the field, a good grounding in the fundamentals is important. No, you don't use them every day. But those who know less have less flexibility in responding to changes in the market.

Phil
A: 

I don't know. It is easy to say to knowing basic low level stuff is necessary but many developers use a database without knowing the low level stuff of that database.

So why is a database different than memory or the operating system or TCP/IP?

tuinstoel
Well, databases are more domain-specific than memory management. If you do database aps, then yes, you should know at least something about the way databases are implemented. If not, well then that's not your domain.
dsimcha
This thread is about knowing some basic low-level stuff, not about knowing at least something about the way something is implemented.
tuinstoel
+1  A: 

For great programmers, yes. You cannot really master the field of programming without having a good grip on the lower levels. (Of course, there is plenty of room for good or even competent programmers who don't know the lower level knowledge.)

A consequence of this is that fluency in C (not C++) is a requirement for any programmer aspiring to master the field. C is the lingua franca of computer science.

JesperE
A: 

It depends a little on which environment they will be working I think. To answer each point a bit more directly:

1) There may be some programmers who know nothing about GC because they don't use it in their field and when they went to school this wasn't a popular thing to teach perhaps. Additionally, there may be some programmers dealing with databases and using T-SQL which doesn't really lend itself to looking at stacks and heaps I think.

2) Once again, if the developer is working within a limited context of say a database or within a specific object model where classic ASP working with COM+ comes to mind and the programmer is doing web pages then assembly isn't necessarily worth having a familiarity.

3) This makes some sense though once again what level of these are worth understanding. I have a vague idea of what out-of-order execution is but I haven't found it necessary to get down to that level of what a CPU does in modern systems. Caching is an excellent example of a term where there may be various levels to it, e.g. at a database level, application level, machine level, where each may vary somewhat. Pipelining would be another term that I don't really know except where in the systems I'm using have them.

4) Pointer semantics, while useful in many programming areas, may not mean much to someone that codes in languages where this isn't something that one can use, e.g. within Visual Basic or even Visual Basic .Net. There are many languages derived off of C where pointer semantics are probably more common to see on some level.

I'll agree that most decent programmers would have visited each of the 4 areas you list so that there is some exposure there, but I wouldn't imply that every decent programmer knows all 4 of those areas.

JB King