A good friend of mine is interested in changing careers to become a software developer, and naturally I’m trying to find ways to help him with that transition. He’s dabbled in software for a long time, writing applications for himself and others to use, in a variety of different languages. However, in order to land a full time developer job at a level he’d be comfortable, he’s asked me what skills/knowledge gaps he has, and what he should do about this – “should I learn ___ framework?” “what about ___ language?” and so on. The answer, as always, is “it depends”.
Once a developer is comfortable with at least one technology and able to build things, the value is now in learning techniques. While learning their first technology, a beginner will do things that will just about work, but that could be done much better. If they are to work on larger projects, or in a team, there are techniques that are needed to try to keep the growth of the project healthy. These techniques can be applied to a technology, but they are bigger than that and can be applied to many different technologies. A great technique to learn early on is how to write tests against software – ideally by learning the Test Driven Design discipline. The technique of TDD can be applied to most languages, and will change the way the learner thinks about building software. Another set of techniques that are worth learning early on are those around workflow, particularly in a team. This might mean learning about agile methodologies, or about version control workflows. Learning these techniques makes it easier to work as part of a software team.
After this point, developers should be continuously learning both technologies and techniques – it’s a fast-changing industry. Most individuals will realize before long that they have a personal preference for one or the other, and will be naturally inclined to pursue that more. Beyond that they may choose to go deep in a small number of areas and specialize, or to gain a broad knowledge of many. I think there is a lot to be gained from investigating a wide range of things, both to know what’s out there and have a better choice of what to specialize in, and to look for paradigms that can give benefits in other areas. I tend to lean towards techniques over technologies, because I find that having a strong knowledge of techniques means that I can apply these across many technologies and learn technologies relatively easily. In many cases, new technologies represent a new syntax on top of familiar paradigms.
When it comes to learning techniques, my main resources are reading and watching presentations. For learning technologies, the best way is by practice. I like to work with small “toy projects” that have relatively little functionality but that allow me to experiment with the technology. I’ve recently been learning F#, a functional language in the .Net ecosystem, and using the examples from Project Euler, a set of mathematical puzzles, as my problem domain. If I were learning something like a client development library (such as Angular, React etc), I might build a small user interface. I try to isolate the area I’m interested in, spending only minimal time on anything else. My F# Project Euler solutions are all about an algorithm, so I simply run them as scripts; when focusing on user interface I might knock together a very basic server to get going, but I’m not interested in writing complex logic or structuring the server any particular way because I can do that as a separate exercise. Having a single goal for these practice projects means I get the most from the time I spend on them, rather than spending all my time on the same things again and again.
For my friend in particular, my recommendation to him is that he focus on techniques for now. He knows enough technologies to build something, and actually is fairly adept at learning new syntax, which makes him able to learn a new language as part of joining a software team. However, as he is self-taught, he currently has large knowledge gaps around techniques. Because of this, if I were recruiting him, I would have to see him as a junior in the team, who is able to write code and get things done but who will need a lot of help from his team-mates to make that code be maintainable. Specifically for him, I would point him towards learning TDD, and the SOLID design principles, to help him gain an appreciation of how to separate concerns and structure components. Armed with these techniques, applied to the technologies he already knows will be enough to get started as a developer – and far more valuable than adding languages and frameworks.