Table of Contents

Introduction

At some point in your career as a Software Engineer you will ask yourself «What should I learn? How can I improve further?». Even if you are new to the field, knowing where to start or having an idea where to go is very useful.

Start with your intrinsic motivation: why are you studying Software Engineering? Do you have a specific goal in mind?

Everyone is different, motivated by different things, with different goals in different times. Know yourself and plan accordingly.

A couple of things to keep in mind:

  • What you are learning is a practical skill, so it is very important to have a project to work on while studying the theory.

  • Perfect is the enemy of good: there are multiple fields you need to be comfortable in, therefore having a working knowledge of everything is better than knowing only a single thing very deeply.

In each of the following sections I will focus on a particular topic required to develop software. Each one of them is more an improvement area rather than a point in a to-do list to remove once you’ve learned something there. Therefore my advice is to learn in a circular way:

  1. read a new concept in the theory
  2. find a good example of an application
  3. apply it to your project (sometimes it required to add new features to your project, other times to rewrite pieces of existing code)
  4. pick a new concept and restart from point 1.

You can repeat this process until you are satisfied and you feel ready to jump on the next topic.

When you have finished with Software Architectures, you are ready to come back and restart from the beginning for a new learning cycle.

How much time you need to spend in each area depends on your personality and use case. For example if you are complete novice and you like quick feedback, you might spend just 1 day on each section; if you are following a study course you might want to find a book on each subject (and complete at least two-thirds of the book with practical exercises); if you are a seasoned Software Engineer who is learning the brand new coolest language in the market or you aim at a career advancement, you might spend more time on a specific area.

The process described here should be generic enough regardless of the specific field of interest (Embedded Programming, Video Games Development, Web Applications, Fin-Tech, etc.)

Context: Domain knowledge, Tools and Environments

Depending on your current level in this section you need to focus on the less intuitive part: the context.

If you are a beginner, for example, you can start by studying what a computer is and how it works (on a high level). Then what are the tools you need to write and execute the Hello World program.

If you got your first job as a Software Developer you might need to learn more on Git, a specific Framework or the collaboration tools your company is using.

There is space here also for domain-specific knowledge in case it is relevant for you.

In summary this is a generic open area where you put what you find important that does not fit in the following categories. Be creative here and think from the big picture.

Algorithms and Data Structures

This is probably the most obvious part because Algorithms and Data Structures are the basics of software. There are plenty of great books on this subject, but you might just need to familiarize yourself with the basic data structures offered in your high-level language of choice and what you can do with them.

Your goal here is to be able to write procedural programs.

Focus on learning the basic syntax of control structures, how to write a function and implement simple algorithms (sort of an array, find the maximum, etc.), if you are a beginner; take a book on the subject and learn how to implement complex data structures in C, if you are more more advanced.

Object-Oriented Concepts and Principles

From the focus on “how to do it”, the main topic of the previous section, we will move to “How to structure and organize your code”: in big projects writing quality code is essential.

Your software should solve a particular problem in the first place, but readability, maintainability and testability are the properties that make it special.

Learn the basic concepts (and the relevant syntax in your language) for Classes, Objects, Encapsulation, Composition, Inheritance, Polymorphism. Study the SOLID principles and find one practical example for each one of them.

Learn also about the Object-Oriented Design or some advanced methodology like Test Driven Design, Domain Driven Design, etc.

In case you are using a procedural language like C, this section is still relevant: function pointers, anonymous nested structs and proper usage of header files can help to increase the quality of code.

Design Patterns

DRY is an acronym for “Don’t Repeat Yourself”. This a good guideline to follow in general. If you find a piece of code that is useful in multiple parts of the program, create a function for it; if you find a useful chunk of data and algorithms, this is a good candidate for a Class; if you are solving the same problem again and again in different contexts with a similar solution, you are identifying a Design Pattern.

There is a very famous book written in 1994 [1], but in my opinion is not the most clear book on the subject. Learn the most common design patterns here or look for some patterns specific to your area of interest (and don’t forget to find a practical example that makes sense in your head to be sure you have understood the pattern).

Software Architectures

Last but not least you can create the most wonderful, efficient and maintainable code in the world, but some problems are addressed by the overall architecture of the software: scalability, reliability, etc.

Learn at least the Layered Architecture which is very useful in the design of both a monolithic application and a single micro-service.

Of course if you already know it, go crazy and learn all the other architectures :)

Conclusions

While writing this article I realized it might be useful to use a table where you can track the relevant topics you want to learn for every section. You can fill the first available column and go through the first iteration of a learning cycle; then get back to the table, fill out a new column and then restart the process.

Area of Improvement Relevant Topics Iteration 2 ……
Context      
Algorithms and Data Structures      
OOP      
Design Patterns      
Software Architectures      

It is also useful to define a time frame for each iteration.

References

[1] Design Patterns: Elements of Reusable Object-Oriented Software, Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides