I wrote this talk as training material for engineers and managers interviewing and hiring in OC Tanner's software engineering department, but also presented it at OpenWest 2015 in Orem, Utah. In it, I discuss a recruiting, interview, and hiring process that is authentic, collaborative, and people-centered - just like we want our work environment to be. Plus we look at the process from the perspective of both the hiring side and the candidate's side.
Let's explore a recruiting and interview process that is people-centered, authentic, and collaborative - just like we want our work environments to be. In that same spirit, let's make it totally transparent. Let's explore the process from the perspective of both the interviewer and the interviewee, the hiring manager and the candidate.
This is the recruiting and interviewing process I'm using at OC Tanner Company in Salt Lake City, Utah, one of Fortune Magazine's 100 Best Places to Work. It's how I interview for the teams I manage, and it's the process I train other people to use.
We'll start with a generalized recruiting process:
Start recruiting a great developer before you need one. Ideally, start recruiting while the developer is still learning to be a good developer, let along a great one. When you need a developer, it's nice to already have candidates lined up.
You want developers to introduce themselves to you, not the other way around. Speak, teach, coach, mentor, sponsor, host, feed, write, tweet, talk, meet, and get noticed being important to the community.
Make your interview process humane. Set an expectation that the process is collaborative, not competitive. When the candidates you don't hire speak well of your process, you have a powerful new tool for recruiting.
We often have specific needs, and we want to tune our recruiting process to meet those needs. Maybe the company is driving up quality, and you want to attract people with experience in software as craft. Perhaps you're carving up a monolithic application and calving microservices. You might want to attract functional programmers, or developers strong in architecture, or programmers in a more obscure language ideal for your application.
For several years I've focused on diversity on engineering teams, especially gender diversity. I have a specialized recruiting process that helps bring more women into consideration for our open positions.
We work with the community to help women get into (or back into) programming, by teaching, coaching, and mentoring groups like Girl Develop It, Railsbridge, and PyLadies. We try to get noticed by women while doing this.
We've reworked our interview process to be friendly to the individual and to humans in general. We've gotten rid of some interview techniques that have been demonstrated to have a gender bias. We set an expectation that we help each applicant accurately demonstrate their current skill level, not just their interviewing ability.
We're starting an internship program, partnering with Girl Develop It Salt Lake City, that will help to bridge the gap between boot camp graduate and marketable, productive developer.
We're presenting our practices within our local tech community, especially in groups that support and encourage developers who are women.
Because of this and other recruiting efforts, the result has been that about half of the candidates we see are specifically targeting OC Tanner for a job, and some are not even applying at other companies.
Before we launch into the mechanics of our interview process, here are some pointers.
Hiring people is a competitive process, and we can't help that. This does not mean that interviewing needs to be competitive too. If you are building teams that collaborate, let your candidates collaborate too. If you are supporting and training your team members to be better developers, do the same with candidates, on a smaller scale.
Share your process with the candidate. Answer their questions directly. Coach them before, during, and after their interview.
Don't stop recruiting just because the candidate is interviewing. Hiring is a two way street: we aren't just hiring them, they are hiring us to be their team and employer. You want the best candidates to choose you.
Going to send a candidate home without an offer? Keep recruiting. Offer a few minutes of mentoring to the candidates you turn down. What did you like about the candidate? What could he work on to be ready for a job with us? When might she try again?
Structure every interview to see the candidate at their best, just like you're going to structure your team to get the best work from your developers. Let the candidate help you with this.
Sometimes an interview just doesn't work. Maybe the candidate is nervous, or has a language barrier, or doesn't gel well with the interviewer. Stay attuned to how the interviews are going, and be ready to change things to make the process successful. At the end, if you didn't get an accurate representation of the candidate's skills, consider whether you want to do that interview over. For example, a candidate who blanks while pairing on a coding exercise may solve a take-home coding interview elegantly.
We want candidates who are "tee shaped" - deep skills in at least one area, but broad skills too. What's the right fit for your team? It's almost never just amazing technical skills with the language. You might want to see your team do more pairing, or better testing. Maybe you want someone who is good at sharing and teaching, or helps build cohesion. Look at how each candidate fits the team along multiple dimensions.
Our collaborative process is only useful if we get your cooperation too.
We want to know where you're at, in both your skill level and your career, so that you'll be happy with the job we offer you.
We want to see you at your best. If we're not getting that, help us figure out a better way of working with you.
Your coding ability is only part of the equation. We also want to see how our goals mesh with your goals.
Here's part of our transparency: we want candidates to know how they will be evaluated, and later, how they performed.
Before you evaluate a candidate's interview, evaluate the interview process. Were you able to get to know the candidate? Do you and the candidate both feel like you got an accurate impression of the candidate's abilities during the interview? If not, is it worthwhile confirming the candidate's skills in another way, like moving to a different space (maybe less casual, like a conference room, or more casual, like a coffee shop?), or with a take home coding exercise, or a corraborating interview with someone else?
I once interrupted an interview taking place in one of our office "living rooms" - small rooms with a couch, a couple of cozy chairs, a big screen TV, and a whiteboard mounted uncomfortably close to the floor. A young woman being interviewed by two engineers (one male and one female) was kneeling on the floor in a skirt and heels trying to solve a coding exercise on the whiteboard. She looked miserable, so we changed just about everything. Instead of the living room, we went to a training room with a desk-height table, office chairs, and bright overhead lighting. Instead of a whiteboard, we had her pair with a female engineer from our team. Instead of being two-on-one, I asked the male engineer to offer the women coffee or tea and then leave the interview. The candidate performed much better under the changed circumstances.
Did you know that the dry erase marker is less than 40 years old? Together with the whiteboard, they are a direct replacement for their predecessors, chalk and the chalk board. A soft rock, and a hard rock.
When we do a whiteboard coding interview, we're asking a software engineer to prove that they have mastered the most complicated devices humankind has created by drawing pictures on a cave wall.
We evaluate candidates using a modified "fist five" consensus method. We rate the candidate after each interview according to this scale:
Often we will have more than one goal in the hiring process. In these cases we might also ask for a percentile ranking of a candidate in comparison to the current team.
For example, maybe we don't just need a Scala developer, but one with enough language maturity to guide solid developers on a team who just don't have as much language experience. In that case, we might be particularly interested in a candidate who ranks in the 95th percentile on language skill, and is comfortable pairing.
Perhaps we have specific goals around improving software quality. In that case, we might prefer a candidate who ranks high in the interview who ranks in the 90th percentile for Software Craftsmanship.
At the end of each interview, your interviewers will already be figuring out how to share their impressions of you with the hiring manager. This is an excellent time to ask what their thoughts are.
Every promising candidate for a job will get at least one interview, and the candidates who receive offers will get seven interviews total.
Let's look at each interview and explore our goals for that interview, along with some ideas for candidates on how to win it.
We don't want to waste the candidate's time, or our time either. The phone screen is a go / no-go interview that determines whether it's worthwhile to bring a candidate in for the on-site interview process.
We want to understand why the candidate is looking for a new job, and why at OC Tanner specifically. Also, we want to make sure the candidate can code.
The best way to win the phone screen is to be an excellent, well rounded developer who knows about the work we do.
Computer programming involves two basic sets of skills: understanding the problems, and knowing how to solve them using computers.
Our problem domain is appreciating people. OC Tanner not only wrote the book, we created the entire field. Chances are good you can relate to the work we do. Most of us like to be recognized for the good we do, and shown appreciation in concrete ways.
There are two sides to a good programmer: discrete skills that help you accomplish specific tasks, and a grasp on theory that lets you generalize your skills to new problems.
A lot of training available to new developers focuses on discrete skills, like creating a web app in Ruby on Rails, or building a user interface in Angular.js. While these are good skills to have, we're going to look for developers who can generalize those skills. Knowing Ruby on Rails is a good thing, but can you do some of the same things in Ruby? What about using another object oriented language like Java? Or a functional programming language like Scala?
The important thing here is not just to know one way to solve a problem, but to be able to efficiently learn other ways to solve problems. This typically comes from studying computer science theory, or from lots of experience.
If you only know one programming language, let's hope it's the one we want you to use on the job. A junior dev needs to know at least that much.
It'd be better to know more than one language though, especially if the job calls for a language you don't know. We'll train a good candidate, especially one who can demonstrate he or she knows how to learn languages.
Writing a new program from scratch is often a waste of time. We want to get boilerplate stuff done within a framework of open source code that other people have written and proven in the field. It's always valuable to have discrete skills and experience with common frameworks in the languages you use. It's often valuable to also understand the patterns they implement, the abstractions they offer, and the opinions they enforce.
In a phone screen, you might be asked about different databases, and it is nice to be able to convey what you do and don't know about them.
Remember, we want to get a feel for where you are in your career so that we can make a good fit for you and for us.
We try to feed every candidate at least once. Some managers prefer to take a candidate to a fancy local restaurant, along with the team of engineers who will be doing the interviews.
I don't. If dinner out is an important part of the recruiting effort, let's do that while we're discussing an offer.
At OC Tanner, we have an excellent cafeteria with an executive chef we recruited away from one of the best restaurants in the area, and while the daily menu may not be a modernist delight, the food is good. More important than the food, though, is that I can make an open invitation to a dozen or more other developers, potential coworkers for the candidate. This gives my candidate a great opportunity to meet the team informally, and gives me a chance to watch how the candidate relates to my team.
The lunch interview is an opportunity for you to learn about us from a diverse group of people working here. Take advantage of that. Ask questions, get to know people. Try to be outgoing.
It's a safe place, and we want you to like us.
We use a variety of programming languages on different projects: Java, Scala, Javascript, Coffeescript, Ruby, and Erlang in my area alone. We want to hire and train developers to be exceptionally competent, often in several languages.
We want to know what language a candidate uses, and how competently they're able to use them. We'll probably look for one or more languages in our list, or similar to the languages in our list. We might also look for candidates who have experience in langauges we think brings a good perspective to their work.
This is a coding interview, and you should expect to have a coding problem to solve. Ideally, you'll do this interview on your own laptop using an environment you're comfortable with, while pairing with one of our engineers.
A lot of places want you to solve coding problems on a whiteboard, as if you're a philosophy professor or a trained monkey. We don't have openings for either in our department. We hire engineers and we want to collaborate with you every day, starting with the day of your interview.
We come up with programming problems from a bunch of different sources, sometimes even our current work. However, if you can solve random problems from ProjectEuler.net, chances are good you can handle our programming problems.
By the time you get through the phone screen, you should have an idea what language or languages we might want you to work with. That's probably not enough opportunity to go learn a new language, but even if you don't know the primary language we're going to use together, it still helps to know at least one similar language and at least two or three languages total. Ideally, you'll be well rounded with an object oriented language plus a procedural language and a functional language.
Some people might not agree with me on this point. We used to act like front end wasn't real engineering, but it's now some of the most difficult programming we do. It's certainly some of the most dynamic programming.
We want to know that you know HTML5 and CSS really well. We'll ask hard questions to test you on this. Also, you'll still need to demonstrate language competentcy in Javascript, understand about shims and polyfills, and show proficiency in frameworks like Angular and React.
As a manager, I'm supposed to communicate with my developers what the problem is and why we're solving it, but not how to solve it. Figuring out the how is engineer's responsibility, so we want to make sure the candidate can do it.
Design patterns are a way of solving problems by seeing how well the problem fits the shape of some known solutions. The idea comes from architecture and the 1977 book by Christopher Alexander called "A Pattern Language". In architecture, a door fits a pattern for entering and exiting a house, and a double-wide French door is an implementation detail.
We have a pattern language for programming as well, and have identified hundreds of different patterns that fit various problems. We want you to know some of those patterns. A junior developer should know the major patterns he or she has used, like a model-view-controller and object-relational-mapper. Senior devs should probably be able to recognize most of the patterns they've used by name, as well as a bunch of patterns they haven't yet used.
Right now, concurrency-oriented patterns and functional programming patterns are particularly interesting to us and to the field as a whole. I'd recommend you learn them.
We want to know whether you're safe around databases, and whether you know how to design and build systems around them. Can you explain why PostgreSQL is a beter open source database than MySQL? (If not, Rob Conery has a great talk on this called "Five things you didn't know about PostgreSQL.")
Can you explain when an ORM is no longer appropriate or performant? When NoSQL is a better choice than SQL? What the CAP theorem is and how to apply it? Why Riak is a better key-value store than MongoDB? Can you make the opposite argument?
We don't have time in a one hour interview to design and build a full stack, highly available, secure, high performance system. We only have time for the fun parts.
What I may not tell you in the interview is that I picked out one of the most important things you might work on when you join one of my teams. I want to see how you approach the problem, and how you related to it. Is this an exciting problem for you? Do you catch on quickly? Do you have experience in the problem domain?
We are improving our quality practices, and while we've got great support from the current members of our team, we also want to hire people who have experience and a commitment to strong quality practices.
Does the candidate write tests? What kinds of tests? Does the candidate write unit tests first or after? Can the candidate red-green refactor? How about acceptance tests and regression tests? Does the candidate know about property based testing or contract testing? How about static analysis? Formal verifications?
Does the candidate pair program? How much? Would they do it full time?
A lot of this interview is about the Extreme Programming (or XP) and Software Craftsmanship principles laid out by Robert C Martin (also known as Uncle Bob). We're kinda hoping you've read these. Either way, there's a good chance you've been training on some of the techniques.
We think the best way to write code is to understand what it's supposed to do, write a test that proves it does it, and then write code that passes that test.
It doesn't actually matter a lot to us whether the test cycle is short term or long term, unit tests or acceptance tests. We want and expect both - short scale, unit test driven development; feature-scaled acceptance test driven development; and bug-scaled regression tests.
Pair programming helps team members learn from each other. It helps keep "institutional knowledge" in more than one head. It distributes accountability. It improves code quality.
We like pair programming and we want to do more of it. We want new hires to expect that, and to participate in making it happen. Some of these skills are aspirational for some of our teams, but we're getting better and part of how we're doing that is by hiring people who bring good habits with them.
Our final interview of the day helps us see how the candidate interacts with the tech community both inside and outside of the office.
How capable is the candidate at receiving help from the community? Does the candidate make use of static resources like tech blogs and community documentation as well as dynamic resources like IRC, Twitter, meetups, and conferences? When he or she describes getting help from someone in the community, do they talk more about the resources, or the people? How valuable is the candidate to the community? Is he or she just a consumer, or also a leader?
None of us got where we are without the help of others, and most of us rely on other people more or less constantly, because we're constantly growing and learning.
Who do you rely on, specifically? There's a big difference between "I Googled this Erlang problem and got a snippet" and "I Googled this Erlang problem and found Fred Herbert's site. He's the guy who wrote 'Learn You Some Erlang' and he works on the routing team at Heroku."
I'm going to enjoy hearing about the other people who help you. Coaches, mentors, community groups, meetups, blogs, twitter accounts, online training courses - the community is full of amazing people helping other people, and recognizing them is an important step in becoming a leader yourself.
Just as a side note, I'd like point out that OC Tanner recognizes and appreciates people. That's our business.
I think Ruby is a wonderful programming language. You know why? Because Yukohiro Matsumoto wanted to optimize for programmer happiness, so he created a language that's easy to think in. Matz was inspired in part by Larry Wall, a linguist who created Perl, a programming language designed to be very expressive. There are poetry contests in Perl.
These aren't just interesting anecdotes. These are some of the reasons you might choose one language or another.
Who created the languages, libraries, and frameworks you like? What kinds of problems were the trying to solve? What kind of elegance and beauty did they bring into the world? If you don't know the stories, you'll never have a full appreciation for the strengths and weaknesses of the languages, libraries, and frameworks you are relying on.
What's your Github username? Twitter handle? Blog URL? Who are you mentoring? Have you contributed to open source projects? How about a major programming language? (My friend Kavita got a pull request merged into Python before she got her first programming job.) Do you coach or mentor anyone? Do you present at meetups, regional conferences, or national conferences? Which books have you written?
These questions scare a lot of experienced programmers, but if it weren't for people who do all these things, we wouldn't be here. We want to see how you see yourself in the community.
If we get to this point, it's because we want to hire the candidate, so we want to write an offer that will make the candidate happy and excited to come work with us. Negotiate transparently as best you can, and communicate a lot. How does onboarding happen? What are the benefits like? What's the drug testing policy? (This one has bitten me several times!)
When you're done with this interview, you should know exactly what the offer will say - and exactly what the candidate will say to it too.
They pay us stupid amounts of money to do this work. It's nice and all, but I couldn't leave tech and go somewhere else and still make anything like the salary I make in tech. Since they're willing to pay us so well, you might as well try to get more for yourself.
Salary negotiation is hard for a lot of people, but here's a tip to make it easier. It isn't your responsibility to make sure you're worth what they pay you. It's your manager's responsibility to make sure you're worth what they pay you. Your manager just needs your help.
Ask for what you want, and let your hiring manager try to figure out whether he or she can make sure you're worth every penny. Research the field, and the area, and the company to that you're in the right ballpark. Ask your hiring manager what the maximum earning potential for the position is. And then ask for the salary you want. Don't hesitate, or waffle, or apologize. Ask.
When you're talking about an offer, take the opportunity to increase your lifetime earning, not just your next salary.
Maybe you need more coding skills, or your need to learn another language. Maybe you want some management experience or leadership training. Maybe you want to do more writing and presenting. Maybe what you really need is someone who can help you figure out what you really need - like a mentor.
What will help you do this job better, and what will help you do the next job better? Propose it as part of your offer.
I've given several variations on this talk, including a version that I gave to the engineers in my department because they are the people who are giving these interviews. I got some interesting feedback.
One day at lunch, for instance, a group of eight developers approached the table where I was eating alone. They wanted to know if the stuff I ask about in the community interview is for real. They asked, "Does this mean I need to use Twitter?" and "Why do I need to know who wrote a library I'm using?" and "Well, I haven't written a book. Am I in danger of losing my job?"
Other people have asked me, "Don't you think this method is a little intimidating?" We talked about famously difficult interviewers for comparison - Google, Disney, Apple. We're interviewing local developers who are also interviewing at these companies, and we're making them offers they want to accept.
I'm finding that this interview process is not intimidating for junior and intermediate programmers. They really appreciate the clear communication and our transparency, and they always leave with good career advice if not an offer. The interview process isn't intimidating for world class developers either, because they expect it. If I came through with an interview that didn't give us all a chance to work together, I think they'd stop paying attention to me.
No matter who is interviewing, I believe it's important to make the process as unintimidating as possible. We're not out to scare people away. We want to attract strong talent at all levels of experience, and with this interview process, we're able to recognize them.