How to stop asking others and learn to learn by yourself.
This is a fundamental topic and will be most useful if you are a complete beginner. Especially, if you always back up to asking your fellow programmer to fix an error or explain a thing you don’t understand—I’ll try to teach you what else you can do instead.
Self-learning is an essential part of programming. Technologies change every day, and you must educate yourself daily not to fall behind. Furthermore, even if we freeze technologies today, there is just too much knowledge for a single person to know everything. That’s why finding necessary information and grasping it quickly is such a crucial skill. Asking others is cool for getting fast results, but it robs you of these self-learning skills.
Asking others is cool for getting fast results, but it robs you of self-learning skills.
Many beginner courses teach programming in a way that students get used for information being spoon-fed and don’t learn to dig for it. (If you never google for an additional piece of knowledge, that is the case.)
That’s ok for basics courses (to not ruin your motivation), but as soon as you start getting some visible results, you should do a bit of self-learning here and there.
You should also understand that most programming you do until you get employed is to acquire skills. That means you should value learning over results—most of the times, crapy shit you wrote yourself is much more valuable than a masterpiece copy-pasted without understanding.
I believe there are two broad categories of questions you usually reach out to others. It is either a theoretical question (how things work or what something is doing), or a more practical “It doesn’t work! Help me!”
This category of questions is the easiest to answer.
If you don’t know what a thing is—google its name. (If it happens to be a general word, add the technology name.) Read what you’ve found. That will usually be an article, an example, or a piece of documentation—get used to reading these. If you still didn’t grasp the thing, try experimenting with it. If you don’t know how you’re probably not ready for it yet—forget about the thing now, you’ll get back to it later.
Learn the basics of google-fu. Though you will rarely need anything except quotes (exact match) and minus (exclude), these will help you enormously.
A special kind of questions in this category is “what if” questions. (“What if I delete this line?” or “What if I initialize this variable to 1?”) The correct answer is usually “Do that and see yourself”—software is extremely flexible and easy to experiment with (that’s why it’s called “soft”).
Another kind of questions in this group is the best practices—when you have two solutions to the same problem, and you can’t tell which one is better. Most of the times, the correct answer is “it depends,” so the question boils down to understanding the pros and cons of each solution are.
What I recommend to do in this case is:
- Think of the pros and cons of each solution yourself.
- Learn more about solutions—try googling pros and cons.
- Ask others. (I believe that this kind of questions is the best to ask as they are rarely documented online, and you might not have enough expertise yet to tell for yourself.)
The latter category of questions is what we programmers call “debugging”—getting rid of errors (bugs) and making programs behave the way we want them to. This is a separate skill and will take a whole life to master. I can’t teach you the whole thing, but I’ll give you a couple of tips to get you started.
The general framework for bug-fixing is as follow:
- find a bug
- find root cause
- come up with a fix
- implement it
The hardest part—and most fascinating one—is finding the root cause. It’s like playing detective except probably much more interesting. Coming up with a solution is usually trivial once you know what’s happening.
So here are the tips.
Check error messages, read and understand them
Often all the evidence lie right in front of you waiting to be found. (And I find it surprising how often it is ignored.)
Check if there are any error messages in your compiler output, browser console, or your log file. Read and try to understand them. If you’re implementing a web layout, check if a browser has applied all of your styles. Check everything that could give you a hint.
The errors might seem cryptic at first, but spend some time and learn to understand them—that will pay off handsomely. If you are presented with a stack trace (a list of function and file names along with some numbers), learn to read them, too.
If you think the errors have been written by a sadist and don’t help a bit, I promise they were not. Providing helpful error messages is a hard task and tool authors do their best. There is a tendency for error messages to become friendlier every year. Nowadays, some compilers even include instructions on how to fix the error—read them.
Tool authors do their best to provide helpful error messages—read them.
If you don’t know what a specific error means, google it (remember to retract all your identifiers from the query)—you’ll often find a description of the error as well as ways to fix it.
Double-check your code for typos
If you’re using a dynamic language, typos will be the most common source of bugs. Before diving headfirst into a long debugging session, ensure you have typed in what you meant to.
Enable syntax highlighting and automatic indentation in your editor (if they are not enabled by default), pay attention when they go weird—that usually means you’ve messed up with syntax (e.g., missed a closing double-quote, a closing bracket, or a semicolon).
You may also configure semantic highlighting in your editor—that will help you catch typos in variable names. (The idea of semantic highlighting is to assign every identifier a different color so that “length” and “lenght” have different colors and are easily distinguishable.)
I find a series of experiment a useful model to think in during debugging. Each experiment should start with a hypothesis, be isolated, and give you more clues.
Think of what you already know and don’t know about the bug, what could cause it, what might be true about it.
Define your search area—where in your code the bug might hide.
The result of this step is a clear understanding of what is already known, and possibly some insights on what might be happening.
Design the experiment.
Start with a hypothesis. Pick a hypothesis that is more likely to advance you or is straightforward to test. Debugging is art so you will rely on your intuition more often than not. Don’t worry—it’ll grow stronger with time.
The experiment could be as simple as reading documentation for the function you just used or running the program with specific input and examining the output; or as hard as rewriting a part of the code and stepping through it with a debugger.
Be clear about what you’re testing, what results you expect, and what they would mean—jumping around the code with a debugger is no help unless you know what you’re looking for.
If you don’t know how to use a debugger, learn it—that will enable you to run more investigations.
Conduct the experiment and collect results.
Repeat the experiment if needed.
Run one experiment at a time.
If you are going to change the code, do not introduce more than one change at a time. If you introduce three unrelated changes, you won’t be able to attribute test results to one of them, so you’ll need to redo the test.
Think what results mean. Is the hypothesis confirmed? Do results stack up with what you already know?
How did the search area change? Ideally, each experiment should shrink it, either by pointing down to a single piece of code (module, function, line) or excluding one.
If you changed the program behavior, revert the changes. Changing behavior invalidates your experiments, as you’re now testing a different program.
Here are some sample experiments you could do.
- Read the documentation for a new function you just used—it might do something different from what you expect.
- Run the application with different input to see if the bug is still there. (e.g., you could pinpoint that the bug only manifests itself on even numbers.)
- Launch web inspector and check what elements got rendered.
- Add a log statement on entry and exit of some functions to verify the call sequence.
- Log a variable’s values at specific points to verify if they are correct.
- Write a simpler program that reproduces the bug, so there are less moving parts—the bug is simpler to catch in a small room.
- Maybe you just optimized a big chunk of a function, so you can revert changes to ensure it is the new implementation is causing the issue.
- (advanced) You can look into a third-party library source code to learn what it is doing with your parameters. Is it doing what you expect?
Note that these experiments rarely involve debugger, and might not even involve your program. As you master programming and debugging skills, you will be able to pinpoint many bugs without even running a program.
Have you ever seen a detective panicking? You shouldn’t, too.
Mixing in strong emotions will disable a part of your thinking, so that will only make it harder to fix the bug. That will also make your process inconsistent, so you end up jumping around changing some random code here and there until you no longer understand what you’re doing.
If nothing works as expected and you don’t have a single clue why, it is natural to panic—don’t. As a programmer, you’ll find yourself in similar situations very often—get used to it and don’t overreact. Remember that you are a detective—be fascinated by the case, and systematically investigate clues to uncover the criminal.
Take a break
Taking a break has numerous benefits:
- if emotions get out of control, it’ll help you to calm down
- it refreshes your energy and cleans your mind
- it kicks in the subconscious mind so that a good idea may pop up in your head
Ask the question
If you got stuck, there is nothing wrong about asking for help. However, you should do this in a way that makes your question easier to answer and shows that you did your due diligence:
- describe the problem
- describe what you’re trying to accomplish and what you get (expected and actual results)
- provide minimal code that demonstrates the issue
- describe what you’ve tried and what results you’ve got
If you don’t have a friend programmer, you could ask questions online. Be sure to follow the rules of the online community you’re asking help from.
Before asking a question online, read a comprehensive How To Ask Questions The Smart Way by Eric S. Raymond.
Self-learning and debugging are two HUGE topics. I’ve barely scratched the surface, but I hope that will help you to unstuck yourself next time.
If you know any other helpful tips, I want to know them, too—post me comments down below.