This is our story. For some of us, those with 10 or more years of experience
in software, it might sound familiar. For the others, still in the early stages
of their careers, there should be plenty of advice about what’s coming up next
in your short-to-medium-term future.
The early stages
We are not entirely sure how, but it happens. A light sparkles and we just
fall in love with programming, maybe after finishing building that university
project or the other piece of software we built just for our own use. So much to
learn, so much to experiment with. There’s this very short reward cycle in
programming that increases our dopamine levels continuously and makes us
addicted to it. We have been bitten by the programming bug, but don’t worry,
it’s not a disease, it’s just brain
We find our first place to work, and we feel very lucky to have been hired for
the job. We start as incredibly self-motivated, we are ready and willing to
learn everything about everything. We don’t mind picking up any of the tasks at
hand. Ticking them off the to-do list gives us that reward our brain is looking
for. We don’t really mind what projects or technologies we are working on
either, as long as we get to learn and build new things.
At this stage in our career, though, we might just not be asking enough
questions. Usually, we think it’s probably because people are just ashamed to
ask, of admitting that they don’t know something. Depending on the personality
this can definitely be the case, but sometimes, as engineers, we just prefer
wasting hours on a problem and get to a solution ourselves rather than asking
for help. This might go back to the reward system, it’s great for our brains to
manage to fix the issue at hand, there’s no satisfaction in being given the
answer to a particularly hard problem. If you can relate to this, make sure you
do ask questions, there’s plenty of challenges ahead, you want to make sure you
maximise the knowledge you gain from the time you spend on this planet and
asking questions is a great way to do just that.
Absorbing the knowledge of someone that spent years learning from his mistakes
in a fraction of the time is invaluable.
We also tend not to challenge our mentors too much, blindly following their
advice. Don’t get me wrong, this is usually good practice, but we should also
make sure we validate things from time to time, especially when they don’t feel
right. At times mentors do tend to become a little overly pragmatic and might
need a shake up. Take your time to build a showcase for what you think is an
improvement so they can easily evaluate it, if it’s good they will embrace it,
they should be experienced and smart engineers. If it won’t work, or it’s not an
improvement, they will help you understand why, and these are all valuable
Another common mistake in our early days is going fast, and I mean, really
fast. We want to demonstrate we are performant, we write tons of code, but
sometimes we are not even sure whether we are actually building the right thing.
This can be a massive waste of your time, so please, slow down, clarify the
requirements again, take a long breath, and work on your tasks with a more
The “fun” game of jumping ships
The first few months or years go by, we reach the point where we seem unable to
step up our game. Our colleagues now look less knowledgeable than they did
before, even our best mentors don’t look that special anymore. We’ve absorbed
all the knowledge we could, so we start looking around in search of a place
where our learning adventure can continue.
We also become a little stricter in our job search, we now want to work in a
place where not only we can keep learning new things we know nothing about, but
where we could also use our favourite technologies to build wonderful things.
During this period we might jump a lot of ships, companies look great on paper,
but once inside it gets boring pretty quickly.
perseverance, we find a great place to work again, or at least one that suits
our current needs, and we get back to work.
There is no such thing as over-engineering
We’ve evolved over time, and if we are unlucky enough, we have developed an
achieving perfection in our code. Refactor after refactor after refactor your
code becomes more and more beautiful to your eyes and more and more obscure to
the other members of the team.
A word of advice*: try to write down how long it takes you to write down your
new beautiful DSL, or super-generic uber-abstract future-proofed solution (that
is only currently used in a couple of places in the codebase). And in addition,
double check your “git diff”.* Have you really improved your code after that
refactor? It’s usually a good sign if you managed to remove a big chunk of
code from the codebase, otherwise, you can always choose to reconsider and
park it in a branch for the time being.
At this stage in our career, we always want to demonstrate how smart we are to
the rest of the company, or the rest of the world. We need this in order to get
that dopamine shot we need to get through our days at the office. Normal tasks
do get repetitive, so this is our escape route. We start spending a lot of time
innovating on what already works and not enough time writing code that is
actually solving business problems.
Even if we know a way that works well and it’s battle-tested in production, we
still seek for “new” ways or magical improvements. We tend to spend a lot of
time trying to refine what’s already working quite well and is clearly
understood by the engineering team.
One of the best pieces of advice I can give for these situations is the
following: having code that works in production gives you more time to
evaluate new methodologies, cutting-edge frameworks and experimental libraries
during not particularly busy times. The stress that comes from new mysterious
production issues is no fun. Make sure you experiment in less critical parts of
the system or build a few well-tested side projects. This will make production
adoption much easier as you will be able to share what you’ve achieved with your
colleagues, get feedback, and eventually manage to have a smoother transition of
your improvements into production.
Another common pitfall is trying to make everything work 100% of the time.
We consider every possible minor edge case and write tons of complex code to
handle it (which might actually make things worse), making the codebase harder
and harder to maintain. You might think this is the only way, but it isn’t.
Imperfect systems are sometimes fine from a business perspective, just ask the
business for their opinion, they might prefer to use their resources and time to
move on and build the next feature instead, and just send an email to a human to
manually fix the problem if it occurs.
Why do we follow the buzz?
Another thing that happens naturally during our careers is this: we just put
the world on pause and start learning something new. It can be a new language,
a new framework, a new methodology, an entirely new area of development, or
something different. But how do we choose?
Sometimes, something just attracts our attention because it seem to solve one of
the problems we are currently facing. Sometimes we just do it because it feels
like the whole world is moving in that direction. Sometimes it’s only for the
sake of getting a better job.
The tricky part is how to learn how to distinguish temporary noise from actual
industry-changing technologies. The only advice I have on how to approach this
comes down to trying things out yourself, and I mean, really trying them
Spend some relevant time on it, don’t just read blog posts about it, dig deeper,
come up with your own pros and cons list. Does it really solve the problems it
is claiming to solve?
After endless time spent mastering frameworks and libraries, I’ve learnt that
the most important thing is keeping them at the edges of my software systems. If
they turn out to be heavily bugged, abandoned or superseded by new alternatives,
they could be easily replaced.
Learning to cut through the noise will make you a much better engineer. New
technologies come up every day, no one forces you to use them.
A very good step towards maturity in software engineering is to prioritise
having working production code over new buzzwords to put on your CV. It can be
tricky at times, and it does not sound cool saying this in an interview, but it
should be far more valuable to a company to have working and maintainable
Please note: this does not mean we should stop being curious or not spend
time on learning the next big thing. We should just try to balance things out
while learning to keep having fun from the junior members of the team, but
accept that you should get the job done sooner rather than later.
The road to greatness
During the transition into more senior positions, we tend to grow more and
more pragmatic. This tends to make us look a little annoying and less
competent to the junior members of the team or the engineers we are currently
mentoring. We also tend not to code as much as before, some of us think trivial
tasks are beneath us, which amplifies the problem, try instead to lead by
example and close down those trivial or boring tasks yourself.
Having enthusiastic team members can help us remember that we should try to
remain curious and keep learning. We should keep trying things out, our
expertise will help you make a much more informed decision on which tech to pick
up compared to a few years back in your career.
It’s not easy to generalise how a senior software engineer looks like after
decades, though. We tend to evolve in different directions, but we still share
the same potential issues.
We are much more likely to fall into the trap of under-engineering. Our
experience now tells us that early abstractions are not going to work most of
the time. Just remember, if your team doesn’t enjoy working on some parts of the
codebase, it’s a sign that it might have been under-engineered and left behind.
It might need improvements, so prioritise it whenever you have time to address
Another likely danger is becoming a victim of our own cargo cults, the ones
we’ve developed over the years. Make sure you challenge them from time to time.
A note on humility
Years of experience don’t directly translate to better-written code, keep asking
for opinions and code reviews. Sometimes I ask my wife (she’s not a
programmer) to proofread my code to see whether she can understand what it
You’ve probably heard this one before, but your experience should have taught
you one critical thing: you can’t know everything. Anyone can still teach
you something you don’t know anything about.
Don’t give up
We all have highs and lows in our software engineering careers. Some of us start
prioritising money over job satisfaction, ending up in either contracting roles
or highly paid boring jobs. Some might move into management in search of a
It can be intellectually challenging to have to deal with a continuous stream of
problems, and in software, this is just how things are. It’s impossible not to
experience those days where it’s just too much to take in, and think: “*Why am I
still doing this? *Everything is
If you feel like you need a change of career, take a break. It usually works
quite well to just disconnect for a few days or even a few weeks. You won’t
believe how much revitalised you will feel when you come back, actually craving
for something to build, or a big mess to sort out.