8 Things That Helped Me Improve My Software Skills

Written by ricvolpe | Published 2021/05/06
Tech Story Tags: software-development | software | software-engineer | programming | self-taught-developer | learning | career-development | growth | web-monetization

TLDR Software engineering is a complex and ever-changing domain. As a self-taught software engineer, I learnt a lot of painful lessons and often changed my mind about things. I want to share with you 8 ideas that helped me improve my software engineering skills and advance in my career. This article requires some understanding of software engineering, at least the basics. If you have no computer science and programming experience, I recommend you start with more introductory material such as this great article from Scott Young on teaching yourself to code.via the TL;DR App

Software engineering is a complex and ever-changing domain. When studying and practising it is easy to form wrong ideas from correct premises. As a self-taught software engineer that went from studying economics to developing large-scale software, I learnt a lot of painful lessons and often changed my mind about things. Thus, today I want to share with you 8 ideas that helped me improve my software engineering skills and advance in my career.
This article requires some understanding of software engineering, at least the basics. Its content is ideal for people who have already started their learning journey and have mastered the basics. I hope that it would help you dive into more advanced topics with more confidence and reach the next stage of your growth. If you have no computer science and programming experience, I recommend you start with more introductory material, such as this great article from Scott Young on teaching yourself to code.
1. Focus on the context of your problems
Image by Xkcd
Software that works solves more problems and makes more money than software considered good by some convention.
Blog posts often focus on sharing best practices because they cannot showcase tangible outcomes (and I am guilty of this!). However, when developers focus on outcomes instead, it can lead to challenging conventions.
Let’s look at an example: version control (ie git). Software design principles such as single-responsibility and separation of concerns suggest that different components should use different repositories. Yet, leading tech companies like Google, Facebook, Microsoft all employ very large mono-repositories for all their code (and for good reasons). Similarly, once my team was looking for a solution to integrate a static data file into our program and I feared criticism in suggesting to simply save the file in git (it was small and was not going to change often) because the principle says that one should never store data in git. It was only after receiving positive feedback on my thinking from a more senior engineer outside the team, that I felt confident enough to suggest it.
It seems that when we are in doubt between favouring the requirements of the context and following a best practice, the former usually pays off.
2. Focus on mastering specific areas of expertise
Image by Riccardo Volpato (2021)
When novices hear experienced engineers saying that they should be able to learn a new programming language within one month, they usually object (or worse, they silently kill their confidence). However, both parts are right in their estimates. This is because learning a programming language often requires knowledge about the problems the language is commonly used for.
Picking a domain and learning about its core concepts and terms first usually makes it much easier to master the tools used to solve problems in the domain. When I avoided this and dove straight into learning how to use a tool, I often end up believing for some time that I knew how to solve problems in the domain, when I actually only knew how to install and debug libraries. In my self-study, I learnt faster when I reviewed the main introductory textbook of the field before playing with related technologies.
For each domain, there usually is a famous textbook that gives an overview of its terminology, problems, solutions, advanced applications and future trends. Some of my favourites are:
3. There are so many different ways of being good
Image by Riccardo Volpato (2021)
Software engineering is a huge field. It is normal to feel there is so much that one doesn’t know. When managed properly, this feeling helps to stay curious and keep learning.
However, it is easy to fall into the trap of believing that lacking knowledge in several areas means that one is not a good engineer. In reality, there are so many different ways of being a good software engineer. Doubling down on a single strength often pays off more than worrying about partially patching many weaknesses.
People often believe that the only way of being a great engineer is to become the stereotypical top coder that hammers out perfect features non-stop for 12 hours a day. Actually, there many non-obvious (and sometimes wrongfully belittled) ways of being a good engineer, such as:
Owing up to our unique background and interests is often the best way to differentiate ourselves. I have often been self-aware of being a self-taught software engineer until I was told by a hiring manager that my diverse background was something that differentiated me positively during the interviews.
4. History matters
Image by xkcd
In an interview with Dr Dobb’s Journal in 2012, Alan Kay said:
“Computing is pop culture. Pop culture holds a disdain for history. Pop culture is all about identity and feeling like you’re participating. It has nothing to do with cooperation, the past or the future - it’s living in the present. I think the same is true of most people who write code for money. They have no idea where their culture came from.”
Knowing the history of computing may seem uncool and unhelpful to implement a feature or fix a bug. But when one is considering using a certain technology it is useful to know what problems it was designed to solve.
History is often cyclical. The most popular database before the advent of SQL was based on a hierarchical data model which represented the data as a tree of records nested within records. SQL was invented because this model didn't work well for many-to-many relationships and joins. In the last decade, to overcome limitations in the scalability and expressivity of the SQL model, people developed document databases (also known as NoSQL). In many aspects, NoSQL has essentially reverted to the hierarchical data model and share many of its challenges.
5. Hyped tools are for experts
Image by Riccardo Volpato (2021)
When we become more aware of the history of computing, we realise that hyped technologies stand on top of many other building blocks. Knowing about them is often helpful if not necessary to master the “cool new thing”. By spending time to strengthen their fundamentals first, novices can then work on innovative applications with competence and confidence.
I first came across this idea in So Good They Can’t Ignore You where Cal Newport argues that innovation happens at the “adjacent possible” of existing fields. To reach it and contribute, aspiring innovators need to first master the existing part of the field. Focusing on hyped tools without strong fundamentals feels great but is often unsustainable past the initial enthusiasm.
6. Coding interviews are deliberate practice
Image by Riccardo Volpato (2021)
Some people argue that coding interviews are a bad hiring practice because they differ too much from the day-to-day work of a software engineer. Differently, I have found that whenever I took time to practice coding challenges, the code I write at work would increase in quality. I achieved better space and time complexity and wrote cleaner code that was easier to reason about.
This is because coding interviews are a way to deliberate practice software engineering skills. In fact, coding interviews fit well the definition of deliberate practice, as
  • they come in various levels of difficulty, so it is easy for a developer to pick questions that push them beyond their comfort level; and
  • they give quick and clear feedback.
However, great code requires more than just passing tests. This is why peer-based interviews, such as Pramp or actual hiring interview, can provide richer feedback than test-based editors like LeetCode.
7. Code says as much about its function as it says about its writer
Image by Riccardo Volpato (2021)
In abstract term, software is a way to represent a desired behaviour or workflow. As such, software is also a medium of communication between the application and the machine, the developer and its team or the developer and her future self.
Consequently, software tells a lot about the knowledge and state of mind of the person or team that developed it. For example, disorganised teams tend to produce messier code than those managed by an opinionated tech lead that enforces a clear style guide.
To write well-structured and understandable code is helpful to start from well-structured and clear ideas about the problem one is trying to solve and its intended solution. When ideas are unambiguous across the team, it is even better.
8. Software has far-reaching consequences
Image by xkcd
We debate a lot on how autonomous vehicles should solve the trolley problem but we don’t blame people for making bad driving decisions under pressure (besides reasonable expectations). Why? We cannot expect people to behave consistently under pressure. However, we can sit down together and decide conclusively how an autonomous vehicle should behave during an incident and script it.
We can think of software as scripted behaviour, like forming a habit or making a commitment: we decide that whenever a given situation arises, we will take a specified action. Making commitments is one of the main ways of influencing the future, so people are careful about it. If you notice, many engineering books end with a chapter about the responsibilities of developing technology.
Beware, accepting that software has far-reaching consequences does not imply that we should be careful about every development decision. An alternative is to write software that is easy to modify so that we can easily adapt it when the circumstances change.
This was a broad article. To recap, the 8 ideas that helped me get better at software engineer are:
  1. Focus on the context of your problems
  2. Focus on mastering specific areas of expertise
  3. There are so many different ways of being good
  4. History matters
  5. Hyped tools are for experts
  6. Coding interviews are deliberate practice
  7. Code says as much about its function as it says about its writer
  8. Software has far-reaching consequences
I hope that at least some ideas inspired you. If not, it’s great that you already know so much! As I wrote this article within few weeks, I am sure many other important ideas shaped my learning but I could not recall them. And perhaps, you are aware of some more! What are the ideas that helped you get better at software engineering the most? I can’t wait to read about them.

Written by ricvolpe | Software engineer and data scientist, driven to build tools that connect and help others.
Published by HackerNoon on 2021/05/06