今日推荐英文原文：《When Programming, Remember That Elephants Don’t Bite — Mosquitoes Do》
今日推荐英文原文：《When Programming, Remember That Elephants Don’t Bite — Mosquitoes Do》作者：Zachary Minott
When Programming, Remember That Elephants Don’t Bite — Mosquitoes Do
It’s the tiny mistakes you make that have the biggest drawbacksOn June 24, 1996, the European Space Agency’s unmanned Ariane 5 rocket exploded only 37 seconds after launch. $370 million and a decade of development were flushed down the drain in a single moment.
The cause? A simple software bug that attempted to store a 64-bit float variable that can represent billions of potential values into a 16-bit integer that can only represent 65,535 potential values. There literally wasn’t enough space allocated to make it into space.
The lesson? It’s the smallest bugs that cause the largest, costliest, and most potentially dangerous issues.
Elephants Don’t Bite, They Just Want to Be Your FriendsWhen reaching program failure, almost every blatantly obvious mistake reveals itself in code. These are mistakes that cause clearly discernable compiler or runtime errors that unmask their identities through the user interface or on compilation.
These mistakes are nearly never a cause for concern because it’s made apparent to us as developers that these are issues that immediately need to be addressed.
Most likely, when an error is visible, we attempt to fix it immediately and will never find ourselves shipping an unquestionably unfinished product or code to production that doesn’t meet the expectation of what is aiming to be achieved.
Elephants don’t bite because we can easily tame them and train them in an intuitive way. They never cause any problems in the long run and don’t do any damage unless you let them. They make themselves easily identifiable and basically say, “Hey, friend. Look at me! Give me your attention and I’ll show you affection. You won’t regret it.”
Mosquitoes Can Swarm You, Give You Lyme Disease, and Kill YouOn the other side of the spectrum, we have mosquitoes — the seemingly inconsequential parts of the code that aren’t made obvious and may mask themselves as hidden figures lurking in the backburners of seemingly working code. They’re ready to pounce and condense the product of your code into shambles.
These could be logical errors, unscalable and non-bulkified design, unclean and messy code, and deficient, non-optimal algorithms.
The problem that lied in the Ariane 5 rocket launch was that they copied working code over from the previously successful Ariane 4 rocket launch — code that they obviously thought would translate but clearly couldn’t match the needs and updated requirements of the environment the Ariane 5 rocket needed.
These types of errors are small but unveil themselves in the biggest ways.
- Logical errors can cause your product to have issues in the way it’s processing and displaying information, taking away from the functionality that was desired and shaving points off a good user experience. This alone can cause you to lose engagement from the audience even when you, as a developer, saw no concerning or immediately discernable issues with the way the application was running.
- Unscalable and non-bulkified design can cause issues such as the Ariane 5 explosion. They had a piece of code that worked under lower computationally intensive environments but didn’t work within environments that are computationally intensive. Ignoring such things can cause system failure, as the system wasn’t designed to handle large-scale operations. Such issues normally identify themselves in well-written test code that aims to put as much stress on the system as possible, but if you don’t write test classes that handle those cases, you may have a black swan waiting to reveal itself and surprise you in malicious ways.
- Unclean and messy code can make it tremendously difficult for anyone to identify errors or issues in the code. On top of that, it increases development costs drastically over time, as the code becomes increasingly difficult to extend and modify. This, in turn, causes things to break more easily and errors to make themselves more present and common. One look at messy code should immediately raise red flags that should incite you to start refactoring.
- Non-optimized algorithms can again lead to poor performance when it comes to computationally intensive operations. It’s easy to gloss over this detail — especially if you’re not yet comfortable with refactoring your code to perform better algorithmically. You normally notice this detail when you’re experiencing long load times, timeouts, or limitations (especially if you’re working with cloud back ends). Something may work well alone, but you need to aim to program with the knowledge that something that works well alone won’t necessarily work well in conjunction with large data sets and other components.
Get the Bug Repellent!OK, maybe I’m taking this metaphor too far, but I think you get the point. Let the small things go unnoticed, and eventually, you’ll be faced with the biggest issues down the road.
In a way, I feel for the programmers of the Ariane 5 incident, but such things make you realize the importance of writing code very carefully and deliberately backed by an immense amount of stress testing and test-driven development.
Programming is so much more than just writing code that compiles and executes. It takes careful and thoughtful consideration — not the drunken sailor approach that plagues many new and seasoned programmers who just slap together pieces of code as if they were trying to fit a cylinder into a square hole. It fits, but it just isn’t right and will not hold up by any means.
So that’s why it’s best to program with these questions in mind when building out code:
- Is my code overly complex? How can I simplify this?
- Have I written rigorous test classes for my code that have strong assertions and tests for multiple different data-saturated and computationally intensive scenarios? Am I aware of all the limitations of my code?
- Are my functions small? Can I abstract methods from large functions into smaller functions?
- Do my variables, classes, and functions have very clear and specific names? Can anyone look at my code and know exactly what it’s doing simply by reading the names?
- Am I duplicating way too many methods that could instead be reused and have generic functionality among multiple different processes? Are my duplicate methods absolutely necessary and do they merit a different scenario of functionality?
- How am I handling errors? Am I throwing errors, using try-catch blocks, and running null checks on variables? Is there a specified process in place to ensure smooth functionality when an error is caught?
- Is my code easily extendable and scalable? If modifications are being made, would I need to worry about any dependencies?
- Is my code bulkified and optimized to handle large amounts of data? Will my code raise an error or time out if put under too much stress?
Mitigate the risk of any errors in your code by doing things that limit the potential of unknown errors and make the state of Schrodinger’s cat known rather than “unknown until observed.”
Parting ThoughtIt’s the tiny things that you do consistently that yield the biggest outcomes. The big things you do rarely ever take the spotlight.
So stop worrying about making huge mistakes. Those big mistakes aren’t what should be concerning you in the long run, as the big mistakes you make are easily fixed, resolved, and strategically tackled.
It’s the small, tiny errors and inconsistencies that you output on a daily basis that should really be a huge cause for concern. Always find ways to mitigate those errors and ensure that you can somehow conclude the definitive outcome of your code base given strenuous and varying scenarios.