Becoming a Self Taught Software Engineer: A Manifesto

Hi everyone,

I got a pretty long one for you. Though it’s not necessarily related to memory, but it is about learning, and I have seen the topic discussed here before.

I’m a self taught software engineer. Recently, someone I know approached me for help. They had heard that I was able to break into the industry without a college degree and they wanted some guidance, as they too are wanting to switch careers and are learning how to code.

At first, I kinda drew a blank. I just didn’t know where to begin. But later I sat down and started writing down my thoughts and experience so I could better help him.

Admittedly, I got a little carried away. It’s a bit lengthy. But any feedback is encouraged, especially if you are a software engineer, or want to become one.

Forgive me if it’s not well written. It started as just some thoughts but morphed into a sort of blog post.

Here are my thoughts on becoming a self taught developer:



Your goal is twofold:

  1. Learn how to develop software, and
  2. Get a job developing software.

The first goal is a bit more involved than merely learning to code. For example, if you can declare variables, functions, and for-loops, you can, ostensibly, “code”. But that doesn’t mean you know how to build working, maintainable software.

The second goal of getting a job building software, shouldn’t be ignored until you deem yourself “done” learning, or until you think you’ve learned enough. In fact, I would argue that you won’t truly learn how to develop software until you get a job doing it.

You have to work toward both goals in tandem. Think of it as a truck (learning to code) pulling a trailer (getting a job). As you reach milestones on your way toward your goal, you throw those milestones into the trailer, so that when an opportunity for a job arises, you can show them evidence of your ability.

And please, above all, remember: Persistence

There is an unknown time and date in the future when you will be extended your first job offer as a software engineer. Keyword: Unknown. While your level of effort and commitment will oscillate over time, you cannot let it reach zero.

Becoming a good software engineer is a continuous pursuit. For as long as your career lasts, you will be working to improve your abilities and expand your knowledge. If you don’t, your career won’t last.

However long you think it will take you to get your first job as a software engineer, your wrong. The fact is, you have no idea how long it will take. I’ve seen some people quit their jobs so they can study programming full-time, hoping that in two or three months, they’ll land a job. Yeah, …maybe. Take whatever risk you are willing and comfortable taking. Just keep in mind that you only have control over how prepared you are for the job, not when the job is offered. You can influence the timing by your efforts, but you cannot control it. So, whatever risks you decide to take, remember that, in reality, you have no idea when they will pay off. So plan accordingly.

An Uncomfortable Truth

Look at the advertising for some of the courses and bootcamps out there.

You’ll see things like “Zero to Hero!”, “Become a software engineer!”, “Become a JavaScript Pro!”.

Look at the sheer number of courses and bootcamps that are available!

“Learning to code” has become akin to a get rich quick scheme. The implication of some of these courses being “Take my 20 hour Udemy course and become a highly paid engineer”. Of course you’ll find the super genius on Reddit who went from zero to hero in a week and now works at Google, and they’re totally not lying. But I speak only to my fellow mortals.

The uncomfortable truth is that becoming a self taught software engineer will take significant time and effort.

Becoming a skilled software engineer will take even more time and effort.

You must be comfortable with this fact if you stand any chance of succeeding.

Sustained effort over a long period of time is the path to success.

Another important fact is that there is a lot of content about learning how to code. Much of it, including the actual documentation for the languages and frameworks you’ll learn, is completely free. On the other hand, there is a ton of paid content as well. There is no shortage of people willing to take your money. Paying for a course when there are free ones available is not necessarily a poor choice. Some content is behind a paywall because it’s really high quality. Some content is just behind a paywall. The problem is that when you’re inexperienced, you don’t have the ability to tell the difference between high quality code and terrible code, let alone good courses and bad courses.

Some people say they prefer to pay for courses simply because it gives them more motivation to actually do the course, so they get their money’s worth. I won’t argue with that, but some of these bootcamps are charging $10,000 to $20,000. Thats a lot to pay for a little discipline. There is a fallacy that exists called the “Price-Quality Heuristic”. It states that the higher priced a product is, the more likely we are to assume it is of a higher quality. Why use freecodecamp.org, when I can pay $400 for a Udacity course? Surely the paid course is better, right? The answer is maybe. But also, maybe not.

I don’t have a solution for parsing out the good from the bad content out there. I’m merely pointing out that you can, in fact, learn how to code 100% for free, if you so choose. The free (or nearly free) resources available are, in my experience, of a surprisingly high quality. Especially for people just starting out. If, after you’ve had a job, you want to learn some niche programming language or a specific software development methodology, by all means, buy a course. There will still likely be free options available, but in my experience when you get into more advanced/niche topics, it may be worth it to pay.

Another challenge, due to the sheer volume of different content, is knowing what to study. What language to choose, what framework within that language, front end, back end, full stack. The list goes on. More important than what you pick is that you stick with what you picked. Do the research. Ask around. But if you are continually jumping around from one language to another, or learning another framework before mastering the first, you will waste time and energy. You will be better served by picking one thing, and getting good at it. Once you get good at it, your skills will more easily transfer to another language or framework (and you will actually have skills to transfer).

How to Develop Software

In the beginning you will follow tutorials. You will code along with an instructor as you learn the basics of the language and, together, build an app. This is the proper order of things.

However, this can go on too long. You’ll finish your course of Udemy or YouTube, sit down to begin working on your own project, and…

You have no idea where to begin. You may attempt another course. Or follow another tutorial. But every time you try to work independently, you can’t seem to make progress. And thus, the cycle continues.

Welcome to Tutorial Hell. Here you will find weeping, wailing, and gnashing of teeth.

To escape, you must learn how to develop software independent of a guide.

To do this, you must stop following tutorials. Instead, use them as reference rather than a guide. So build your own app, but don’t bite off more than you can chew. In fact, if you’ve already built an app by following a tutorial, build that app again. But this time, rather than following along with the tutorial, use your previous code and the tutorial as a reference, but not a guide. If you get stuck, go back and look at your old code or use the internet. As a last resort, reference the tutorial. Build this same app over, and over again. Each iteration, start a new project. Don’t throw away your old code. Eventually, you’ll want to go back to your oldest projects and do code reviews with yourself. See if you can find where you improved and perhaps where you still need improvement.

Your goal in doing this is, in part, to become familiar with the patterns of software development, i.e. how to structure your app, how to manage state, separation of concerns, etc. Your also discovering why things are done a certain way, which will help you remember them. There is a saying in chess that you will learn more from your losses than your victories. The same is true for software development. You will learn more by encountering challenges and solving them on your own, than you would by having someone tell you exactly what to do. The caveat to this being, if you’ve been stuck for a while, get someone to help you, whether from the internet, or someone you know. The benefits of solving a problem you’ve been stuck on can have diminishing returns if you remain stuck for too long.

Through the beginning iterations of your app, your goal is not to write “clean code”, or even “good” code, however an experienced dev might define it. Not yet. Your goal right now is to escape tutorial hell and get to a place where you can build simple apps independently. You will pick up some good code habits (and bad ones) through osmosis as you iterate through app, solving challenges as they arise.

In the beginning, you will be dealing with something called “cognitive load”. In short, cognitive load means your brain can’t focus on too many things at once, and remain effective. When you are learning how to be a software developer, there is way to much information for you to even attempt to learn it all, let alone apply it all, at once. As you climb out of tutorial hell, your cognitive load will decrease. You’ll no longer have to think as hard about things. Things that were once challenging will become a non-issue. As the level of difficulty decrease as you loop through this cycle, you can add features to your app that were not shown in the tutorial. Try new things, but incrementally. Don’t do too much at once.

Now, what I’ve just written is controversial. In fact, I’m torn on the issue myself. I’m referring to my advice that you need not worry about writing good quality code yet. The definition of quality code is hotly debated in itself, but I define it as, basically, just Functional Programming, which I’ll explain later. There is an argument to be made that learning, and practicing good habits will make your life easier. That by practicing writing “clean code” you can keep complexity at bay, and avoid developing too many bad habits that may hurt you later on.

The conundrum, as I see it, is that by learning and practicing “good code”, while learning a programming language and a framework (and who knows what else) all at the same time, your cognitive load will reach overload levels. You simply can’t do it. On the other hand, complexity in your app is a big driver of cognitive load, not to mention bugs. In the end, I think an iterative approach is best, and you can shift your focus to other things as you cycle through the process of building this app. I’m more than willing to be wrong on this, and if someone disagrees, weigh their reasons against mine and decide for yourself which approach is best.

Preparing Yourself For a Job, Along The Way

While you are building these apps, you should be throwing milestones into the trailer, so to speak. I mean pushing your code to github. If its enabled, you will see on anyone’s github profile, a contribution graph. It shows the number of contributions, public or private, an individual has made over time. This is the evidence of your ability. Even if the repositories you contribute to are private, you still want proof that you can code or at least have written code.

You’ll notice many professional developers hover around 1,000 commits per year, plus or minus a couple hundred.
If you make 3 commits per day, every working day, you will have a 780 commits by the end of a year. 780 commits will result in a nice, full contribution graph, which can be very helpful to a new developer looking to get hired.

Not to mention that being able to use git is a must have for any employer.

On the topic of a portfolio or personal website, it’s my belief that the importance of this is overstated (usually by people pushing a course). I still feel it’s important, particularly for someone with zero experience, but I’m afraid that a poor quality portfolio can do more harm than good, and that you’d be better off with no portfolio and a full contribution graph.

When you begin working on your resumé and applying to jobs, remember, you are not applying for favors. The overall tone of your resumé should not be “I know I don’t have any experience, but I promise I’ll work hard if you just give me a chance!”. The opposite will serve you better. Your resumé is an advertising document, and your message should be one of “This is what I can do for you, and here is the evidence.”. I’ve seen too many resumés that read like a cry for help, rather than a display of value. It’s not your job to tell the employer why they shouldn’t hire you.

There are plenty of resources out there for resumé help, so I won’t go into it too much. I will only add that similarly to the over abundance of coding bootcamps and courses all wanting your money, the same exists for resumés. Be selective with what you are willing to pay for, and search out the free or nearly free options available. Remember, K.I.S.S. Keep It Simple Stupid (or Stupid Simple). Your resume is not an art project. Keep it easy to read so employers can see what you’re offering at a glance.

When applying for jobs, keep in mind that, especially for junior positions, there can be hundreds, or even thousands, of applicants for a single job posting. To put it bluntly, the odds are not in your favor. This means firstly, if you have connections or you are able to network, do it. You have to. In any case, you have to go the extra mile. If they ask for a cover letter, write one. If you can, follow up with an email. Anything to tip the scales in your favor. At the end of the day, this is a numbers game. Apply to everything. This process alone requires significant time and effort sustained over a long period of time. Again, Persistence.

If you wait to begin applying for jobs until you feel ready, or you think you’ve learned enough, you’ll never apply. There is no obvious stage of the process I can point to and say “this is when you start applying”. All I can say is, start applying sooner than later. At the very least, if you get any interviews, they will be good practice and give you an idea of what to expect. The worst that could happen is they actually offer you a job!

Conclusion

When I was offered my first job as a software engineer, I was elated. I was so happy that I had achieved my goal. It was a challenging goal. As my start date approached, I became nervous. I didn’t feel ready, and I worried that I had not prepared enough. I worried that they would discover that I was a fraud and I didn’t know what I was doing, and that they would swiftly terminate my employment. In truth, I have heard of this happening, and I’ve seen it happen first hand (though not to me) at a company I worked at. An under prepared developer landed their first job and just couldn’t hack it. It does happen. All I can say is, try your best. If you get a job, and they fire you, so what. Keep trying. In my experience, when I landed my first job, I was able to improve at a much faster pace. It was not because the company provided mentorship (they did not). The mere fact that I was able to code for eight hours a day, solving real problems helped me to improve more than anything. At the end of the day, to get good at coding, you have to code a lot.

It was not an easy journey for me. I am not a super genius from Reddit. It took me about two years of sustained effort before I got my first job. In retrospect, I could have done it faster (maybe), if I had avoided some of the pitfalls I have outlined. I got stuck in tutorial hell. Sure, I built lots of apps. But always with a tutorial. I jumped around to different languages and frameworks. Being mediocre at many things is not better than being really good at one thing. I wasted a lot of time. It is only when I focused, and forced myself to work independently, that my trajectory increased dramatically.

5 Likes

@Dr.Bennet, as a self-taught programmer and instructor, I can affirm that the advice you are giving is excellent!

I taught a bootcamp for C# for thousands of dollars but my training was all free. My city library had a free subscription to O’Reilly’s Safari Books Online. Invaluable!

Solving problems with code taught me the most. And letting a future employer see your code solutions with appropriate comments to document it on github is part of the necessary process.

I know that it takes up to five years for someone to learn how to refactor their code into “quality code.” so that’s not important for a newbie. What is important is that the code works and can pass tests that are documented in the code. Does it handle alpha characters for numeric input? Can it handle out of range numbers? Etc.

Great advice!
Doug

I didn’t really see you explain Functional Programming (FP) later on, so I assume you meant explaining quality code (so not FP but “code that functions” or “code that works” basically). Careful when coming up with you own definitions like this, FP does exist and has for a long time. Common Lips and Scheme for example are FP languages and have been around for over half a century. In fact, lambda calculus which is a precursor of FP has been around since the 1930s.

And just in case anybody here thinks I’m being pedantic… pure functional programming languages don’t have loops; they don’t have variables either. Anyways…

@bjoern.gumboldt Point taken. By FP, I’m mean avoiding shared mutable state, side effects, and a whole bunch of other stuff you correctly pointed out I forgot to explain. Thanks for the feedback.

@thinkaboutthebible I appreciate you taking the time to read and give me feedback!

1 Like

@bjoern.gumboldt Maybe I should remove that part all together? FP may not be the most beginner friendly topic, which was kinda the point I was making anyway.

1 Like

Ok, so I re-read the entire thing and the paragraph about FP twice. Are you maybe talking about functional programming in JavaScript or something? When I read it, there seems to be a logical jump there into something entirely different…

I don’t know about that. I don’t see much of an issue starting somebody out in Scheme or Lisp as a language. I mean how is recursion harder than a loop or vice versa? I just wonder why you’re talking about FP at all though. I don’t really see any mentions of procedural programming or OO code.

You mention “app” throughout your post. So, I don’t know how talking about Swift as a language for iOS (as a hypothetical) and how to get started, etc. then all of a sudden gets you to MVVM design pattern in SwiftUI when you didn’t mention MVC models the whole time you were talking about Swift. Not that you mentioned any specific languages, but to better show what I read when I look at what you wrote.

Like this confuses me as a statement. FP languages are immutable, you don’t have to worry about that in the first place. I mean, I don’t know but I wouldn’t say “quality code” equals FP. I’ve seen good and bad in Lisp and I’ve seen good and bad in C++. So yeah, I don’t know…

…so, you do mean FP as in “functional” not as in “a program that functions,” i.e. “works,” right?

@bjoern.gumboldt When I refer to functional programming, I’m referring to functional programming as a paradigm. I’m not referring, necessarily to Functional Languages like lisp or Haskell or what have you. The person I wrote this for is learning JavaScript, as are most beginners, so that may be a bit of context that I left out. So, yes, I suppose I’m referring to functional programming in JavaScript. But, again, that’s a whole can of worms.

So when I say I define good code as basically functional programming, I’m saying, as a rule, keep your functions small and pure if possible, avoid shared mutable state, and the list could go on. There are obviously exceptions to the rule. But like I said, it’s a debatable topic, and I’m open to being wrong.

And you’re right, my FP claim kinda comes out of nowhere, so it may be better left out.

1 Like

Okay, now I see where you’re coming from… honestly, in that case I’d leave it out. You put “Software Engineer” (not Full Stack Web) in the title of the post and you’re talking about “quality code” in general, not in the context of JavaScript and there are other languages out there where FP is not something that will make it “more quality” code, so it’s not a silver bullet.

I think it’s good you kept the post general/generic to some extend, so in that case the FP part really should go; otherwise, it just turns into something too specific that doesn’t match the rest of your post. Because in the context of the rest of what you wrote, I read FP as general FP and not within the context of Javascript, hence the above…

1 Like

Your article is a good overview how someone can do it.

I would sum the process up like that:

while !finished:

  • Learn the coding part ( syntax / semantic of the programming language you want/need)
  • Learn programming techniques
  • choose a simple project for the language:
    ** start planning
    ** write code

Later in job it could be that you need to change your coding habits to be in the company standard rules for coding.

I think functional programming paradigm is a good thing to follow.

I program myself in different languages to write business applications for my work place.

And find it interesting how easy or hard it can be to solve a problem.

But a good thing to look for if you want to be a good programmer is to make a program that is also a documentation.

How many times I found myself a year later in the position to do not know why I wrote a function this way or that way.

Since I discovered different habits and tools that help me alot in doing literate programming.

I use some tools that help me with the literate programming.

The biggest thing that helped me was setting a small project scope and finishing it, instead of constantly switching languages or courses. I also asked other developers to review my code early, since bugs and confusing structure teach you more than another polished tutorial. GitHub is useful, but a clear README and being able to explain your decisions matter more than an impressive commit count.