So, you want to be a wizard? Presented by Julia Evans at SRECon Americas.
“The first problem with being a wizard is that computers aren’t magic”
This is a talk about learning hard things and understanding complicated systems. It covers six different skills that when applied, will make everyone else think that you’re a wizard:
- Understand your systems
- Ask great questions
- Read the code
- Debug like a wizard
- Write down a design
- Understand the big picture
Understand your systems
Understanding your system means that you have a lot more context about what you’re working with. When people start throwing technical jargon such as
layer 4 proxy or
user space around, you’ll be able to keep up with the conversation.
Understanding your system means that you can debug really hard problems. Most people turn to Google when encountering a problem and just try each result in order until the problem resolves itself. Understanding how HTTP works when configuring
nginx gives you a massive advantage. You’re not just taking a shot in the dark, you’re taking what you know and making educated guesses.
Finally, understanding you system allows you to innovate. If you don’t understand how things work, it’s almost impossible to build something totally new on top of it.
Learn fundamental system concepts – “What’s a system call?”, “What does a packet look like?”, “How does TCP work?”. Write tiny experiments to prove your knowledge. Julia suggests building a small TCP stack from scratch (she used Python and it took around a week). Use that TCP stack to download a website and be amazed that you really understand how TCP works.
Run as many experiments as you can. Write a tiny operating system (Julia wrote a keyboard driver). Ask questions such as “What happens if I run out of memory?” and do it on purpose to test your hypothesis. There are only two rules when it comes to experiments.
It doesn’t have to be good, or even work. However, you do have to learn something
Read things that are too hard for you. Even if you only understand every other word, it’ll push you to learn more. Linux Kernel Development by Robert Love and Networking for System Administrators by Michael Lucas are recommended.
Work with a tool in your job – it gives you opportunities to tinker and learn. When you don’t understand something, dig in, figure it out, learn something new.
Ask great questions
This was my favourite part of the talk. Asking questions is a tough skill – perhaps even harder than answering questions.
Start by stating what you know: “So, I know that when the database gets a lot of writes, the hard drive can’t keep up”. This helps organise your thoughts and allows the person you’re asking to detect any misunderstandings you may have, as well as helping them avoid answers that are too basic or advanced.
When finding someone to ask, don’t go straight for the most experienced person. Ask someone with just a little more expertise than you, who you think will know the answer. This reduces load on the more experienced person, helps everyone grow / establish knowledge and lowers the bus factor in your teams.
If it’s a complex topic, do some research before asking questions. “So, I found out that creating database indexes takes time and I have questions about how that affects performance”. This shows the person that you’re asking that you’ve tried to solve it yourself and you’re genuinely interested in the answer.
Ask yes/no questions, such as “Does MySQL use hash joins?”. This lowers the burden on the person helping as they can give you a yes or a no in response. However, this usually gets a “yes, but…” response that contains a lot more information than they may have volunteered if you didn’t ask them a yes/no questoin.
Always ask people how they do things. If they don’t really know (they just do it, it’s almost like muscle memory now), ask if you can watch them do it some time to learn.
Finally, ask questions in public. This allows everyone to learn the answer, even if they hadn’t yet come up with the question. It is especially important for senior team members
to ask questions as it shows more junior members that it’s ok to not have all the answers, and the questions they ask are usually quite interesting.
Read the code
Whilst Ask great questions was my favourite part of the talk, I think that Read the code is the most valuable. I’ve lost count how many times in my career that being able to dive in to an unknown code base and work out what’s happening has saved my hours or weeks of pain.
There are two main use cases for reading the code:
- Understanding a mystery error message e.g. “Something broke”
- You can read the code around that error to gain an idea of what was supposed to happen
- There’s usually a clear reason why that branch of code was triggered which helps you debug the calling code
- No docs? No problem! Find out by reading the code
- This is the more common use case. Developers love writing code way more than they love documenting it
- When presented with a library and no docs is usually to read the code
- It may contain inline comments to help you find your way
- At a minimum, you’ll get to see the API signatures and how it’s intended to be called
Debug like a wizard
The key thing to remember is that the bug is happening for a logical reason. Any time we find ourselves saying “it’s impossible!” we have to remember that it’s not impossible, as it’s already happened. It’s our job to find out why it happened.
The first tool in your debugging toolkit is optimism. Be confident that you can find and fix the bug. Build up a solid debugging toolkit that you can reach for to help investigate. Tools such as
tcpdump and a debugger are invaluable for this. You can read Julia’s Linux Debugging Tools zine on her website.
Learning to like debugging makes life much easier. When you find yourself thinking “Oh no, a bug!” turn it around and think “I’m about to learn something new”.
Write down a design
Before you start building something, write down your intended design. This document can have many different names:
- Design doc
- Project brief
- Tech spec
- Architecture doc
At the end of the day, it’s just a few pages that explain what the problem is, why we need a solution and what your proposed solution is.
Julia used to be scared of writing design documents. There was a worry that if she did everyone would list things that she got wrong and there would be 10,000 comments on there pointing out that it was all incorrect. Or even worse, she’d put in all that effort and no-one would comment at all.
Instead of writing huge documents that no-one wants to read, write a small summary instead. Take 30 minutes to write a document that contains
- What is the problem
- Why is this important?
- What is the proposed solution
- How does this impact other teams?
- How do we know that it’s working?
If you’re feeling good about the design doc, you can take it one step further and perform a pre-mortem. This is where you imagine it’s 6 months in the future and the project totally failed. Make a list of what happened to cause a failure, why it happened and how it could have been avoided. This will help you minimise risk whilst implementing your solution.
Once you start building a solution, expect things to change. Change is normal, change means that you’re adapting to the real world, learning things that you didn’t know before. Any time there’s a change from the design document, record the change in a changelog. At the end of a project, review the changelog and work out why the final implementation is different to the original design and what we can do next time to make sure that the number of changes is minimised.
Understand the big picture
Finally, we need to understand the big picture. Working in isolation means that you don’t have a complete understanding why you’re building the system you’re working on. You may be missing important requirements or limitations. Approach project planning with excitement and curiosity, eager to learn about the problem that you’re trying to solve. Figure out why implementing a solution now is important (or even if it’s important. Your time may be better spent doing something else).
Understanding the big picture leads to better technical decisions. There may be security requirements that mean you have to implement the system in a certain way. Or, there may be performance requirements but no security requirements which means you can do certain things to speed processing up that wouldn’t be safe to expose externally. Understanding
the initial requirements generally leads to a better technical solution.
Wizards aren’t real, and computers aren’t magic. People that look like wizards are just people that know their tools, ask the right questions and understand the big picture. You can be a wizard too! Ask questions in public, read something that’s hard for you and keep learning.
Michael is a polyglot software engineer, committed to reducing complexity in systems and making them more predictable. Working with a variety of languages and tools, he shares his technical expertise to audiences all around the world at user groups and conferences. You can follow @mheap on Twitter