Listening time: 26:04
Learning to code - or learning any new skill - is hard, but it doesn't have to be overwhelming. In this episode, Preethi discusses her tried and true strategies for learning, how to tackle challenging problems, and the methods that help her add new tools to her kit.
Written by Preethi Kasireddy: https://twitter.com/iam_preethi
Read by Abbey Rennemeyer: https://twitter.com/abbeyrenn
Original article: https://fcc.im/2uG4B0F
Learn to code for free at: https://www.freecodecamp.org
Intro music by Vangough: https://fcc.im/2APOG02
Being an efficient learner is at least as important as being an efficient coder.
When you’re a developer, your job requires you to learn every single day — in spite of the constant lure of distractions like Hacker News, Twitter, Reddit, and Facebook.
You constantly encounter new code bases and new technical challenges at work. Home is no better, as you tackle open source repos and personal projects, each with their own processes and challenges to tackle.
The tech world changes fast, and it can feel like a full-time job just keeping up with the latest tools, languages and frameworks.
Long story short: learning is hard. Yet, we need to be able to learn quickly and effectively to thrive.
In the past year, I went from not knowing how to use the Chrome debugger to working as a software engineer for a leading cryptocurrency company. In the process, I rapidly learned a new skill (coding).
That said, learning didn’t come easy for me.
Honestly, every new concept was a struggle. There were too many unknowns, and too much uncertainty.
“How in the world is this sustainable?” I thought to myself.
“If this is what learning to code is supposed to feel like every day, I’ll be miserable. Is this really my passion?”
“Wouldn’t this be easy for me if this was my passion? Do artists struggle to produce art? Do writers struggle to write a great book? Do athletes struggle to do well in a race? Are we supposed to struggle when we’re pursuing our passions?”
“Shouldn’t I be finding pleasure in this?”
Does it ever get easier?
Yes, it does. A year later, tackling new programming concepts is still “difficult” in the sense that it requires discipline and hard work.
But it’s also become an enjoyable process, rather than an overwhelming one.
What happened in the last year to make that shift possible?
Simple: I changed my perspective on learning. What once struck me as “difficult” became “engaging.”
In the rest of the post, I’ll explain how this transformation happened.
Just getting started
Learning to code is hardest at the beginning.
For example, think about the first programming language you have to learn. You want to tackle the small things like syntax and style. But first, you have to comprehend difficult core concepts like values, types, operators, control flow, functions, higher order functions, scopes, closures, recursion, and so much more.
It feels like learning to juggle — but starting with eighteen pins instead of two.
When I first learned about closures, it took me many weeks to truly understand the concept. I thought I understood it when I read about it. But when I tried to identify and use closures in practice, I’d find myself stumped.
That wasn’t unusual. I’ve observed this process as a teacher as well: new concepts don’t usually click the first time around. Or the second. Or even the tenth.
But for those who stick it out long enough, there will be a “breaking point” where things suddenly begin to make sense. In my example, I read literally every blog post, Stack Overflow post, and spec on the internet about closures.
Everything I read and experimented with gave me a new perspective, until eventually, I had a 360-degree mental picture of how closures worked. Closures “clicked.”
Getting to a point where I felt this sense of understanding of closures was super important, because it was rewarding and encouraged me to go for more — including writing my own blog post that explained the concept.
Learning is a process, not a goal If we see learning as something we “have” to do, then we rush to get it done so that we can spend the rest of our time doing something more “fun” — something we “want” to do.
The problem is that it’s impossible to know everything about anything, so viewing learning as a race leads to burnout and disappointment.
Instead, if you see learning as a process, you’ll appreciate the small victories and insights along the way. This will drive you to constantly move forward.
You can compare it to exercise. Workouts hurt, and then the pain ends as soon as your workout ends. But it’s never gone. It’s waiting for you the next time you workout. Except each time, the pain becomes less piercing. You learn to cope with it. You become familiar with the pain, and it just becomes part of the routine. You are rewarded by better health and a better physique and are incentivized to keep going.
Exercise creates a positive feedback loop.
The same is true for learning.
Turning learning into an engaging process
Imagine building your very first web application.
At first, all you’ve got is a daunting, blank text editor. The task of building the app seems almost insurmountable. You know nothing, and have so much to learn before you can make this happen.
Thankfully, you decide to go for it anyway.
From then on, your main focus becomes to do one small step at a time.
First, you create an idea. What will you build? Who’s the end user? What are the constraints?
Second, you prototype or sketch out some rough designs for what you think it might look like. You ask your friends or the internet for feedback, and iterate to make it better.
Third, you research languages, tools, and frameworks that will work best with your requirements.
Step by step you discipline your mind to channel all its energy towards this one goal.
Sometimes you’re writing code.
More often than not you’re stalled at some bug or error.
Sometimes you’re too tired to do any work, so you take a break.
Other times, you don’t feel like writing code. That’s okay. You spend your time researching or reading up on topics related to your project.
Eventually, after a few weeks of hard work, you’ve built a foundation that can handle your big ideas. Suddenly, working on your app doesn’t feel as painful. You see the reward of the initial set of hard work, and now it’s just another piece of code you need to write or another bit of refactoring you need to do — which you’ve done 100s of times already, no problem.
You turned what was once a daunting or dreadful activity into one that is complex and engaging.
This is how we grow. This is how we get better. Whether it’s programming, dancing, running, or reading: it’s not easy, and there won’t ever be a time or place when you’re “done” learning.
Instead, enjoy the process of investing your energy into something, and enjoy the pain that comes along with it. You’ll start to notice that you no longer describe it as “pain” — because what was once painful becomes a symbol for what’s next: a sense of personal accomplishment and self-satisfaction.
In other words, struggle and enjoyment will start to mean one and the same thing. Remember the cycle:
One approach to learning technical topics
Let me tell you a little about the learning process I follow. This isn’t the be-all-end-all of learning styles, so if something different works for you, please share it in the comments! In case you can’t tell, I’m a nerd about this stuff :)
Let’s use the process of learning the React.js library as an example.
What is the motivation for learning this? First step: I’d start with a Google search for the React.js documentation and read a bit about the background and motivation for the library.
Knowing the “why” behind any topic is incredibly helpful for framing the learning process. It answers questions like:
How is this different from other solutions?
How useful is this to me?
What problems does this solution aim to solve?
Is this just a new shiny tool that’ll only be useful for a few months or will it fundamentally change the way I think and code?
Reading and understanding core concepts
Second, I’d read through any intro articles or examples provided in the docs.
Notice I’m not touching any code yet. Reading and sinking in the core concepts comes before hands-on experimentation. It’s incredibly important to do this because it lays the foundation for the rest of my learning.
Even though I might be able to get away with blindly using React.js without learning the core concepts, eventually it’ll catch up to me when I run into a bug.
First time coding
After spending some time on the above steps, I start to get the gist of what’s going on, or maybe even feel like I totally get it. Then it’s time to jump into some code.
I typically try to build something really small with any new tool by following a video tutorial (e.g. on egghead.io) or a written tutorial before jumping into custom projects.
When you get stuck
…And then, inevitably, I get stuck.
Reading the docs seemed like a piece of cake, but actually using it in practice makes me realize I have no idea what’s going on.
This is when I start to feel that dreaded “just give up” feeling. But instead of giving in when the going gets tough, I remind myself that pain == gain. Turning back would be cowardly.
Here’s what I do instead:
I first narrow down and figure out what I’m actually stuck on — i.e. define the problem. Then I come up with a hypothesis for what I think could be the root cause or causes of the problem. Even if I have no idea, I just make a guess.
Then I step away from the problem and my computer and do something that relaxes me. This is incredibly hard to do when I’m so upset about the problem I’m stuck on, but letting go of the problem works wonders. (Ever notice how great ideas always strike in the shower?)
Now I try to debug with my hypothesis in mind. I get as far as I can on my hypothesis without looking for answers online — there’s something beautiful that happens when you try to solve problems by truly thinking deeply about them on your own first. Even if you’re going down the wrong path, the fact that you made the effort teaches you a lot and you remember the problem space much better next time you run into it.
If my hypothesis leads to an answer, hooray! I’m done. If not, I Google search for documentation, blog posts, or Stack Overflow posts that could help me get closer to the answer.
While reading, I take notes on any and all pieces of information that could potentially be helpful.
Still no solution? That’s fine. I’m sure I learned something valuable by reading through all that, even if it didn’t directly help me solve the problem at hand. Who knows when this knowledge might come in handy next time?
At this point, if I’m truly stuck, I will either post a question on Stack Overflow or ask a co-worker or developer I know.
Otherwise, I rinse and repeat until I get closer to the final solution. At some point, the answer always comes.
At times this process takes a few seconds, and other times it takes hours (or days). Either way, the process itself is incredibly beneficial to your skill set as a developer.
Getting stuck on a bug feels like stumbling in a dark tunnel looking for a ray of light. You eventually find it, but along the way you discover so much about the tunnel — and it’s knowledge about the “tunnel” that makes you strong as a coder.
Think of debugging as a chance to explore rather than a detour from your goal, and it becomes much more fun.
Rinse and repeat
By this point in the learning process, I’ve built something small and tackled some small hurdles along the way. As you can see, it was a struggle — clearly, I need some more practice with the new tool.
So, once again I try to build something on my own. Rather than jumping straight to a big custom project, I’ll look for a repo to base my application on.
For example, if there’s an online CRUD todos example (of course) using React.js, maybe I’ll build a different type of CRUD application. Just different enough to keep me engaged, but not so different as to make me discouraged if something goes wrong.
Mastery requires repetition, so I keep building more small projects until I feel like I’ve got the core concepts down.
Eventually, I begin to be able to piece things together on my own without constantly referencing documentation or examples. Only then do I finally adventure out and build something from scratch on my own.
Throughout this process, I aim to make the process fun and engaging. I’m constantly pushing myself to work on things that are harder than what I am capable of in the moment, but not throwing myself into the deep end so that I get discouraged and never finish.
Finally, I make sure to step away as soon as I find myself getting too frustrated to enjoy the project.
Learning is fun
With some effort and structure, learning programming turns out to be incredibly fun. At first it’s incredibly complicated, and in my opinion that’s why so many people get scared away — not because it’s “boring,” but because it’s “hard.”
After you go through this learning process a few times, processing new information becomes a muscle memory. You don’t really think about it. You just learn to ride the pain wave and find joy in the reward.
Like magic, it becomes “easier” to learn.