A willingness to admit when they don’t know things. This is a surprisingly hard thing to do. Removing your own ego from things helps a lot in ways that are hard to communicate.
As much as we’d like to think this is true, one of the best programmers I know is also the least likely to admit when they don’t know something. Being good at programming is their skill, and their skill is why people care about them. Hence, admitting they don’t know something is not something that comes naturally to them.
I think it’s more true to say that programmers are generally nice. But I’ve found a surprising number of counterexamples.
Have encountered that too. However even those reluctant to admit mistakes, lapse of knowledge or misconceptions to colleagues/public/management do seem to quietly note that for themselves. Doubling down on your mistakes doesn’t get one very far in the trade perhaps.
My personal rule of thumb is to not be lazy and instead of saying I don’t know, I go and learn. That works as long as there’s no urgency or risk. But if learning is not an option, one should of course never pretend to know.
My rule of thumb is similar except I modify it to say: “I don’t know, let’s find out.” And then bring the other person along with me while I learn about the subject.
The same way you get good at anything: practice, don’t give up when you fail, power through when the going is tough or boring, and continually try to improve yourself (i.e. don’t stagnate).
To explain a bit: ten years ago I was visiting an old friend. My friend & I had worked together a couple gigs earlier, and indeed, my friend had also worked with one of my colleague’s I had just then, back when the both of them had been in the Bay Area ten years earlier yet. And my friend asks, “So, does [your colleague] still write comments the way he used to?” I wasn’t quite sure what he meant, and so my friend went on to explain how, somewhere in the heart of this video-streaming in the 90s C++ codebase, he came across a multi-paragraph comment explaining a single, critical line. (It was in a signal handler for illegal CPU instructions…and updated a memory address in the code to a NOP when some matrix operation wasn’t available on the CPU.)
And I’ve always thought that’s a sweet story, that you might remember a colleague’s work ten years later, not just for the elegance of it, but for the time taken to explain it. Indeed, this particular colleague (his name’s Jeff) remains the best teacher I ever had in the trade, and probably the best programmer I’ve worked with, too. This wasn’t just because of his generosity – he was pragmatic, had abundant experience, and was almost inexhaustibly optimistic. But, I think generosity was the key. Eventually he just kept a sign on his desk that said “interrupt me,” so people knew he was available to talk and to hear what you had to say.
The ability to envision an output and given certain inputs and constraints be capable of building a system that meets the requirements. Computer programmers use computers so concepts related to that, i.e beautiful code, encapsulation and modularity, DRY, deadlines, extensibility, hardware management, etc. are all just constraints.
The only way become a better computer programmer is by writing more programs and reading the code of programmers better than yourself.
Read, program, read, program. I’m not there yet but I suspect it ends when you die or become a manager.
Paul Erdos didn’t make a difference between those. Reportedly, about those who stopped doing math he said they had “died”, but those who wouldn’t have stopped if they were still alive had “left”.
To add onto the other great answers: a great programmer is one who documents their code, the architecture it fits into, and the requirements it fulfills. Uses autogenerated documentation where possible to keep code and docs in sync. Documents why the code is doing what it is doing, and generally not what the code is doing. Good documentation is the core of being able to interact productively with other team members, because it means you have the skill to explain your piece of the project and the discipline to keep that information up to date.
There is an incredible amount of answers that are all valid for this question but I’ll try and share a few that I find important:
Being a good communicator is invaluable. You have to be able to share your thoughts both verbally and in writing while being receptive to others. Knowing how to ensure that others understand you makes a lot of programming much simpler.
Having a desire to always be learning keeps you current and allows you to apply new ideas to things you already know. Plus, it will help alleviate feelings of burnout if you get stuck doing the same type of work for a long period.
The ability to think abstractly will transform ideas into software. When you can break a problem into discrete parts, it makes it much more approachable for you and your team.
It is important to know that you will fail from time to time. You can do everything in your mind to avoid failing but it is inevitable. Not repeating history is what matters most in these types of situations. You will automatically be a better programmer and person if you see the bright side of the failure.
Remember the human element to programming. Be gracious when critiquing others and look forward to getting help.
It may be a truism, but good programmers do not really differ from good engineers:
being reliable, owning matters/subjects that have been entrusted to them or that they started on their own,
communicating in a clear and accurate fashion, be it talk, mail, doc, design, code,
dealing with mundane tasks that have to be done without grimacing,
easily decomposing bigger concepts or tasks into smaller ones,
finding root causes of issues methodically, but often having good intuition to significantly speed up the process,
having exploratory and open mind, always willing to learn something,
openly admitting failures when they happen, learning from them, and not letting same kind of failures to repeat,
persevering when necessary, but also not caring too much about less important matters,
planning appropriately work that needs to be done, thus being able to detect inadequate resources (knowledge, manpower, time) early on if there are constraints that cannot be lifted,
understanding how to cut corners if needed to deliver, but also fixing technical debt afterwards.
How to improve? Practice.
Do. Fail. Learn. Repeat.
Communication is more important than people tend to think (as in, programmer stereotypes). This means writing code that’s clear and not clever, writing comments to clarify where the language’s expressiveness falls short or anything which isn’t immediately obvious from the code. It also means writing clear commit messages, so that if someone needs to go investigate why something was done, the commit tells you everything. So not just “fix ticket 1234” but also explain in a high-level what the changes you made do and why, including any pitfalls or possible points of improvement. Documentation is important too, but very hard to keep up to date.
There are, and I have worked with, insanely “good programmers” in the sense that they can make a computer do anything, but good luck trying to maintain their code. I would definitely not give those guys commit access to my open source projects because the code would be a mess in no time. I’m sure I’ve written code like that occasionally and I am sorry for the people who have to maintain it.
Aside from that, technical skills are very important: Knowing about security, performance characteristics (preferably down to the metal) and having a good sense when things could or should be done different are important as well. So know when you might need a better algorithm or need to restructure the code instead of plodding on with the current approach.
Reading and understanding code well enough to make big changes to it without breaking shit is also a very important skill to have. You will typically be working much more on existing code bases than writing brand new code over your career.
Many of the softer skills you can learn by working with great programmers and picking up their good habits. You’ll notice this when working on something; and also bad habits will start to irritate you when you’re for example trying to debug other people’s code and need to find out why something was done a certain way. Also listen to other people’s complaints about things you did and take them to heart.
The technical skills are relatively easy. Find great textbooks and read them. Try to keep in mind what your weak spots are and improve them (or try to pick a niche that suits your skills better; no sense in banging your head against a brick wall). Take an interest in the craft and have side projects (or try to pick a challenging day job, but that’s much rarer), and read things like lobste.rs :)
Communication is so important. If you don’t want to be treated like a code-monkey, make sure to talk to the business people too! By understanding their problems and how they think, it will help building a rapport and also make sure that the decisions they take are informed by the engineers.
A few times in my career I was able to either re-scope or prevent projects that wouldn’t solve the original problem the business people were having. For some reason they had already zoomed into a solution instead of leaving that part of the job to the engineers.
At that moment I was suddenly a 1000x engineer :-D
Ah yes, absolutely. Knowing when not to code, and when to escalate up the hierarchy to avoid getting bogged down in something that is going to cost too much money or make the product strictly worse is a very important skill to have as well. Also, being able to articulate why something is going to take a lot of time or why it is hard is useful as well. When it takes less time or is easy, that’s rarely an issue :)
In general, the ability to think in the big picture as well as being able to sweat the details (and not unnecessarily bore the business folks with those).
An eagerness to learn. Trends in software and frameworks come and go. Interesting technologies will pop up. It’s not just an eagerness to “keep up”, it’s an eagerness to expand your toolbox with new tricks, techniques, and paradigms.
Just a note that the diverse answers and responses to this question point to the question being insufficiently specific or bounded. I find it abhorrent to consider programmers who can not be friendly or have an ability to consider when they don’t know something or are wrong, but i realised that caring about this is only relevant to some subset of work environments.
So probably this point needs a bunch of broad categories where different styles of programmers are acceptable/beneficial.
Iirc some big telecom company ran a study on what good engineers do differently from their less productive peers, and the one thing that stood out was that they communicated well. Unfortunately, I’ve lost the reference to this study so if someone knows what I’m on about, please comment so I can find it again.
Other than that, I personally value when people can break down problems into a common set of sensible abstractions, and generalise across non-obvious relations.
But then as others have said, putting emotion aside and evaluating things objectively is also a very useful skill.
I could list a lot more, but those are the three biggest ones for me, I think.
Perhaps I should write an article distilling my ideas concerning this.
A good programmer is likely going to be a hacker (not a cracker). A hacker is someone with a nice sense of aesthetics and creativity, as two qualities. A hacker is going to implement software he designed himself, likely for his own use. You can be a good programmer, just writing the same things others do, with libraries others wrote, and other such things, but I’d be inclined to classify that as average, rather than good, which I’m considering above average.
A hacker is probably going to design and implement libraries for his own purposes, rather than reuse something someone else wrote, but this is debatable. A hacker should have a genuine interest in the topic, so a hacker is likely going to know a wide variety of languages, learning more as mastery of one is achieved. I’d be inclined to argue a hacker will work with languages such as Lisp, APL, and machine codes more than Go, C++, and Java; note that the former group is filled with variety, whereas the latter group is roughly the same language.
You can be a hacker in isolation, but a hacker is likely going to have some manner of home group of sorts. A hacker probably spends all or most errant thought mulling over the topics of interest. If you’re a programmer just for your job and you don’t think of it much or at all outside, then you can be an average programmer, but not a hacker.
Tying in with the creativity and whatnot mentioned earlier, a hacker is going to create novel things and be interested with potentially obscure things. I’m a hacker and I have a tiny little esoteric language and work with CHIP-8 a good amount; I work on a novel machine code development tool I’ve designed. This isn’t boasting, but merely examples.
As you can guess, I’ve described a good bit of myself in this message. I won’t claim to have distilled the essence of being a hacker in this message and probably not in any articles I write about it, either, but I do believe this is at least a good general idea. If you’ve not done so, you could bother RMS with this question. That’s all.
In my opinion, the single most important trait that a good programmer has is that they don’t give a shit what anyone in this thread says. If you are a legit programmer, you are very unlikely to care about whether you fit into any of the buckets listed here. You know you’re good, and you know it’s a waste of time to worry about any of this.
That, I think, is the single trait that all good programmers share. They waste no time in worrying whether they’re good enough.
The way to cultivate that skill is simply to do a lot of programming for the sake of programming. Don’t worry about making a career of it; do it for fun.
A willingness to admit when they don’t know things. This is a surprisingly hard thing to do. Removing your own ego from things helps a lot in ways that are hard to communicate.
As much as we’d like to think this is true, one of the best programmers I know is also the least likely to admit when they don’t know something. Being good at programming is their skill, and their skill is why people care about them. Hence, admitting they don’t know something is not something that comes naturally to them.
I think it’s more true to say that programmers are generally nice. But I’ve found a surprising number of counterexamples.
Have encountered that too. However even those reluctant to admit mistakes, lapse of knowledge or misconceptions to colleagues/public/management do seem to quietly note that for themselves. Doubling down on your mistakes doesn’t get one very far in the trade perhaps.
My personal rule of thumb is to not be lazy and instead of saying I don’t know, I go and learn. That works as long as there’s no urgency or risk. But if learning is not an option, one should of course never pretend to know.
My rule of thumb is similar except I modify it to say: “I don’t know, let’s find out.” And then bring the other person along with me while I learn about the subject.
The same way you get good at anything: practice, don’t give up when you fail, power through when the going is tough or boring, and continually try to improve yourself (i.e. don’t stagnate).
Intellectual generosity.
To explain a bit: ten years ago I was visiting an old friend. My friend & I had worked together a couple gigs earlier, and indeed, my friend had also worked with one of my colleague’s I had just then, back when the both of them had been in the Bay Area ten years earlier yet. And my friend asks, “So, does [your colleague] still write comments the way he used to?” I wasn’t quite sure what he meant, and so my friend went on to explain how, somewhere in the heart of this video-streaming in the 90s C++ codebase, he came across a multi-paragraph comment explaining a single, critical line. (It was in a signal handler for illegal CPU instructions…and updated a memory address in the code to a NOP when some matrix operation wasn’t available on the CPU.)
And I’ve always thought that’s a sweet story, that you might remember a colleague’s work ten years later, not just for the elegance of it, but for the time taken to explain it. Indeed, this particular colleague (his name’s Jeff) remains the best teacher I ever had in the trade, and probably the best programmer I’ve worked with, too. This wasn’t just because of his generosity – he was pragmatic, had abundant experience, and was almost inexhaustibly optimistic. But, I think generosity was the key. Eventually he just kept a sign on his desk that said “interrupt me,” so people knew he was available to talk and to hear what you had to say.
The ability to envision an output and given certain inputs and constraints be capable of building a system that meets the requirements. Computer programmers use computers so concepts related to that, i.e beautiful code, encapsulation and modularity, DRY, deadlines, extensibility, hardware management, etc. are all just constraints.
The only way become a better computer programmer is by writing more programs and reading the code of programmers better than yourself.
Read, program, read, program. I’m not there yet but I suspect it ends when you die or become a manager.
Paul Erdos didn’t make a difference between those. Reportedly, about those who stopped doing math he said they had “died”, but those who wouldn’t have stopped if they were still alive had “left”.
To add onto the other great answers: a great programmer is one who documents their code, the architecture it fits into, and the requirements it fulfills. Uses autogenerated documentation where possible to keep code and docs in sync. Documents why the code is doing what it is doing, and generally not what the code is doing. Good documentation is the core of being able to interact productively with other team members, because it means you have the skill to explain your piece of the project and the discipline to keep that information up to date.
There is an incredible amount of answers that are all valid for this question but I’ll try and share a few that I find important:
I would say the best programmers:
Working on any of those should help :).
For team programming you can also add some things like teamwork and communication.
How does one, become intelligent (asking for a friend)
I haven’t figured it out yet.
Practice and diligence, like anything. Grit matters more than anything.
Oh, and humility. Nothing is simple :)
It may be a truism, but good programmers do not really differ from good engineers:
How to improve? Practice.
Do. Fail. Learn. Repeat.
Communication is more important than people tend to think (as in, programmer stereotypes). This means writing code that’s clear and not clever, writing comments to clarify where the language’s expressiveness falls short or anything which isn’t immediately obvious from the code. It also means writing clear commit messages, so that if someone needs to go investigate why something was done, the commit tells you everything. So not just “fix ticket 1234” but also explain in a high-level what the changes you made do and why, including any pitfalls or possible points of improvement. Documentation is important too, but very hard to keep up to date.
There are, and I have worked with, insanely “good programmers” in the sense that they can make a computer do anything, but good luck trying to maintain their code. I would definitely not give those guys commit access to my open source projects because the code would be a mess in no time. I’m sure I’ve written code like that occasionally and I am sorry for the people who have to maintain it.
Aside from that, technical skills are very important: Knowing about security, performance characteristics (preferably down to the metal) and having a good sense when things could or should be done different are important as well. So know when you might need a better algorithm or need to restructure the code instead of plodding on with the current approach.
Reading and understanding code well enough to make big changes to it without breaking shit is also a very important skill to have. You will typically be working much more on existing code bases than writing brand new code over your career.
Many of the softer skills you can learn by working with great programmers and picking up their good habits. You’ll notice this when working on something; and also bad habits will start to irritate you when you’re for example trying to debug other people’s code and need to find out why something was done a certain way. Also listen to other people’s complaints about things you did and take them to heart.
The technical skills are relatively easy. Find great textbooks and read them. Try to keep in mind what your weak spots are and improve them (or try to pick a niche that suits your skills better; no sense in banging your head against a brick wall). Take an interest in the craft and have side projects (or try to pick a challenging day job, but that’s much rarer), and read things like lobste.rs :)
Communication is so important. If you don’t want to be treated like a code-monkey, make sure to talk to the business people too! By understanding their problems and how they think, it will help building a rapport and also make sure that the decisions they take are informed by the engineers.
A few times in my career I was able to either re-scope or prevent projects that wouldn’t solve the original problem the business people were having. For some reason they had already zoomed into a solution instead of leaving that part of the job to the engineers.
At that moment I was suddenly a 1000x engineer :-D
Ah yes, absolutely. Knowing when not to code, and when to escalate up the hierarchy to avoid getting bogged down in something that is going to cost too much money or make the product strictly worse is a very important skill to have as well. Also, being able to articulate why something is going to take a lot of time or why it is hard is useful as well. When it takes less time or is easy, that’s rarely an issue :)
In general, the ability to think in the big picture as well as being able to sweat the details (and not unnecessarily bore the business folks with those).
Finishing tasks, taking responsibility over their code, testing their code, and the ability to create good commit messages.
An eagerness to learn. Trends in software and frameworks come and go. Interesting technologies will pop up. It’s not just an eagerness to “keep up”, it’s an eagerness to expand your toolbox with new tricks, techniques, and paradigms.
An interest for learning concepts and principles rather than tools and tips. An attitude for questioning common wisdom.
Output
Just a note that the diverse answers and responses to this question point to the question being insufficiently specific or bounded. I find it abhorrent to consider programmers who can not be friendly or have an ability to consider when they don’t know something or are wrong, but i realised that caring about this is only relevant to some subset of work environments.
So probably this point needs a bunch of broad categories where different styles of programmers are acceptable/beneficial.
Iirc some big telecom company ran a study on what good engineers do differently from their less productive peers, and the one thing that stood out was that they communicated well. Unfortunately, I’ve lost the reference to this study so if someone knows what I’m on about, please comment so I can find it again.
Other than that, I personally value when people can break down problems into a common set of sensible abstractions, and generalise across non-obvious relations.
But then as others have said, putting emotion aside and evaluating things objectively is also a very useful skill.
I could list a lot more, but those are the three biggest ones for me, I think.
Perhaps I should write an article distilling my ideas concerning this.
A good programmer is likely going to be a hacker (not a cracker). A hacker is someone with a nice sense of aesthetics and creativity, as two qualities. A hacker is going to implement software he designed himself, likely for his own use. You can be a good programmer, just writing the same things others do, with libraries others wrote, and other such things, but I’d be inclined to classify that as average, rather than good, which I’m considering above average.
A hacker is probably going to design and implement libraries for his own purposes, rather than reuse something someone else wrote, but this is debatable. A hacker should have a genuine interest in the topic, so a hacker is likely going to know a wide variety of languages, learning more as mastery of one is achieved. I’d be inclined to argue a hacker will work with languages such as Lisp, APL, and machine codes more than Go, C++, and Java; note that the former group is filled with variety, whereas the latter group is roughly the same language.
You can be a hacker in isolation, but a hacker is likely going to have some manner of home group of sorts. A hacker probably spends all or most errant thought mulling over the topics of interest. If you’re a programmer just for your job and you don’t think of it much or at all outside, then you can be an average programmer, but not a hacker.
Tying in with the creativity and whatnot mentioned earlier, a hacker is going to create novel things and be interested with potentially obscure things. I’m a hacker and I have a tiny little esoteric language and work with CHIP-8 a good amount; I work on a novel machine code development tool I’ve designed. This isn’t boasting, but merely examples.
As you can guess, I’ve described a good bit of myself in this message. I won’t claim to have distilled the essence of being a hacker in this message and probably not in any articles I write about it, either, but I do believe this is at least a good general idea. If you’ve not done so, you could bother RMS with this question. That’s all.
In my opinion, the single most important trait that a good programmer has is that they don’t give a shit what anyone in this thread says. If you are a legit programmer, you are very unlikely to care about whether you fit into any of the buckets listed here. You know you’re good, and you know it’s a waste of time to worry about any of this.
That, I think, is the single trait that all good programmers share. They waste no time in worrying whether they’re good enough.
The way to cultivate that skill is simply to do a lot of programming for the sake of programming. Don’t worry about making a career of it; do it for fun.