Six years ago I wrote about five lessons I learned as a beginner software developer. Back then the lessons were about learning to write code: building a foundation, mastering concepts, and putting in the reps until things finally clicked.
The job looks a lot different now, because as a senior engineer I write far less code than I used to, and lately, with AI doing most of the typing, I barely write any at all. The hard part stopped being the syntax a long time ago, and what actually moves the needle now is judgment, communication, and knowing which problem is worth solving in the first place. Here are six of the lessons I’ve picked up on that side of the desk.
1. Listen to Problems, Not Solutions
When you collect feedback, people rarely hand you a problem; they hand you a solution. A stakeholder asks for a button that exports to CSV, or a user asks for a setting to turn off the thing that keeps interrupting them, and if you take those requests at face value you’ll spend your time building exactly what was asked for, which is not always the same thing as building what was actually needed.
Your job is to peel back the layers and keep asking why they want it. Maybe they want the CSV export because they’re copying numbers into a spreadsheet every Monday to build a report that nobody upstream actually reads in that format, or maybe they want to silence the interruption because it fires at the wrong time and not because the feature itself is useless. The proposed solution is a window into the problem, but it is never the problem itself.
This matters because the solution someone reaches for is usually a bandaid, since they’re working around a roadblock and the workaround is the only fix they can picture from where they happen to sit. When you understand the actual problem, you can sometimes remove the roadblock entirely instead of paving over it, and that is the difference between shipping a feature and actually fixing something.
So drill down and keep asking why until you hit the real constraint, because the best solution is often one that nobody requested, simply because nobody on the outside could see the whole picture.
2. Learn to Speak to Your Audience
Being right is not enough on its own, because if the person across from you doesn’t understand what you said, then your correctness never actually left your own head.
Engineers default to the deepest level of detail we have, because that’s the level we live at, but the business stakeholder deciding whether to fund your project does not need to hear about the database index you’re worried about. They need to hear what it costs, what it unlocks, and what the risk is if you skip it, while a functional partner needs to know how it changes their workflow and the end user needs to know what changed and why it helps them. It is the same underlying truth every time, but it turns into three completely different conversations depending on who is sitting across from you.
Learning to read the room and adjust your register on the fly is one of the highest-leverage skills you can build, because it is what lets you turn a technical reality into a decision that someone else can act on. I’ve watched great technical arguments die in a meeting because they were pitched at the wrong altitude, and I’ve watched mediocre ones win because they were explained in terms the audience actually cared about.
Match the level of detail to the listener, lead with what they care about, and save the depth for the people who asked for it.
3. Refine Relentlessly
Scope creep is real, and it is patient, because it rarely shows up as one big bad decision and instead arrives as a steady drip of reasonable-sounding additions, each one small on its own, until the thing you set out to build has tripled in size and quietly lost its center.
The defense is to constantly question what actually needs to get done, not what would be nice to have and not what someone might want eventually, but what this specific piece of work needs to accomplish and what the smallest version of that worth shipping actually looks like. Everything that doesn’t serve the goal is a candidate for cutting, and most of it should be cut.
Spreading yourself thin trying to do everything is just as dangerous as doing nothing at all, because both end with nothing finished to a standard you’re proud of. I would much rather do three things and execute them really well than take on ten and deliver ten mediocre results, especially since the ten will cost you more, teach the people around you that your work needs a second pass, and leave you exhausted on top of it.
Doing fewer things well beats doing everything poorly, so refine until what’s left is the part that actually matters, and then go do that part exceptionally.
4. Constant Feedback Is Essential
Engineers get feedback for free and we barely even notice it, because every pull request is a built-in checkpoint where someone else reads your work, questions it, and catches what you missed before it ships. We’ve so thoroughly normalized this that we forget how unusual it is to have a structured second opinion baked into the daily workflow.
The lesson is to extend that loop everywhere else, because proposals, research spikes, technical specs, and architecture decisions all get better when someone else pokes at them before they’re final. The PR process feels obvious because it’s automatic, and the trick is being just as deliberate about it for the work that doesn’t come with feedback built in.
And feedback is more than collecting comments, because the real value is in actually using them. It takes humility to hear a perspective different from your own and let it change your output, especially when you’ve already grown attached to your version, but other people see angles you can’t, and the work is almost always better for it. Output shaped by good feedback beats output created in isolation nearly every time.
Stay humble, ask for the read before you’re done, and treat the response as something to act on rather than something to merely acknowledge.
5. Make Your Work Visible
It is easy to disappear into the work, picking up a ticket, finishing it, picking up the next one, and repeating that cycle indefinitely. The work gets done, and it gets done quietly, but the problem with quiet work is that it caps your influence at the boundary of whoever happens to be watching, which is usually nobody.
Making your work visible to your manager, and to leadership more broadly, opens doors that would otherwise stay closed, and your influence grows when you can both produce consistent results and make sure those results are actually seen. Some of this happens naturally as you seek feedback, because asking for input on your work also surfaces it, but a lot of it is as simple as letting your manager know what you’ve actually been working on.
This is where a lot of engineers, myself included for a long time, get it backwards. In one-on-ones it’s tempting to spend the whole time on roadblocks and what’s going wrong, because that’s what feels urgent, but you should bring those and bring the wins too. Talk about what went well, what you’re proud of, and the thing you think you’ve been doing better than anyone gives you credit for, because nobody else is going to narrate your contributions for you.
Do good work, and then make sure the right people actually know that it happened.
6. Never Stop Learning
I said this in my first post, and it’s worth repeating because it has only become more true with time, since being an engineer is a commitment to learning for as long as you choose to do it.
As a senior it’s doubly true, and for a reason I didn’t expect, because I write less code every year and with AI now writing most of it I sometimes write none at all. You might think that would make deep technical knowledge matter less, but it’s exactly the opposite: when you’re not the one typing every line, your understanding of systems, software principles, and the technologies underneath everything becomes the entire value you add, since you have to know what good looks like in order to recognize it, to steer toward it, and to catch the moment it starts going wrong.
The tools will keep changing, but what doesn’t change is that the people who understand how things actually work are the ones who stay useful no matter what those tools eventually become.
Looking back at the lessons I wrote down six years ago, they were almost entirely about the code, and yet the lessons I’d give now are barely about code at all. They’re about problems, people, and judgment: hearing the real problem underneath the request, speaking so that the person across from you actually understands, protecting your focus, taking the feedback, making the work visible, and refusing to coast on what you already know.
That’s the part of the job that doesn’t get automated, because the code was always the easy part, and that has never been more obvious than it is right now.
Keep learning, because the ground keeps shifting under all of us, and that constant shifting is the best reason there is to stay curious and never stop growing.