Estimated reading time: 7 minutes
Want to become a better software engineer?
What if I told you it was possible without any code?
And there was not one way, but three different ways! (We'll get to those in Part II and Part III)
Now, you'll notice I never said that these were easy changes. Or that they would be easy to incorporate as habits.
This article will show you to become a better software engineer by learning to prioritize between the "urgent" versus the "important".
This will take work, and dedication. The payoff? You'll lead your field as a software engineer.
As a software engineer, you are going to run into tasks with different priorities.
And these tasks will have real business impacts.
And it's going to be up to you to determine between what's important, and what's urgent.
As our 34th president Dwight D Eisenhower once said, "What is important is seldom urgent and what is urgent is seldom important".
There's even an entire Eisenhower decision matrix to help you prioritize .
But to keep things simple, I'm going to go over the big idea: As a software engineer, it's your job to balance the urgent things with the important things.
Let's define "urgent" and "important":
Urgent tasks demand your immediate attention. These include situations where your software takes a catastrophic outage. Generally speaking, it's a fire and you need to put it out.
On the other hand:
Important tasks benefit you in the longer term. These tasks don't demand your immediate attention and may not even provide any upfront benefit. Think of these tasks like planting a carrot. You might not see any results immediately, but you'll have something to eat three months from now.
If you want to move to the next level, you need to learn how to balance the two.
It's hard because urgent tasks shout at you to get them done. You also get a sense of satisfaction as you put out these fires. However, my advice to you is to minimize the time you spend on urgent tasks, and maximize the time you spend on important tasks.
By definition, software engineering itself is an important task.
What I mean is most non-technical people look at code from the surface with a binary yes or no approach: Does the code do what I want it to do? There's only two answers to such an absurd, reductionist question.
But as engineers, we know that there's more to it. There's different gradations of solutions. Sure, you can live in a house made of mud and sticks. And you can also live in a modern home with indoor plumbing and air conditioning. To ask the question of ,"Can you live in it?" misses the point entirely.
Let me return to what President Eisenhower said about the important and the urgent. If you want to make it to the next level, by definition, you have to be able to do the urgent things by putting out fires. That's basically the barrier to entry.
However, what's even more important is to have the foresight to do important things with a delayed payoff. This will actually result in you having to put out less fires.
Software engineering is important because you are dealing with almost pure thoughts. And working with pure thoughts is very difficult. As Fred Brooks said in The Mythical Man-Month:
The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by exertion of the imagination.
And in order to do software engineering well (building a modern home, and not a mudhouse), you have to do all of these upfront tasks that provide little to no immediate benefit like coming up with a clean design or a proper testing strategy. I can't even make this up. This is inherent to "doing" software engineering.
But that's not all. Software engineering is an annealing process. So you have to go back and continuously refactor and improve it, which again, doesn't provide any visible functionality!
But think about what you're doing: You're taking all this "thought-stuff" in your imagination and translating it into code that meets a business need. How much more vague and hand-wavy can you get? Software engineering at its core is such an ambigious process that it is impossible to scale an organization without investing time in important tasks.
My point is:
If you want to do software engineering well, you have to prioritize doing the important things over the urgent ones, even if it seems like it should be the last thing you should be doing.
Yes, I am saying, and giving you permission, to add extra unit tests, take more time to flesh out your design, and to take another day to come up with a proper CI/CD process, even though it might delay adding new functionality or features.
When you do software engineering correctly, you write more robust code, and you build better software, period.
The more you focus on doing important things with a delayed payoff, the less time you have to spend putting out fires.
But how do you actually do this?
Wondering how to get started?
There are two scenarios here, and they are both straightforward.
The first scenario is when you have a greenfield application. Unburdened and free of any prior constraints, poor architecture, or other anti-patterns. You really need to come out guns blazing here. Ideally the senior engineers on your team will be working on a clean design and a proper testing strategy.
Ask to be included in those meetings so you can learn.
On the other hand, if those aren't on your team's radar, this is an area where you can stretch your wings and lead the effort. Learning by doing is one of the most effective ways of learning. Ask questions, work with the senior engineers, and most importantly, don't be afraid to speak up and contribute. Even if your design isn't right, you are still taking the initiative to do things the right way.
But what if you're not building a greenfield application? Maybe you've inherited a ball of mud. How do you start?
It's important to adopt a piecemeal approach. Obviously, you're not going to have the same freedom with a greenfield application, so you're going to have to work in small chunks.
Here's an example:
You're adding some new functionality and you notice that there aren't any unit tests written. What do you do? Do you open up the PR without unit tests thinking, "Well, there weren't any unit tests for it in the first place, so that makes it okay for me to add code without testing it"? WRONG!
Of course you need to add unit tests! Remember - the title of the article is How To Become A High Performing Software Engineer. You should add those missing unit tests.
The point I really want to drive home:
You should always focus on building for the future. Even if there's no immediate payoff today, I guarantee you will see the fruit of your effort later down the road. In the example I just gave, we can very clearly call out the urgent vs the important.
The urgent task is to finish the feature. The important task is to add that extra unit test. As a high performing software engineer, it is your responsibility to reach higher and do both.
Now these were two examples. There's going to be many more scenarios in your own career that demand you to make the right decision between doing what is urgent and what is important. Sometimes it'll be really obvious, and other times not so much.
And to be honest with you, there may be 100% valid cases where you have to forgo the important task and think very short-term. It just doesn't make sense to put in the work for a delayed payoff. You will definitely encounter those.
But the thing to remember here is that you should trend in the direction of spending more time on important tasks, than you do on urgent tasks that don't provide anything substantive. Invest in work that leads to a delayed payoff.
Write another unit test, add another integration test case now, so you can have a smoother ride later.
I'll see you guys in Part II!