In the time since I first wrote about my software engineering internship program I’ve gotten a bit more organized and had some new observations and insights. The philosophy behind the program is the same, but I can now better discuss the practical implementation, side-effects, and ROI. If you are interested in starting your own program, you should definitely read my first post on the topic as it covers the strategic elements in greater detail.
Return on Investment
Running the internship has costs. They are:
- ~15% of the mentor’s salary
- ~5% of the coach’s salary
- The intern’s salary
- The cost of equipment
- The cost of a Pluralsight License
- The cost of Clean Code and The Pragmatic Programmer
How do we justify this to the business? How is the program cost-effective?
After the bootcamp phase of the program the interns can usually write test-driven code with a level of quality approaching that of any other software engineer. We give them projects to work on that would not otherwise be approved. They “fill in the gaps” solving problems for our development organization.
Here are some of the projects they’ve worked on:
- GitBack – a console application used to backup all of your git repos to disk
- It’s open source. Feel free to use it and/or enhance it.
- A web application portal to host prototypes of tools and reports needed by the business that don’t neatly fit into any existing application.
- A web application to report on our hardware eco-system–which machines are used for what in which environments?
- A web application to scrub and provision sql server databases into non-production environments for testing purposes
The other major way we benefit as a department is that we get the opportunity to work with people while they’re starting out. We train them to build software our way. We get to know their warts, and they ours. When we have open positions, we prefer to offer them to people we know. We have had 2 direct hires of college students out of our internship program. When they come to work for us, they already know they like our environment. That may not sound like a lot but it can add up fast when you consider recruiter fees.
But wait! There’s more!
Alternative Career Path
After I’d been running the program for a year or so, something interesting happened: We had a member of another department request to go through our internship program. He wanted to effect a career-change into Software Engineering. Since we already had the program in place, we were able to accomodate him. Before he had even finished the program, we had another member of our organization request the same thing. We are able to provide an alternative career path to our organization and the development department benefits.
As of this moment we have hired:
- 2 interns out of college
- 2 career changes out of our internal organization
- 1 career change from outside our organization
That’s roughly 20% of our development organization.
Further, we have made the program available to people in other departments whose jobs require that they write code even though they’re not software engineers. It is my hope that this will result in higher quality code across the rest of our organization as well, though that remains to be seen.
The curriculum of the program has remained largely unchanged since I first wrote about it. However, I’ve found that I can make it largely self-serve for the first 4-6 weeks by organizing it as a sequence. This reduces the amount of time I need to spend mentoring the intern. Of course, once they get started on their real project my investment will be greater.
Here is the updated curriculum:
- Clean Code
- Read chapters 1-9 before the refactoring your homework exercise.
- Setup your dev machine (we have powershell scripts for this).
- Learn about Github & Branching
- Refactor your own school homework exercises to improve the readability of your code
- you are practicing what you have learned in Clean Code
- Movies Tutorial – build an ASP .NET MVC web application
- watch ASP .NET MVC 4 Fundamentals
- Sections 1 & 2
- The purpose here is to learn in detail what you did in the Movies Tutorial
- watch MVC5 Fundamentals
- Identity & Security
- Web Api 2
- Entity Framework 6
- Music Store Tutorial – build another ASP .NET MVC web application
- You should see that you are much faster this time around.
- You should understand the “why” in the steps of the tutorial.
- Nerd Dinner Tutorial – here’s another version updated for EF4
- These tutorials are out of date. To complete the project you will likely have to switch between them.
- Use EF Code first instead of what’s in the tutorial for data access.
- Stop when the tutorial tells you to import MicrosoftAjax.js.
- Chris will give you his speech on why this file is historically important and why we’re not going to use it.
- You’ll use jquery instead.
- Pair on the Bowling Game Kata
- Implement Fizz Buzz on your own using TDD.
- Learn about Dependency Injection
- Introduce Fakes, Stubs, and Mocks using this PluralSight video on Rhino Mocks
- Practice using Mocks and Stubs using this exercise
- Get started on your first real project!
Introducing an college internship program into a development organization can be a difficult challenge. There are precious little resources available on the topic. Here are some thoughts I’ve put together after working with interns over the last year and a half.
What Does Your Department Want?
Deciding what value you hope to gain will go a long way toward helping you decide what the features of a good internship program should be. From the intern’s perspective, they want an opportunity to learn, to network, and to gain experience. If you don’t have anything that you want out of offering an internship, it will be hard for you to run it effectively.
For our part, we want to expand our existing “learning organization” culture. We regard our interns as potential sources of hiring. We want to improve the overall quality of software in general by teaching new programmers some of our hard-won knowledge of principles, patterns, and practices. We want to aid our business by making interns available to work on small-scale projects that almost never get prioritized.
Establish a Primary and Secondary Mentor
Each intern should have a primary mentor who is responsible for directing their day-to-day activities. In addition, each intern should have at least one adjunct mentor who checks in with them each week to see how they are doing. Often a different ear will hear things that the primary mentor will not, such as if the primary mentor is moving too fast or too slow, or if a different teaching technique would be helpful. This feedback is important to gain early so that the learning process can be tailored to the individual intern.
As a mentor and trainer to interns you will be confronted with the sheer number of concepts, processes, tools, techniques that you simply take for granted. In our shop interns have routinely never seen source control, build servers, unit testing, code bases with more than a few hundred lines, third party tools such as ReSharper, third party libraries such as jQuery, and project management tools. We have to teach them all of those things before they can be productive in our business.
In its current incarnation, our interns spend 20+ hours per week in the office. Below are the materials that I really want them to learn over the course of their internship. Time is short and there is a lot to learn, but the mentor should resist the desire to go too fast. I’m covering concepts with my interns that it took me 10 years to learn. I’m trying to introduce them to these concepts so that they understand them well enough to begin using them in just over a month. This is an enormous challenge for both the intern and the mentor. The mentor needs to remain patient and allow the intern time to digest and practice what has been covered so far before diving into the next subject.
Most importantly, do not push the interns to learn topics that build on other topics they do not yet understand. For example, don’t teach mocking tools before they’ve learned the basics of Test Driven Development.
Interns need time to practice the material you are teaching them. Remember, you have been doing this for years. They’ve been doing this for days. The difference is important. Given them breakable toys to work on. Teach them the concept. Pair with them to practice the technique the first time. Follow up with a different practice exercise for them to do on their own to be sure they have it. If you can’t find a good practice exercise, create one. If the intern does not seem to be “getting it” from you, consider having the intern work with someone else for the material in question. Sometimes an alternate perspective is all it takes to make the material sink in. If that still doesn’t work, move on to something else and come back to the material later.
It can often be hard for interns to “get started” with whatever task they’re supposed to be practicing. For example, after reading about Test Driven Development, they may feel confident that they understand the concepts. In practice however, they are often unable to write their first tests. As the primary mentor, you will need to work directly with them to help them “get over the hump.” By pairing with them, you will see concretely what they do and do not understand. You should give broader context for what they do understand, and direct their learning and practice toward what they do not understand.
Learning is what the intern is here for, but where do you start? How do you work with someone with no prior work experience? How do you teach them all those things you take for granted? We want to welcome new people into the software development industry, but we don’t want to sacrifice code quality.
I accomplish this in a couple of ways.
The first thing I do with a new intern is setup an online Kanban board with them. I’m using Trello right now. This is important to keep track of each intern’s progress. Further, the intern’s learning is a project in it’s own right, so it’s natural to treat it the way we treat other projects.
During the first month they are given the time and space they need to read, watch training videos, and practice what they’ve learned on breakable toys. I spend 1 to 3 hours per day working side-by-side with the intern during this period to guide their learning. The order of the learning is not terribly important, though there are logical dependencies between some concepts that need to be observed.
I require that all of their work is placed into source control. I want the intern to get comfortable with github right away as all work should be done using source control. Many interns have never worked with source control at all, so learning git right away can be challenging. A good exercise for learning github is to have them import their school projects into github. If the intern likes the command-line that’s fine, but I usually tell them about great GUI tools such as SourceTree. I find that the GUI really helps people new to Git grok the concepts. (I still use the GUI myself .)
The other thing I think it’s important to discuss early is the value of clean code. Our interns are given copies of Clean Code and Clean Coder on their first day. Of all the books listed, this is the one it’s most important to me that they read. A recent idea I had about how to practice cleaning code is have the intern use their own school projects (now conveniently located in github) as refactoring exercises.
An intern is not going to master any of the content (that takes continued practice over years), but they will be much further ahead starting their career armed with a basic grasp of the principles, patterns, and practices that it took the rest of us years to learn. The learning should be aggressive and focused on making them productive in your environment as quickly as possible.
It’s natural that interns would want to work on something useful for the business. The biggest bottlenecks to making that happen for us are process compliance, automated testing, their ability to navigate large projects, and knowledge of software architectural patterns. Our shop places a high value on automated testing for production code. TDD is difficult for experienced developers to learn, so asking an intern to do it on the first day might be a bit much. This is why we don’t expect useful code out of our interns in the first month. That time is to be spent learning.
After the first month we begin introducing them to code bases we intend to use. These code bases are typically larger than the code that they have been working with in school, so it’s important to spend some time teaching them how to navigate the projects. This time should include a discussion of the logical division of responsibilities inside the project as well as mundane items such as useful keyboard shortcuts in whatever developer tools you are using.
Below is the basic curriculum I put interns through in their time with us. I encourage them to get through as much of the reading and training materials as possible. I start putting them on real code after the first month. I pair with them to find out what they do and do not understand. I do not push them to study topics that build on concepts they do not already grasp. This curriculum is tailored for our environment. We are a Kanban, C#, Continuous Integration shop that highly values clean code. Your curriculum should be tailored to the tools that you use every day in your work.
- Import your school homework projects into Github
- Introduce ASP .NET MVC using Nerd Dinner Tutorial
- Refactor your own school homework exercises to improve the readability of your code
- Introduce Unit Testing using Bowling Game Kata
- Introduce Test Driven Development using Fizz Buzz
- Practice using Mocks and Stubs using this exercise
- Write something in a different programming language than you’re used to (Ruby or Clojure perhaps)
- Search for Type: CTRL+T
- Extract Method: CTRL+RM
- Extract Variable: CTRL+RV
- Rename: CTRL+RR
- Duplicate Line: CTRL+D
- Open Available Refactorings: CTRL+SHIFT+R
Visual Studio Keyboard Shortcuts
- Find current file in solution explorer: ALT+SHIFT+L
- Navigate to implementation of method: CTRL+CLICK
TDD – Mocking
- Our SDLC