The last time we recruited a UX/UI designer, it took more than 100 days to find the right person. But we weren’t in a rush – and neither should you.
The Empirical Laws of Software Engineering
Many times I’ve heard about various laws in programming, so I did some research, trying to find as many of them as possible.
In my opinion, the laws could be divided into:
- Empirical laws verified many times, so they are unlikely to be rejected
- Empirical laws verified a few times, so they could be rejected
- Laws not checked empirically, so we don’t know whether they’re true
- Principles which tell how we should work
However simple it seems, it’s difficult to assign the laws to these categories, so I decided to publish only grouping them by domain (AI, Coding, Communication, Company, Estimation/time management, Hardware, Information, Management, Measure, Networks, Problem solving, Product, QA, Queueing, Requirements, Security/cryptography, Skills, Software architecture, Software performance, Statistics, Technology, UX) and relative importance from my point of view.
So let’s talk about some of the most important laws.
The empirical laws of software engineering everyone should know
Knuth’s Optimization Principle
“Premature optimization is the root of all evil.”
In my opinion, that’s not always true. If we know a given part of the system will be essential for the general performance and another solution could give a few times faster execution, than the currently developed solution, we should change our approach.
Anyway, in let’s say 95% of cases this principle is true: if we try to optimize too much, we can spend too much time on implementing our current stuff, and the future can be even worse because we’ve chosen code which is not the easiest to maintain.
“When debugging, novices insert corrective code, experts remove defective code”
In my opinion, it doesn’t need any explanation.
“Be conservative in what you do, be liberal in what you accept from others”
When developing a library, an HTTP API, a class, a module or a function, we should provide backward compatibility and become even more flexible about the received arguments. This rule applies in real life as well – we should be conservative towards ourselves but liberal/tolerant towards others.
“All complex systems that work evolved from simpler systems that worked”
When we create a new innovative system, we should start with something simple that works, which will later evolve to a more complex solution. However, if we work on such things that are very similar to what we’ve worked on many times, we can have a plan and work just according to this plan because there’s a good chance it’ll succeed.
PS. This law works well for building minimum viable products, you can read more about that in the article “What is MVP / Minimum Viable Product?”
Tesler’s Law of Conservation as Complexity
“Every application has an inherent amount of complexity that cannot be removed or hidden. Instead, it must be dealt with, either in product development or in user interaction.”
I don’t think this requires an explanation.
“The speedup gained from running a program on a parallel computer is greatly limited by the fraction of that program that can’t be parallelized.”
In order to profit from parallelization, most of the system must be parallelized and we should reduce the bottlenecks.
“The time it takes your favorite application to complete a given task doubles with each new revision”
It’s exaggerated for most cases but it’s mostly true because new features require checking more conditions or just loading more code into RAM so it decreases the performance.
“If people listened to themselves more often, they’d talk less.”
For efficient communication, it’s very important to listen due to the following reasons:
- We must know other people’s opinion in order to choose the best solution.
- We must also listen to ourselves in order to check whether we’ve communicated what we really wanted to say e.g. reading a sent email, a sent Slack message or a posted GitHub comment in order to avoid a situation where a simple typo like changing only one character changes the meaning diametrically.
- When we have communicated something important, we should ask our interlocutor not only whether they understood but in which way they understood.
- If you listen carefully, it’s more likely your interlocutors will listen to you as well.
“To understand what another person is saying, you must assume that it is true and try to imagine what it could be true of.”
Even if you disagree with somebody, you should imagine they’re right in order to:
- Apply a part of their opinion because it’s maybe about 20% true.
- Build a team of people who understand each other, even when they disagree so it’s easier to get a consensus.
“In any dispute the intensity of feeling is inversely proportional to the value of the issues at stake.”
Sometimes we debate very long about some minor issues. It’s important to talk with coworkers in order to find an optimal or near-optimal solution. However, sometimes it’s a waste of time, e.g. we discuss something for a few hours, which reduces the implementation time by only one hour and gives nothing to the application user. Therefore, the rule of thumb is to have discussion time proportional to the issue importance, which can be measured by implementation time, earned money or production users number.
Parkinson’s Law of Triviality
“Members of an organization give disproportionate weight to trivial issues”
Similar to the Sayre’s law. An explanation is when a developer spends most of time on coding, especially implementing only a little part of the system like a microservice, CSS, deployment, they can forget about the purpose of the whole system so they tend to optimize their piece of work, which can sometimes optimize the whole system.
However, very often it has no effect or a very small effect on the whole system. An example is one developer loves short code so he spends a good deal of time on code shortening, and another developer loves long code so he spends much time on making code longer; the effect is their work is mutually annihilated.
“When diagnosing, one should first consider the obvious”
Very useful in many areas of work and life. No explanation necessary.
“It works better if you plug it in.”
Another formulation of the Sutton’s law.
“The simplest solution is most likely the right one.”
Similar to the Sutton’s law and the Sattinger’s law. The difference is it’s about the simplest solution across solutions where many of them can be obvious.
IBM Pollyanna Principle
“Machines should work. People should think.”
We don’t know how intelligent the AI will be but currently it’s not too intelligent, so the developers, business analysts and UX engineers must predict various scenarios, and the machine should do the things which can be easily programmed e.g. people shouldn’t perform manually searches across big data.
Dilbert Principle and Peter Principle
“In a hierarchy every employee tends to rise to his level of incompetence.”
The Peter principle assumes an employee is promoted after success at each position, so finally he reaches a position where he’s not successful, so he gets stuck there. On the other hand, the Dilbert principle assumes an employee is promoted after showing an incompetence, so at a higher position he’ll be incompetent as well, but this higher role shouldn’t do any damage because it’s a manager role, which has in fact no responsibilites.
Maybe these rules are sometimes true, but it’s possible that somebody who was jealous of his coworkers being promoted formulated that.
Estimations & time management
“You cannot have a baby in one month by getting nine women pregnant.”
Very often adding new developers to a project doesn’t cause the work to be finished earlier because it’s not always that a given piece of work can be divided into smaller parts which could be implemented simultaneously.
“Adding human resources to a late software project makes it later”
It goes even further than Frisch’s law. An explanation is adding new people makes the old developers waste their time on mentoring.
“It always takes longer than you expect, even when you take into account Hofstadter’s Law.”
A recursive and very true law which in my opinion doesn’t need any explanation.
“Work expands so as to fill the time available for its completion”
Even if we estimate very carefully, we can very likely finish our work after the ETA because knowing we have a long amount of time, we work so slowly or we start working very late, so the result is either finishing exactly at the deadline or even later.
An implication is we shouldn’t estimate too carefully because it doesn’t necessarily decreases the probability of underestimation. Another explanation is when we have a lot of time for something, even if it’s finished, we can always improve it, so we keep optimizing until the deadline.
The 90-90 Rule
“The first 90 percent of the code accounts for the first 90 percent of the development time. The remaining 10 percent of the code accounts for the other 90 percent of the development time.”
The last 10% of the work is usually the most difficult, so it can last a very long time or even never be fully completed.
“Elevated arousal levels can improve performance up to a certain point”
A useful law for the people accountable for the work environment. No explanation necessary.
“People under time pressure don’t think faster”
Similar to the Yerkes–Dodson law. People under time pressure can work faster if it’s possible to get the work done before the deadline.
The 5 laws of software estimates
1. Estimates are Waste
2. Estimates are Non-Transferable
3. Estimates are Wrong
4. Estimates are Temporary
5. Estimates are Necessary
They could seem to be contradictory, but the 1st rule says time spent on estimation doesn’t bring any new features, so we cannot spend too much time on it. However, the 5th rule says they are just necessary, so we should estimate all tasks but not spending too much time on estimation.
The Law of False Alerts
“As the rate of erroneous alerts increases, operator reliance, or belief, in subsequent warnings decreases.”
It’s very important to have DevOps alerts e.g. a given microservice is down or deployment failed but it’s also important to not have too many alerts because when very frequent they become spam. Even worse are false alerts, which make the alerts untrustworthy.
“An information retrieval system will tend not to be used whenever it is more painful and troublesome for a customer to have information than for him not to have it.”
It’s important to have some equilibrium between storing information and its cost, e.g. storing all the document modification history or storing logs.
“A man with a watch knows what time it is. A man with two watches is never sure.”
It’s important to have a single source of truth.
“When a measure becomes a target, it ceases to be a good measure.”
A very important law. When wy try to optimize a given measure (like number of commits, finished user stories, number of bugs), we’ll optimize it but the measured value (which is immeasurable directly like work quantity and quality) won’t necessarily be optimized.
In my opinion the only good measure is money because when somebody gives me money, they have less so spending money on something usually means it is important.
“If the same tests are repeated over and over again, eventually the same test cases will no longer find new bugs.”
It’s similar to Goodhart’s law about tests – when we have test cases fixed, the production code can evolve in such a way that it will only satisfy the test cases but it will not work for most scenarios. Therefore it’s important for both the production code and the tests to be written by the same team and be code reviewed.
“Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand.”
It’s important to have both developers who understand the product and a product owner who understands the development. At least one person should understand both the product and development well. Otherwise, the requirements may very likely never be met, sometimes because the technology doesn’t allow us to satisfy the requirements.
Order of Priorities
“Order of priorities: Functionality, Fidelity, Efficiency”
First we should implement the working features (of course working doesn’t mean working in 20% of scenarios but rather working in 90% of scenarios), then we should fix bugs (to have working features at 99.9% of scenarios) and finally improve the performance.
Security & cryptography
“If there is a wrong way to do something, then someone will do it.”
It’s usually true and in my opinion it doesn’t require an explanation.
“If something can go wrong, it will”
Another formulation of Murphy’s law.
“Anything that can go wrong, will—at the worst possible moment.”
Similar to Murphy’s law and Sod’s law, but it goes even further.
“Low performers are unable to recognize the skill and competence levels of other people, which is part of the reason why they consistently view themselves as better, more capable, and more knowledgeable than others.”
After initially gaining new skills very quickly, people tend to view themselves as highly skilled but later they realize they have many faults.
“Some of the most crucial steps in mental growth are based not simply on acquiring new skills, but on acquiring new administrative ways to use what one already knows.”
Usually we don’t have to memorize everything but just know the place where we can get a given piece of information. However, when we used given tools often, it’s good to remember how to use them, but even in this situation it can be enough to just use them and we can memorize without any additional learning.
“For many events, roughly 80% of the effects come from 20% of the causes”
It explains many areas of work and life.
Jakob’s Law of the Internet User Experience
“Users spend most of their time on other sites. This means that users prefer your site to work the same way as all the other sites they already know.”
Even if you’re Google or Facebook, users spend most of their time on other sites on average so you should avoid surprise. It applies to creating an HTTP API or an API of a library, class, module or function as well.
“For a new software system, the requirements will not be completely known until after the users have used it.”
It’s impossible for business analysts to predict all the possible scenarios as there are only a few of them and there can be millions of production users.