Quick – give me a technology which you are better at than anyone you know. The kind of deep knowledge that would allow you to ace any off-the-cuff quiz thrown your way.
If you’re anything like me, you probably can’t say that you truly are deeply knowledgable in anything. Like most people, my focus lies in the tools and methods that get my job done. Often these jobs require a lot of repetition, where unknown solutions are just a search or two away.
According to the authors of Apprenticeship Patterns, this is a problem. By developing only a superficial knowledge of a technology, you are setting yourself up for pain later down the line and building a product on shaky foundations. Blindly relying on quick-fix solutions results in potentially sloppy implementations using concepts you don’t fully understand.
Today’s post will look at some common symptoms of shallow knowledge, the value of nurturing a deep knowledge of your tools, and ways in which you can achieve it.
(This post is part of a series inspired by the book Apprenticeship Patterns. Find the rest of the series here.)
You may be wondering at this point if it’s really worth it. After all, you go to work every day and get the job done. Someone is already paying you, so is the extra effort for deep knowledge really worth it?
Here are some reasons why the investment is worth more than you might think:
Have you ever searched Google for an answer to a problem only to come up short? This is especially common with languages and tools that are still in their infancy; answers are naturally harder to come across.
For those with a shallow understanding, it can quickly start to feel like they’re bashing their head against a wall. Some respond by endlessly Googling for a solution they’ll never find. Others, if they have the opportunity, will go and ask someone on their team with a deeper knowledge.
If you are the one with that knowledge, then you don’t have to rely on anyone else. You will have a solid foundation of knowledge to help guide your search for a solution. You will be familiar with the standard library and the code’s documentation, such that navigating them won’t slow you down.
On top of this, you will be able to rely more on your own code. I have written insufficient tests because I didn’t know about the intricacies of the tools I was using. The scary thing is that I wasn’t even aware. It took someone with more knowledge pointing it out to me, or unexpected behaviour in my code.
If you understand your tools deeply, you will build systems that you can confidently say are high-quality and resilient.
Despite common belief, developers are responsible for more than just typing out endless lines of code. Yes, it is a large part of what we do, but we are also responsible for communicating with the business about what we are doing, why, and how it is benefiting the company.
If you don’t deeply understand the tools that you are using, why should anyone trust you? While it’s absolutely fine to not have the answer to every question, people are going to respond to you a lot better if you can talk about something with confidence.
Why is this important? Because you are there to influence the technical implementation of a solution, not simply follow instructions. Your job is to deliver a high-quality product, and that can involve negotiation between businesspeople and other developers alike. Without being able to talk in detail about something with confidence, you are unlikely to change anyone’s mind.
A lot of developers will accept a shallow understanding as “good enough” for their day job and leave it at that. This means that you set yourself apart by building a deep knowledge of something. This is especially helpful when applying for a new job or looking to progress in your current one.
Good luck is when opportunity meets preparation, while bad luck is when lack of preparation meets reality. - Eliyahu Goldratt
You will create other opportunities for yourself as well. You could try your hand at teaching others, or contribute to the community or code of an open source tool.
Most people would agree with the notion that having only a shallow knowledge of your tools and languages is not ideal. But if that’s the case then why is it true for so many of us? Why do we neglect to build up a deep understanding of the things we use on a daily basis?
The context on which the authors base their pattern describes problems that most developers will be able to relate to: tight deadlines, complexity, and the need for a broad set of skills. In a way, all three feed into one another; modern developers are often involved in full-stack development or DevOps, expected to know about front-end, back-end, infrastructure and a whole plethora of other subjects.
Each of these is as endlessly complex as you are willing to uncover, and gaining a genuinely deep understanding of every one would take years. Throw in that your boss needs the project done by next week, and you can figure out the rest.
Regardless of whether we have the time and resources to gain a deep understanding of something, it’s really hard! It takes hundreds or thousands of hours of deliberate practice.
The key word there is “deliberate”. You could spend a few thousand hours retyping the same “Hello world!” implementation in Python, but I can guarantee that you won’t be a Python expert by the end of it. Knowing how to practice deliberately with your tools and techniques isn’t easy; it takes effort, planning, and discipline.
I don’t think this one takes much explanation. Sometimes we just want to do nothing, and this desire often overrules our rational mind telling us to practice.
You may be reading this, thinking “this isn’t about me, I’m deeply knowledgable about all the tools that I use”. If that is truly the case then feel free to stop reading! Consider, though, that you might be experiencing the Dunning–Kruger effect, overestimating your own ability.
I’m sure there are endless symptoms of shallow knowledge, but here are some that I’ve come across.
Stack Overflow is an absolutely brilliant website that should be used by all developers. However, if you find yourself regularly copying and pasting code snippets without fully understanding what the solution entails or reading the explanations and comments, then you are settling for a shallow understanding.
Many developers often find themselves bouncing from one Stack Overflow thread to another trying out every vaguely similar solution, instead of using the lessons from each to synthesise their own. This is a passive approach to problem solving rather than the active approach required for deep knowledge.
We’ve all done it. The Hail Mary of the desperate developer. Printing things like “GOT HERE” to the console can be a life-saver in a pinch. However, if you are regularly relying on such tactics to understand the code that you work with, it’s a sure sign that you need to spend some more time getting to know it. Most languages have debugging tools which make this process a lot more flexible and constructive.
There are some incredibly powerful tools for developers out there. I’m constantly blown away by the capabilities of the IntelliJ IDE, for example. It seems a shame not to use such impressive tools to their full potential.
A little up-front learning could allow you to automate a lot of laborious text editing tasks. It could also mean that you rely less on your mouse/touch pad.
That may come across as a little pretentious, but a lot of small actions can add up over time.
So you’ve dug deep, done some reflection and realised that maybe you don’t know your tools as deeply as you could; what can be done to fix it? Here are some suggestions from me:
The thing to do if you really want to get to know your tools is to use them repeatedly and conscientiously. We use our tools on a daily basis, but this is not enough to gain a deep knowledge of them. Repetition builds habits, which aren’t always good habits. If you use your tools without paying attention, you are unlikely to improve.
Instead, you should be reflecting on your use and knowledge of your tools while you use them. For every action you take, ask yourself if it is the most suitable for the situation.
Likewise, ask your colleagues for feedback on the ways that you use your tools. More experienced members of your team especially will be able to give clarity or share tips.
Constantly ask yourself, “what are the deficiencies?”. When you have identified them, figure out what steps you need to take to improve and fix them. Are you being lazy and neglecting to memorise a shortcut? Are you making blind assumptions about how an API works?
Use such discoveries to guide your learning, instead of mindlessly continuing. There is always room for improvement.
You could even consider putting yourself into manufactured situations. For example, I have toyed with the idea of trying an hour a week when I am not allowed to use the touchpad at all. This is a lot easier to try if you work alone, but in my case I have to find a willing pair first!
Read the documentation (RTFM)
This is one which I really struggle with. I absolutely hate reading documentation for libraries, APIs, languages, you name it. I find the process dense, and in some cases stressful when there is time pressure. It is truly my belief that reading documentation is an art form, just one I have yet to learn.
In all seriousness, it is quite likely that if you have a question about a tool or language that needs answering, there will be an answer somewhere in the documentation. This is not always the case, but knowing how to quickly find what you need in the documentation is a skill worth knowing. Reading the documentation for a product in more depth and being generally familiar with it is an important part of having deep knowledge.
Consider trying something like this: set yourself a project using a language you would like to learn more in-depth, and restrict yourself to using only official documentation or articles in order to get the project done. No quick fixes from Stack Overflow, no random blog posts. Official documentation only. This will force you to learn to read docs, and where they are lacking, will teach you how to investigate and explore your tools.
A similar approach that relies less on documentation, which could be wrong or out of date, is to read the source code if available. No matter what the docs say, if the code does something else then that is the truth of the matter.
Having a good knowledge of the standard library and implementation of your tools provides a reliable foundation on which you can build more in-depth, specialist knowledge.
This is an approach I have only recently come to appreciate. Unlike the print("GOT HERE") approach discussed above, using debugging tools allows you to get a real-time view into the way your programs work.
Reading the source code is easy enough to suggest, but the sheer size and complexity of some systems can make it impractical. Executing code with a debugger and stepping through one command at a time can really help to visualise the sequence of events a system produces and the interactions it has.
If nothing else, a debugger can provide you with questions you can use to expand your understanding. If you see some unknown, unusual object being called as part of a framework you are using, you can start to investigate what that object is/does, and start to build up a more substantial understanding.
This is another one which I only recently came to appreciate, while a colleague and I were trying to figure out how to test something in the React framework using Enzyme. My more experienced colleague had a completely different way of approaching the problem.
After we had spent some time playing around with the code trying to get it to work, she started to look in the open issues section of the API’s GitHub page. Sure enough, before long we had found an issue which described the one that we were facing. Before that, I would never have thought to find out more about a tool by looking at the work being done to it.
This practice has several benefits. The first is that you start to get an appreciation of what is lacking in the tools that you are using. My colleague and I had simply assumed that because React behaved in a certain way then a testing utility like Enzyme would have the means to test it, but we were wrong. Deep knowledge can save you from tripping up on similar problems further down the line. It could even inform significant changes in the tools that you use.
The second benefit is that knowing what’s missing gives you an opportunity to contribute. There are few ways more effective to become knowledgable than contributing to the creation of a tool. Not only do you need a good understanding of how a system works if you want to change it, but it also gives you the opportunity to work and communicate with those who have been there from the start.
Do you have a different definition for deep knowledge?
Do you know anyone who has deep knowledge of their tools? What effect does this have on the way they work?
Let me know in the comments below!