My #1 Strength is Competition. I enjoy being good at things. I really like being able to benchmark my performance against peers and/or standards. I love being able to outperform everyone else.
Without a doubt, running has stoked my competitive spirit. I ran cross country and track on teams in high school and college. I qualified for and then ran the 2018 Boston Marathon. I finished 31st of 18,355 participants in the Marine Corps Marathon in Washington, DC. I won the Race 13.1 Durham half marathon outright.
However, I did not make it to the starting line of the Boston Marathon without training. I put in consistent work over the course of many years to build the strength and endurance needed to tackle that challenge. I would have to do the same in software.
Serious runners make serious training plans. To become a serious software engineer, I made a plan. The plan consists of three strategies: write code, connect with a community, and develop expertise. Together, I believe they have helped me outpace others in my learning and put me on track to continue to improve for years to come.
Strategy #1: Write Code
To become a better developer, you must write code. Convincing yourself that you understand a concept is profoundly different from actually implementing the concept in code.
I spent a long time thinking that I understood how authentication works. At the most basic level, it sounds simple enough. You provide credentials to prove you are who you say you are, the server verifies them. But authentication has not been that simple for a long, long time. Now, there is typically a “handshake” that occurs between you or the application you are using and an Identity Provider. Information goes back and forth several times, using asymmetric encryption. There are also an endless number of ways that the authentication process can be exploited if it is configured incorrectly. You will find a wide range of opinions on if you should store credentials, where to store them, and what should actually be stored.
I tried to get my head around authentication for months. But it did not start to make sense to me until I implemented authentication in a few different applications. I followed a very detailed guide on authentication in NestJS, then I created a proof of concept app that used OAuth2, and finally I developed a Shibboleth authentication microservice.
My projects loosely followed a progression that evokes a quote usually attributed to Kent Beck:
Make it work, make it right, make it fast.
The purpose of my first attempt was to make something, anything, that worked. Not something that could necessarily be put in production at Google. Just something that ostensibly did what it was supposed to do. I followed an existing guide. The happy path seemed to work. Mission accomplished.
The next attempt was to implement something that might more closely meet my needs. I have built applications that rely on external providers (like Google or Garmin), so using an OAuth2 process often makes sense for me. Luckily, OAuth2 is extremely well documented by multiple sources, so I had plenty of resources to turn to along the way when I got stuck. Eventually, I ended up with a functioning login process that I could apply to real applications.
Finally, I wanted to make the authentication process reusable, so I built a microservice that was compatible with the identity provider we use at work. This time, I took care to consider the choices that I was making along the way and how they might impact me in the future. This time, it needed to be ready for production.
However, if you think I got it 100% right on the first (or third) try, you are mistaken. I sent my code out to be reviewed for code quality and a security audit. At each step, I got helpful feedback that something could be improved or made more secure. This is where I learned the most.
Instead of dealing with abstract concepts or hypotheticals, I was now improving actual code that I wrote. The lessons learned here were immensely valuable. I was becoming a better developer.
Strategy #2: Connect with a Community
Software is for people. It may run on machines, but it is designed by people, built by people, and used by people. People are the most important part of software.
Human beings, who are almost unique in having the ability to learn from the experience of others, are also remarkable for their apparent disinclination to do so.
- Douglas Adams
You have something to learn from everyone you encounter. So, it makes sense to make a point of encountering others if you intend to learn. However, not all opportunities are equal. A great professional community should:
- Encourage members to share their expertise for the benefit of others
- Provide a forum to discuss issues and trends in the field
- Contribute to members social and emotional well-being
Not every organization does these things. I have attended several events in the past that were billed as technical presentations but turned out to be thinly veiled sales pitches. It was clear to me that I was not in the right place when I had people I had never spoken to chasing me out of these events to ask if we could connect on LinkedIn. The answer was no.
In contrast, one group that I have enjoyed being involved with is Devs @ RTP. From the very beginning of my journey, they hosted presentations on topics that interested me, and people who wanted to keep the conversation going afterwards. While I can make no promises that your local groups will be as cool as Devs @ RTP, you should explore what is available in your area.
In a different way, I have also found podcasts to be a good way to get a feel for what is going on in a particular community. Sometimes they cover broad subject matter, like Programming Throwdown. Or sometimes they are more specific, like Angular Air, and Go Time. Each of these has struck an excellent balance by having a large enough following that you can engage with other listeners, and small enough that you might also get to talk to the hosts.
Finally, I have recently become more engaged in the Go community. There is a massive Slack workspace (55,000+ people in the general channel, 1,400+ channels) but it is filled with influential figures in the community. One of my first interactions, I had just watched a YouTube video of a conference presentation, then found my questions being answered on Slack by the presenter of the session I had just watched. I was able to directly say thank you to the hosts of a podcast I enjoyed. There are channels for a number of my areas of interest where I can get great feedback from real people.
Different kinds of community suit different people. Find one that makes you feel like you belong.
Strategy #3: Develop Expertise
Stop me if you know this one…
We’re looking for a junior developer. Requires 3+ years of experience in Java EE, 2+ years of experience in ASP.NET, at least 4 years of experience with Azure SQL, 3+ years of DynamoDB, 2+ years of Anthos.
Nice to have: Core maintainer of Kubernetes. Show us the web browser you designed (must have at least 2% market share worldwide). Will need to write a COBOL compiler during 30 minute technical interview. Advanced juggling skills preferred.
After reading job descriptions like this (okay, maybe not exactly like this, but close), no one should be surprised that software engineers often feel overwhelmed during the search process. Many job descriptions are not realistic. In some cases, there is literally not a single person on the planet who will be able to fulfill all of the requirements and “nice to haves.”
Many people, myself included, tried to cope with this early on by learning everything possible in an attempt to become the mythical “full stack” developer. But there are too many languages, skills, and technologies to learn. You will not be able to. Better people than you and I have tried and failed.
However, you can usually dig very deep on something and become the most knowledgeable person you know on that subject in a relatively short period of time. In my first months as a full-time developer, I kept hearing about and seeing references to Kubernetes. But I had no idea what it was. In fact, no one in my immediate circles knew a whole lot about it. I decided to find out.
I quickly realized that there was a reason people were talking about Kubernetes. And that it could be part of the solution to problems I was encountering. I decided to spend some time learning and experimenting. Then I presented what I learned to a small group of developers at work. More people than I expected showed up, and some of them began looking into it, as well.
The next year, I was invited to attend a multi-day intensive training with developers from another department because they knew it was an area of interest for me and because I had helped get others interested. By no stretch of the imagination could I have called myself an expert when I gave that first presentation. But I continued to learn. When I attended the training the next year, I found myself well situated to share actual experience with my colleagues and give folks someone to reach out to when the trainer was no longer around. Right or wrong, for some people in that small circle, I was now their local expert on Kubernetes.
Perhaps you expect me to conclude by telling you that I got a new job at a big tech firm that pays an unimaginable amount of money. Or that I built some impressive piece of software that you use every day. Or that you should now buy the wonderful products I sell.
But none of that is true. I doubt that is how the story goes for most of us. Despite my competitive instincts, I do not find it especially meaningful to measure my success in dollars or GitHub stars. At this point in my career, I measure myself in learning and progress.
My story is that I planned to become a better software engineer. I wrote real code that is used in real applications, I found people who share my interests and communities where I feel I belong, and in some circles people now look to me as an expert on some topics. After two years, I am not a junior developer playing in a sandbox. I am a software engineer ready to rise to any challenge.
If you are also an ambitious developer who wants to tackle big problems and get better at what you do, what is your plan?