top | item 12297046

The traits of a proficient programmer

305 points| kiyanwang | 9 years ago |oreilly.com | reply

136 comments

order
[+] jcbeard|9 years ago|reply
Probably the most important bit of the entire article, which you can probably get from many self help career books (applies to all, not just programmers): "Ask others to explain why they do things, but don't just accept dogmatic reasoning. Demand examples and inquire about context, so that you can try to imagine what it is like to be in their shoes. Doing this is tremendously valuable because it allows you to see the strengths and weaknesses of ideas in their natural habitats."

One thing I can add is always question. There's a reason kids ask tons of questions, they want to know. Asking questions not only increases your own knowledge, and that of the person answering, but it also creates a culture where complacency is extinct. The one thing I hate more than people that litter are people that say "oh, well, that's the way I've always done it." There's lots more I dislike above that, but...complacency is the death of innovation. Then again, sometimes things just work....but that shouldn't stop you from trying to improve it.

[+] mVChr|9 years ago|reply
This reminds me of the woman who was teaching her daughter to cook a pot roast the way she remembered her mom doing it. You take the meat, cut off four inches from one end and throw that away, put the rest in the pan in the oven at 350 for 3 hours. One holiday when the daughter was hosting grandma came over early to help and saw her cutting the end off the pot roast. She asked why and the daughter said that was how her mom said she did it. "Oh child, I only did that because our pan was too small!"
[+] sbov|9 years ago|reply
Sure. Sometimes. Othertimes, you have to recognize that you aren't an expert, and that the real "why" is beyond your reach. If you're in this situation, you're probably better going with the herd.

I run across this sometimes with my boss. He asks why we do X, can't we do Y? I respond: X is common and a well vetted practice, I don't know the security implications of Y. Then he says: lets use Y unless you can think of a concrete reason not to.

In the meantime, I'm not really qualified to analyze Y in the way X has been analyzed. I would rather stick with X, even if my reason is dogmatic.

[+] zamalek|9 years ago|reply
Dogma is the roadblock to a lot of progress, not only software development.

> Asking questions not only increases your own knowledge

Acknowledgement of being wrong or in doubt is a prerequisite of asking a question. Our current approach to education discourages being wrong - although it is difficult to imagine any other system with the amount of children that need to be educated today.

[+] branchless|9 years ago|reply
but we've always littered, it'll be fine...
[+] yawz|9 years ago|reply
A competent programmer knows that tomatoes are fruits. A proficient programmer doesn't put tomatoes in a fruit salad. :)
[+] syntheticnature|9 years ago|reply
To bring this full circle, "a marketing guy can sell a tomato-based fruit salad."
[+] the_watcher|9 years ago|reply
I like this. It can be applied in a much broader range of professions than just programming, but it's a nice, memorable analogy.
[+] miguelrochefort|9 years ago|reply
Why wouldn't you put tomatoes in a fruit salad?
[+] matthewowen|9 years ago|reply
Fun fact: the US Supreme Court says that for the purposes of trade and commerce, tomatoes are vegetables.
[+] Rexxar|9 years ago|reply
I'm maybe too cynical but I always think the main motivation of such articles is to pretend the author is a very good programmer with the implicit assumption that "if you have an opinion about what make a good programmer, you necessarily should be a very good programmer".
[+] mgrennan|9 years ago|reply
This is where the use of "Older" IT people would help. Take all the new ideas and innervation and filter it through the 60 year old IT guy (Knowledge experts).

Explain your ideas well with examples. Lesson how that problem has been solved before. Don't build new ideas on old code. Find shortcuts to the results.

Don't be naive. Ignorant is better.

Naive is not knowing your don't know.

Ignorant is knowing your don't know.

[+] makmanalp|9 years ago|reply
I've worked with some older folks with a ton of experience (think: programmed in the 80s or earlier) before, and I have huge respect for those folks who can see a disaster coming miles away, or have been around the block enough times to have formed solid opinions on many subjects.

---

Although, while more often than not true (perhaps partly due to survivor bias), I do think that it's not a given that old programmers are wonderful. Some older folks do seem very set in their ways and unwilling to experiment in a way newer programmers aren't.

The natural example is that you hear a lot of "ah it's like <blah> all over again" where blah is something like winforms or activeX or CORBA or lisp or OSGI or what have you, but it's frustrating to come into everything with that baggage.

Yes it might be the same idea, but it might be executed quite a bit better! Perhaps much wider platform support, perhaps lower total cost of ownership, perhaps increased viability under current conditions, perhaps much larger community of people and tools!

The cycle turns much quicker than it used to, and using older, more mature but inferior technology sometimes does have a big effect on the bottom line or provides a disadvantage over competitors in a way that I don't think it did as much earlier on. Granted, this isn't always the case and knowing when it is also matters.

I think "strong opinions loosely held" is a great motto, and a lot of these folks follow that motto to wonderful effect.

---

It is also entirely possible do essentially the same project over and over in a multi-decade long career, and learn nothing material from it all, and I've seen that happen too.

---

In conclusion, I think older programmers can be a great asset to your team, and are often overlooked for no good reason. But they're also people like everyone else.

[+] mgrennan|9 years ago|reply
Yes I'm 60 with deep knowledge.

Electronics, assembler, system / language / application development, data structures and flow design, protocol design, UI design and now working on AI.

[+] Namrog84|9 years ago|reply
I used a simpler analogy in a c++ class I used to teach.

Some people might argue that setting a variable to 0 or something is pointless if you now your about to use it. But while technically it could add overhead. The chance of bugs forming from a future refactor is decreased. And those who track down sporadic uninitialized value bugs should know why it's almost always better to just initialize values. And not implicitly always trust the compiler will catch complain and or a future less knowledged developer won't accidentally do something silly.

Many habits in programming are formed from habits and we're told to not do thibgs(1 entry and 1 exit. No goto. Etc..) but few can back it up with why and when it might be a worthy edge case

[+] ww520|9 years ago|reply
Way back when I went for an interview. That was when Java started to get popular. The interview involved some coding, and I set a variable to 0 at declaration. The interviewer asked me why I did that. I said I know the language already initialized it to 0 but I like to clearly document the init state of the variable so others can have an easier time to understand. He said others should have known the language well enough to know the initial state of a variable. We went back and forth for a few minutes on the importance of code reading and code efficiency. At the end I realized I didn't want to work with people who were so pedantic on minute detail of a language. I later declined the offer, not that it was a good offer anyway.
[+] anarazel|9 years ago|reply
I dislike that for another reason: It prevents the compiler from telling you that you're using an undefined value. Just setting vars to 0 doesn't mean that that's the right value.
[+] raarts|9 years ago|reply
A competent programmer knows variables should be initialized. A proficient programmer always checks if they are when changing code.
[+] monksy|9 years ago|reply
In C++ you're right. The value isn't predefined unless you calloc. In java there are default values. I.e. for an int it's 0 and a string it's an empty string. There is even a Checkstyle violation for this style choice.
[+] okreallywtf|9 years ago|reply
Despite the reception this article seems to be getting here I find it speaks to me pretty directly and summarizes some observations I've been making lately.

I consider myself an intermediate developer (at just under 3 years out of school at my first job) and I feel like for the first year or two I increased my competence rapidly (and with it, salary thankfully) but I'm at a point where without branching out into other areas it will be more difficult to continue acquiring pure competence or I will do so at a flat or decreasing rate because of the increasing complexity of concepts left to improve upon (within my day-to-day work, not including side projects and academic pursuits).

On top of that I work with a small team of other developers who are all highly competent but only some of whom fit the description of proficient developers in the article. I think the article describes really well the differences between the two types, and I have tried to nail down what the proficient developers do and how I can acquire the same skills and instincts they have.

The main things I have noticed are a) as the article discussed, always being able to debate the pros and cons of an approach beyond just best practices and without regurgitating things that renowned developers have espoused and b) being able to be able to drill into problems in the code-base or our process even if its due to technical debt that other competent developers are willing to work around, but more importantly knowing when it is appropriate to down a rabbit hole and when it isn't.

I'm lucky to be able to see the distinction in action and overall I think the article helps to describe a distinction that I haven't been able to verbalize.

[+] mod|9 years ago|reply
> But the place where the intermediate programmer tends to get stuck ... is thinking that the difference between a beginner and an expert can be measured in how much stuff you know.

> And at its essence, proficiency is about "why you do things a certain way"—It's the difference between understanding each of the parts of a problem individually, and understanding how the parts fit into the whole.

So I guess it is about stuff you know.

The article then goes into further specifics about how you have to know when to apply what you know.

[+] adekok|9 years ago|reply
I'm sure everyone has worked with someone who has memorized a lot, but doesn't know how to do much. Their productivity is limited.

There are also people with innate "know how", who can get things done without much background knowledge. They just know how things work.

My $0.02 is that experts have both of the above skills. They know a lot more than average people, and have better techniques for doing things.

My experience has been that once you reach a certain level of expertise, it's better to "know how", than to know things. For the software I've written, I just forget about the minor details, and have to look them up again. The details aren't important, and just aren't worth remembering.

In contrast, remembering the problems and solutions is much more important. The solutions can be applied to multiple problems in a way that simple "memorization of facts" cannot.

[+] TheOtherHobbes|9 years ago|reply
No, it's not about stuff you know.

This was posted recently, but it was so good it's worth repeating:

http://blog.robertelder.org/50-interviews-with-facebook-twit...

The interesting point is the distinction between skill and talent.

Skill is close to competence. You can solve well-defined problems using standard tools and practices.

Talent is close to proficiency. You can not only improvise good solutions for novel problems, but you can also prioritise problems intelligently to achieve strategic goals, because you have a clear view of how the codebase fits into your business or project.

Without talent you can waste a lot of time by picking the wrong tools, or using tools in the wrong ways. Even though your code may be perfectly correct, the solution built with the code can still be completely wrong or useless.

In fact talent is somewhat orthogonal to skill. You can have an untrained version of that overview talent, but it's not so useful if it isn't grounded in skill.

When you have both, you have real proficiency - good code doing the right things to solve the right problems.

[+] CoolGuySteve|9 years ago|reply
A dungeons and dragons player would recognize this as the semantic difference between the "intelligence" and "wisdom" stats.
[+] vonmoltke|9 years ago|reply
I interpret "stuff you know" as easily-recallable facts. Obviously at the highest level view knowledge is what separates a beginner from an expert. Knowledge is much more than "stuff you know", though. It is about understanding why, knowing how to handle non-textbook situations, and knowing where to find the facts you need when you need them.
[+] collyw|9 years ago|reply
I think he is arguing for having depth as well as breadth of knowledge.

Certainly when I am looking at CVs and see every framework under the sun listed when we are looking for a Django dev, I assume they have done the Django tutorial, maybe a little more then moved onto the next framework.

[+] dingdongding|9 years ago|reply
As a programmer I always write code considering if a new guy wants to take over my code, he should be able to understand it and use my code with as little complication as possible. Things should be simple enough that when a new guy takes over your code he can be onboarded soon and doesn't have to ask someone to explain him the magic pattern or secret sauce to under teams code.
[+] horizone|9 years ago|reply
I am some what the opposite. The person that comes after me should be able to read and understand what I wrote without line by line documentation. If they can't, they are not fit for the position. Although, if there is a quirk within the code where something needs to be explained, it will have documentation.
[+] hasenj|9 years ago|reply
What the article describes as "competence" sounds like total incompetence to me.

If you learn a pattern from a book or a class or a blog post, and then you apply it in a project just because "the book said so" you are not a competent programmer.

This might be an artifact of English not being my first language, but I would reverse the definitions.

Proficiency means knowing how to use something.

Competence is knowing how to do something properly, which implies having a deep _understanding_ about what is going on.

That seems to be how people use these terms anyway (regardless of the dictionary definition).

Proficient in jQuery: knows the ins and outs of most jQuery functions and plugins.

Competent in jQuery: non-sensical statement.

Proficient in git: knows most useful commands and arguments.

Competent in git: almost a non-sensical statement.

On the other hand:

Competent front end developer: understands how to develop a web based application UI from scratch without being tied to a specific product domain.

At least that's how I understand these terms.

[+] practicingdev|9 years ago|reply
To me the terms are roughly interchangeable if taken in their general meaning, or at least easy to confuse with one another.

But when I wrote this article, I hinged it off of specific definitions assigned to the terms in the Dreyfus Model, which although not exactly commonplace, is an established bit of literature (for example, Pragmatic Press uses Dreyfus Model to indicate expected skill level for readers of their books)

So I stuck with their definitions and attempted to restate those definitions (informally) in the article.

But I'd be fine with you calling these Thing 1 and Thing 2, as long as they mapped to the definitions provided.

What the article refers to as competence (Thing 1) is something programmers generally recognize as valuable, because it is valuable! Essential, in fact.

What the article refers to as proficiency (Thing 2) is something programmers probably also recognize as valuable, however... many do fall into the trap of thinking this: Thing 2 is what you get from being really good at Thing 1 in many areas.

In truth, Thing 2 is what you get from being halfway decent at Thing 1 in many areas, and then with a view of the bigger picture, getting really good at specific aspects of Thing 1... in the context of your actual work, goals, etc.

In other words, Thing 2 = Thing 1 X TheBiggerPicture.

Now if I were to use my own way of thinking about this... I actually thing of Thing 1 (competence) as tactics, and Thing 2 (proficiency) as strategy.

But I think that could end up leading to an even more confusingly overloaded set of terms.

[+] nimblegorilla|9 years ago|reply
I agree that better terminology would be something like competent and master.
[+] squiguy7|9 years ago|reply
> Patterns, principles, idioms, libraries, language features—these are all tools. But a truly proficient programmer fits the tool to the job, not the other way around.

This isn't a unique statement but many people forget it.

We all have our favorite tools and we criticize others that don't have complete parity. Picking a tool to use is often the hardest part considering there are so many nowadays. It's easy to rule out a hammer when you want to tighten a screw but in order to build a skyscraper you need to start with something.

[+] jwatte|9 years ago|reply
"so many people struggle with high level programming ideas, like design patterns"

That sounds more like the movement from "apprentice" to "journeyman." Is it really expected that professional, experienced programmers should struggle with the appropriate application of known techniques?

[+] foxFive|9 years ago|reply
As a budding programmer I like the ideas here, but I want to take it with a grain of salt and figure it's best to have a wide breadth of knowledge before going deep. Or rather, gain competence before striving for mastery.
[+] awkward_yeti|9 years ago|reply
> Pick a small number of specific skills you're simply good but not great at.

I am struggling with this one since forever, what are the skills-set a programmer should enumerate through ? like how good they can connect to a DB provider ? or how quickly they can set up a web server ? what qualifies as a skill in this context ?

[+] avindroth|9 years ago|reply
This article is way too long and without a proper table of contents. I don't know what's important or not, so at a first glance I could not gauge opportunity costs.

And also lists are meant for small items, not paragraphs.

Readability is respect for the reader.

[+] ovrdrv3|9 years ago|reply
It isn't often that you click on a link to the book referred to and it is the pdf, sweet!
[+] facepalm|9 years ago|reply
Nobody knows everything, so I must admit I don't see the point of the article. Maybe sometimes you get lucky and have the relevant knowledge for seeing the big picture. At other times you won't have that knowledge. Are you proficient?
[+] tooljob|9 years ago|reply
>> But a truly proficient programmer fits the tool to the job, not the other way around.

A truly proficient programmer finds the right tool for the job, learns best practices on how to use that tool; makes mistakes, learns and improves.