What is Stack Overflow for?
Power tools are helpful — but use them safely.
This blog post describes an anti-pattern in how some aspiring software engineers use the Internet. My observations are my own, and I have made little effort to connect them to scientific studies. Nevertheless, I hope they are helpful to someone.
The Internet Anti-Pattern
As a professor of Computer Engineering, I teach and mentor many aspiring software engineers. These proto-engineers face a temptation that I did not have to struggle with when I was a student: Stack Overflow and its brethren.
Most programming-themed Internet help sites emerged while I was in college, and my friends and I made fun of them for being so limited. How times have changed. Nowadays, it seems as though you can answer almost any programming question with a Google search that lands in a highly-voted answer at sites like Stack Overflow and Quora.
Sometimes I see this convenience lead an aspiring software engineer astray. Here is the Internet Anti-Pattern: programming by dint of repeated recourse to Stack Overflow, copying code to address each error, and ending up with a partial solution that you don’t fully understand. Some of my students end up tied in knots, and report spending a long time — over 10 hours! — in unsuccessful Stack Overflow sleuthing.
Tips for effectively using Stack Overflow
Take a moment to reflect
The next time you find yourself headed to Stack Overflow looking for help, ask yourself a few questions:
- “Do I have enough expertise to understand whether the advice is sound?” If you do, splendid. But if not, your time might be better spent developing your expertise.
- “Will I be able to debug this code snippet when it doesn’t work?” Most Stack Overflow posts need to be tailored to your context, and many have subtle errors because they are intended as illustrations. You should never take code from someone else without knowing how it works.
- “How critical is it that I fully understand this problem and its solution?” In engineering work, some knowledge is critical and other knowledge is not. Most engineers don’t need a deep mastery of date-time formats or the RFC defining valid email addresses. Internet resources are a great way to find suitable code snippets for such tasks, which you can then bury within a friendly API in a utility library. But if you are working on code for critical business processes (or the key algorithm in your school project), step carefully.
- “How long have I been looking for a solution to my problem?” Personally, I use a “5 minutes” rule. If I’ve been looking for a solution for more than 5 minutes, this is usually a signal that there’s something wrong with my question. That means I should switch to studying and developing my understanding of the problem and the tools I am using. An alternative explanation is that my problem is sufficiently obscure that I am one of the first people to try to solve it — so I’d better focus on solving it!
Sharpen your axe
If I had a choice between (a)spending 10 hours debugging errors I didn’t quite understand, or (b) spending 9 hours with a technical manual, and then 1 hour applying my newfound skills, I know which I would choose. There’s an old saying by J. Strong: “Time spent in sharpening the axe may well be spared from swinging it.” You should seek to develop long-term reusable skills, not just flitting from one quick fix to another.
In software engineering, there are a thousand tutorials that walk you through writing your first Android app, setting up your first website, even implementing your first Linux kernel module. These resources are valuable, but don’t become overconfident. If you complete one of these tutorials, you now know enough to start exploring. Don’t stop there! Here’s what I suggest you do next:
- Have an attitude of seeking to master the topic you are studying. Spend time with the topic — whether that’s a programming language, a framework, a technology stack, a query language, a design pattern, or an algorithm. Are you learning Android? Take half a day and read through the Android developer manual. Are you learning C++? Take Stroustrup’s advice. Are you learning about design patterns? Study under the Gang of Four.
- As you aim for mastery, make sure you apply what you’re learning! Sketch some UML diagrams, try out TDD for yourself, write a few map-reduce queries. But don’t experiment on a “live patient”. A bit of practice in a standalone program can illuminate an issue buried in the bowels of your program. Then you can transfer what you’ve learned into your real project.
Don’t try to get-rich-quick, don’t seek to become an expert without investing in expertise, don’t misunderstand the nature of mastery. Experts are experts because they have invested their time wisely. You can develop expertise by reading enough Stack Overflow posts, I suppose, but this is a painful path. If you think your expertise is lacking, your time will be much better spent studying and practicing than searching and floundering.
Am I just a cranky old man?
I would be remiss to avoid some reflection about the “unhelpful tools” to which I had access as a student. Personal laptops were mainstream, IDEs were maturing, and Linux distributions and virtual machine technology was consumer-friendly (though the driver ecosystem wasn’t quite there yet). These technologies were themselves a set of “power tools” beyond what the previous generation of computing students had dreamt of. I’ve spoken with older tech workers who learned on laptops that weighed ten pounds, who learned at the public library, and who started on mainframes with punch cards — each generation seems to think that the tools available to its successors makes them soft.
I do wonder if there is a paradigm shift here, however. Although my “programming grandparents” worked out their algorithms by hand and triple-checked them because it was so expensive to embody them as punchcards, although my “programming parents” had to make a special trip to the library to program, and although I did my schoolwork in the comfort of my dorm room, in each of these generations we would primarily rely on our own know-how, supplemented by that of our friends and our textbooks. Our successively more powerful tools improved our efficiency, but at the same task: communicating our own thoughts to our computer.
The information power tools available to the current generation are of a different kind. They enable a new form of programming: the programmer as conduit, communicating someone else’s thoughts to the computer. Becoming an effective conduit takes practice, correctly distinguishing between good and bad content and fitting it into the frame of their program. This is a hard task for a novice.
Nobody needs to deeply understand every aspect of a codebase. Abstracting away details is the key to building complex systems, common to every engineering project. Mechanical engineers don’t need to understand every gear in a system, and electrical engineers don’t need to understand the purpose of every resistor in a circuit. Similarly, software engineers don’t need to understand every detail of their system. We build libraries, name them well, structure them using design patterns, and integrate them into ever-more-abstract APIs.
But the “Internet Anti-Pattern” occurs precisely at the point where you do need to understand the details of some part of your system. When you find yourself uncertain, you must decide: Should I ask someone else for help, or should I seek deeper understanding? Each path is helpful at the proper time.
It is not my intention to discourage an aspiring software engineer from using the resources on the Internet. There is so much wonderful content available for free, and many kind engineers who want to share their expertise. But these resources are a “power tool”. If you know how to use them, they will help you. If you don’t, you may do yourself more harm than good.