If there is something most programmers are missing (at least, I miss it) that’s a mentor, a guy who knows what to say and when to say it.
This is, clearly, a problem and lots of books try (even) to solve it, developing more or less specific subjects with different degrees of analysis.
In his 90 pages book (actually 40, when printed on a pdf), Robert L. Read summarize these subjects in a way he wanted to have them when he was 21.
I strongly suggest you to read his “How to be a programmer“, available under the GNU Free Documentation License.
Here are the most impressive sentences I’ve found:
About improvements
What do you do when you start to run out of low-hanging fruit? Well, you can reach higher, or chop the tree down.
About design
Don’t become dogmatic about particular design styles.
About estimate
There are of course, unknown unknowns, or unk-unks. Unk-unks by definition cannot be estimated individually. You can try to create a global line item for all unk-unks, or handle them in some other way that you communicate to your boss. You cannot, however, let your boss forget that they exist, and it is devilishly easy for an estimate to become a schedule without the unk-unks considered.
About estimate
In a team environment, you should try to have the people who will do the work do the estimate, and you should try to have team-wide consensus on estimates. People vary widely in skill, experience, preparedness, and confidence. Calamity strikes when a strong programmer estimates for herself and then weak programmers are held to this estimate.
About time
The basic rule is that everyone benefits from talking to you a little bit, and the more they talk to you, the less benefit they derive. It is your job to provide them this benefit, and to get the benefit of communicating with them, keeping the benefit in balance with the time spent.
It is important to respect your own time. If talking to someone, even if it will cost them time, will save you a great deal of time, then you should do it unless you think their time is more valuable than yours, to the tribe, by that factor.
About documentation
Life is too short to write crap nobody will read; if you write crap, nobody will read it. Therefore a little good documentation is best. Managers often don’t understand this, because even bad documentation gives them a false sense of security that they are not dependent on their programmers. If someone absolutely insists that you write truly useless documentation, say “yes” and quietly begin looking for a better job.
About documentation
[…] write self-explanatory code and only document code in the places that you cannot make it clear by writing the code itself.
There are two good reasons for this. First, anyone who needs to see code-level documentation will in most cases be able to and prefer to read the code anyway. Admittedly, this seems easier to the experienced programmer than to the beginner. More importantly however, is that the code and the documentation cannot be inconsistent if there is no documentation. The source code can at worst be wrong and confusing. The documentation, if not written perfectly, can lie, and that is a thousand times worse.
About time
Programmers often succumb to this because they are eager to please and not very good at saying no.
There are four defenses against this:
- Communicate as much as possible with everyone in the company so that no one can mislead the executives about what is going on,
- Learn to estimate and schedule defensively and explicitly and give everyone visibility into what the schedule is and where it stands,
- Learn to say no, and say no as a team when necessary, and
- Quit if you have to.
About culture
You can be a good programmer without going to college, but you can’t be a good intermediate programmer without knowing basic computational complexity theory. You don’t need to know “big O” notation, but I personally think you should be able to understand the difference between “constant-time”,”n log n” and “n squared”. You might be able to intuit how to tradeoff time against space without this knowledge, but
in its absence you will not have a firm basis for communicating with your colleagues.
About stress test
The purpose of stress testing is to figure out where the wall is, and then figure out how to move the wall further out.
About abstractness
The final result would have been better if the energy spent on abstraction had been spent on keeping things short and simple.
About learning
When learning a new programming language, try to do a small project it in before you have to do a large project. When learning to manage a software project, try to manage a small one first.
About planning
Make sure you plan includes time for: internal team meetings, demos, documentation, scheduled periodic activities, integration testing, dealing with outsiders, sickness, vacations, maintenance of existing products, and maintenance of the development environment. The project plan can serve as a way to give outsiders or your boss a view into what you or your team is doing. For this reason it should be short and up-to-date.
About meetings
Meetings are sometimes necessary, but smaller is usually better. The quality of communication in small meetings is better, and less time overall is wasted.
About disagreement
Disagreement is a great opportunity to make a good decision, but it should be handled delicately. Hopefully you feel that you have expressed your thoughts adequately and been heard before the decision is made. In that case there is nothing more to say, and you should decide whether you will stand behind the decision even though you disagree with it. If you can support this decision even though you disagree, say so. This shows how valuable you are because you are independent and are not a yes-man, but respectful of the decision and a team player.
About poor code quality
Remember that a good design will be resillient against poor code implementations. If good interfaces and abstractions exist throughout the code, then the eventual rewrites will be far more painless. If it is hard to write clear code that is hard to fix, consider what is wrong with the core design that is causing this.
About software system dependencies
Having the source code for a component decreases the risk by a factor of four. With source code, you can evaluate it easier, debug it easier, find workarounds easier, and make fixes easier. If you make fixes, you should give them to the owner of the component and get the fixes incorporated into an official release; otherwise you will uncomfortably have to maintain an unofficial version.
About software matureness
Here are ten questions you should ask yourself about it:
- Is it vapor? (Promises are very immature).
- Is there an accessible body of lore about the software?
- Are you the first user?
- Is there a strong incentive for continuation?
- Has it had a maintenance effort?
- Will it survive defection of the current maintainers?
- Is there a seasoned alternative at least half as good?
- Is it known to your tribe or company?
- Is it desirable to your tribe or company?
- Can you hire people to work on it even if it is bad?
A little consideration of these criteria demonstrates the great value of well-established free software and open-source software in reducing risk to the entrepreneur.
About the “obtain or build” decision
You should think twice before building something that is big enough to serve as the basis for an entire other business. Such ideas are often proposed by bright and optimistic people that will have a lot to contribute to your team.
About growing professionally
Assume responsibility in excess of your authority. Play the role that you desire. Express appreciation for people’s contribution to the success of the larger organization, as well as things as that help you personally.
About interviewees
Good people want to be hired for their skills, not where they worked last or what school they went to or some other inessential characteristic.
About talking to non-technicals
You should assume that you will miscommunicate and watch carefully to find this miscommunication. Try to get them to summarize or paraphrase what you are saying to make sure they understand. If you have the opportunity to meet with them often, spend a little bit of time asking if you you are communicating effectively, and how you can do it better. If there is a problem in communication, seek to alter your own practices before becoming frustrated with theirs.
About vague requirements
It is impossible to satisfy a vague requirement […] If the requirement can be made more crisp, it will often become merely hard […] If there is not crisp definition of success, you will not succeed.
About pressure
Time-to-market pressure is the pressure to deliver a good product quickly. It is good because it reflects a financial reality, and is healthy up to a point. Schedule pressure is the pressure to deliver something faster than it can be delivered and it is wasteful, unhealthy, and all too common.
About users
The more time you spend with users the better you will be able to understand what will really be successful. You should try to test your ideas against them as much as you can. You should eat and drink with them if you can.
Guy Kawasaki[Rules] has emphasized the importance of watching what your users do in addition to listening to them.
About team
Your greatest responsibility is to your team. You should know each of them well. You should stretch your team, but not overburden them. You should usually talk to them about the way they are being stretched. If they buy in to it, they will be well motivated. On each project, or every other project, try to stretch them in both a way that they suggest and a way that you think will be good for them. Stretch them not by giving them more work, but by giving them a new skill or better yet a new role to play on the team.
You should allow people (including yourself) to fail occasionally and should plan for some failure in your schedule.
[…]
It is an odd fact that is not reflected in salaries that a good programmer is more productive than 10 bad programmers. This creates a strange situation. It will often be true that you could move faster if your weak programmers would just get out of the way. If you did this you would in fact make more progress in the short term. However, your tribe would lose some important benefits, namely the training of the weaker members, the spreading of tribal knowledge, and the ability to recover from the loss of the strong members. The strong must be gentle in this regard and consider the issue from all angles.
About team leading
One of the keys to team leadership is to facilitate consensus so that everyone has buy in. This occasionally means allowing your teammates to be wrong. That is, if it does not harm the project too much, you must let some of your team do things their own way, based on consensus, even if you believe with great confidence it is the wrong thing to do. When this happens, don’t agree, simply disagree openly and accept the consensus. Don’t sound hurt, or like you’re being forced into it, simply state that you disagree but think the consensus of the team is more important. This will often cause them to backtrack. Don’t insist that they go through with their initial plan if they do backtrack.
About boring tasks
Try to find some way to get the computer to do the task for you or to help your teammates do this. Working for a week on a program to do a task that will take a week to do by hand has the great advantage of being more educational and sometimes more repeatable.
About system evolution
It is good to think of software as growing, because it allows us to make useful progress before we have a perfect mental image. We can get feedback from users and use that to correct the growth. Pruning off weak limbs is healthful.
About managers’ myths
For that reason, you should recognize these beliefs as myths:
- More documentation is always better. (They want it, but they don’t want you to spend any time on it.)
- Programmers can be equated. (Programmers vary by an order of magnitude.)
- Resources can be added to a late project to speed it. (The cost of communication with the new persons is almost always more taxing than helpful.)
- It is possible to estimate software development reliably. (It is not even theoretically possible.)
- Programmers’ productivity can be measured in terms of some simple metric, like lines of code. (If succinctness is power, lines of code are bad, not good.)