Talks

The Practical Guide to Building an Apprenticeship

GORUCO 2018: The Practical Guide to Building an Apprenticeship by Max Tiu

GoRuCo 2018

00:00:14.179 Hey everybody, this is the practical guide to building an apprenticeship. My name is Max Tiu, as you said, and you can find me all over the internet, including Twitter and GitHub. I have the pleasure of sharing this talk with the Alter Day. Last year, I got to do something really cool that I didn't think I’d ever be able to do. I was able to create and program for entry-level developers and bring new people into this industry, which is something I'm really proud of.
00:00:36.690 I think that apprenticeships are a severely underrated part of our professional systems and they deserve a bit more attention for a few reasons. For one, they fulfill a very real need. With coding boot camps becoming generally more accessible, there are a lot of junior developers out there, yet we rarely see open junior positions. There are many fantastic and eager folks who are just waiting for an opportunity to be seen. Furthermore, when we do see junior positions, they often ask for things like three years of experience. There must be some kind of role in the middle, and apprenticeships fill that gap.
00:00:54.149 They also help unify and engage teams. When your team can rally around the common goal of teaching a new developer who is excited and ready to learn, they will unify and get excited. Additionally, they help create more diverse and inclusive organizations. Historically, the tech population tends to look quite homogenous, especially here in the U.S., where we have a bit of a white male problem. However, we are increasingly seeing juniors emerging from code schools or who are self-taught and are members of groups that are underrepresented in tech.
00:01:15.270 Apprenticeships provide these individuals the jump-start into long-lasting careers as engineers that they truly need. So, what exactly is an apprenticeship? It's an entry-level program designed for brand-new software engineers to sustainably grow their knowledge, establish a solid foundation for their craft, and learn more from their experienced peers. For our program, which we built, it ended up being a four-month-long program, where the end goal was that the apprentices were hired on as full software engineers.
00:01:40.710 A question I often get when talking about apprenticeships is how they differ from internships. Internships tend to focus on one specific project, such as hiring an intern to write your API documentation. They can carry a somewhat negative connotation, where an intern is often just tasked with less important work, and they are generally shorter term, especially within colleges. You might hire them for the semester, and then they’ll be gone.
00:01:47.360 Apprenticeships, on the other hand, prioritize sustainable growth. Instead of doing just one project, apprentices are exposed to various learning opportunities and focus on honing their craft because such programs are an investment in them as developers. They also tend to be longer-term. Our program lasted four months, but many programs can extend over a year.
00:02:07.770 Thus, when considering whether to pursue an apprenticeship over an internship, it’s essential to lay the groundwork. This groundwork involves all the planning and preparation before you can put anything into motion. What do you need? Three things: you need a plan, you need cash, and you need buy-in. If you expect someone to dedicate their energy and time to learning and growing, you cannot have them worry about putting food on the table.
00:02:36.000 Ideally, you want buy-in from everyone in your engineering organization, but that's often not feasible, especially as you scale. However, you must at least have buy-in from your boss or perhaps their boss if you are at a larger organization. This can vary in difficulty, but for for-profit companies, they will typically need to justify the time and monetary costs of your program.
00:02:56.000 You can do this by highlighting material costs. Apprentice programs usually eliminate onboarding costs that often occur with more experienced engineers. With those engineers, you spend time training them and helping them get to know your systems and domain. In contrast, apprentices will be learning your stack while they learn to program and code. Therefore, when you hire them on as experienced engineers later, you do not have the additional learning time.
00:03:32.800 Apprenticeships also help eliminate recruiting costs. In environments where we are spending tens of thousands of dollars for someone else to source candidates, there is such a high demand for this kind of program and entry-level position that candidates will flock to you. This has been our experience. This also helps in hiring senior developers if that’s your thing. For many people, when I (as a senior engineer) look at companies with apprenticeships, it sends a positive message: ‘Hey, we are a company that values growth and learning. Come learn and grow with us.’
00:04:01.370 Of course, there are the immaterial benefits that come from this initiative, such as increasing diversity in background and skill, improving team connectivity, and enhancing developer productivity. When you have a senior and a junior working together on a project, yes, the junior will be learning a lot, but so will the senior; they will learn just as much, if not more.
00:04:28.250 Once you've convinced your boss that you're ready to start, you need to determine a few things: how long the program will be, how many apprentices you'll hire, and who will do what. Defining these roles is crucial to ensuring that everything gets done and that apprentices have designated mentors for various questions. We decided on a four-month-long program, and we knew we wanted to hire two apprentices because this is a manageable number for a smaller team. They could even pair together.
00:05:05.800 Regarding roles, we had one program coordinator-mentor combo, a manager, and multiple people to help with the hiring process, reviewing applications, and those types of activities. You should also decide what the apprentices should know when they arrive, what you want them to learn while they are with you, and how they will learn those concepts. These criteria will vary by organization. For us, we knew we wanted them to have built some web applications before and to have basic programming knowledge, including control flow.
00:05:49.490 We also aimed for them to learn refactoring, testing, best practices, and most importantly, confidence in themselves as developers. We believed pair programming would be beneficial since it is an effective way to share knowledge and allows apprentices to gain exposure to different areas of the code base and the product.
00:06:37.300 Next, it is vital to have a game plan. Leading up to this program, I conducted extensive research to create a thorough plan. I consistently referred back to that research throughout the program. My master plan included details about our goals, the types of individuals we wanted to hire, the tasks they would be working on, and how we would help them learn. All this planning was crucial as we moved into the implementation phase.
00:07:19.160 The actual process of hosting the apprenticeship breaks down into three phases: hiring, onboarding, and growing. Let’s first discuss hiring apprentices. Our goal here was to establish an unbiased, even playing field for our candidates. This aligns with our overall goal of increasing diversity by removing as much bias as possible from the hiring process.
00:07:45.990 Our hiring process had three phases: application, code challenge, and final interview. We introduced an automation system throughout the entire process leading up to the final interviews. When a candidate submitted an application, they were assigned a hashed candidate ID, which was the only way they were identified until we spoke to them in person.
00:08:07.440 During the application phase, we used a form that included several questions about themselves and the type of work they liked. We specifically stated that we were looking for individuals without any previous professional programming experience. Despite this, candidates often attempted to compensate by emphasizing their other experiences. The scarcity of junior positions is so acute that we've conditioned individuals at the beginning of their careers to apologize for still being in the learning process.
00:08:50.970 In the application, we also asked them to describe a problem that challenged them while learning to code and how they ultimately overcame it. This question was instrumental in our decision-making process. The worst responses helped us identify candidates who may not have put much thought into their answers, while the best responses allowed us to understand their thought processes and methodologies in debugging.
00:09:12.720 To review the applications, we created a rubric to standardize that review and, again, remove bias. We asked reviewers to rate each application based on enthusiasm, curiosity, and drive, using a numerical scale of 1 to 6 to eliminate any easy outs with middle numbers. This numerical data helped us make data-driven conclusions in the hiring process. If a candidate consistently received lower scores from every reviewer, it indicated they were probably not a good fit. Conversely, if they received consistently higher scores, they were likely a strong candidate.
00:09:42.850 Next, we moved to the code challenge. When crafting a code challenge, you first need to decide what you want to learn about your candidates while they perform the task. We knew we wanted them to demonstrate control flow and comfortability with writing Ruby. Our chosen format was a TDD-style task where we provided a file of failing tests that the candidates needed to write code to pass.
00:10:09.620 Designing the code challenge was challenging, as it was difficult to reverse-engineer what we anticipated candidates would be able to handle while still allowing room for them to go above and beyond. Each candidate had their GitHub repository where they could push their solutions. The challenge involved helping teachers score multiple-choice tests while gaining insights into their students' performance.
00:10:32.240 We included extensive README files in the repos, as we knew some candidates may not have encountered automated testing before. It was vital for them to understand how to run RSpec tests, recognize what failed tests looked like, and identify when they had passed. Moreover, we provided an empty class template for them to write their code and included a comprehensive set of RSpec tests to guide them.
00:11:12.940 It was crucial that we grounded our tests in reality. For instance, if we were testing for scenarios where users pass nil values, applicants should know that nil in Ruby represents absence or 'no answer,' which would mean a student skipped a question. We ensured that the candidates only had access to the context we provided so that they could focus on solving the given problems.
00:11:49.920 In order to anonymize the code challenge, we developed a script that scrubbed each candidate’s commit author information and submitted pull requests to a separate repository associated with their candidate ID. This approach allowed us to preserve the commit history without revealing the identity of the candidates. We could review how each candidate structured their commits and assess their thought processes through their coding practices.
00:12:27.560 The pull request format allowed reviewers to evaluate submissions in a familiar environment, using GitHub's built-in tools for code reviews. We used a similar rubric as with the applications to standardize this review process. We tested for specific skills we wanted candidates to demonstrate, such as control flow and their comfort with writing idiomatic Ruby.
00:12:48.640 Additionally, we ensured that reviewers provided feedback to all applicants. We wanted this program to be an investment in the community, not just a way to bring talent into our organization. Even if candidates weren’t selected to move on in the process, we aimed to give them actionable feedback so they could learn and grow, regardless of the outcome.
00:13:24.300 This leads us to the final interview stage, which was the first time we could put names and faces to the submissions we received. Our final interview consisted of three phases: a product and company introduction, a technical conversation, and a behavioral interview. The technical conversation was tailored differently from the usual format for experienced developers, as we couldn’t rely on technical jargon or standard questions that would assume prior knowledge.
00:13:55.240 By using the code challenge as a focal point for discussion, both parties could refer to code they had seen. We could ask candidates questions like, 'What challenged you while completing this exercise?' to gauge how they tackled problems, reflecting their thought processes through their submissions. We also incorporated the feedback from the code challenge review into the interview, allowing us to see how candidates processed that feedback.
00:14:24.660 The behavioral conversation included standard job interview questions, but one question we found valuable was, 'What would you change about the school you attended—be it a code school, university, or self-taught program?' This question helped us understand the candidates' needs in learning and how we could meet those needs.
00:15:05.940 To improve the hiring process, I recommend utilizing an HR platform. At the time, our company was small without one of those systems, so I ended up utilizing a suite of Google Docs, Sheets, and Forms to run the process. While it worked, I realized that all the time I spent on this could have been better invested in the program itself.
00:15:57.000 I also suggest not limiting the code challenge to one programming language, if feasible. The server-side application code at our company was written in Ruby, so as a Rubyista, that made it challenging to test candidates from PHP or Java backgrounds, who faced significant hurdles adapting to Ruby. We lost great candidates who struggled to overcome that barrier.
00:16:24.200 Being direct with your application questions is crucial. Candidates are striving to answer the questions you provide, not decipher any implicit meanings, so ensure that your questions are explicit. After hiring some fantastic apprentices, it was time for onboarding.
00:17:09.150 Our onboarding goals were to position apprentices for success and teach them the essential concepts they needed moving forward throughout their careers. We aimed to provide them with a similar onboarding experience as our full-time developers and included various info sessions that covered important parts of our application and codebase.
00:17:38.080 One unique experience we designed for apprentices was a scavenger hunt. We provided them with questions—such as identifying the name of a controller action—that required them to use contextual clues to find answers. This method familiarized them with our extensive production codebase in a low-risk, enjoyable way while ensuring they learned foundational concepts.
00:18:17.960 In addition, we hosted information sessions to cover foundational concepts, such as object-oriented programming and debugging. These were topics we typically expected more experienced developers to grasp, but we recognized that we couldn’t hold entry-level developers to the same standards.
00:19:02.620 To improve onboarding further, I recommend giving apprentices early exposure to processes your team uses, such as sprint planning and point estimation. About midway through our program, an apprentice asked me what a sprint was. As someone deeply ingrained in the software culture, it hadn’t occurred to me that they might not know that term. This reminder made it clear that we should start introducing these concepts early on instead of towards the middle.
00:19:58.800 Now, it’s time to grow your apprentices. There is plenty of information available about engineering leadership and how to foster developer growth. However, we will keep this discussion focused on apprenticeship programs. Our goals were to anticipate the apprentices’ needs, foster an inclusive and friendly learning environment, and encourage their independence, which is a strong indicator of experience.
00:20:35.640 We organized the growth period into two phases. The first phase was an initial ramp-up period, where they worked on internal tasks—small adjustments, bug fixes, and so on—to build confidence. The second phase then transitioned them into customer-facing work with our regular product teams. This exposure provided valuable insights into different parts of our codebase and various team dynamics.
00:21:21.440 We aimed to set clear expectations from the start, informing apprentices that their ultimate goal was to be hired as engineers after completing the program. We provided them with a checklist of goals they should aim to achieve throughout the program.
00:21:50.490 This checklist included recommendations such as verifying that their changes functioned as intended and leveraging the expertise of their coworkers. Regular communication was also essential; we conducted one-on-ones to monitor progress and address any challenges they faced.
00:22:25.720 We allowed apprentices to participate in team rotation decisions, which helped them discover their preferences—whether they enjoyed front-end, back-end, or specific aspects of development. Encouraging their involvement in these choices facilitated their personal growth.
00:23:06.450 Additionally, it is vital not to be afraid to let them fail. There will be instances when an apprentice suggests an approach you instinctively know will fail. In those situations, you should try to remain silent and allow them to explore their thought process. Seeing the error messages and understanding why they occur is part of their learning experience.
00:23:57.640 To enhance the growth phase, you should look for early warning signs and intervene when necessary. Junior developers often struggle to admit they are having difficulties because they may not feel they truly own their roles yet.
00:24:08.400 Another issue arose when team leads we were working with were uncertain about what the apprentices knew or should be taught while they were with the apprentices. We decided to address this by creating an outline for the apprentices detailing what they would be expected to learn throughout the program.
00:24:58.810 Now that we understand these lessons learned, we can utilize them to mentor and grow other developers, as well as run our own apprenticeship programs. To wrap up, we constructed a master plan for our program, utilized a fair, anonymous hiring process to onboard great apprentices, set them up for success through onboarding, and cultivated them into productive software engineers.
00:25:49.630 I am happy to share that we successfully hired both apprentices after the program, and they have been productive, valued members of their teams since September. In terms of lessons learned throughout this process, I want to emphasize the importance of listening to your gut feelings about candidates—such as one who seemed overconfident—but also maintained strong technical skills.
00:26:25.230 Give yourself ample time during this process. Our program was greenlit in June, but once we developed a plan and realized we had to finish before Christmas, we needed to shorten the program from four months to three. It's crucial to allocate sufficient time, as this process takes time, but it is worth it.
00:27:03.380 Always keep your goals in mind throughout. It can be tempting to choose easier paths or yield to specific demands. You must remain focused on creating a meaningful impact. I’m proud to say that our program was able to provide W-2 jobs with living wages and full benefits, which is not typical for entry-level positions. Such opportunities are crucial to making a small yet significant change.
00:27:29.740 This is our opportunity to make a big impact on a smaller scale. We often claim we want to bring diverse talent into this industry and value education and growth in our organizations—this program is a concrete way to do all of this.
00:27:51.320 Thank you! I'm Max Tiu, and you can find me on Twitter and around the internet. I would also like to thank everyone who helped me throughout the research and implementation phases of the program. I will be around today, so please feel free to come find me to discuss apprenticeships!