What Makes Great Programmers Different?
drdobbs.com
drdobbs.com
All of the very best programmers I know work incredibly hard and never allow a massive boring task to derail them. It's an interesting combination of confidence ("I can solve this insanely hard problem") and humility ("I am not above doing this crappy work").
Sometimes the solution is to automate the boring stuff; other times it's literally just getting through days of grunt work. The very best programmers I know are willing to do both, and know when to do which.
The reality is that different people have varying strengths and weaknesses for specific tasks; people have different rates of personal development in different areas. It is not a matter of "good programmer" vs "bad programmer"; it is a matter of "That person can do that task in a better way than I can" or "That person can do that task more efficiently than I can" by some perceived measure of "better" and "efficient". The comparisons between people are relative, not absolute, and divided across many kinds of traits.
However, this article does bring up a number of traits that many of us can probably agree with as "goals to achieve in personal development". For that, it has great conversation value. Personally, I like the notion that memory might be correlated to some quality of design and output.
If I were to pick a trait of importance for a programmer, it would be "Consistently improves bottom line growth." Things that factor into that might be "Writes maintainable code" and "Knows his tools well", but it is debatable that these subtraits have a clear correlation with "bottom line growth". Has anyone actually measured these things?
1-A serious amount of fucks are given both via attention to detail, polish, and no corners are cut. I have been lazy comparatively and often accepted "good enough." I'm working on changing this so that my priority is what is awesome for the user, not easiest for me to implement.
2-At the micro level, before setting out with any new technology, he tests its properties thoroughly. For example, benchmarking each part of the setup on its most intensive tasks before building with it. No "assuming it will work" based on breathless blog posts. Using his intuitive sense of what is expensive, he also optimizes expensive operations in loops by hand (like mysql complex queries).
3-A well thought out, and well practiced tool-chain for development. Ex: Using vim and knows it well, pays for tools to make life easier, has easy backups with time machine to easily go back, etc.
4-Diverse range of skill, and eagerness to dive into something new at any point.
5-An ability to rapidly debug problems. I haven't pieced together how this skill is built, except it involves the usual logic combined with a better memory than mine (so remembering what to rule out) and a pattern recognition that comes from remembering similar problems.
Point 5 is something my former manager once told me. He'd done RoboGames or something like that as a grad student, and he found that invariably, the teams that won were the ones who had built the best debugging infrastructure into their robot, so that when it didn't behave as expected, they knew exactly what was wrong.
This is as much a property of the program as of the programmer. The best programs usually have debug information built into the structure of the program itself, along with an easy UI for viewing that debug info so you don't have to stare at log lines all day. Once a couple programmers start doing this and everyone else realizes how much time it saves, it becomes part of the culture of the organization, and everybody starts designing programs with an eye toward "Will I be able to figure out what's wrong if this doesn't work?"
I was able to improve my own skill in the matter with the "Learn to Debug" section in the "How to be a Programmer Book": http://samizdat.mines.edu/howto/HowToBeAProgrammer.html
On point 5, thing is as a programmer (any career actually) with years of code experience, you just know the possible cause for any bug, and what function/class is at fault.
I've been able to debug more effectively than my coding skill level would imply by dint of my better recall ability.
I tend to think that being great can be a relative term as well. There's different needs. A great programmer who is a genius at coming up with innovations can't always focus to actually get any real work done. A programmer who isn't very creative may plow through tasks like a steamroller. One may be great at intuitive designs, another is great at hard-core algorithms. Which one is the greatest? Depends on what job they're supposed to be doing. Of course a terrible programmer can wreck any of these scenarios.
In other words, there really are no great programmers, there is only great programming.
I actually agree to some degree. Though it could definitely said that it's easier(less time & struggle) for some to create great programs than it is for others.
My entire life as a programmer has been about consistent and constant improvement. A little bit of improvement every day, every project. Committing to the craft(reading, exploring new langs/tools) will definitely allow you to create better and better code as the years go by.
This is very high praise.
I think the difference between his categorization of "Good programmers" and its subcategory of "Really good programmers" is the more interesting one though. Too many programmers seem to lack (or have lost) that drive to continually improve themselves, having become content with treating programming as nothing more than a 9-to-5 job during which they do little more than apply past knowledge. Like the article states, doing this puts them "at risk of slipping into the lower grouping by letting their skills atrophy".
The "Really good programmers" on the other hand are the ones with drive, with motivation; the ones that at least aspire for greatness even if they might stall out at merely being "very good". Every great programmer was once just a "Really good programmer", but you can't go from good to great without that passion.
I've run across a fair number of the 9-5 guys who used to be really good/good & use that as motivation to never allow it to happen to me. Always gotta push forward.
When I see code execute I almost unconsciously understand what the code is doing at a procedural and sometimes assembly level, as well as what it is doing at an architectural level. It's the skill you need if you are going to work on intentionally undocumented code. It means when I encounter a bug, I know what construct I'm looking for: "ah, yes, there it is." When I architect something it is as simple as it needs to be to do the right thing and I don't have to put any extra effort in to have it communicate meaning through structure. My challenge is to provide guide posts to other programmers coming later to help them swap between those levels, because I don't need them myself, or do what I do now and work with other people who's minds also work this way. If I come back to code I wrote five years ago I still grasp exactly what is going on, and the chances are pretty good I remember the exact code.
I'm still not one of the greatest programmers I know, though. Those can both simultaneously consider multiple levels of abstraction and leave that aside to consider tiny pieces. I can sit down and carve away marble to leave a program; they can sit down and merge tiny chips of marble into something that looks exactly like I would have created out of whole cloth.
For them, unit testing is easy. For me it is challenging and a necessary chore.
On the other hand, at least 40% of my job doesn't benefit from this, mostly because of missing tools. Moving into CMake was fantastic, because finally I could apply the same approach to release engineering I applied to writing code. There are definitely roles for which this is massive overkill, and lots of people who work this way spend all their time building tools to support it rather than producing software used by consumers.
It is worthwhile to note that Steve, Linus, Feynmann (last one in physics, not coding) all belong to this category. These are the people who do programming (or whatever else they like) for their own pleasure - to derive fun out of. They are unafraid to challenge the status quo - and they are exactly the ones who cause disruptive changes in the world.
If at all, the slowness with which their reputation is dying makes me happy - because though they are capable of having highest success rate in creating start ups, unfortunately not all of them will succeed in building their own company. And it will be a sad world if these people are not allowed in established companies to make the changes that can swing the world in the organization's favor.
If you inherit a program from some other maintainer, there is a learning curve no matter what. A good programmer quickly learns how it's put together and plays the field they're on.
There is always a learning curve when taking over a project.
Nobody has an innately poor memory unless they've received egregious brain damage.
This isn't that surprising: different people do different things, and their ideal programmer is relative to what they do. Somebody more business oriented would value more maintainable software and good team-working; a hacker type would value "getting things done" and "worse is better"; a more academic type would value novel and nontrivial work. Of course, in reality, what different people value is more nuanced, but the core point remains: there is no single definition of greatness.
- Their code is large, messy and bug-laden
- They have very superficial knowledge of their problem domain and their tools
- Their code has a lot of copy and paste, and they have very little interest in techniques that reduce it
- They fail to account for edge cases while inefficiently dealing with the general case
- They're always rushing around putting out fires, trying to look like heroes battling vast problems against impossible odds
- They never have time to comment their code or break it into smaller pieces
- Empirical evidence plays no role in their decisions
It would be hard to self-test, but some clues would be: do you think you're the best programmer in the world? Do you find code with a lot of functions messier and harder to understand than code with only a few large functions? Do you routinely copy code from one place to another and make a few small changes to it? Do your programs tend to be a few huge files or lots of small files? When you're asked to make a change, do you usually have to touch most of the code or just a small chunk of it? If you say 'yes' to most of these, you're probably bad. If not, you're probably alright. :)
Another clue is to go read the CodeSOD articles at The Daily WTF[1]. If you find them funny or horrifying, you're probably alright. If you don't understand what makes them terrible, you're probably bad.
There are known knowns, known unknowns, and unknown unknowns. The problem with really bad programmers, is that the unknown unknowns for them are really large... so they have no ability to gauge just how incompetent they are.
If someone is trying to improve themselves they are at least "not bad". And probably will be good/great some day.
I would not refer to this as "memory", but as understanding. Memory is of course involved in understanding, but it is not sufficient for it, and does not by itself enable the ability to shift.
Many other fields have been so heavily regulated by government that truly pushing the boundaries is either far more painful or impossible, therefore the pace of improvement in them is far slower than it is in the world of software.