A practical guide for software engineers
Here at MarketInvoice, tech and software engineering are a large part of what we do. As we grow, it’s imperative that we bring on new and experienced software engineers to help us #MakeItHappen.
Perhaps you’re a new software engineer looking to join our team. Or maybe you’ve been building software for a while, are considering a career in Fintech and MarketInvoice has caught your eye. If either of these is you, you may be wondering ‘how can I become a really good software engineer?’ Or, ‘how can I become an even better software engineer?’
I’ve been regularly asking myself the first question since I joined MarketInvoice a few months ago. I’ve found this quote by the late W. Edwards Deming (best known for spearheading reform in Japanese innovation and quality manufacturing post-WWII) useful:
“It is not enough to do your best; you must know what to do, and then do your best.”
This is just as true whether you’re working in manufacturing and innovation or in software engineering. In this article, I’ll briefly dive into what software engineering is; the mindset and the technical and non-technical skills an excellent software engineer should possess; and suggested strategies for growing as a software engineer.
Before we can assess how good our engineering skills are, we need to clearly define what we’re measuring. A Google search for the definition of software engineering returns several slightly varied results. But each is centred on the fact that, at its core, software engineering is the systematic application of engineering principles to the development of software.
In his highly recommended book, What Every Engineer Should Know About Software Engineering, Philip A. Laplante goes into more detail about the activities involved in software engineering – from requirements gathering and software design, to implementation, software testing and maintenance.
Taking it a step further, The Guide to the Software Engineering Body of Knowledge (an internationally recognised collection of generally accepted knowledge about software engineering) suggests 15 knowledge areas that every software engineer should be well-versed in. These include software construction, software configuration management, the software engineering process, software quality and software engineering economics. That’s a mouthful, right?
Truth be told, though they’re useful references, those books can be quite heavy reading. It’s often difficult to distill their content into an actionable strategy for developing as a software engineer.
However, the skills and knowledge they describe have a few common themes: problem solving, modelling and a few other skills which are applicable to all types of engineering. Before we look at these in some more detail, let’s consider helpful mindsets for becoming an excellent software engineer.
Who’s the greatest software engineer of all time? That’s a controversial question. But it’s clear that some of those who have had the most widely felt impact on the field of computer science have worked consistently hard at their craft for a long time. As an example, I’m sure most of us are aware that Microsoft, Apple and Linux – global tech giants – were created by people who were fairly young but also very, very good at building things using computers, having been developing this mastery from childhood.
Whether or not we end up creating technology of such global impact, we would do well to adopt some of the traits of such software engineers. They were curious; they fed their curiosity by studying topics that interested them; and they persevered in building software then ruthlessly improving it with the end-user in mind.
For the software engineer aspiring for excellence, this might translate to grit (or dogged perseverance) and willingness to make mistakes, learn from them and regularly review lessons learnt. Such attitudes lay good ground for developing the skills that are needed to make useful software.
Almost all software engineering aims to solve a problem. It follows that, to build software efficiently and effectively, you need to clearly define the problem to be solved. But as simple as it sounds, it’s not always straightforward. Business requirements aren’t always initially clear and it can be difficult to identify when a problem should be declared ‘done’ or solved.
Problems that are clearly stated are sometimes referred to as ‘tame problems’ (don’t mistake them for simple ones though!). On the other hand, design theorists Rittel and Webber introduced the term ‘wicked problem’ to describe the alternative type of problem (here’s a link to their paper). You know the type I mean: the one where a stakeholder asks you to (re)design a web page or build an API to do ‘X’, where ‘X’ is a set of features which will inevitably expand.
Such problems warrant an iterative approach which might consist of gathering initial requirements, mocking up solutions, getting stakeholder feedback and repeating the process. Consequently, a software engineer needs excellent communication and negotiation skills to be able to explain constraints while eliciting the true needs of the stakeholder and managing the scope of the solution.
Another useful skill for this process is the ability to identify the root cause of a problem, also known as root cause analysis. The faster you can identify the core issue, the faster you can propose the most helpful and sustainable solutions. And this is why modelling, being able to abstract away unnecessary details and seeing what really matters are such important skills for software engineers to develop.
These skills come with increasing experience. To help yourself develop them, immerse yourself in your company’s industry. Understand the problems that are genuinely relevant. Constantly think about how to design the optimal solution that provides the most impact in your given context. Over time, this will become a natural way of thinking.
Chances are, if you’ve ever applied for an entry-level software engineering job, you’ll have noticed a strong emphasis on skill with data structures and algorithms. While these form a large chunk of many undergraduate university Computer Science degrees these days, they’re just the foundation where technical skills are concerned. There’s so much more to learn!
First things first: if you’re a software engineer, it’s likely that some of your time will be spent writing code. So, especially if you’re just starting out, it’s important to master at least one programming language. If you’re not sure where to start, learn the standard libraries of the main language used where you work. At MarketInvoice, a significant part of our codebase is developed using C# and the .NET platform. So C# is currently my language of choice.
But as my manager, Mason, once wisely said, “the degree to which you’ve mastered a language is evident by the degree to which you can build robust and useful software with it”. So, once you’ve got the fundamentals of the language down, start building software with it (on and off the job) to round out and deepen your skills.
‘But what if I’ve already mastered a language? Aside from learning other languages, what can I do to #AlwaysBeLearning?’ Many things! For example, learn to write automated test suites; understand the most important software design patterns (such as the singleton, factory and strategy patterns) and methodologies and know how and when to use them; and learn to debug your code well. Russel Simmons, Yelp Co-Founder, says this is a quality of great programmers.
That is by no means a comprehensive list. Technology is changing at such a rate that there’s always something to be learning – from the fundamentals of data science and machine learning, to how to incorporate DevOps into your team’s workflow. Most importantly, as you learn, share your knowledge and help develop your teammates into great software engineers too; you’ll grow your leadership skills in the process. We do this at MarketInvoice through fortnightly tech talks and our wiki. It’s all part of upholding our #1Team1Dream value.
So, there’s a brief and high-level overview of what software engineering is; helpful mindsets for developing as an engineer; and technical and non-technical skills that a new or experienced software engineer should be developing. There are many more that could have been added but this is a good starting point.
To round off, here’s my current high-level strategy for developing as a software engineer, as well as some of the resources I am or will be using:
- Master C# and React.js (using the C# docs; this React nanodegree; as well as on and off the job projects)
- Learn and practice test-driven development and test automation (using this course and Growing Object-Oriented Software Guided by Tests)
- Learn and practice the most important design patterns (using the Pluralsight Design Patterns Library)
- Learn good practice of software architecture and design (using this Udacity course)
- Learn the fundamentals of DevOps, data science and machine learning, all areas that I’ve been interested in since university days (this, this and this are great resources, respectively)
- Develop soft skills related to communication and leadership (I’m doing this by writing documentation on our wiki and I’ll be giving tech talks)
As well as taking courses and reading, my aim is to get as much practice with these skills by building stuff. I encourage you to do the same! What skill are you going to start with first?
If you’re a software engineer interested in working in Fintech, check out the roles on our Careers page.
To your success!