The remaining promises of the oath reflect a commitment to the team.
Promise 7. I will continuously ensure that others can cover for me and that I can cover for them.
Segregation of knowledge into silos is extremely detrimental to a team and to an organization. The loss of an individual can mean the loss of an entire segment of knowledge. It can paralyze the team and the organization. It also means that the individuals on the team don’t have sufficient context to understand each other. Often, they wind up talking past each other.
The cure for this problem is to spread knowledge through the team. Make sure each team member knows a lot about the work that other team members are performing.
The best way to spread that knowledge is to work together—to pair, or mob.
The truth is that there’s hardly any better way to improve the productivity of a team than to practice collaborative programming. A team that knows the deep connections among the work that’s being done can’t help but be much more productive than a group of silos.
It is also important that the members of the team see and interact with each other very frequently. The best way to achieve this is to put them into a room together.
In the early 2,000s, I owned a company that helped organizations adopt Agile development. We would send a group of instructors and coaches to those companies and guide them through the change. Before each engagement began, we told the managers to rearrange the office space so that the teams we would be coaching worked in their own team rooms. It happened more than once that, before we arrived to begin coaching, the managers told us that the teams were already much more productive just because they were working together in the same room.
I’m writing this paragraph in the first quarter of 2021. The COVID-19 pandemic is beginning to wane, vaccines are being rapidly distributed (I will get my second shot today), and we are all looking forward to a return to normal life. But the pandemic will leave, in its wake, a large number of software teams who work remotely.
Working remotely can never be quite as productive as working together in the same room. Even with the best electronic help, seeing each other on screens is just not as good as seeing each other in person. Still, the electronic systems for collaboration are very good nowadays. So, if you are working remotely, use them.
Create a virtual team room. Keep everyone’s face in view. Keep everyone’s audio channel as open as feasible. Your goal is to create the illusion of a team room, with everyone in it working together.
Pairing and mobbing enjoy a lot of electronic support nowadays. It is relatively easy to share screens and program together across distances. While you do that, keep the faces and the audio up and running. You want to be able to see each other while you are collaborating on code.
Remote teams should try, as hard as they can, to maintain the same working hours. This is very difficult when there is a huge East–West distribution of programmers. Try to keep the number of time zones in each team as small as possible, and try very hard to have at least six contiguous hours per day when everyone can be together in the virtual team room.
Have you ever noticed how easy it is to yell at another driver while driving your car? This is the windshield effect. When you are sitting behind a windshield, it’s easy to see other people as fools, imbeciles, and even enemies. It is easy to dehumanize them. This effect happens, to a lesser degree, behind computer screens.
To avoid this effect, teams should get together in the same physical room several times per year. I recommend one week each quarter. This will help the team congeal and maintain itself as a team. It is very hard to fall into the windshield trap with someone you ate lunch with and physically collaborated with two weeks ago.
Promise 8. I will produce estimates that are honest in both magnitude and precision. I will not make promises without reasonable certainty.
In this section, we’re going to talk about estimating projects and large tasks—things that take many days or weeks to accomplish. The estimation of small tasks and stories is described in Clean Agile.1
1. Robert C Martin, Clean Agile: Back to Basics (Pearson, 2020).
Knowing how to estimate is an essential skill for every software developer and one that most of us are very, very bad at. The skill is essential because every business needs to know, roughly, how much something is going to cost before they commit resources to it.
Unfortunately, our failure to understand what estimates actually are and how to create them has led to an almost catastrophic loss of trust between programmers and business.
The landscape is littered with billions of dollars in software failures. Often, those failures are due to poor estimation. It is not uncommon for estimates to be off by a factor of 2, 3, even 4 and 5. But why? Why are estimates so hard to get right?
Mostly it’s because we don’t understand what estimates actually are and how to create them. You see, in order for estimates to be useful, they must be honest: They must be honestly accurate, and they must be honestly precise. But most estimates are neither. Indeed, most estimates are lies.
Most estimates are lies because most estimates are constructed backward from a known end date.
Consider HealthCare.gov, for example. The president of the United States signed a bill into law that mandated a specific date when that software system was to be turned on.
The depth of that illogic is nausea inducing. I mean, how absurd. Nobody was asked to estimate the end date; they were just told what the end date had to be—by law!
So, of course, all estimates associated with that mandated date were lies. How could they be anything else?
It reminds me of a team I was consulting for about twenty years ago. I remember being in the project room with them when the project manager walked in. He was a young fellow, perhaps twenty-five. He’d just returned from a meeting with his boss. He was visibly agitated. He told the team how important the end date was. He said, “We really have to make that date. I mean, we really have to make that date.”
Of course, the rest of the team just rolled their eyes and shook their heads. The need to make the date was not a solution for making the date. The young manager offered no solution.
Estimates, in an environment like that, are just lies that support the plan.
And that reminds me of another client of mine who had a huge software production plan on the wall—full of circles and arrows and labels and tasks. The programmers referred to it as the laugh track.
In this section, we’re going to talk about real, worthwhile, honest, accurate, and precise estimates. The kind of estimates that professionals create.
The most important aspect of an estimate is honesty. Estimates don’t do anybody any good unless they are honest.
Me: So, let me ask you. What is the most honest estimate you can give?
Programmer: Um, I don’t know.
Me: Right.
Programmer: Right what?
Me: I don’t know.
Programmer: Wait. You asked me for the most honest estimate.
Me: Right.
Programmer: And I said I don’t know.
Me: Right.
Programmer: So, what it is?
Me: I don’t know.
Programmer: Well, then, how do you expect me to know?
Me: You already said it?
Programmer: Said what?
Me: I don’t know.
The most honest estimate you can give is “I don’t know.” But that estimate is not particularly accurate or precise. After all, you do know something about the estimate. The challenge is to quantify what you do and don’t know.
First, your estimate must be accurate. That doesn’t mean you give a firm date—you don’t dare be that precise. It just means that you name a range of dates that you feel confident in.
So, for example, sometime between now and ten years from now is a pretty accurate estimate for how long it would take you to write a hello world program. But it lacks precision.
On the other hand, yesterday at 2:15 a.m. is a very precise estimate, but it’s probably not very accurate if you haven’t started yet.
Do you see the difference? When you give an estimate, you want it to be honest both in accuracy and in precision. To be accurate, you name a range of dates within which you are confident. To be precise, you narrow that range up to the level of your confidence.
And for both of these operations, brutal honesty is the only option.
To be honest about these things, you have to have some idea of how wrong you can be. So let me tell you two stories about how wrong I once was.
The year was 1978. I was working at a company named Teradyne, in Deerfield, Illinois. We built automated test equipment for the telephone company.
I was a young programmer, 26 years old. And I was working on the firmware for an embedded measurement device that bolted into racks in telephone central offices. This device was called a COLT—central office line tester.
The processor in the COLT was an Intel 8085—an early 8-bit microprocessor. We had 32K of solid-state RAM and another 32K of ROM. The ROM was based on the Intel 2708 chip, which stored 1K × 8, so we used 32 of those chips.
Those chips were plugged into sockets on our memory boards. Each board could hold 12 chips, so we used three boards.
The software was written in 8085 assembler. The source code was held in a set of source files that were compiled as a single unit. The output of the compiler was a single binary file somewhat less than 32K in length.
We took that file and cut it up into 32 chunks of 1K each. Each 1K chunk was then burned onto one of the ROM chips, which were then inserted into the sockets on the ROM boards.
As you can imagine, you had to get the right chip into the right socket on the right board. We were very careful to label them.
We sold hundreds of these devices. They were installed in telephone central offices all over the country and—indeed—the world.
What do you think happened when we changed that program? Just a one-line change?
If we added or removed a line, then all the addresses of all the subroutines after that point changed. And because those subroutines were called by other routines earlier in the code, every chip was affected. We had to reburn all 32 chips even for a one-line change!
It was a nightmare. We had to burn hundreds of sets of chips and ship them to all the field service reps all around the world. Then those reps would have to drive hundreds of miles to get to all the central offices in their district. They’d have to open our units, pull out all the memory boards, remove all 32 old chips, insert the 32 new chips, and reinsert the boards.
Now, I don’t know if you know this, but the act of removing and inserting a chip into a socket is not entirely reliable. The little pins on the chips tend to bend and break in frustratingly silent ways. Therefore, the poor field service folks had to have lots of spares of each of the 32 chips and suffer through the inevitable debugging by removing and reinserting chips until they could get a unit to work.
My boss came to me one day and told me that we had to solve this problem by making each chip independently deployable. He didn’t use those words, of course, but that was the intent. Each chip needed to be turned into an independently compilable and deployable unit. This would allow us to make changes to the program without forcing all 32 chips to be reburned. Indeed, in most cases, we could simply redeploy a single chip—the chip that was changed.
I won’t bore you with the details of the implementation. Suffice it to say that it involved vector tables, indirect calls, and the partitioning of the program into independent chunks of less than 1K each.2
2. That is, each chip was turned into a polymorphic object.
My boss and I talked through the strategy, and then he asked me how long it would take me to get this done.
I told him two weeks.
But I wasn’t done in two weeks. I wasn’t done in four weeks. Nor was I done in six, eight, or ten weeks. The job took me twelve weeks to complete—it was a lot more complicated than I had anticipated.
Consequently, I was off by a factor of 6. Six!
Fortunately, my boss didn’t get mad. He saw me working on it every day. He got regular status updates from me. He understood the complexities I was dealing with.
But still. Six? How could I have been so wrong?
Then there was that time, in the early 1980s, when I had to work a miracle.
You see, we had promised a new product to our customer. It was called CCU-CMU.
Copper is a precious metal. It’s rare and expensive. The phone company decided to harvest the huge network of copper wires that it had installed all over the country during the last century. The strategy was to replace those wires with a much cheaper high-bandwidth network of coaxial cable and fiber carrying digital signals. This was known as digital switching.
The CCU-CMU was a complete re-architecture of our measurement technology that fit within the new digital switching architecture of the phone company.
Now, we had promised the CCU-CMU to the phone company a couple of years before. We knew it was going to take us a man-year or so to build the software. But then we just never quite got around to building it.
You know how it goes. The phone company delayed their deployment, so we delayed our development. There were always lots of other, more urgent issues to deal with.
So, one day, my boss calls me into his office and says that they had forgotten about one small customer who had already installed an early digital switch. That customer was now expecting a CCU/CMU within the next month—as promised.
Now I had to create a man-year of software in less than a month.
I told my boss that this was impossible. There was no way that I could get a fully functioning CCU/CMU built in one month.
He looked at me with a sneaky grin and said that there was a way to cheat.
You see, this was a very small customer. Their installation was literally the smallest possible configuration for a digital switch. What’s more, the configuration of their equipment just happened—just happened—to eliminate virtually all of the complexity that the CCU/CMU solved.
Long story short—I got a special-purpose, one-of-a-kind unit up and running for the customer in two weeks. We called it the pCCU.
Those two stories are examples of the huge range that estimates can have. On the one hand, I underestimated the vectoring of the chips by a factor of six. On the other, we found a solution to the CCU/CMU in one-twentieth the expected time.
This is where honesty comes in. Because, honestly, when things go wrong, they can go very, very wrong. And when things go right, they can sometimes go very, very right.
This makes estimating, one hell of a challenge.
It should be clear by now that an estimate for a project cannot be a date. A single date is far too precise for a process that can be off by as much as a factor of 6, or even 20.
Estimates are not dates. Estimates are ranges. Estimates are probability distributions.
Probability distributions have a mean and a width—sometimes called the standard deviation or the sigma. We need to be able to express our estimates as both the mean and the sigma.
Let’s first look at the mean.
Finding the expected mean completion time for a complex task is a matter of adding up all the mean completion times for all of the subtasks. And, of course, this is recursive. The subtasks can be estimated by adding up all the times for the sub-subtasks. This creates a tree of tasks that is often called a work breakdown structure (WBS).
Now, this is all well and good. The problem, however, is that we are not very good at identifying all the subtasks and sub-subtasks, and sub-sub-subtasks. Generally, we miss a few. Like, maybe, half.
We compensate for this by multiplying the sum by two. Or sometimes three. Or maybe even more.
Kirk: How much refit time until we can take her out again?
Scotty: Eight weeks, sir. But you don’t have eight weeks, so I’ll do it for you in two.
Kirk: Mr. Scott, have you always multiplied your repair estimates by a factor of four?
Scotty: Certainly, sir! How else can I keep my reputation as a miracle worker?3
3. Star Trek II: The Wrath of Khan, directed by Nicholas Meyer (Paramount Pictures, 1982).
Now this fudge factor of 2, or 3, or even 4, sounds like cheating. And, of course, it is. But so is the very act of estimating.
There is only one real way to determine how long something is going to take, and that’s by doing it. Any other mechanism is cheating.
So, face it, we’re going to cheat. We’re going to do the WBS and then multiply by some F, where F is between 2 and 4, depending on your confidence and productivity. That will give us our mean time to completion.
Managers are going to ask you how you came up with your estimates, and you’re going to have to tell them. And when you tell them about that fudge factor, they’re going to ask you to reduce it by spending more time on the WBS.
This is perfectly fair, and you should be willing to comply. However, you should also warn them that the cost of developing a complete WBS is equivalent to the cost of the task itself. Indeed, by the time you have developed the complete WBS, you will also have completed the project, because the only way to truly enumerate all the tasks is by executing the tasks you know about in order to discover the rest—recursively.
So, make sure you put your estimation effort into a timebox, and let your managers know that getting better refinement on the fudge factor is going to be very expensive.
There are many techniques for estimating the subtasks at the leaves of the WBS tree. You could use function points or a similar complexity measure. But I’ve always found that these tasks are best estimated by raw gut feel.
Typically, I do this by comparing the tasks to some other tasks that I’ve already completed. If I think it’s twice as hard, I multiply the time by two.
Once you’ve estimated all the leaves of the tree, you just sum the whole tree up to get the mean for the project.
And don’t worry overmuch about dependencies. Software is a funny material. Even though A depends on B, B often does not have to be done before A. You can, in fact, implement logout before you implement login.
Every estimate is wrong. That’s why we call it an estimate. An estimate that is correct is not an estimate at all—it’s a fact.
But even though the estimate is wrong, it may not be all that wrong. Part of the job of estimation, then, is to estimate how wrong the estimate is.
My favorite technique for estimating how wrong an estimate is, is to estimate three numbers: the best case, the worst case, and the normal case.
The normal case is how long you think the task would take you if the average number of things go wrong—if things go the way they usually do. Think of it like a gut-level call. The normal case is the estimate you would give if you were being realistic.
The strict definition of a normal estimate is one that has a 50 percent chance of being too short or too long. In other words, you should miss half of your normal estimates.
The worst-case estimate is the Murphy’s law estimate. It assumes that anything that can go wrong will go wrong. It is deeply pessimistic. The worst-case estimate has a 95 percent chance of being too long. In other words, you would only miss this estimate 1 in 20 times.
The best-case estimate is when everything possible goes right. You eat the right breakfast cereal every morning. When you get into work, your coworkers are all polite and friendly. There are no disasters in the field, no meetings, no telephone calls, no distractions.
Your chances of hitting the best-case estimate are 5 percent: 1 in 20.
Okay, so now we have three numbers: the best case, which has a 5 percent chance of success; the normal case, which has a 50 percent chance of success; and the worst case, which has a 95 percent chance of success. This represents a normal curve—a probability distribution. It is this probability distribution that is your actual estimate.
Notice that this is not a date. We don’t know the date. We don’t know when we are really going to be done. All we really have is a crude idea of the probabilities.
Without certain knowledge, probabilities are the only logical way to estimate.
If your estimate is a date, you are really making a commitment, not an estimate. And if you make a commitment, you must succeed.
Sometimes you have to make commitments. But the thing about commitments is that you absolutely must succeed. You must never promise to make a date that you aren’t sure you can make. To do so would be deeply dishonest.
So, if you don’t know—and I mean know—that you can make a certain date, then you don’t offer that date as an estimate. You offer a range of dates instead. Offering a range of dates with probabilities is much more honest.
Okay, let’s say that we’ve got a whole project full of tasks that have been described in terms of Best (B), Normal (N), and Worst (W) case estimates. How do we aggregate them all into a single estimate for the whole project?
We simply represent the probability of each task and then accumulate those probabilities using standard statistical methods.
The first thing we want to do is represent each task in terms of its expected completion time and the standard deviation.
Now remember, 6 standard deviations (3 on each side of the mean) corresponds to a probability of better than 99 percent. So, we’re going to set our standard deviation, our sigma, to Worst minus Best over 6.
The expected completion time (mu) is a bit trickier. Notice that N is probably not equal to (W-B), the midpoint. Indeed, the midpoint is probably well past N because it is much more likely for a project to take more time than we think than less time. So, on average, when will this task be done? What is the expected completion time?
It’s probably best to use a weighted average like this: mu = (2N + (B + W)/2)/3.
Now we have calculated the mu and sigma for a set of tasks. The expected completion time for the whole project is just the sum of all the mus. The sigma for the project is the square root of the sum of the squares of all the sigmas.
This is just basic statistical mathematics.
What I’ve just described is the estimation procedure invented back in the late 1950s to manage the Polaris Fleet Ballistic Missile program. It has been used successfully on many thousands of projects since.
It is called PERT—the program evaluation and review technique.
We started with honesty. Then we talked about accuracy, and we talked about precision. Now it’s time to come back to honesty.
The kind of estimating we are talking about here is intrinsically honest. It is a way of communicating, to those who need to know, the level of your uncertainty.
This is honest because you truly are uncertain. And those with the responsibility to manage the project must be aware of the risks that they are taking so that they can manage those risks.
But uncertainty is something that people don’t like. Your customers and managers will almost certainly press you to be more certain.
We’ve already talked about the cost of increasing certainty. The only way to truly increase certainty is to do parts of the project. You can only get perfect certainty if you do the entire project. Therefore, part of what you have to tell your customers and managers is the cost of increasing certainty.
Sometimes, however, your superiors may ask you to increase certainty using a different tactic. They may ask you to commit.
You need to recognize this for what it is. They are trying to manage their risk by putting it onto you. By asking you to commit, they are asking you to take on the risk that it is their job to manage.
Now, there’s nothing wrong with this. Managers have a perfect right to do it. And there are many situations in which you should comply. But—and I stress this—only if you are reasonably certain you can comply.
If your boss comes to you and asks if you can get something done by Friday, you should think very hard about whether that is reasonable. And if it is reasonable and probable, then, by all means, say yes!
But under no circumstances should you say yes if you are not sure.
If you are not sure, then you must say NO and then describe your uncertainty as we’ve described. It is perfectly okay to say, “I can’t promise Friday. It might take as long as the following Wednesday.”
In fact, it’s absolutely critical that you say no to commitments that you are not sure of, because if you say yes, you set up a long domino chain of failures for you, your boss, and many others. They’ll be counting on you, and you’ll let them down.
So, when you are asked to commit and you can, then say yes. But if you can’t, then say no and describe your uncertainty.
Be willing to discuss options and workarounds. Be willing to hunt for ways to say yes. Never be eager to say no. But also, never be afraid to say no.
You see, you were hired for your ability to say no. Anybody can say yes. But only people with skill and knowledge know when and how to say no.
One of the prime values you bring to the organization is your ability to know when the answer must be no. By saying no at those times, you will save your company untold grief and money.
One last thing. Often, managers will try to cajole you into committing—into saying yes. Watch out for this.
They might tell you that you aren’t being a team player or that other people have more commitment than you do. Don’t be fooled by those games.
Be willing to work with them to find solutions, but don’t let them bully you into saying yes when you know you shouldn’t.
And be very careful with the word try. Your boss might say something reasonable, like “Well, will you at least try?”
The answer to this question is
NO! I am already trying. How dare you suggest that I am not? I am trying as hard as I can, and there is no way I can try harder. There are no magic beans in my pocket with which I can work miracles.
You might not want to use those exact words, but that’s exactly what you should be thinking.
And remember this. If you say, “Yes, I’ll try,” then you are lying. Because you have no idea how you are going to succeed. You don’t have any plan to change your behavior. You said yes just to get rid of the manager. And that is fundamentally dishonest.
Promise 9. I will respect my fellow programmers for their ethics, standards, disciplines, and skill. No other attribute or characteristic will be a factor in my regard for my fellow programmers.
We, software professionals, accept the weighty burden of our craft. We brave folks are men and women, straight and gay, black, brown, yellow, and white, republicans, democrats, religious believers, and atheists. We are humans, in all the many forms and varieties that humans come in. We are a community of mutual respect.
The only qualifications for entry into our community and for receiving the acceptance and the respect of each and every member of that community are the skills, disciplines, standards, and ethics of our profession. No other human attribute is worthy of consideration. No discrimination on any other basis can be tolerated.
’Nuff said.
Promise 10. I will never stop learning and improving my craft.
A programmer never stops learning.
I’m sure you’ve heard it said that you should learn a new language every year. Well, you should. A good programmer should know a dozen or so languages.
And not just a dozen varieties of the same language. Not just C, C++, Java, and C#. Rather, you should know languages from many different families.
You should know a statically typed language like Java or C#. You should know a procedural language like C or Pascal. You should know a logic language like Prolog. You should know a stack language like Forth. You should know a dynamically typed language like Ruby. You should know a functional language like Clojure or Haskell.
You should also know several different frameworks, several different design methodologies, and several different development processes. I don’t mean to say you should be an expert in all these things, but you should make a point to expose yourself to them at significantly more than a cursory level.
The list of things you should similarly expose yourself to is virtually endless. Our industry has experienced rapid change over the decades, and that change is likely to continue for some time. You have to keep up with it.
And that means you have to keep on learning. Keep reading books and blogs. Keep watching videos. Keep going to conferences and user groups. Keep going to training courses. Keep learning.
Pay attention to the treasured works of the past. The books written in the 1960s, 1970s, and 1980s are wonderful sources of insight and information. Don’t fall into the trap of thinking that all that old stuff is out of date. There is not much, in our industry, that actually goes out of date. Respect the effort and accomplishments of those who came before you, and study their advice and conclusions.
And don’t fall into the trap of thinking that it is your employer’s job to train you. This is your career—you have to take responsibility for it. It is your job to learn. It is your job to figure out what you should be learning.
If you are lucky enough to work for a company that will buy you books and send you to conferences and training classes, then take full advantage of those opportunities. If not, then pay for those books, conferences, and courses yourself.
And plan to spend some time at this. Time every week. You owe your employer 35 to 40 hours per week. You owe your career another 10 to 20.
That’s what professionals do. Professionals put in the time to groom and maintain their careers. And that means you should be working 50 to 60 hours per week total. Mostly at work, but a lot at home too.