So you want to be a software engineer? — Part 1
Engineering internships suck, here’s how to fix them
“One of Azimo’s four core values is ‘for the people’. We build our products with this in mind, but we created Azimo Labs and our internship program for the same reason: we want to share our knowledge and experience so that it benefits as many people as possible.”
Internships should be about nurturing talented people and giving them the tools to succeed. You don’t need an intern to make coffee and you shouldn’t need an intern to churn out your unit tests.
We designed the Azimo mobile engineering internship to simulate, as far as possible, the daily life of a full-time software engineer. Our selection process is therefore designed to test all the skills an entry-level engineer should be focusing on. Here’s what we think the brightest and best need to succeed:
Our selection process has three steps:
- Remote meeting with the engineering team (approximately 30 minutes)
- Coding task (two-week deadline)
- Interview with engineering and HR teams in our office (approx. one hour)
We advertised the internships in April for a July start at our office in Krakow, Poland. Of the applicants, 25 of which were selected for a remote interview. Candidates spoke to two native app engineers and were asked to discuss the basics of:
- Android SDK (Activities, Services, UI components, basic patterns like Adapters, ViewHolders)
- Java (Collections, OOP, software design patterns like Singleton, Factory)
- iOS SDK (ViewControllers, lifecycle, UI components, auto-layout, data management solutions)
- Swift/Objective-C basics (ARC, class vs struct, access levels, optionals, software design patterns)
- Software testing
Of the 25 candidates, 10 made it through to the coding task. We asked candidates to create a simple application accessing the Github API. The task is described in full on our Github account. Our goal was to validate the candidate’s knowledge in the following areas:
- Networking, connecting with a REST API
- Dealing with data: caching it (optional), processing, displaying it in the user interface
- Navigation between screens
- Code/project structure, design/architectural patterns (optional)
We think that basic knowledge of the above is a minimum requirement for any entry-level Android/iOS developer. At this stage, however, we didn’t evaluate UI/UX unless the candidate asked us to. Information on the screen just had to be readable.
All app submissions were carefully checked for bugs and had their functionality validated. Candidates with the most promising code were then invited to Krakow for a face-to-face interview.
We talked about the candidates’ project, their ideas, their solutions and the problems they encountered. We also gave our feedback on different approaches and discussed what problems they might have in the long-term, such as scaling up the number of users or having other engineers work on the code.
Two candidates were selected to join the mobile development team and are now working on Azimo’s Android and iOS apps until the end of their summer break.
We tried to be transparent about our initial criteria, most of which can be found in this post announcing our internship program.
We were delighted to receive so many applications from excellent candidates but only 25 could make it through to the next round. Here are the criteria that we used to decide which applicants should be offered a remote interview:
- The candidate has open source work available online, no matter whether it was a commercial, personal or coursework project. By sharing work publicly, candidates show that they are serious about their code and open to peer review.
- The candidate has created an Android or iOS app, so we could see which area of mobile development she or he has tried (e.g. networking, database, layout).
- OR the candidate has taken a course in mobile app development.
- The candidate wrote a cover letter. It didn’t need to be long, we just wanted to understand their motivation for joining us.
- The candidate is studying at a Polish university. On this occasion we wanted to support our local schools, meet with candidates in person and hopefully spread our knowledge into the education system.
All the candidates invited to a remote interview met the standard we expected at that stage. To narrow the shortlist, we added some new criteria:
- The candidate has some experience building mobile apps (not games) in a native environment (Android SDK in Java/Kotlin, iOS SDK in Objective-C/Swift)
- A candidate has experience in some of these areas: networking (including accessing REST API), databases (data persistence or caching), adapting UI elements (including dynamic collection views).
- A candidate has some basic knowledge of programming languages: Java (Android), Swift/Objective-C (iOS), including types, optionals, collections.
- A candidate knows programming patterns, including basics: creational, structural, behavioral and at least general knowledge about architectural patterns and dependency injection.
- A candidate did unit tests in the past or can explain how to do them and why they’re useful.*
*This was met by the fewest candidates, which was disappointing. Very few applicants had any experience in software testing. We were shocked to learn that it wasn’t part of most courses. If you’re curious about why we think testing experience is so important, check out our post about software testing.
Automated testing will set your engineering team free
“Automation frees engineers to focus on the things that matter and unleash their creativity”
We then picked ten candidates to proceed to the coding test.
MobileInternshipTask - Programming task for mobile internship candidates
All of the apps submitted for the coding challenge were a delight to review. Each took a different approach to solving the problem, some of which we hadn’t considered ourselves.
Here are some of the criteria we used to evaluate the apps:
- The project has good code separation:
- The project uses Dependency Injection pattern (no matter which library), at least for components like the Github API client, views presenters or models.
- The project implements an architectural pattern (like MVP, MVVM) and separates things like views, application logic and external components (e.g. networking, database).
- The project has signs of being extendable and testable in case of future development.
- The project uses external libraries for things like networking (e.g. Retrofit), JSON parsing (e.g. Gson) and others (e.g. Android Architecture Components). This was important — good engineers recognise that open source libraries can save hours or even weeks of manual work.
- While the list of things in the project was well defined, we appreciated things that were done out of scope, such as pagination. We believe that great solutions come from proactive software engineers who cooperate with others and share more than they were asked for. Remember that often you will be the only technical specialist on a project and your insight can be priceless.
- The source code is easy to read and maintain:
- It’s focused — each class, method and module exposes single-minded functionality
- It’s clean — contains no duplication, no leftovers (e.g. old comments) and is well formatted
- Has a good balance between the amount of code in a single class (everything-in-activity-class) and the number of separate classes.
Developing intuition about clean code takes many years of craftsmanship, but there are ways to get a head start (e.g. from books like Clean Code by Robert C. Martin).
What we teach
We decided not to have a dedicated program or project for our interns but rather to embed them in the team instead. After one week of onboarding, our new team members started writing code for production.
The team provide guidance and supervision to the interns. There are also 1:1 meetings and as much feedback as we can reasonably give, though we encourage autonomy in finding solutions for problems.
What did we learn?
An internship isn’t just about having an additional team member, we also learned a lot about our processes, our culture and the way we work:
- We learned better ways to pass on knowledge to less experienced colleagues
- We learned more about our onboarding process, especially how helpful it is for people starting their career
- We identified some weaknesses in our process — code reviews, testing and lint checks, the release process. All processes should be fast, easy and consistent regardless of how experience the engineer using them is
- We learned how to make our own code more accessible, so that it can be understood, maintained and developed by less experienced people
Our interns have already started sharing their experience. Check out the Language Switcher Tile, the very first Android open source (highlighted in AndroidWeekly Issue 321) built as a part of our internship. We couldn’t be more proud 😊!
Language-Switcher-Tile - An android plugin that allows you to easily change your device language.
Our program’s primary goal was to help aspiring software engineers start their careers, whether at Azimo or another company. We’re honoured to share what we’ve learned while building technology that changes lives all over the world.