DEV Community

Cover image for How Do You Ensure That Your Code is Scalable & Maintainable?
Ben Halpern Subscriber for CodeNewbie

Posted on with Erin A Olinick

How Do You Ensure That Your Code is Scalable & Maintainable?

This is a common interview question for new coders, and the goal in replying is to show the interviewer that you understand the importance of scalability and maintainability in coding, and that you have experience with techniques and best practices that help ensure these qualities in your code.

CodeNewbies: How would you answer - or have you answered - this questions?

Experienced Coders: How do you ensure that your code is scalable and maintainable? And what advice would you give for answering this question?


Follow the CodeNewbie Org and #codenewbie for more discussions and online camaraderie!

#codenewbie

The most supportive community of programmers and people learning to code.

Latest comments (27)

Collapse
 
namenotavilable profile image
Adam Markiewicz • Edited

big O notation and comment it properly i suppose

Collapse
 
stalwartcoder profile image
Abhishek Mishra

Thanks @gloriwortiz for putting this! :)

Collapse
 
aradwan20 profile image
Ahmed Radwan

I would start with the following:
1- Break code into smaller reusable components/functions
2- Follow concise naming conventions
3- Write clear and short comments
4- Ask for feedback, if someone else could understand it, then many will do.
5- Build while you're in a tester mindset.
6- CI/CD tool is your best friend to automatically build, test, and deploy
7- Ask if is it efficient, can I write it more efficiently?

Collapse
 
eljayadobe profile image
Eljay-Adobe

How Do You Ensure That Your Code is Scalable & Maintainable?

Lots of excellent answers to this question.

In practice, in my experience...

I tell the PMs that we need to do some work to address the technical debt that had been incurred from the previous cycle.

The PMs prioritize that work. Invariably, it gets prioritized behind all the feature work for the current cycle.

Little-to-none of the technical debt work gets addressed from cycle-to-cycle. New feature work is created which is dependent on the behavior of the technical debt, so that behavior becomes ingrained β€” it's load-bearing behavior, even though it was unintended and expected to have been temporary.

As the intentionally incurred technical debt accrues from cycle-to-cycle, it becomes a drag coefficient that saps productivity. Or the agile crowd would say it saps velocity.

The developers wallow in a mess, productivity suffers, and the total cost of owning a mess is ignored due to the tyranny of the day: getting the next feature out the door.

The code is "scalable and maintainable" only by herculean and sisyphean efforts. And all too frequently, developers have to rise to the challenge again and again to put forth those heroic efforts.

Once the code is in the bad state, some of the policies mentioned in the other answers are imposed on the developers in order to make things better. But those "best practices" policies do nothing to address the underlying problem that the underlying code base is a mess. Dev resources need to be chartered to transform the long neglected bad code into good code.

Collapse
 
szeredaiakos profile image
szeredaiakos • Edited

This is a very interesting question. In my experience, one needs multiple 5year span projects under it's belt to answer this question with any degree of insight. Books can also help. It is definitely not a noob question.

I am in a constant battle with these 2. It is very relevant for me. I can give some insights.

Maintainability is the ability of the code to change. Scalability is the ability of having a piece of code run more work.

The point where these 2 intersect is coupling. Maintainability:

  1. You can't maintain a - lets say - module if it is full of afferent and efferent couplings.
  2. You can't maintain a piece of code which suffers changes for every, seemingly unrelated task.
  3. You can't maintain an application where a request for change regularly forces you to change multiple modules.

In the face of scaling, you could just scale the entire service. That usually only raises eyebrows in your financial department and gets rejected. So analogously:

  1. Breaking away a deeply coupled part of the code involves duplicating the couplings and increasing costs.
  2. shoveling shit in a neat pile is a good idea, but most likely it will stay stinky.
  3. You have to work on 2 services for a single task. That is slow.

Buzzwords:
Testing: tho' you need a degree of decoupling to comfortably write tests, it is not mandatory. You can test deeply coupled code. It's all just a matter of setting up your test-rig.

Common standards and practices: there is 100% chance you will screw up your projects with it. SPECIAL standards an practices is what you are looking for. And, obviously, the discipline to maintain them, and the creativity to change them.

S of SOLID: the S is REASON for change. The reason for change is completely different from what a code does. Afterall, there are hundreds of ways to achieve the same goal in programming. The S drives you towards domain partitioning. 99% of 'vocal developers on the web are erroneously driven towards functional partitioning. In the context of serviceable decoupling boundaries they are just simply wrong. You are not selling "redis connection" to your customers, you are not selling "css" to your customers, you are not selling "main menu" to your customers. What you sell to your customers have, and should have the highest number of changes to ensure most optimal satisfaction.

Code duplication: a piece should repeat at least 3 times in the EXACT form before it becomes a (for ex.) library entry. The actual repetition dictates repetition, NOT speculation. And, parallel code is a far more dangerous than tens of thousands of lines of repeating code.

Code comments: use them regularly. A comment like "// filter users based on roles" is the first step towards creating filterUsersByRoles(users, roles). Either create it on your refactoring phase, or pair program it with someone who can. All comments are TODOs.

Legacy code: legacy code is not necessarily bad code. Always consider that your code is the bad code. Translation and some minor refactoring is probably all you need, rather going after the broken systems of a 6 months exp. developer-youtuber driven by vanity. The prime concepts of software development have been here since 80's. All we did for the past 40 years is mostly rename them and call them "best practice".

Collapse
 
brense profile image
Rense Bakker

When they ask questions like this, they want to hear keywords like: design patterns, loosely coupled, SOLID principles, etc. But honestly no company I ever worked for had achieved truly maintainable and scalable code... Its the holy grail of software engineering. At most what you can achieve is a basic understanding of the code base among all team members that will live on until the last team member with the knowledge is replaced.

Collapse
 
vsnguyen profile image
Vietson Ng

Agree! When I hear people say that they have 100% test coverage, I generally just laugh because I'm sure there are "no-cov" or similar comments everywhere. It's like people way I painted this entire wall brown without using the color blue.

Collapse
 
mistval profile image
Randall • Edited

Maintainability: My favorite trick for this is to architect everything with testability as the chief architectural goal. Not only does this help you to efficiently achieve great test coverage, which itself is good for maintainability (keeps you from breaking stuff), but I find that this approach naturally leads to modular and cohesive code.

Scalability: I wouldn't usually worry too much about mega-scalability up front because it might just be a waste of time. Many, many projects run just fine forever on a handful of machines all talking to one database instance. It's usually hard to know whether you'll need to go beyond that scale or not, and designing for it might be a waste of time due to the added complexity. If you're sure you'll need it, then by all means, design for that up-front. But it really does happen that sometimes people try to design for scalability that they never end up using, I've seen it.

One technique that I like, which preps you for needing to scale, but without introducing too much complexity, is building a modular monolith. What I mean is for example, have a "users" module, a "photos" module, a "posts" module, etc, and have those be separate in code and have them be able to talk to independent database instances. But then just deploy them all as one package and have them talk to the same database instance (but different logical databases inside of it). If that database instance gets too hot one day, and the posts module is mostly the culprit, then pull out the big guns and refactor it to use Scylla or something, and start deploying the code in separate containers. To be honest I haven't had to do that yet in my career, but I'm looking forward to the day!

Modest scalability is a different story. A modestly sized project can still be crippled by bad database indexing and query writing, ignoring time complexity, etc. I don't have any super specific tips about this, you just have to learn about the basic good performance practices of the technologies you're using.

I like to think that I get a little better at these things every day, but I still have a long way to go! These are very hard problems and as others have said in the comments, nobody has all the answers.

Collapse
 
cloutierjo profile image
cloutierjo • Edited

I believe it's impossible to build totally maintainable code initially. First focus on your requirement writing the cleanest code you can as you go, but do not over engineer it before it's needed. Chance are either this requirement is never going to be revisited again and thus you have more complexity than useful or is going to be totally changed in unexpected way and the great architecture you built will be in the way of the new requirement.

Most of the time, keeping the code simple is the most maintainable solution.

The same goes with scalability, don't architecture for scalability before you need it, chance are the boundaries you'll create will be at the wrong place and again in your way.

Some comments may only be visible to logged-in visitors. Sign in to view all comments.