8 February 2023
Supporting Junior Developers and Apprentices
Supporting Junior Developers and Apprentices
We work with a number of companies who want and need more developers working for and with them. One path we offer is our apprenticeship program, though we also do a fair amount staff augmentation. A thing we have seen time and time again is that teams that do (or want to do) a great job of bringing on junior developers are also teams that generally hire well. Most companies cannot compete with the big tech companies for senior-level talent, and so must learn to hire junior and mid-level folks and then develop them into senior developers.
To that end, here is a list of practices that we’ve seen good teams do well and that make it much more likely that they’ll successfully grow and keep the junior developers they do hire.
Be interruptable
The single most important thing you can do to support new team members is to be interruptable and to seek out interruption, or at least to designate one or more existing team members as interruptable.
New developers (and truthfully all developers of any skill level) will occasionally get stuck and will occasionally need help getting un-stuck. Experienced developers have the wealth of experience and prior knowledge, and so can usually get un-stuck faster. Junior developers do not.
By giving new hires someone they can interrupt during the day, at any time, we give them a way to build (or regain) momentum and to ensure that the work they are doing is correct before too much effort has gone into a fruitless approach.
The person (or people) you designate do not need to be the senior-most developers. They do need to be competent, cheerful, and willing to slow down to make sure everyone is keeping up. Some of the most effective folks I’ve seen in this role have been mid-level developers with excellent communication skills and a willingness to call for backup when needed.
At least early on your designated interruptees should be given leeway with deadlines – if possible they shouldn’t be the ones responsible for the most urgent tasks. They should also be given clear direction (especially early) to make time to check in on the new hires, to offer to pair program, and to make time.
This strategy asks more of your team than the usual “let them sink or swim” approach, but it’s also significantly more likely to result in junior developers who become productive and grow into solid mid-level developers.
Document set-up
The first experience with your application that any new-to-your-team developer will have is usually the task of setting up their development environment. With junior developers and apprentices (or folks who are making a tech stack switch), this may be their first experience with your particular language and framework choice, period.
The more you can document about set-up (and the better your team is at keeping those documents up to date), the better.
Even better still is automating as much of that environment set-up as possible.
If you are on a small team with relatively little churn, one chore that you can assign is for a developer to periodically (every 3-6 months is a fine cadence, though adjust this up or down based on how much your environment changes over time) set up a fresh development environment and validate the documentation and steps.
Doing this makes it much, much faster for your new hires (particularly those new to the career) to get up and moving.
Calibrate expectations
There is no such thing as a developer, of any level, who can truly come into a brand new team, codebase, and company, and “hit the ground running” at the same pace the more established team members do.
Experienced professionals can ramp up fairly quickly. It’s still a somewhat heavy lift to learn a new codebase, a new business, and sometimes a new business domain or tech stack, along with a new team and where the coffee makers are and how they work.
This can vary based on complexity of the codebase and domain and prior knowledge, but I’ll usually expect junior developers to have pushed up some production-ready code (not much, but at least a few lines) and gotten it merged inside of the first week.
More generally, what I expect of junior developers is that they start by becoming more confident and comfortable making changes to existing code (including writing tests where relevant) as they work toward being able to deliver a relatively small new feature from start to finish (usually inside of a few months). They’ll need some help, but mostly they’ll need well-structured opportunities to safely do the work.
Whatever the expectations, they should be communicated both clearly and often, and the manager of those new hires should be evaluating against expectations frequently. This way problems can be solved proactively and there are far fewer unpleasant surprises.
Set the foundation
When hiring junior developers or developers who are changing tech stacks, it will take some time for them to get up to speed on the languages, frameworks, tools, and codebases your team uses and supports.
The most successful hiring teams I’ve seen have a strategy in place for getting these new hires feeling confident and competent with the languages and particular idioms before they’re tasked with delivering work. A week or two invested in early training can (relative to “take a look at the code and see what you can figure out, then ask us if you have any questions or want to buy a book or class”) accelerate productivity by several weeks.
Doing this requires that you have a pretty good sense of the actual functional requirements of the job. You don’t need to be a Ruby on Rails expert to be productive with Rails, but you do need to be able to navigate the codebase and reason about how this particular codebase works.
(If you want help mapping the functional requirements of the job, or structuring this type of training, reach out)
Map the business
Software development is often the act of codifying (very literally) the practices and processes of the business. We typically write software to solve problems for people and business, and to make money for the business that owns the software.
The actual code we write sometimes feels like an implementation detail.
Any new developer, but especially a junior developer, needs to understsand what problems the software aims to solve and for whom. They also need to be able to draw some connection between the work they do and how their employer achieves its goals. More to the point, they need to know why they’re writing software beyond “I was given this ticket and told to work it.”
This knowledge needs to live somewhere accessible, and usually needs to be written down and maintained.
We don’t expect junior developers to start out as domain experts. But they will need, relatively quickly, to be able to support those domain experts. Smart employers and team leaders will make it a point to get any new developer to the team (junior or otherwise) acquainted with the business at large, or at least the parts that their software supports.
Pair more often
One of the best ways to learn your way around a new city is to be shown around by someone who already lives there.
The same is true for codebases of even moderate size.
With deliberate pair-programming, we can accelerate the growth of junior developers by giving them someone who can offer feedback, get them un-stuck, and show them how to approach problems. We also get a bunch of other benefits from pairing (better code, fewer errors, better architectural choices, and so on).
Where this really gets cool is when you can have junior developers pair with each other, or with others who are a year or two further along in their careers. By solving problems together, both developers in the pair learn and grow in ways that either wouldn’t happen (or would happen much more slowly) if they were left to their own devices.
Hire in groups
When we do apprenticeships, we always bring on at least two apprentices (along with the embedded apprentice mentor), and we do this for a few reasons.
The first is that a pair of apprentices will learn from each other, particularly as they work together.
The second is that training and onboarding a new a single hire is time-intensive. On the other hand, it only takes a little bit more time to bring on a second, third, or even fourth new hire if everyone starts at the same time. Hiring in groups makes onboarding more efficient.
The last is that junior developers (and apprentices) have the effect of energizing the team. One new junior developer can be easily ignored (lots of teams have adopted this sort of ad hoc “sink or swim, but don’t get in the way” approach, much to their own detriment). Having two or more new hires forces the entire team to meet that energy and to grow from it.
Be intentional
The practices outlined above are things we have seen be successful in multiple places. They are not the only ways to be successful.
The most successful teams we’ve seen have taken stock of their current contexts and come up with a deliberate, intentional, actionable plan. Most of the teams we work with hire, at most, a few new developers per year. These teams need less formal structure than, say, a large company that hires several hundred new developers per year. They must still be intentional.
The ultimate goal is for new hires, junior or otherwise, to join the team and become productive contributors to the things that matter, ideally sooner rather than later. Teams that treat onboarding as a first-class entity (rather than an afterthought) will see their new hires be successful sooner and have longer tenures (on average). Teams that support new hires well will have far fewer “bad” hires than otherwise. And teams that support their junior-most hires really well will see their mid-level and senior hires benefit as well.
If we can really clearly answer “What does success look like, and what does it require from us?” we can help everyone on the team help the team at large achieve that success.