2022 Performance Review

2022 was my first year as a full-time software engineer. I'm grateful that from the beginning it was a smooth, natural transition. After finishing my undergrad in December 2021 and wrapping up my time as an engineering intern, the only discernible change in my day-to-day was the number of hours I worked. Credit for this goes to SimpleNexus, who places an astonishing and enabling amount of trust in their interns.
As always, it's been a year of learning and stretching. Looking back and completing a performance review was surprisingly inspiring, and I'd like to synthesize a handful of core points from my ~1,500 word official report.
(I wouldn't have blamed my manager if he immediately sent that novel back. As the frustratingly un-quotable saying goes, "If I had more time, it would have been shorter.")
I won't summarize everything, but here are some of the most impactful lessons I've learned and things I've changed.
Decisions informed by 100% understanding
Software engineering is often characterized by becoming familiar with systems. It's an everyday practice in the first 2 years of working at a new company, and remains common for even longer at fast-moving companies. Having checked both of those boxes, this year was an exploration through the dark woods of complex configuration, third-party systems, legacy code, and unexpected but suddenly vital new processes.
During this journey, I noticed an internal compass tracking how familiar I felt with this particular patch of trees. Could I give a fellow traveler directions? Or are there still areas I haven't explored yet?
It's important to feel that familiarity with a system before making decisions that impact it. In fact, I'm so convinced of this that I push (at least myself) for "100% understanding".
What is 100% understanding? It's not the next pair of cultural buzz-words, but it is a clear bar of comprehension before commitment. It's doing everything we can to be informed before going down a road that could be expensive to backtrack.
The cautious engineer will point out that "100% understanding" is arrogant and unattainable - and they're probably right. It's debatable whether a perfect understanding for any system is really possible. Yet many engineers (myself included) often assume they understand every detail.
Just as it's dangerous to make uninformed decisions, it is equally dangerous to overestimate and assume. But 100% in my mind doesn't refer to 100% of "everything out there". Instead it means "everything I know about" or "everything I'm aware of". If there are any unanswered questions or complexity tickling the back of my mind, I feel that it's important to seek that out.
I'm still not perfect at this. Especially in high-stress situations (like responding to escalated support tickets), it's tempting to seize the first explanation I come across. But I try to slow down and reach a sort of zen before acting on each problem to be solved. I've found that this helps me make the better choice more often, and reach the destination faster.
Make documentation a habit
In our team's recent sprint retrospective, I was reminded of a quirky engineering personality trait I have: genuinely enjoying writing documentation. Call me crazy, but a fresh Confluence doc is one of the things I look forward to most when digging into a new project.
This enthusiasm for documentation is related to my thoughts around "100% understanding". What good is that understanding if it only exists inside one engineer's brain? The industry knows that tribal knowledge and low bus factors are bad, but a healthy culture of documentation can still be rare.
What motivates me to write documentation is picturing how useful it will be for me and my coworkers in the future. It's like a warm security blanket - I can sleep soundly knowing I won't need to retrace my steps the next time I need to understand these settings or support this request. Also, like all good habits, it's self-reinforcing. Every time documentation saves me time and headaches, my eagerness is boosted.
Present potential solutions instead of problems
This principle has been on my mind for a while. I've sat in a lot of meetings where the attendees have talked through difficult problems. While I know this practice can produce elegant and team-driven solutions, in reality I often find myself exhausted afterwards without clear direction. The common denominator for this feeling of exhaustion is big, new problems. Problems that have only just been introduced to everyone there.
In my experience, the best solutions to these problems don't begin during a meeting. High quality solutions require a careful understanding of the problem (do I sound like a broken record yet?), which is impossible after a 5-minute explanation.
Does the following scenario sound familiar? A teammate encounters a complex question that will require a thoughtful solution. The question is raised at the next standup meeting, where it takes about 10 minutes of follow-up discussion to make sure everyone understands the context. What happens next is a sort of old-West style, "shoot from the hip" brainstorming. Everyone presents their first impressions, often realizing or pointing out flaws on the spot. Even if a solution is agreed upon, it's likely that everyone involved will have a different opinion 30 minutes after the meeting is over.
What works better? I don't have the silver bullet, but I believe it's important to always bring at least one potential solution to these discussions. This is helpful for two reasons:
- It clarifies the problem. Complicated technical issues can be difficult to present accurately. Even a mediocre solution will help drive home the core problem that needs to be solved.
- It provides a more defined foundation for discussion, and catalyzes more solutions. It's remarkable how quickly this can happen. Time previously used to come up with (and then weed out) first-draft fixes can instead be immediately applied to second and third drafts.
With all that said, I hope no one ever feels discouraged from bringing up a problem without any prepared solutions. This will happen to everyone, and it's what teams are for. When those situations inevitably occur, I find it's helpful to acknowledge that we don't have to decide on the best solution right then. Initial discovery can be delegated ("I can spend time exploring our options here") or committed to as a team ("Let's all take 15 minutes to brainstorm around this problem before our next meeting").
Looking forward
I'd like to focus on these areas in the upcoming year:
- Resolve the root problems (not just the surface issues) with forward-thinking solutions. My team has set a similar goal of replacing existing manual processes with automated or self-serve features.
- Simple solutions to complex problems. Over-engineering is obvious in hindsight because the unnecessary pieces stand out. In contrast, simple approaches stand out now and later. I'm especially excited to iterate towards simplicity, continually asking the question "How can this be streamlined?".
- Building sustainable front-end code. This is at the same time the most technical and the most vague of my goals. I've noticed that front-end code has a tendency to quickly become confusing and unnecessarily complex. Is it possible to approach the front-end in a way that invites healthier changes? Stay tuned to find out! (I have a hunch that ridiculously small components may be a good step in the right direction).
What are your thoughts? How did your approach to engineering change last year? What did I get terribly wrong here? Let me know! Feel free to reach out directly 📬
Thanks!