Providing a Rewarding Software Internship

Stormi Hoebelheinrich · Apr 24, 2020

Philosophy · Internship

A team of people around a laptop

There are many paths into software. Some start a career right out of college, some self-teach in the evenings for years, others smash away at intensive summer boot camps, and some seem to roll into this world with a penchant for technology. For a lot of us, it’s a combination of these. Eventually, we transition into the professional side of software (though it sometimes doesn’t feel like it at the time). Maybe that means getting hired to build a website for your uncle's small business, starting an internship or apprenticeship, landing a full-time gig in a fancy office, or somewhere in between.

For me, it was an internship fresh out of a boot camp with a small but mature company in Portland, Oregon. It was an experience, though imperfect, I’m immensely thankful for. Shortly after completing my brief internship, I was hired by Olio Apps, a Portland-based software consultancy. As a company, Olio Apps focuses on building web and mobile apps, but as a team, we’re encouraged to focus on personal development through skill-building and sharing. One way we do this, while also giving back to the development community, is by occasionally offering internships to junior developers. We’ve seen several rounds of interns, and each time, we learn something new and refine the process. This year, I was given the opportunity to lead the internship. Thanks to careful planning, the support of the whole team, and two excellent interns, I’ll be the first to report it was a smashing success.

Internships can come in many shapes and sizes, and can have mixed results for the interns as well as the company. There are a lot of factors to consider when planning to host interns, such as company size, senior developer availability, project complexity, intern skill level, etc. Some factors can be controlled, and others can’t. But there are a few things that can help maximize the value of the internship both for the interns and the company. If you or your company is considering offering an internship in the future, or already has an internship program, here are some of my top tips.

Choosing Interns

To find interns, we typically work with a local code school, Epicodus, and are given 10 or so junior developers to interview. We have quick, speed-dating-like interviews that are 30 minutes long. For us, it feels like seconds. But for them, most of whom are experiencing their first ever technical interviews, I’m sure it feels like hours. The code school then does the final match-making based on both the interviewers' and interviewees' responses. Because of this process, we don’t get the final say in who our interns are, but for the most part, we’ve had good luck with getting our top choices.

Two people in an interview

At Olio Apps, we kind of make a holiday of the intern interviewing and selection process, pausing our work to meet the interns and talk about how the interviews went. We involve the whole team in meeting and selecting the interns because team cohesion is an important part of our company culture. Based on our collective experience working with different types of people, we coined our ideal candidate “the humble ass-kicker.” We look for someone who is the right combination of cultural fit and skills (or perceived ability to obtain skills). That may seem obvious to some, but it can sometimes be tempting to lean toward someone who has impressive hard skills but lacks in personality, or vice versa. From experience, we’ve learned that a blend of hard and soft skills is essential, especially because there’s a lot of collaboration and pair-programming encouraged during the internships we offer. If someone isn’t easy to work with, it’s difficult for everyone.

It can be challenging to get a sense of a junior developer’s skills and personality during a brief 30-minute interview. We do about 5 minutes of “meet the whole team,” followed by 10 minutes of non-technical, cultural fit questions, and then dedicate the final 15 minutes to a collaborative whiteboarding exercise. Whiteboarding can be intimidating for junior developers, but it gives us an opportunity to see how they operate under stress, how they solve problems verbally and visually in real time, and how they ask questions and engage with team members. It also gives them a taste of a real-world technical interview, which is good for their professional development. After the 30 minutes are up, one of our team members usually offers to take them for coffee to answer any of their questions and decompress after the interview. Interviewing is always a two-way street (though sometimes it doesn’t feel like it as a junior developer), and it’s important to us to make a good impression with the internship candidates.

Pre-Internship Planning

Having a plan for the internship is vital. Through our years of offering internships, there has always been a rough plan that includes a few lectures, practice problems, toy apps, and eventually test writing and basic tickets in various real-world projects. This time was different. As the internship facilitator, I created a structured (yet flexible) five-week plan that would provide a guide for the interns, as well as me, while I navigated taking on this new role and continued to fulfill my other roles as technical lead for Shoutbase and architect on other projects.

planner with sticky notes

The plan included a one-week ramp-up of JavaScript skills, which included reading materials, coding exercises, code review, and topic lectures. After the ramp-up, they were introduced to the Shoutbase code and the detailed tech design I had created for the feature we would implement together. I took the challenging parts while they started taking from an organized set of tickets. Starting small, they worked on writing unit tests for stateless utility functions, similar to what they had seen in coding exercises the week before, followed by writing different stateless utility functions themselves. After that, they moved to writing simple React components. By week three, they were writing progressively more challenging React components and integrating reusable existing components. After that, they added functionality to their components using our in-house rendition of Redux called Sitka. By the end, they got to experience the end-of-sprint testing, debugging, and bug-fixing cycle.

Having a detailed tech design and a structured plan of attack was critical to the success of the internship. It helped me communicate what I needed from them and eliminated any confusion around basic things (like what to name a certain function) as well as more major things (like state management and expected behavior). It also allowed me to step away and work on other duties while remaining confident that they could work independently and deliver what was expected, even as juniors.

Maintaining flexibility was also key. Each week had its own set of goals that could be fine-tuned based on the week before. Throughout the internship, we focused on learning and writing quality code, rather than stressing over hard deadlines. This gave everyone room to make mistakes, enjoy the experience, and learn.

Involving the Whole Team

Beyond an introduction to writing code in a professional environment, a primary feature of an internship is exposure to senior developers. That way, interns get to hear different perspectives around programming, working in the industry, and tips and tricks. While I was the primary facilitator for the internship, each Olio Apps team member had their moment to shine by delivering a talk in their area of interest or expertise. The talks gave a primer on new subjects or expanded on what the interns had learned in code school. In all, there were over a dozen talks that included our company's philosophy for writing code, tooling to enhance productivity, pull request etiquette, ES6 syntax and conventions for clean JavaScript code, writing unit tests, advanced CSS and styling techniques, React, Redux-Saga, Sitka, frontend and backend architecture, sprint planning, QA, and manual testing.

The talks served many functions. Of course, they helped teach the interns skills they could then apply to their work, but it also gave the team members an opportunity to stretch themselves. While preparing for their talks, many of them refined their own understanding of certain topics and had to take on the beginner’s mindset, in order to simplify complex ideas into their simplest forms. It’s a challenging but rewarding task. In addition to that, junior developers often ask great questions that can spur conversation and even challenge senior developers' understanding.

We also recorded these talks. By recording them, the information could be shared internally amongst current and future team members. Instead of siloing information into a few “topic experts,” we can now create a bank of tribal knowledge of which we all share. And having a set of videos geared toward junior developers is a great place to start. Additionally, we can share these videos with future interns and potentially externally as well, to spread our knowledge beyond the company.

Scoping a Project for Beginners

At code school, the students become very familiar with creating short-lived projects from scratch. For us, it’s important to provide a more real-world experience for the interns where they can be introduced to a sophisticated, public-facing app. It’s also essential to create a safe playground environment, where the focus can be on learning without the potentially stressful pace or standards of client work.

eye glasses on a desk in front of a computer

The timeline for the internship lined up ideally with the introduction of a new feature to our internal project, Shoutbase. I had already implemented the majority of the backend for the feature, and the interns ramped up just in time to help me start on the frontend. The UI was relatively complicated, including forms, state management, and communication with the backend—“not your average code school project,” to paraphrase one of the interns. One might say it was a relatively ambitious internship project. Despite this, the interns were able to complete a huge chunk of the feature, and they exceeded our original goals for the internship.

The key was dividing the work into incremental pieces that the interns could understand and then progressively introducing more difficult tasks as their skills developed. While the end result of the feature was similar to how I (or another senior developer) would have written it, the path we took to get there was much different.

Normally, when I’m planning to introduce a new UI feature, I will break up the feature into pieces and create tickets that consist of isolated chunks of end-to-end functionality. This includes any state management, utility functions, tests, styles, and behavior. I had the interns start in areas more familiar to them, like writing stateless utility functions and tests, which strengthened their skills in that area, and then we branched out from there. Breaking the work up in a way that allowed them to focus on the same type helped them gain mastery in an area before moving on. In the end, we could weave the pieces together into a working UI.

The proverbial saying, “Measure once, cut twice,” is valuable philosophy for developers, but sometimes, it’s good for a junior developer to have to “cut” the same piece of code two or three times to understand the difference between “functioning,” “better,” and “best” code. There were a couple occasions where I provided a ticket with little guidance, reviewed the resulting code with a little more guidance, and then challenged the interns to try once again to take their code to another level. Though being asked to write the same piece of code over for the third time might be frustrating for some, a beginner with the right attitude is going to gain a lot of value from the experience and learn how to challenge their own code to reach a higher standard beyond being “done” or “functioning.”

The first couple of weeks, I understood that I was spending more time reviewing and re-reviewing the interns’ code than it would have taken me to write it myself. But I also understood that the time I was taking to write out thoughtful critiques, provide links to further reading on the topics, and offer suggestions, rather than giving out all the answers, was an investment into developing their skills. And that benefitted me as well: in the final weeks of the internship, they were able to work relatively independently and deliver code that needed very little revision.

Defining a Workflow

Creating a consistent workflow helped the internship run smoothly for everyone. From the interns’ perspective, the workflow was relatively simple. Each Monday, we would review the progress from the week before and plan the following week based on the master plan I created pre-internship, factoring in any necessary adjustments. For me, I needed to integrate the internship workflow into my other responsibilities. This was particularly challenging for the first couple of weeks, when the interns needed the most guidance. To help alleviate this, I created a schedule of black-out times when I was unavailable, and the interns would have to rely on each other or ask a different team member for help. This helped me get my own work done, and it also gave the interns the opportunity to interact directly with the other developers at Olio.

man writing workflow on a whiteboard

Another important part of the workflow, beyond just slinging code, involved giving and receiving feedback. Feedback is essential for growth, and encouraging two-way feedback ensures that both parties are getting what they need and that the process improves over time. Each Friday, the interns were involved in our team’s weekly retrospective, which is an informal meeting where we reflect on the week, celebrating the highs and discussing solutions for any low points. By involving the interns in the retro, we gained insight into their experiences that helped us create a better internship for them and hopefully others in the future, leaning into the positive aspects and attempting to eliminate or mitigate any negative aspects. They also got to participate in one of my favorite rituals of the company, and hear the thoughts and emotions of more senior developers as we experienced and navigated through the highs and lows of creating software.

Words of Caution

After recently concluding a very successful internship, it’s easy to focus on the positive aspects, but I think it’s also important for me to address a possible downside that could impact both the company and the intern. Offering an internship can take a lot of resources. If you’re unable to front these resources, or if you think a low or unpaid internship is a good way of getting cheap code, think again. As I stated before, for quality results by the end of a several-week internship, significant investment by one or more senior developers is vital.

Two people shaking hands

Personally, I think offering an internship is a combination of two things:

  • an opportunity to give back to the developer community by giving the interns real world experience
  • an opportunity to meet new developers as a trial period for possible hiring into your company

Both of these opportunities involve having respect for the intern's time and effort, instead of seeing them as a resource for cheap code.

Conclusion

By now, I hope it’s clear that offering an internship can be a valuable experience for everyone at a software company. Whether you’re considering taking interns for the first time or you’re a seasoned pro at hosting interns, hopefully, you feel inspired to provide an internship that strengthens your team, empowers junior developers, and gives value to everyone involved. If you’re interested in hearing more about internships at Olio Apps, check out this post by former interns and current full-time employees, Ami and Cory: Internship Experience.

Interested in working with us?