General Information
This is a 2008 book consisting of 55 facts and 10 myths about developers and programming in general. All materials are divided into specific groups, such as management, development, and others.
It’s worth noting right away that almost all the topics and questions discussed by the author are highly debatable, and different readers may have strongly differing opinions. To save time and space, I’m not going to describe my own views on each point. Here I’ll simply list all the facts and myths, and give an overall evaluation of the book at the end. Each fact or myth is presented in the format of a medium-length article, so if you're interested, you can choose to read specific topics rather than the entire book. Before listing all the facts and myths, I’ll also point out that the author follows a clear structure when presenting material:
- First, he discusses the fact or myth itself.
- Then he outlines the arguments and debates around it.
- Finally, he provides sources of information related to the topic.
Programming Facts
Human Factor
- The most important factor in software development is not the methods and tools used by programmers, but the programmers themselves.
- According to research on individual differences, the best programmers outperform the worst ones by up to 28 times. Considering their compensation is never proportional, the best programmer is the most valuable asset in the software industry.
- If a project is behind schedule, adding more manpower will delay it even further.
- Working conditions greatly influence productivity and the quality of results.
- The hype surrounding tools and methodologies is a plague on the software industry. Most improvements in tools and methods lead to a 5–35% increase in productivity and quality. However, many of these improvements are touted as giving "an order of magnitude" advantage.
- Learning a new tool or method initially decreases productivity and product quality. The benefits only come after the learning curve has been overcome. Thus, introducing new tools and methods makes sense only if a) their actual value is evident, and b) one has the patience to wait for the payoff.
- Developers talk a lot about tools. They try many, acquire them in abundance, but rarely use them effectively.
- One of the most common causes of project mismanagement is poor estimation. (The second reason is discussed in Fact 23.)
- Most project estimates in software are made early in the lifecycle. This doesn't concern us until we realize the estimates are made before the requirements are defined, and thus before the task is understood. Therefore, the timing of the estimates is usually inappropriate.
- Most project estimates in software are made by top managers or marketing staff—not by those who will develop the software, nor by their supervisors. So the wrong people are doing the estimating.
- Software project estimates are rarely refined later. In other words, estimates made by the wrong people at the wrong time typically remain uncorrected.
- Since estimates are so often incorrect, there's little reason to worry about software projects not finishing on time. Yet everyone worries anyway.
- There is a lack of communication between managers and programmers. One study of a project considered a failure by management (due to unmet estimates) found that the developers viewed it as the most successful project they’d ever worked on.
- Feasibility analysis of a project almost always gives a "yes" answer.
- Small-scale reuse (via subroutine libraries) has been around for almost 50 years and is well-understood.
- Large-scale reuse (via components) remains largely unsolved, though it’s widely agreed to be important.
- Successful large-scale reuse is most effective within families of related systems, and thus depends on the application domain. This narrows its potential applicability.
- There are two "rules of three" in reuse: a) reusable components take three times the effort of single-use components, and b) a reusable component must be tested in three different applications before it's general enough to be included in a component library.
- Modifying reused code is highly error-prone. If more than 20–25% of a component needs to be changed, it's better to rewrite it from scratch.
- Reusing design patterns addresses many issues that arise with code reuse.
- Increasing task complexity by 25% increases software solution complexity by 100%. This is a fact of life—not something we can easily change (though we should always aim to minimize complexity).
- 80% of software development effort is intellectual. A large portion of this is creative work. Only a small part is technical.
Requirements
- One of the two most common causes of project mismanagement is changing requirements. (The other is discussed in Fact 8.)
- Fixing requirement errors is most expensive when found in production, and cheapest when caught early in development.
- Missing requirements are the hardest type of error to fix.
Design
- As we move from initial requirements to architecture, we are overwhelmed by a flood of "derived requirements" (requirements tied to specific design decisions) caused by process complexity. This list is often 50 times longer than the original.
- The best design solution to a programming problem is rarely the only one.
- Design is a complex, iterative process. The initial design solution is likely wrong, and definitely not optimal.
Coding
- Programmers move from design to coding when the task is broken down into "primitives" understood by the designer. If the coder is not the same person as the designer, the designer’s primitives may not match those of the coder—leading to trouble.
- COBOL is a very bad language, but all others (for business data processing) are much worse.
- The error correction phase is the most labor-intensive part of the software lifecycle.
Testing
- It turns out that in software which a typical programmer assumes is thoroughly tested, only about 55–60% of logical paths are actually verified. Using automated tools such as coverage analyzers can raise this to approximately 85–90%. Testing 100% of logical paths is practically impossible.
- Even if 100% test coverage were achievable, it wouldn't be sufficient as a testing adequacy criterion. Around 35% of software defects are due to missed logical paths, and another 40% stem from unique combinations of logical paths. These cannot be identified with 100% test coverage.
- Without instrumentation tools, it is nearly impossible to effectively eliminate errors. Debuggers are widely used—unlike other tools, such as coverage analyzers.
- Tests are rarely automated. That is, certain testing processes can and should be automated. But a significant portion of testing work cannot be automated.
- An important addition to testing tools is programmer-written built-in debug code, preferably included in the object code depending on compilation directives.
- Thorough inspections can eliminate up to 90% of errors from a software product before the first baseline test is run.
- Thorough inspections offer many benefits but cannot replace testing.
- It is widely acknowledged that post-mortem reviews (also called retrospectives) are important both from the user's perspective and for process improvement. However, in most organizations, such reviews are not conducted.
- Inspections involve not only technical factors but also social ones. Focusing too much on one at the expense of the other is a direct path to disaster.
- Maintenance typically accounts for 40 to 80% (on average 60%) of the total software cost. Therefore, this phase of the lifecycle may be the most important.
- About 60% of maintenance costs go to code improvement and about 17% to bug fixing. Thus, software maintenance and support mostly involve adding new features rather than fixing issues.
- Maintenance is a solution, not a problem.
- When comparing software development and maintenance, they are mostly similar—except for an additional task in maintenance: "learning the maintained product." This task takes about 30% of the total maintenance time and dominates the maintenance effort. Therefore, maintenance is more labor-intensive than development.
- Improving software development quality leads to more maintenance, not less.
Quality
- Quality is a combination of properties.
- Quality is not defined by user satisfaction, meeting client requirements, acceptable cost and delivery time, or reliability.
- There are certain errors that most programmers are prone to make.
- Errors tend to cluster.
- There is no single best approach yet developed for eliminating errors.
- Errors are inevitable. The goal is to avoid critical ones or minimize them.
Efficiency
- Efficiency depends more on high-quality application design than on high-quality programming.
- The efficiency of high-level language code, compiled with appropriate optimization settings, can reach 90% of the efficiency of functionally comparable assembly code. In some complex modern architectures, it can even be higher.
- There are trade-offs between size optimization and speed optimization. Often improving one will degrade the other.
On Scientific Research
- Many scientists working in the software industry tend to defend their theories rather than conduct research. As a result: a) the value of some promoted theories is much lower than their advocates believe; b) there is a lack of research aimed at determining the actual value of these theories.
Programming Misconceptions
- You can't manage what you can't measure.
- Management can ensure software quality.
- Programming can and should be impersonal.
- Tools and technologies are universal.
- Programming needs more methodologies.
- To estimate cost and set deadlines, start by counting lines of code.
- Using random input data is a good way to optimize testing.
- "All bugs are shallow given enough eyeballs."
- Knowing the cost of previous maintenance allows predicting future maintenance costs and deciding whether to replace a product.
- People can be taught to program by showing them how to write code.
Conclusion
Although the book was written back in 2008, I still recommend it to those studying programming. One downside that immediately stands out is that it's difficult to confirm or refute the percentages and figures the author cites for certain facts. Also, a few facts have become outdated. That said, the overwhelming majority of the material remains relevant and will be useful not only for developers but also for managers.