Growing as a Software Engineer
My experience of being a software engineer changed quite a lot since the beginning. I hope that my journey proves helpful, inspiring, or just plain fun.
Let’s start at the beginning…
Stage 1: OMG! My code works!
As any software engineer would tell you, the moment when your first code works is a special one. You can feel the power, the rush of adrenaline, and hunger for more.
You don’t care how the code looks like, as long as it works, and that’s okay. This is the right time to play and make a mess. I know I did.
You can recognize yourself (or a junior colleague) in this stage if you see yourself getting to the point where your code works, feeling proud, and saying you’re done.
Stage 2: Perhaps I could reuse this…
After a while, you find yourself saying “OMG” again, but this time because of seeing the monster you’ve created. You have no idea where anything is, and there’s no way to change anything because it’ll come crashing down (literally).
However, you start seeing repeating code patterns and this brings you to the next stage — reusing code. You start with creating functions and this cleans up the code pretty nicely. At this point you can find your way around the code again, so you start producing more and more features.
As your code approaches a thousand lines, even functions can’t help you. Luckily, classes come to the rescue and you learn how to encapsulate similar functionality in logical units. This is a big milestone in your career because it teaches you the basic principles behind good software. However, it doesn’t come easily — you’re literally learning to think differently.
Stage 3: Seeing the Matrix
As the complexity of your projects increases, you start seeing larger patterns. You figure out how to organize your code into modules, libraries and services, so you can reuse them on different projects. You can see how those units interact with each other and what their roles are.
At this point you consider yourself more of an architect than a coder. You’re building virtual universes with their own rules and agents. You don’t care anymore about if-s, else-s, loops, functions or even classes. You care about the responsibilities of your components, how they communicate, and the flow of information. You’re probably spending more time in front of a whiteboard than a computer.
This is a very empowering stage because you feel that you’re also starting to understand the real world better. You can see the repeating principles, the basic forces behind everything, and sometimes even influence them.
Stage 4: There’s no perfect world
As you shape your virtual universe, you start being frustrated. You start seeing multiple ways to achieve the same goal, but none solves the problem completely. It’s like a law of physics that doesn’t allow you to craft a perfect solution. Your younger self would’ve just picked the first solution that comes to mind, but you start seeing “the other side” — every solution has its consequences down the line.
You now have to learn how to make good trade-offs:
- Will you go with asynchronous requests that improve performance but introduce complexity and increase chances for bugs, or with synchronous requests that do the opposite?
- Will you introduce another programming language into your stack in which you’re able to solve a particular problem quickly, knowing you’re forcing others to learn another thing, risking unknown bugs and introducing more maintenance?
- What about replicating databases? Using microservices? Centralization or decentralization? …
Stage 5: Code doesn’t matter, people do
After solving many technical challenges, you feel like you finally have a good grasp of the insane complexity of software engineering. The code looks good, everything (mostly) works, but somehow you feel more and more behind with the business demands.
You realize you can’t do it alone, so the team starts growing. Soon enough, one of two things (or both) will likely happen:
1. You have even more work to do because every decision has to go through you.
2. You feel like you’re losing grasp and the codebase is diverging in uncontrollable directions.
Either way, you find yourself writing less and less code. Your role is no longer to be the smartest and solve hard problems. This is hard to accept because solving challenges gave you a steady dopamine flow and that’s how you measured your self-worth.
However, you’re still a problem solver, whether you decide to go on the management path, or towards being a the tech lead. The trick is to reframe the picture. You’re not solving bugs or service performance issues anymore, but you’re solving team efficiency problems, making sure everyone understands the goals, ensuring quality with processes, and above all — sharing knowledge.
It’s now your job to make sure your team is building the right things, doing so efficiently, and growing together. If you imagine your company as one big machine, you can see that your job didn’t change much, just your tools. Some of the questions you may face:
- How will you track progress and measure success?
- Will you invest a month to build a stable solution or create an ugly but working prototype in a week?
- Will you buy an off-the-shelf solution or implement your own?
- How will you share knowledge in a scalable way?
- Which guardrails will you implement to make sure your team is safe?
- How will you measure someone’s performance and ensure they have a quick feedback loop?
- How will you make sure everyone is working towards the same vision?
Those are often more challenging then engineering problems, but also more rewarding in the long run. If you succeed, you’ve multiplied your impact and created a culture that will continue to reap the rewards generations down the line.
This is story of how I experienced my journey and how I see the path ahead. I have shared my journey with the hope of helping those that are just starting out, or feel like they’re stuck. I would love to hear from those with more experience to shine more light on what lies beyond.
For more growth advice see my previous blog post: https://betterprogramming.pub/junior-to-senior-developer-in-2-years-3740bd8f8cca