Tips for efficient learning from a self-taught programmer
Tags: beginners, productivity, learning, community
Published: 2023-10-21 03:34:57


For almost 6 months now I have been between jobs as a programmer. It’s not been an ideal situation, however, when one door closes another door opens. The mantra I have lived by has been “The longer I am out of the industry, the better I will be as a developer”. I have made it my mission to stay busy, to network and to upskill as much as possible and in spite of the uncertainty of the situation the experience has had some very rewarding moments.

Since I never went through any official institution for my programming education, self-learning is something I am very familiar with. I will go over some of the guiding philosophies I have worked with as well as some of the mistakes I have made.

## Skill acquisition
Skill acquisition is an interesting topic. There are definitely right and wrong ways to go about it depending on what you’re trying to accomplish and your own learning style. If done right, learning a new skill should be enjoyable, include continuous progress, and burnout should be minimal. If done wrong, it can lead to frustration, exhaustion, learning bad practices that you will need to unlearn, and burnout.

I have a lot of views on how to go about learning new skills all of which could take up their own post. Some of these include staying humble while maintaining a growth mindset, limiting your focus to a few things at any one time, working smart as well as working hard, choosing what habits to embed, making sure the level of challenge is appropriate [^1], engaging in deliberate practice [^2] and a great example to start off this post…

## Learning concepts before specific details and building on those foundations
Any given skill you can learn has its immutable foundations/basics upon which everything else is built. Whether it’s your basic step in dancing, understanding the different chords in music or understanding the basic movements in strength training the theme remains the same. While learning you will do yourself a huge disservice if you skip the basics and move straight on to something more advanced. My favourite example of this phenomenon remains Brazillian Ju-Jitsu where the difference between an inch of space or a grip variation is often the difference between something working consistently, or barely working at all.

Programming is not an exception to this rule and there are countless examples of foundations that need to be set before being built on. Using the library React as an example, how many issues will a developer run into if they try to learn it before getting a base in HTML, CSS and JavaScipt separately? How can you understand the Virtual DOM if you don’t understand the DOM? How can you understand when and why to use state if you don’t understand re-renders and what causes them? How will you debug issues caused by stale closures if you don’t understand how closures work?



![React learning path map](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b7402ttom08n5beeomcz.PNG)
<figcaption>
An example of a pre-laid-out plan for learning a specific library (in this case React). Credit to Ramesh Fadatare from Java Guides for the image: https://www.javaguides.net/2022/01/reactjs-roadmap-for-beginners.html
</figcaption>

Zooming out even further, what about concepts that are consistent throughout all of programming? How much easier is it to learn a new language if you already understand the basics of data structures and algorithms? What about static vs dynamic typing or Big-0 notation? Building a solid base of understanding in these universal concepts will pay dividends later on in your journey as it will make picking up new languages all the more seamless.

So how do you accomplish this with self-learning? How do you avoid skipping ahead without learning the foundations first? You need the discipline to prioritize your own understanding of concepts above immediate gratification and progression. You also need the humility to admit when you don’t know something and be able to circle back to reaffirm your knowledge.

The result of this will be a continuous and deliberate pace of learning where you are consistently improving and always challenged just beyond your own understanding.




![small stairs vs big stairs as an analogy for learning](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/owetobupzzxv5p795z6n.PNG)
<figcaption>
Smaller steps towards your goal are a better long-term strategy</figcaption>
It is important to understand that you will miss things in your journey, you will get frustrated and there inevitably will be times when you need to circle back to the basics. When this happens, it is important to approach the situation with humility, a willingness to learn, and most importantly to go easy on yourself[^3].

Some more points…

### Keep things specific
First and foremost, you should have a specific goal for what you want to accomplish. Programming is a broad field and it can often be overwhelming if you try to take on too many different things at once. You need to be honest with yourself about your current skill level, where you want to be and how you plan on getting there. You will do yourself no favours by overestimating or underestimating your skills as one could lead to burnout and the other can lead to time wasted in recapping things you already know. You need to ask yourself the following questions:

- _What do I know now?_
- _What do I want to learn/be able to accomplish?_
- _How will I get there?_


![drawing of ladders showing one long ladder will get to a destination better than 3 short ladders](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sq7zll5yyth0xz3f9uc9.PNG)



Once you have the answers to these questions written down you will have a North Star for how to proceed. Now you can go about the next steps in a more methodical and educated way. If you are new to programming entirely or new to a language, then the next step I would recommend is…

### Online Courses
I am a big advocate of online courses (Udemy in particular) however I see them as an introduction to a language and not a be-all end-all for self-learning. It is also very important to be deliberate in what course you choose and to know why you’re choosing it. Always read the reviews carefully, make sure the course is appropriate to your level and watch the sample videos to make sure that you gel with the instructor. Furthermore, it is important that the courses have sections where you are forced to think through problems yourself based on what you have learned.

A mistake I made early on was copying the code from the course content, making sure it worked and then moving on to the next slide. My code worked, but by the end of the course, there was next to no chance I would be able to replicate what I had written by myself.

Doing an online course is a huge time investment (generally >12 hours of content) on top of the cost of the course itself so choose wisely.

While completing courses it is important to take notes and understand the why behind the code that is being shown as opposed to just blindly copying whatever is being shown to you. If possible, take your time with the course, change and experiment with the code to see the results. Make sure your understanding is correct and then once you’re finished it’s time for the next step...

### Personal Projects
A great way to go about learning new languages/libraries is to complete your own personal projects using them. The fact is to have literacy with a programming language you will need to have an environment where you are regularly solving your own problems, getting familiar with documentation, making mistakes, and learning from them.

There are hundreds of suggestions for personal projects to undertake online[^4](Toy Robot being a personal favourite). I think it is wise to try to choose something that will keep you motivated. This could be a project that might be useful in your everyday life, a game or a project you do with a friend or colleague.

### Use of git issues/planning
As a learning developer/programmer, it is important to embed the habit of planning the code you will write before you write it and understanding the technology you are using. The context for any given problem you are trying to solve will help you solve the problem, continue to see the big picture and make the overall experience more enjoyable.

Using git issues is a great way of planning as it will train you to always step back and methodically think about whatever problems you are trying to solve. For personal projects, I have found having a few core issues where the rules of the project are written (folder structure, basic architecture, data flow etc) with other issues being written and checked off for ongoing work.

But issues are not limited to personal projects, if you’re practising interview questions, then it is also a very good time to write an issue or take notes somewhere breaking down the question into smaller parts. If you have a tech interview and the interviewer sees you taking 5–10 minutes to plan your code before you start then it is going to reflect very well on you.

If you do all of this correctly your code will be cleaner, your architecture will be more consistent, and when things go wrong you will be able to understand why with more clarity and over time you will become very familiar with the documentation for whatever language(s) you are using.

### Networking
This could include attending meetups, posting on forums, reaching out to people on LinkedIn or anything involving expanding your network of developers. The less lonely your journey is the better. In my experience, programmers are often very keen to help you solve whatever problem you might have.

More experienced developers will be able to steer you in the right direction and answer questions. Furthermore, there is a lot of value in being able to have simple and enjoyable conversations about your craft with like-minded individuals.

The good thing about our community is that it’s full of passionate people who are always willing to share their knowledge. My general rule with networking is, you won’t know unless you ask, so reach out!

### A mindset to avoid: “I just want to get this working”
If learning is your goal, then a toxic mindset to have is “I just want to get this working. Understanding the code or writing it in a clean and expandable way is secondary”. The pitfalls of this mindset include dirty, difficult-to-read code, excessive-tech debt and often your code base turning into a big ball of mud[^5].

Not only will this lead to inefficient learning, more frequent bugs in your code, and poor habits being embedded but it is also a mentally exhausting way to go about coding and learning. This instant gratification mindset is a recipe for burnout and is something that has cost me dearly in the past.

### AI and learning
AI is an inevitable part of the industry and learning to code. It’s difficult to predict what the future will be and that goes beyond this post, however, as far as self-learning is concerned it can either be a very powerful tool or a hindrance. Remember what was said earlier about learning basic concepts and then building on them? This is where AI can really shine and act as an extremely patient teacher of sorts.

![A robot teaching a class](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/khq7emlwbp40povtoixh.png)
<figcaption>Is the future really so bleak?</figcaption>
The beauty of AI bots like ChatGPT or Bing AI is that you can ask them questions in your own language and ask qualifying follow-up questions. Maybe something in the documentation is not quite clear and the way that it’s written is not obvious to you. That’s when you can log into ChatGPT and ask directly “Is the following concept an example of A or B?” and continue to rephrase the question until you are clear on the concept.

### AI for research/ git issues
If we go back to the example of using git issues to plan out our code. If you’re by yourself, then how are you going to know what the best folder structure is? I just asked ChatGPT “Can you give me a basic file setup for a React application?” and the following code along with an explanation of each file was given to me within seconds:
```
my-react-app/
  ├── node_modules/      // Dependencies installed via npm or yarn
  ├── public/            // Public files, like HTML and static assets
  │   ├── index.html     // Main HTML file
  │   ├── favicon.ico    // Favicon
  │   └── manifest.json  // Web app manifest (for PWA)
  ├── src/               // Source code for your React app
  │   ├── index.js       // Entry point for your app
  │   ├── App.js         // Main component
  │   ├── components/    // Directory for reusable React components
  │   │   ├── Header.js
  │   │   ├── Footer.js
  │   │   └── ...
  │   ├── styles/        // CSS or SCSS files
  │   │   ├── main.css   // Main styles
  │   │   └── ...
  │   ├── assets/        // Static assets like images
  │   │   ├── logo.png
  │   │   └── ...
  ├── package.json       // Project configuration and dependencies
  ├── package-lock.json  // Lock file for package versions (if using npm)
  ├── yarn.lock          // Lock file for package versions (if using yarn)
  ├── .gitignore         // List of files/folders to be ignored by Git
  ├── README.md          // Project documentation
```
The above isn’t anything revolutionary but there is a good chance that it’s much more scalable and easy to work with than anything a new developer may have come up with by themselves. Furthermore, you can ask about appropriate architecture, separation of concerns, or almost anything you can think of.

## The limitations of AI and how to not use it
If we circle back to the bad habit code first ask questions later ChatGPT can also be used as its own Band-Aid solution. It is possible for you to copy and paste your code into ChatGPT and say, “Make this work” and after a few prompts have the code working without you understanding the how or the why. In some instances, this may be extremely useful but where learning is concerned, it is equivalent to a teacher flat-out giving you the answer.

Furthermore, ChatGPT as an example is not up to date on technology after 2021. For this reason, it will not be able to provide effective advice on the features of more modern versions of libraries (React 18 or NextJS13 as two examples).

### To summarise

The way I see AI at this point is it is a tool that can augment our abilities as a programmer and make us more efficient. To use gaming terminology, let’s say that using AI can increase your efficiency by 50% as a developer. This is great but you will need to level up your baseline skills to make sure that the 50% is 50% of a substantial number[^6].

- _If AI is used as a crutch, you will not level up as a developer and you will hit a ceiling._
- _If AI is used as a learning tool as well as something that can increase efficiency, then really the sky is the limit._

## Wrapping up

If you made it this far then congratulations! This post was much longer than I had originally intended. Originally, I wanted to write a brief post about how I use AI for learning but it just kept on growing. Other questions inevitably popped up such as, _What is efficient learning?_”, “_Why do I do things this way?_” or “_Is this good advice for someone else?_”.

There is a good chance that some of the advice I have provided here isn’t for you, and that is perfectly fine. There really is no one-size-fits-all-all advice when it comes to learning or life, and some people thrive off diving straight into the deep end and learning the foundations as they go.

The truth is that I have had to work against my own nature and unlearn a lot of bad habits during my journey as a developer. Every mistake I have outlined here is a mistake that I have made in the past, this post has been the result of wisdom gained from the 20–20 vision of hindsight.

Skill acquisition is a very broad topic and at its core, it’s a study of human nature. If you found this post interesting then I recommend checking out the books ‘Mindset’, ‘Grit’ and ‘Atomic Habits’. If you liked this post then give me a follow because I feel I am beginning to find my voice and I want to continue applying some of my other life lessons to tech-related topics.

[^1]: The relationship between skill and difficulty is an idea I’ve gotten from reading about Flow State. If a challenge is above your current skill level then anxiety comes into play. Imagine asking someone fresh out of a coding boot camp to make high-level decisions for your organization and implement the code, it’s unlikely to go well for anyone. If a challenge is too low for a person’s skill level then boredom comes into play. Where learning is concerned ideally the challenge should be just above your current skill level at all times. https://www.theworldcounts.com/purpose/what-is-flow-in-psychology.
[^2]: Deliberate practice explained: https://jamesclear.com/deliberate-practice-theory. 
[^3]: Mental health and positive self-talk are worth their own posts. I encourage you to remember that the journey towards bettering yourself is rarely if ever, a straight line and to also take stock of the progress that you have made.
[^4]: Stephan Miller at Codecademy has some good recommendations: https://www.codecademy.com/resources/blog/20-code-challenges/
[^5]: Brian Foote and Joseph Yoder’s 1999 paper “Big Ball of Mud” is still very much worth a read and holds up well today. http://www.laputan.org/pub/foote/mud.pdf 
[^6]: I really hope this made sense 🤦‍♂️