Three years ago I was asked to mentor a junior developer named Sarah. She was sharp, eager, and completely overwhelmed by our legacy codebase. My first instinct was to protect her. I gave her small, isolated tasks and reviewed every line she wrote. I thought I was being supportive. What I was actually doing was teaching her to wait for permission.
One Friday we had a production bug. Nothing catastrophic, but urgent. Sarah had been with us four months. I almost didn't include her on the call. Then I remembered what my old mentor told me: emergencies are where juniors learn the most, if you let them. So I pulled her in. And then I made it worse by hovering. Every time she hesitated, I jumped in with the answer. After twenty minutes she just stopped talking and let me drive. I realized I'd conditioned her to think her ideas weren't good enough unless I validated them first.
The next week I changed my approach. Instead of reviewing her code line by line, I asked her to walk me through her thinking before she wrote a single line. We'd spend fifteen minutes at a whiteboard. She'd explain the problem, the data flow, the edge cases. I'd ask questions like what happens if this API times out or how would you test that. I didn't give solutions. Sometimes she'd get stuck and sit in silence for a minute. That silence felt awful. I wanted to fill it. But I learned that if I fill the silence, I steal the learning.
We were working on a batch job that needed to handle partial failures. Sarah proposed a retry loop with exponential backoff. I immediately wanted to point out that our message queue already had built-in retries and she was reinventing the wheel. But I bit my tongue and asked what would happen if the process crashed after a successful write but before the ack. She stared at the board for a long time. Then she asked if we could make the operation idempotent so retries were safe. That was exactly the right answer, but she arrived at it herself. If I'd told her the answer, she would have nodded and forgotten it by next week.
I've also made the opposite mistake. Early in my career I mentored a junior by throwing him into a massive refactor with no guidance. He floundered for two weeks, produced spaghetti, and lost confidence. I thought I was being hands-off and respectful of his autonomy. I was actually being lazy. Mentoring is not about finding the midpoint between micromanaging and neglect. It's about adjusting your involvement based on what the person needs that week, sometimes that day.
I now start every mentoring relationship with a simple question: when you get stuck, what do you do? The answers tell me everything. Some juniors immediately Google. Some ask a colleague. Some stare at the screen hoping it fixes itself. My job is to teach them the meta-skill of debugging their own confusion. That means giving them a structured way to ask for help: what have you tried, what do you think is happening, what would you try next. I've had juniors solve their own problem halfway through typing the question in Slack. That's the goal. Not that they never need help, but that they learn to extract maximum value from every five minutes of help they get.
The hardest part of mentoring junior developers isn't technical. It's emotional. You have to watch someone struggle and resist the urge to rescue them. You have to accept that they will write code you would never write, and sometimes it will be better. You have to be patient with yourself too, because you'll get it wrong constantly. I still do. Just last month I caught myself rewriting a junior's pull request instead of leaving comments. I had to go back and explain why I made each change. That took longer than if I'd just guided her from the start. But next time she'll remember, and I'll remember to keep my hands off the keyboard.