Being a mentor for more than five years assured me that every single form of mentoring is beneficial for both sides – the mentor and the mentee. In many companies, rather than a one-time event, it’s a part of a bigger process, like onboarding or regular project- or company-wide pair programming sessions.
But what if you suddenly have a one-time occasion with someone? It happens from time to time – someone is absent, and you are expected to make up for the missed mentoring session, there’s a blocker on another project, and you are an expert in the area, or you were asked for help.
How to make the most of it? I have to admit that learning from mistakes is the most effective way. It not only gives you a better understanding of the final solution but is also harder to forget. However, it’s hardly applicable in one go.
Or is it?
Teaching through mistakes
When we say people learn from mistakes, it usually means their own mistakes. It’s okay, as everyone will have more than enough situations to
make a mistake learn while working. But if we’re talking about mentoring, the mentor usually goes straight for the correct – and often final – solution. I was also doing that.
Then I noticed that some people ask me about the same thing again, a week or month later. Of course, in general, it’s not a problem – I’m here to help! But I’d rather spend twice as much time once and make sure they’ll understand and remember. This kind of approach is crucial, especially for interns, juniors, and other developers whose main goal should be learning, not delivering.
The idea is simple: force people to make errors. Not any kind of errors, but the ones I want. That allows me to actually help the person and tackle almost every technical topic at the same time. Debugging? Profiling? Filing an issue in this popular open-source package they’ve been learning for weeks? You name it.
Keep in mind that if the problem (or the solution) will be easily memorable for the learner, they’ll benefit from it more. Make a show out of it! One thing I like doing the most is to take the solution a person has, improve it drastically, prove to them it’s incorrect(or slow), and finally replace it with a much simpler one.
Error driven development
Not every error is valuable enough to learn from. For example, syntax errors, incorrect API usage, or misconfiguration are not. What makes a good learning error, then? Ideally, it should be non-trivial and not uncommon. Bonus points for every Stack Overflow answer that suggests doing it.
You not only have to be able to actually solve the problem but also think about how to use it. It’s not something we’ve ever learned or practiced. Programming is about creating and improving correct and efficient solutions – not incorrect or slow ones! (At least not deliberately.)
And yes, an inefficient intermediate solution can also be a good idea. It makes an excellent opportunity to show an anti-pattern, a better API for certain operations, or analyzing profiler results. You can also focus on some particular techniques, like LRU (Least Recently Used) caching, batching, or how important it is to prevent megamorphic functions.
Generally speaking, going for the most promising looking yet incorrect solution once or twice works best. It’s enough to tackle the topic of choice and not too much to grasp. Also, make sure to save these partially working checkpoints! It’s essential to let the mentee compare it with the final one.
Be strict, not mean
When developing this intermediate incorrect solution, the other person may foresee your planned mistake. It’s up to you to decide what to do here. Sure, you can just“shh” them and proceed. But it may be better to do a pause and tell them – at this very moment – that you know it and want to finish anyway.
You have to remind yourself not to treat the other person as an idiot. Really, you want to teach them, not prove them wrong. (You are at work, not in the YouTube comment section.) It’s okay if they suggest something (even far more) incorrect. In a way, they told you exactly what they don’t know!
Answering questions is also a little tricky. You want to make sure they’ll focus on the good parts or the understanding of the bad ones. Never lie to them! If you’re going to skip a part of the answer just for now or instead of a complete answer, tell them a simplified one, and let them know immediately. It’s good to know that there's more. In the end, there always is.
Finally, make sure that the final solution actually works. If the time is running up, simply rush up for the solution. Leave insightful comments. Maybe even record the session. Tell them to read through it afterward and write down questions if they’ll have any. Leaving them with a half-ready or half-incorrect solution is not only unhelpful but also mean.
It takes a lot of practice to switch from going straight for the solution to sort of “checkpointing” a few incorrect ones on the way. Personally, I was doing it for more than two years to get to a point where I became fluent at it.
I have to say, I don’t have as many occasions to do it as I’d want to, but when I do, I really enjoy it. Sometimes we even end up with some sort of homework! It’s not much, often a single function to be simplified, a repeated piece of code that should be shared, or a type that can be generalized.
We learn from mistakes. Make them. Know them. Teach them.
Mentoring as a process, rather than a one-time action, deserves a text on its own. No worries, it’s on my list.
Mentoring is a part of being a project tech lead in Vazco. On top of that, we organize short pair programming sessions (30 minutes) between randomly selected people once a week. There’s also a solid dose of working closely with a “buddy” during the onboarding process (described in On Recruiting Full Stacks).
As a tech lead, my uttermost goal is to let other people do their job. Itincludes defining the architecture or getting rid of technical obstacles but also helping them when needed. If half an hour of my time can save you an hour or two of debugging – that’s great. But if you’ll need four hours to develop something I could do in one, then it’s still your task.
Once I helped a colleague with animations in React. It worked but required a
setTimeoutto correctly synchronize DOM effects using
refs. We’ve made a clean and fully functional version within ~40 lines. Then we separated this logic into a new component with functional
useRef, resulting in ~10 lines of code instead.
A friend of mine once said, “if you respect your work, you have to make sure you’ll have enough of it”. I guess we all know where it’s coming from.
It’s not uncommon for technologies to have several levels of complexity. One can understand the basics and use them daily without an in-depth understanding. Idioms, (anti-)patterns, and a general overview of the difference between a high- and low-quality solution are more important than some implementation details. (And yet I love the V8 blog.)
Software architect at Vazco. He also publishes other articles on his blog.