I recently picked up a copy of The Clean Coder: An excellent book about the non-technical aspects of being a senior software engineer.
Below are my notes taken while reading the book.
Management sometimes doesn’t view software engineers as professionals in the same way, for example, they treat lawyers as professionals.
In this situation management is likely to babysit the engineers, micromanage them, and be more prone to asking them to sacrifice their personal lives for the current project.
As an engineer this situation is undesirable. This book intends to show you how to present yourself and interact as a professional.
Specifically:
“Upon reflection I realized that shipping without testing the routine had been irresponsible. The reason I neglected the test was so I could say I had shipped on time. It was about me saving face. I had not been concerned about the customer, nor about my employer. I had only been concerned about my own reputation.”
“I should have taken responsibility early and told Tom that the tests weren’t complete and that I was not prepared to ship the software on time. That would have been hard, and Tom would have been upset. But no customers would have lost data, and no service managers would have called.”
It is the lot of a professional to be accountable for errors even though errors are virtually certain. Practice apologizing.
Apologies are necessary but insufficient. As you mature, your error rate should rapidly decrease toward the asymptote of zero.
QA should find nothing.
If a bug reaches QA, figure out why those bugs managed to escape your notice and do something to prevent it from happening again.
Every time QA, or worse a user, finds a problem, you should be surprised, chagrined, and determined to prevent it from happening again.
100% line coverage is a minimum bar of quality, in the opinion of Robert C. Martin.
Merciless refactoring: Every time you look at a module you make small, lightweight changes to it to improve its structure.
Train yourself outside of work. For your career.
Train your juniors! The best way to learn is to teach.
Know your business domain well enough to be able to recognize and challenge specification errors.
Stick to your guns RE schedule estimates. Professionals speak truth to power. Professionals have the courage to say no to their managers.
Negotiate!
Being a team player means player your position as well as you possibly can, and helping out your teammates when they get into a jam.
There is no “trying”.
If you are not holding back some energy in reserve, if you don’t have a new plan, if you aren’t going to change your behavior, and if you are reasonably confident in your original estimate, then promising to try is fundamentally dishonest. You are lying. And you are probably doing it to save face and to avoid a confrontation.
(Passive aggression is when you let someone else hang themselves through inaction on your part.)
Confidence and error-sense is the key to mastery.
Write code to reveal intent.
Worrying? Tired? Don’t code!
The author avoids the flow zone. I find it useful for routine code, and less useful for novel code.
Music can be a plus or minus when writing code. It only works well for me when I’m writing routine code (and not novel code).
Interruptions happen. Try not to be rude.
Refinding your place after an interruption can be tricky. I personally find having an active card useful, as I can just review the card and the checklist on it that I was working through.
Acceptance tests are a special kind of automated test that specifically test the stakeholder-desired behaviors of a feature. Once the acceptance tests pass, the feature is “done” from the perspective of the stakeholders. This is extremely powerful.
Acceptance tests should be written as a collaboration of the stakeholders and the programmers.
Unit tests and acceptance tests (which are not the same thing) are documents first and tests second. Their primary purpose is to formally document the design, structure, and behavior of the system. The fact that they automatically verify the design, structure, and behavior that they specify is wildly useful, but the specification is the true purpose.
Make sure that all your unit tests and acceptance tests are run several times per day in a continuous integration system.
It is very important to keep the CI tests running at all times. A broken build in the CI system should be viewed as an emergency, a “stop the presses” event.
Automated tests can act to:
Automated tests can be classified based on the size of the things they put under test:
There are two truths about meetings:
Be very careful about which meetings you attend and which you politely refuse.
One of the most important duties of your manager is to keep you out of meetings.
Have an agenda and a goal: If you are asked to go to a meeting, make sure you know what discussions are on the table, how much time is allotted for them, and what goal is to be achieved. If you can’t get a clear answer on these things, then politely decline to attend.
Focus is a scarce resource, rather like manna.
It is wise to manage one’s time to take advantage of when focus-manna is available. Focus-manna is a decaying resource so it often needs to be used when it is available.
Sleep is paramount to recharge focus.
Power naps also work well for me personally.
The Rule of Holes: When you are in one, stop digging.
Messes slow you down but don’t stop you. Messes are worse than blind alleys because you can always see the way forward, and it always looks shorter than the way back (but it isn’t).
Businesses like to view estimates as commitments. Developers like to view estimates as guesses.
Commitment is about certainty. Other people are going to make plans based on your commitments.
An estimate is not number, despite it often being presented as such. Rather, it is a distribution.
There is a system of estimation called “PERT” or “trivariate analysis”. You give an estimate as a combination of {Optimistic Estimate, Nominal Estimate, Pessimistic Estimate}, which creates a beta distribution. These distributions can be added together to determine the combined time distribution for performing a series of tasks.
Estimating tasks with a group of team-members is more accurate than estimating by oneself. There are many techniques for this. Probably the most famous is “planning poker”. There is also “affinity estimation” and “flying fingers”.
You know what you believe by observing yourself in a crisis.
If in a crisis you follow your disciplines, then you truly believe in those disciplines. On the other hand, if you change your behavior in a crisis, then you don’t truly believe in your normal behavior.
Choose disciplines that you feel comfortable following in a crisis. Then follow them all the time.
Avoid creating surprises. Nothing makes people more angry and less rational than surprises.
When assigning work to folks, there’s no such thing as half a person. You cannot sensibly tell a programmer to devote half their time to project A and half their time to project B.
For a 12-person team, here’s a suggested team composition:
It’s reasonable to assign multiple projects to a single team. Particularly if the team has gelled.
On the other hand assigning multiple projects to a single person is not a great idea.
Software apprenticeship: A very interesting idea. Consider the following levels of proficiency:
(See the descriptions in the book.)
A craftsman is someone who works quickly, but without rushing, who provides reasonable estimates and meets commitments. A craftsman knows when to say no, but tries hard to say yes. A craftsman is a professional.
School can teach the theory of computer programming. But school does not, and cannot teach the discipline, practice, and skill of being a craftsman.