paint-brush
Code and the Art of Motorcycle Maintenance: Typical Rookie Faultsby@shcherbanich
167 reads

Code and the Art of Motorcycle Maintenance: Typical Rookie Faults

by Filipp ShcherbanichAugust 16th, 2024
Read on Terminal Reader

Too Long; Didn't Read

Coding is actually a motorbike, a very powerful and fast one. With coding, just like with riding, you need to be responsible and conscious to stay in the saddle and double that to be a winner. In this article, I want to share my thoughts on what both new and seasoned developers should remember when creating software.
featured image - Code and the Art of Motorcycle Maintenance: Typical Rookie Faults
Filipp Shcherbanich HackerNoon profile picture


Coding is easy, they say, it’s just like riding a bike. Well, programming is actually a motorbike, a very powerful and fast one. With coding, just like with riding, you need to be responsible and conscious to stay in the saddle and double that to be a winner. Indeed, riders and coders share the same rookie mistakes: neophytes often tend to focus on fast, powerful tools and innovative tricks, believing that this alone defines a true master. This mindset is partly due to the "Dunning-Kruger effect," where novices fail to grasp the complexity and significance of their profession. Fortunately, with experience, even the most fervent beginner realizes that the art of programming involves much more than just selecting the optimal algorithm. In this article, I want to share my thoughts on what truly matters for a programmer and what both new and seasoned developers should remember when creating software and writing code.

Readability over performance, but not always

What do typical novice motorcyclists start with? Numbers and gadgets. Power, torque, performance parts to bite off theoretical milliseconds on a quarter-mile… Just as if they are about to hit the MotoGP starting grid. Meanwhile, their primary task is just learning how to ride safely. In a similar fashion, beginner developers often get fixated on code performance where it's unnecessary. Articles debating whether `dict()` or `{}` is more efficient in Python, or the pros and cons of using frameworks despite their potential to decrease performance, fuel this obsession. While understanding the intricacies of your programming language is beneficial and sometimes crucial – such as in software for airplanes, stock trading robots, or medical devices – it isn't always critical for the majority of programs we create daily. Even if you're working on performance-critical software, it's essential to know which parts of the code require high performance and which do not.


What always matters, however, is code readability. Numerous studies and surveys confirm that developers spend more time reading and understanding code than writing it. For instance, the study "I Know What You Did Last Summer – An Investigation of How Developers Spend Their Time" found that only 4% of time spent in an IDE is used for editing code. The Global Code Time Report, based on a survey of over 250,000 developers, revealed that respondents spend only about 52 minutes a day actively writing code. The rest of the time is spent discussing and planning the project, with about 41 minutes dedicated to reading code in the IDE and project documentation.


In most cases, our goal is to create a maintainable product that won't require complex support and will thrive in a competitive environment. This doesn't mean we can completely ignore performance; we must find a balance where maintainability and performance coexist. If high-performance code is needed, we can optimize slow sections after the project's launch.


Also keep in mind that compilers and interpreters evolve, but your code remains the same. A super-hyper-optimized magical code snippet written for one compiler version might become an irrelevant fizzle for another. Plus, future developers – or even you – will need to work with that code. So, when should we sacrifice readability for performance?


Identifying when to prioritize performance over readability involves pinpointing bottlenecks in your application:


  • Profiling the Application: If profiling reveals that specific critical code sections significantly impact performance, optimizing these fragments might justify reduced readability.

  • Load Testing: Simulating high loads can help identify performance bottlenecks before they become real-world issues.

  • User Feedback Analysis: Collecting feedback from users can highlight areas with poor performance.

  • Logging and Monitoring: Analyzing execution logs and metrics can identify problematic areas during the application's real-world operation. This stage might uncover unexpected issues, such as improper API usage causing performance problems.

  • Static Code Analysis Tools: Some tools can suggest performance improvements during code reviews. Automatically running these tools during task reviews is a good practice.


These tips can help identify your application's weak spots, allowing you to focus on necessary optimizations. Based on my personal experience, these optimizations are less likely to involve exotic language constructs and more likely to involve optimizing database interactions or external API usage.

Documenting helps understand the work done

While out on the road, one of the crucial safety skills is being predictable and, likewise, reading others’ intentions. In coding, just like in riding, you cannot directly read other people’s minds. On two wheels, you have to notice subtle movements and predict what others will do the next second. Programmers possess (but do not always employ) a powerful tool to replace telepathy: paperwork. Most developers agree that documentation is crucial for a project, as evidenced by surveys like the Stack Overflow Developer Survey 2023, where 90.36% of respondents use technical documentation regularly. However, they often can't find all the answers there, turning instead to Stack Overflow (82.56%) and various blogs (76.69%). Another study, Microsoft Research: The Daily Life of Software Developers, shows developers spend 1-2% of their day on documentation, with 10.3% of respondents losing a lot of time due to poor or outdated paperwork.


Documentation can take many forms, from detailed project descriptions in systems like Confluence to code comments and automatically or semi-automatically generated project description websites. It can even be as simple as a README file in the project's root directory. Regardless of the format, the process of creating documentation goes way beyond just conveying information about how the product works. This process makes us rethink what we've done, which can often lead to improvements in the API and overall architecture. I have often realized, while documenting the functionality I've created, that it might be difficult to work with, and I've found ways to fix that.


It's important to remember that maintaining documentation always requires significant effort, especially if the project is in a stage where it frequently changes. In such cases, you should weigh all risks and carefully consider what logic to document. If your project has reached a mature state, good documentation will bring more benefits than challenges: new developers can onboard and gain momentum faster, while long-time employees can quickly figure out how certain features work. Additionally, documentation with a good search functionality in a large project with many teams can prevent feature duplication.

Telling others what you are up to is no shame

Using turn signals is the most basic form of being a predictable rider. Similarly, code commenting is probably the easiest and most straightforward way of telling others what you are doing. And, just as with using blinkers, it does not make you less cool. I know, there's a common belief that comments are unnecessary because the code should be self-explanatory. But, nah, I don't fully agree with that. Quality code can often be intuitively understood thanks to good variable and function naming, clear structure, and adherence to clean code principles. However, even in such cases, well-thought-out comments can provide invaluable information.


Comments play a crucial role when it comes to complex algorithms or solutions that require additional context to understand. They can explain the "why" behind an approach, which isn't always obvious from the code itself. This is particularly important when the code is optimized for performance, but its intentions and logic are not immediately clear. Comments can also help reconsider whether the chosen algorithm is moving in the right direction.


Comments are lifesavers in complex business logic or project-specific requirements, which might not be obvious to new team members or in case of long-term project support. They help retain knowledge within the team and make it easier to transfer projects between developers.


Of course, it's essential to avoid excessive commenting where comments state the obvious or become outdated and misleading. Their purpose is to ensure clarity and support understanding of the code, not to clutter it with unnecessary information.

Testing: a tool for code understanding and verification

Ok, now imagine we finally learned how to ride and now we want to try our luck on a real race track. Well, we will soon find that real racing is not just about being able to ‘pedal to the metal’. It involves training and testing and fine tuning your machine to suit your habits and racing conditions. Same applies to code: it should be thoroughly tried, tested and corrected if necessary before it can be launched for a real spin. So approaching code testing with maximum responsibility is crucial. Tests are often seen merely as a bug-finding tool, but their role is broader:


  • Error and Defect Detection: Testing identifies errors and unforeseen behavior before the product reaches the user, enhancing quality and reducing user issues.
  • Code Understanding: Creating test scenarios requires a deep understanding of the code's structure and functionality, promoting better comprehension of the program's logic and interaction.
  • Documentation Supplement: Tests can serve as usage examples for functions and methods, helping locate information about the project's functionality and assisting new specialists by providing real-use cases.


Effective testing is vital for producing high-quality, reliable, and understandable code. However, just like documentation, testing can be resource-intensive, particularly in the project's early stages. Balancing the necessity of testing with time and resource constraints is essential.


It is also obvious that absolute test coverage for complex code is simply unattainable. Thus developers must prioritize testing key functions and critical code sections, knowing when to stop to avoid an endless testing cycle.

Love your code like you love thy friend and take care of it

Finally, no motorcycle can be reliable without proper maintenance. There are quite a few people that neglect this aspect of riding, but they make stories (ranging from funny to scary to sad) that we definitely do not want to be part of. In the programming world, just like in motorcycling, code  maintenance isn't just a recommendation but a necessity, especially for long-term projects. Lack of maintenance and updates leads to product obsolescence and security vulnerabilities.


When code isn't updated for compatibility with the latest compilers and interpreters, updating it can (and actually will) become increasingly difficult. Your product might stop working with new OS versions if you're developing a desktop or mobile application. For a website, it might cease to function due to outdated tools and technologies. The simplest issue might be an expired security certificate or outdated software for its renewal.


Regular updates and refactoring are also crucial for maintaining code readability. This keeps the project manageable, simplifying future changes and feature additions.


In short, love your code and devote time to it – but not excessively, or you'll end up like the protagonist of "The Zero Theorem." Good luck!