Originally posted on McKinsey Digital: https://medium.com/digital-mckinsey/3-mistakes-i-made-learning-the-software-engineering-skillset-and-how-to-avoid-them-8e194ff09b01
Trying to learn about Software Engineering can sometimes feel like attempting to dig a bottomless pit; there are never ending facets to delve into and whenever you believe you’re close to mastering one area, the landscape shifts and suddenly there is yet more to learn.
Consider web development as an example. There have never been more tools available to assist, but building a website that functions well remains a deceptively complex task. Cloud technologies have made it easier to publish a website but even the choices called for here require engineers to undertake research. Would it be best to select a S3 bucket (file storage system) to host a static site, or create a mini server in either LightSail or a very compact EC2 instance? Once this decision is made, we need to build functions. If your site needs to be shoppable you’ll require a shopping cart and session management that a simple HTML file won’t meet, but which front-end language do you opt for — React, Angular or Vue — and which database paradigm should you use to ensure user data is stored — whether that’s Key-Value (Redis), Wide Column (Cassandra), Document (Mongo), Relational (Postgres), Graph (GraphQL, Search Engine SOLR) or Multi-Model (a combination of different paradigms)?
It does not take long to realise that software engineering is littered with decision points, all of which could be possible rabbit holes that have the potential to baffle even the most experienced practitioner. With this in mind, I wanted to share key learnings acquired throughout a decade of acquiring the software engineering skillset — framed through the mistakes made along the way. This is by no means an exhaustive list — we all continue to pick up fresh lessons every day — but it should hopefully help to accelerate the lifelong learning required to remain a proficient software engineer.
There are certain facets of software engineering that generate diminishing returns the longer you invest time in them. Maintaining a delicate balance over just how much time to invest in certain areas can prove difficult and we can all name topics that we have sunk unnecessary time and resources into learning about. My own examples of this were algorithms and whiteboard coding.
As I progressed in my career, I noticed that more technically-savvy companies tended to favor whiteboard coding — writing code on a whiteboard — during the job interview process. This idea of vetting engineers by asking them to implement an algorithm without the use of the very tools they would likely be using in the eventual role may seem counterintuitive, but it is a well-established model in large tech organizations. I quickly realized I was unprepared to tackle this kind of problem and I became obsessed with mastering it.
I purchased a whiteboard, invested in a library of technical interviews books from How to Crack the Interview Code and Grokking Algorithm, to Algorithms for Dummies. I even subscribed to Leetcode.com! I attempted a daily random algorithm in Leetcode, starting off on a whiteboard first.
Over time I certainly improved and common algorithms became easy to implement in whiteboard sessions. However, I was struck by a moment of clarity after spending days attempting to whiteboard the N-Queen problem. Upon solving it, I realized that it would have no tangible impact on my current workflow and would only really be helpful if called upon to solve it in an interview — an unlikely prospect.
Be conscious of the topics you invest time into. As engineers we can expect to be constantly bombarded by this week’s new buzzword or trend. With so much to master, understanding where to focus is key in progressing your career. Regular introspectives can be incredibly helpful here. Some useful questions to constantly keep front-of-mind when upskilling are: Does this help me in the long run? Will this still be relevant in a few years’ time? If the answer is no, step away.
In most cases it is a bad idea to obsess over one area of software engineering to the detriment of others. Spread your time and acquire a broad breadth of expertise. Imagine going all in mastering only Adobe ActionScript as your primary programming language. ‘What’s ActionScript?’ you ask. Exactly.
With such a breadth of areas to learn about, it is only natural that some parts of software engineering will interest you more than others. For example, I struggled to get excited when trying to learn about front-end topics and this meant that upskilling in this area felt like a chore and subsequently took more time than it should have. While learning how to float divs and create pixel-perfect UI did not intrigue me, front-end display has been a crucial area in many projects I have worked on and is valued by colleagues and clients alike, so I needed to upskill.
In order to overcome these learning humps, I needed to envision the topic in a way that was relevant to me. If I imagined skin in the game while learning about something, the dynamic would change. For example, I reapproached the front-end display as though I was building my personal website to showcase my engineering skills. Suddenly I was eager to understand how to avoid unaligned menus and shaken navigation, as I recognized this would undermine anything I could say about my own engineering skillset.
I have found this approach useful across a variety of subjects. For example, when learning about shell scripting I considered the many daily tasks that would benefit from automation and how this would lift my productivity. I created a script to manage and categorize my email, making it easy to clear my inbox. It was a joy to work on and by engaging more with the topic I acquired the skill set more quickly.
Tailor your learning process — do not be afraid to step outside the tutorials and set your own tasks, particularly if the end product is a fresh skill and a new work hack.
“The more I learn, the more I realize how much I don’t know.” ― Albert Einstein
‘Imposter Syndrome’, as coined by Adam Grant in ‘Think Again’, is the sensation that you don’t know what you are doing when in reality you are perfectly proficient. This imbalance of competence and confidence is highly prevalent in software engineering thanks to the industry’s continually shifting landscape of relevant technology and trends, plaguing experts and novices alike.
At the opposite end of the spectrum lies the ‘Dunning Kruger’ effect — an overestimate of capability while still a relative novice. This too is a risk in our sector, thanks to the often rapid progression from amateur to novice and the false confidence this can often generate. Adam Grant refers to this as ‘Mount Stupid’.
Like many in our industry, I surfed these various waves as I dove down software engineering’s numerous rabbit holes until I arrived at what Adam Grant refers to as ‘confident humility’. This is the sensation of understanding there is a wealth of expertise you have still not acquired, while remaining confident in your capability to learn new things. The process of lifelong learning as a software engineer often boils down to maintaining this delicate balance and the sooner you arrive at this point, the easier it will be to approach the industry’s never ending warrens of new tech.
Lifelong learning is becoming an increasingly common term in the tech and wider business world and as software engineers you will come across it in job applications, onboarding experiences and day-to-day life. Regard it as just the latest boardroom buzzword at your peril — in our industry, it is a crucial part of the job and one of the ways to demonstrate your value throughout your career.
The capability to quickly create and deploy new solutions, using the latest innovative tech, will be a transformative competitive advantage for years to come and engineers will be central to this, so continued personal development is anything but an optional extra. I hope this article offers useful insight into how to approach lifelong learning as an engineer.