People often imagine that only low-level software made in a rush is capable of having bugs due to poor programming techniques or inexperienced programmers. From my personal experience during the past 20 years though, this has rarely been the case.
Junior to mid-level programmers aren't necessarily the culprits when it comes to writing breaking code. For one, most early stage developers aren't usually working on critical components for a billion dollar company. That's left to the more seniors developers often times. And if there is going to be a bug presented into the system, it's going to happen at this level.
But there are a few common practices that can for sure increase the chances of software developing issues at some point down the line. Here are a few ways that production level software will
at some point develop bugs that can affect usability, security, privacy
and more.
5. Documentation
Real-life code isn't like the stuff that you read about in books or watch on YouTube. It is messy to say the least. At least, it can be. It's alive and constantly changing in logic and often times worked on by many hands. And unless there is some way of keeping track of these changes, things will get lost in translation inevitably and result in the system, not failing, but also not working as specified.
This is why many large organizations have entire documentation protocols in place. And while tedious and relatively a boring part of the job, it is very much an important aspect of writing maintainable and safe code.
At my very first programming job, my day to day work (at least early on) involved mainly writing documentation for the development team. This included meeting notes, emails and anything else that would be valuable to know from a coding perspective.
What do you document that is so important? Typically any code that isn't clear by just reading it, such as unique business logic rules or temporary security patches that you jerry rig up on a Friday night and hopefully fix on a Monday.
function calcTotal(amount1, amount2, multiplier){
return (amount1 - amount2) + (amount1 * multiplier); // needs context
}
That quick sample method above needs some form of context before anyone can make changes to it. If new business rules were introduced into the equation, odds are that someone who has never seen that code before might introduce some form of bug into the mix.
And it is not at all an uncommon scenario. I have personally worked on many different projects in which there was little to no documentation written and where the person who had developed the code no longer worked at those particular companies.
When changes need to be made, or even worse, when a bug is found in an obscure part of the code, you inevitably have to tread lightly.
4. Repo's
Ideally, you always want some way to rollback your code to a safe and more stable version in case you introduce breaking changes into the code. And even more ideally, you might want to rollback just specific modules, so that you aren't causing too many system-wide changes all at once. And that takes some architecture, some dev-ops and a decent plan of action in your source control.
For one, you should always be working under some form of cloud based source control. That could be either the ever popular GitHub or BitBucket.
It's not just about having a remote repo setup however. It's more about using it effectively. That means setting up branches when needed and consistently checking in your code changes.
Often times when working on large code bases, you will inevitably run into things that don't quite make sense. Perhaps new code was added without you being aware of it and in this regard, being able to see just who made the commit and when can prevent you from making assumptions about the code.
3. Specsheet
This is probably the number source of bug creation in the professional world. In the business world, things change very quickly. Sometimes even before you are even done with a project, it has already seen its share of specification changes.
Features can be removed and added almost on a daily basis and often times unused code is left behind. While that code might go unused and might not pose an immediate threat, it can cause confusion down the line to an unsuspecting developer.
In this regard, a bug isn't so much your code not running correctly but more so your code not doing what it was intended to do. And this can happen at any point in time.
Imagine your code running perfectly fine today, but at some point in the near future someone makes the decision to change certain variables. As soon as that choice is made, your code is essentially broken.
2. Complexity
One of the easiest ways to incorporate bugs into your work is to over-engineer your code. What is over-engineering you might ask? Essentially the term is used to describe adding too many features to a system to the point where the value of the features being added begins to decrease the overall value. Mixed with improper documentation (mentioned above) this can lead to code that is difficult to read and more importantly, difficult to edit.
There is no real way to avoid this in the long term. The bigger the project that you are working on, the more complex the logic will become.
A few thousand lines of code is relatively easy to manage. But a few million lines of code will require some kind of system in order to maintain.
I've worked on incredibly complex systems in the past. Systems that took years of development to complete. And while they performed their duties well, making any form of change to these systems was typically something that required days of research.
Often times, this can be attributed to using 3rd party packages in excess as this limits the amount of changes that you can make overall and introduces an entirely new set of methods and properties into the equation.
1. Outdated
And lastly, even if you have the perfect code base that runs incredibly well and that is fully documented in perfect detail, eventually it will begin to show its age. Often times this can take years, but it is almost inevitable in the long run.
Deprecated code doesn't necessarily break your projects, as they take years to be fully dropped and supported, but they can increase the likelihood of creating bugs in the future. And those are the most dangerous errors that you can create.
The Year 2000 Problem was a clear example of this in action. For those unfamiliar, the Y2K bug brought to light in the 90's, created a global panic as the year 2000 approached. The issue was that older software systems tended to store calendar year's using 2 digits (1999 => 99, 1904 => 04).
This was mainly due to data storage limitations in the earlier days of computing. The concern was due to the fact that in those particular systems, the year 2000 would be represented as 00 causing unknown but far-reaching errors.
Developers during that time worked around the clock in order to prevent any possible issues when the clock struck 12am in the year 2000.
It really goes to show that an optimization and memory saving feature today can become a nightmare in the not so far future.
Now that you have a better idea as to how bugs are introduced into code, you can hopefully plan ahead in the future in order to mitigate as many you can.