Image: Narrative History Dream
When I was younger, I remember having some odd ideas about what it meant to learn. Now I look back and wonder why I had such strange and unproductive notions. In particular, I recall that I thought learning meant reading a textbook very diligently from beginning to end. I would even read the forewords. Maybe that was just me!
However, I think the education system at every level does tend to suffer from problems that prevent people from learning effectively: Students are shepherded through too many subjects at a time and learn the material in a linear and rote manner. As a result, I think it's not uncommon for people to promptly forget much of what they "learned" in school, including at colleges and universities.
The following are some heuristics I've built up over time which have helped me when I'm learning something new. If you have the luxury of learning something on your own, consider trying these out. Even if you're in school, I hope some of these ideas may be of help if you actually care about learning instead of just getting through the classes.
With almost any technical subject, it's easy to get involved in all of the complicated details. Doing so prematurely can be a bad idea though. If we don't understand the broader context, those technical details can quickly overwhelm us.
When you're first reading about a given topic, try to grasp the big picture. Why is this important or useful? How does it fit with other topics or technologies? What's the problem that it's trying to solve? Is there another way to look at this? Answering questions like these will give you a perspective that will help motivate a deeper understanding as you dig into the more technical details.
Building intuition is a gradual process. Often clues can be found sprinkled through a given book or other source of information. Keep an eye out for the clues and use them to build up a picture in your mind of the high level principles and connections. Always keep asking yourself: "What's the big idea here?"
In the same way that there's financial debt and technical debt, there's also knowledge debt. If we're faced with something we don't understand, often the temptation is to move ahead anyway, hoping it won't bite us later. In fact, sometimes that's okay. Maybe an in-depth understanding isn't necessary - we just need to get a specific thing done. Or maybe going further into the material will elucidate the point we're stuck on right now.
Both of these things can be true sometimes, but it's not a good approach to leave behind such gaps as a matter of course. It will cause the foundations of our knowledge to get more and more shaky. Eventually, that's precisely what will stall progress completely. For instance, a lot of people think math is "too hard." I believe the reason is that they kept being pushed along in school to more advanced topics, but all the while they were leaving more and more loose ends behind.
This is a big area where I think education can be improved. Kids should be evaluated on their fundamental understanding, and they should be able to keep revisiting older material as they go on to make sure they have fully mastered it. Children all develop differently: To me, that's one of the most serious problems in education, the desire to keep pushing forward in a linear way with a shallow and rote process.
Any technical subject, including math, computer science, and programming, requires effort (at least for us mortals), but if you take it one step at a time, and you make sure to master the individual steps along the way, you can go a lot further than you might think.
Just as test-driven development is about writing code to satisfy a measurable criterion - making a test pass - I like applying the same notion to learning. Learning can seem like a passive process of osmosis. However, it's easy to fool ourselves into thinking we understand that way. It's okay to read something lightly to get a broad overview of a topic, but if we really want to understand how to apply our knowledge, we should make the learning a result of solving problems.
We can start with a simple problem and learn just enough to solve it, kind of like making a test pass in TDD. Moving on to a similar, maybe slightly harder problem, can we solve it without doing any extra reading? If so, great. Otherwise, we go back over our material to find what we need. This makes our reading much more active and goal-oriented.
The more problems we can solve and the more diverse those problems are, the stronger and more concrete our understanding becomes. This is the only real measure of how well we understand something.
Reading a single textbook or article is usually a bad idea. Any source of information will be written in a particular context. It will skip some steps and also make assumptions about what you know. If you're confused (and even if you're not!), look for alternative sources that explain it.
If the material you're reading seems too advanced, look for more beginner-friendly treatments. If you're reading about something in a particular programming language and it is not making sense, try to find the same topic addressed in a language you're more familiar with. Maybe what you're currently reading is too technical. In that case look for high level descriptions to build intuition about the subject. In that regard, I really like the idea of ExplainLikeImFive.
I've talked to a lot of graduates from different schools in many fields about their experiences, including math, science, medicine, dentistry, etc. Often enough, it's the same story: Learn by rote, pass the exam, forget most of it, and repeat. I don't think it's the students' fault either. Students are loaded with so many classes to take each semester that it's very hard to do even a halfway decent job of actually learning. I think this is true in pretty much every field of study, and it's certainly true in CS.
For most people, I think that cutting down the number of courses and focussing on fundamentals would be much better. When a student completes a class, it should mean they have mastered the material. The same idea applies for people learning on their own: Pick one or two subjects to work on at a time, and pay careful attention to really figuring them out.
While solving pre-defined problems is very useful, it can get monotonous. There's also something a bit passive about it. It's better than just reading, but we're still leaving it up to someone else to test our knowledge.
How about coming up with our own problems? When you're learning something new, ask yourself questions about it. What does this imply? Is there a more general way of looking at it? Is it similar to something else? Can it be applied like so?
If what you're learning is related to programming, you can write small programs to test your ideas. You can also come up with larger projects to work on. These larger projects will force you out of the tidy confines of well-defined exercises. You'll need to integrate disparate areas of knowledge and think creatively to make your way around roadblocks.
Also, challenge the material and look for mistakes. Don't just take everything as gospel. Even when there aren't mistakes, this kind of active learning will ensure that you really do get it. You will explore edge cases and counter-intuitive possibilities. Doing so will make your understanding robust: You'll know how something works, and you'll also know in a hands-on, concrete way, the limitations and exceptions that go along with it.
Sometimes we don't realize that we missed something in our study until later. We start a new topic and suddenly things we thought we understood become confusing. That's a good time to stop and go back to review that earlier subject matter. Don't just re-read it passively though. Go hunting for insights relative to the new information you're grappling with: Real understanding is not a linear process. It's iterative. There is a continual need to go back and shore up gaps in our learning that maybe we didn't even know were there.
When I am studying something new myself, I find that I will regularly return to the same material several times. The first time I may struggle with completely new concepts. The next time around, I will start to get it. The third time, I begin to focus in on a smaller number of things that stand out as being harder than the rest. As time goes on I come up with more of my own questions and sometimes push the material into directions that are not mentioned in the book, article, or tutorial that I've been reading.
It can also be okay to study something up to a point, put it away, and return to it later on. Often we can acquire background knowledge in the meantime that makes us more prepared to tackle the material again once we come back to it.
Often, especially in the field of technology, there tends to be a bit of an obsession with specifics, like a particular programming language, library, or framework. I think this is a tendency we should resist, especially since technologies go through such incredible turnover. The darling of the moment may be all but forgotten in a couple of years.
If you start your education with specific technologies, I believe it will limit your ability to adapt, or to switch from one area to another. In addition, when we learn a particular technology in isolation, it often makes our level of understanding more superficial. It means that as soon as we leave the comfort zone of the context in which we learned the technology, we can quickly become lost.
Focussing on fundamentals means trying to identify the core concepts and building blocks underlying any technology or paradigm. Doing so is like having a good understanding of how to build things using lego blocks. It gives you the power to imagine any structure and build that from scratch rather than having to follow the blueprint that comes with a pre-packaged set.
Any specific technology can be seen as some combination of fundamental ideas applied in a particular way. Looking at things in this way is very powerful. It's like a superpower, allowing you to pick up new things more quickly than other people and leaving them wondering how you did it!