00:00:21.279
Hi Joël, thanks so much for coming in.
00:00:26.320
Thanks for having me here for the interview.
00:00:32.320
Yeah, I'm really excited to get started. I know that you got an email talking a little bit about what our interview process is like, but I thought it would be good to go over it in person.
00:00:37.360
I'll give you a chance to ask any questions that you might have.
00:00:43.840
That sounds good. I'm feeling a bit nervous; I feel like I haven't busted out my whiteboarding skills in a little while, but I think I got this.
00:00:52.000
Yeah, interviews can be pretty stressful, and I know that whiteboarding interviews, especially, can be nerve-wracking because they're a little confrontational and the questions are often not what you would do every day as a developer.
00:01:00.160
But here at thoughtbot, we've put a lot of work into thinking about how we can make our interview more collaborative and closer to the work that you would actually be doing.
00:01:06.080
That sounds great.
00:01:12.159
Just to give you an idea of what we're going to do here, we're going to walk through a scenario, and I'll ask you a few questions. It's really an opportunity for us to discuss the questions and how you might approach them.
00:01:23.680
They're a mixture of technical questions as well as consulting questions.
00:01:29.600
Okay, I'm kind of curious. You mentioned consulting questions.
00:01:35.840
I work at a product company; I've never consulted. Can you give me a heads up on what those are going to be like?
00:01:41.200
Yeah, that makes a lot of sense. By consulting questions, I mean questions about product scope, team interactions, and processes.
00:01:46.240
These are things that are really important for a developer's day-to-day job but aren't necessarily about technical implementation.
00:01:52.399
Okay, so like Agile stuff?
00:02:04.960
That's definitely a big part of it, but there's also going to be stuff that goes beyond just process.
00:02:10.160
Alright, that sounds good. Let's do it.
00:02:20.800
For this first question, let's imagine that you're a developer at thoughtbot, and you're rolling onto a new project.
00:02:26.720
Your client is a gym in the area, and they have an existing code base that they're looking to expand upon.
00:02:32.319
They want to build a system that allows users to schedule sessions online.
00:02:38.400
Currently, all of their gym-goers are calling into the gym to schedule a class, which is not ideal.
00:02:44.640
So to get us started, how would you begin onboarding and getting to know an existing codebase?
00:02:51.680
I think I would probably look in the models directory first.
00:02:57.680
Assuming this is a Rails app, I would look for a user model since there's often a lot of logic in there.
00:03:04.400
I would also try to find the so-called 'god object' of the system.
00:03:10.080
There's often a lot of business logic centralized there, and I can see where some of the pain points are.
00:03:15.280
This would give me a good idea.
00:03:20.400
Nice, I think that makes a lot of sense. I like the strategy of finding the god object and then fanning out from there.
00:03:26.959
Are there other techniques that you might use?
00:03:32.319
Yeah, I think I might look at the routes file to see if things are sort of RESTful.
00:03:38.239
Actually, let me take that back. The first thing I would do is run the test suite.
00:03:44.319
I feel like that's the first thing I should say in a thoughtbot interview—testing is very important.
00:03:50.000
Yeah, we do like tests a little bit at thoughtbot. I hope you don't feel like I was fishing for a particular response.
00:03:56.000
I really just wanted to give you an opportunity to talk about all the different ways that you might onboard onto a project.
00:04:04.159
Now let's imagine that you've gotten to know the codebase and feel confident.
00:04:10.720
The client is itching to get started, and they are looking to thoughtbot for help defining what an MVP might look like.
00:04:16.000
I'll tell you a little bit about the requirements they've given us, and we can talk through the process of scoping an MVP.
00:04:22.240
Okay, so let's imagine that they're building a website. They want users to be able to book appointments through the website without having to call in.
00:04:30.800
They're planning on opening a new location sometime next year, so they imagine that this new location will have a different schedule.
00:04:37.760
They also run promotional events throughout the year. The next promotional event they're planning is sometime at the end of June.
00:04:45.280
During these events, they're going to have extended hours, but they sometimes do promotional events with shortened hours.
00:04:51.520
They're also closed on major holidays.
00:04:57.680
Given all of that, what do you think should be the MVP of this product?
00:05:05.120
I think when scoping an MVP, it's important to find what the core problem is that we're solving, and here it's self-service.
00:05:13.680
If a client can self-serve at the gym, then whatever minimum piece of software we build that allows for that is successful.
00:05:19.440
In that spirit, particularly given that the new gym will only be opening next year, we could probably cut that functionality and say we don't need support from multiple locations in version 1.
00:05:26.320
Okay, that makes sense, and I think that reasoning is solid.
00:05:30.160
Do you feel like being able to handle closures for holidays is core to the app?
00:05:38.080
That's tough. It adds a lot of complexity to the logic, and I'd rather not have to do it.
00:05:43.280
At the same time, it's hard to go to market without that.
00:05:50.400
If, say, you mentioned we'd be closed on the Fourth of July, if a client were to book an appointment for that day and then show up to the gym, it would be closed.
00:05:57.440
That costs us a lot in terms of goodwill and probably costs some actual dollars as well. It's just a bad experience all around.
00:06:04.000
Yeah, I agree. Having a client book a session, and then the gym is closed, is probably a really bad user experience.
00:06:10.080
Is there anything you could see changing about the requirements that would make you more comfortable cutting scheduling from scope?
00:06:17.440
Was that the wrong answer? Was I supposed to say yes?
00:06:22.400
No, I just think that talking about scheduling is interesting, and it might be worth discussing how this could change for you to feel more comfortable cutting it from the MVP.
00:06:28.080
Um, I wonder how often this project releases.
00:06:34.720
I ask because at my current company, we are on a two-week sprint cycle, and we release once at the end of every sprint.
00:06:41.279
So sometimes it can take maybe two sprints for something to go from idea to production.
00:06:48.320
Given that July 4th is pretty close, I feel less comfortable without that built into the initial release.
00:06:54.240
It makes sense that taking a month to ship something when you're trying to get out an MVP quickly would be stressful.
00:07:01.280
It doesn't mention it in the initial prompts, but at thoughtbot, we usually run one or two-week sprints.
00:07:07.520
It depends on the project and what makes sense for the team.
00:07:13.200
In this situation, maybe it would make more sense to have shorter sprints with a one-week sprint.
00:07:19.760
Okay, out of curiosity, have you ever worked on a project that used a continuous deployment approach?
00:07:26.240
Yes, and I think that's a really good point to bring up.
00:07:31.680
I do continuous deployment on my current project for really similar reasons.
00:07:38.080
The client is trying to ship a new set of features, and we deployed something initially that we wanted to build up quickly.
00:07:44.000
So I think that would work really well on this project.
00:07:50.400
If we had these tighter iterations, I would be more comfortable with a tighter MVP.
00:07:56.320
Those two things tend to go together in my mind.
00:08:03.760
I think that approach makes a lot of sense, and I'm glad you brought up these techniques around delivery that are also important for MVPs.
00:08:10.720
One alternative that we might consider—and this is something we did at my current company when we first launched—might be to go live with a beta version.
00:08:18.080
What we want to test and get feedback from our users is if self-service works and what things we need to learn from that.
00:08:25.920
Holidays are just a special case that will take time to gather feedback.
00:08:33.440
If we were to ship a version that doesn't have holidays in it, but maybe only to selected users and communicated with them that this is beta software,
00:08:42.000
and that it allows booking any time—even on holidays—then we could send out an email reminder a week before, saying the app will allow booking on July 4th.
00:08:50.560
Just a reminder that we are closed that day.
00:08:57.840
Yeah, that would allow us to gather user feedback and get the iteration loops tighter, while not having the pressure of shipping to people on July 4th.
00:09:04.960
I think that's a great idea. I also like that because when you're putting out an MVP, there might be some user experience issues or small bugs.
00:09:11.680
Having this beta version sets expectations for users that this is going to get better and it's normal to have a few rough patches.
00:09:19.760
I feel like, with that, we really talked over what an MVP would look like, and we can maybe start thinking about how we would implement that.
00:09:25.440
That sounds good. Just to reiterate where we landed: we want to initially build out a flow that allows a user to go online, book an appointment, and we're not going to worry about any flexible scheduling.
00:09:32.640
You can say the gym just has nine-to-five hours, and we also won't worry about multiple locations.
00:09:40.000
So given all of that, how would you go about modeling these different objects and how they're related to each other?
00:09:46.079
I think it would have some kind of Trainer object and then a Schedules table.
00:09:57.760
There would probably sit between the two, maybe like a Slots model or something that could belong to both a Trainer and a Schedule.
00:10:05.839
I guess we'd have to probably pre-generate those ahead of time.
00:10:11.760
Actually, can I take that back? I can see where this is going, and I actually did this on another project, and it didn't turn out too well.
00:10:20.000
This was a payroll application I was building, and we leaned too heavily into Active Record associations for all our modeling.
00:10:28.640
Core to that was the concept of a pay period and everything associated to a pay period.
00:10:35.680
This meant I had to pre-generate them every month, and then we hit a daylight savings boundary and things got weird.
00:10:41.840
We ended up with hours associated with the wrong pay period, or maybe orphaned, or not associated to a pay period at all.
00:10:48.000
We ended up with a lot of issues with our payroll reports, which is not something you want on a payroll system.
00:10:54.160
This bug wouldn't die; every few months we'd run into another variation of it and think, 'Oh, the pay periods strike again.' So, no, I'm going to stay away from pre-generating those things.
00:11:02.560
Okay, I'm sort of trying to visualize this in my head.
00:11:09.760
When I think of a calendar, I probably don't want to model the white space on the calendar but rather the individual events on it.
00:11:16.000
So, what if instead of having that table that sits between the Trainers and the Schedule, we have a table that represents appointments?
00:11:22.080
These are slots that have already been taken, and when we want to show what's available for others to take, we can calculate that at runtime based on what we know has already been booked and the current schedule.
00:11:30.560
So just to go over, to make sure I understand your solution, we would have a Schedule table with the hours associated with a number of appointments.
00:11:36.960
Trainers would also have many appointments, and an appointment would be for a particular Trainer at a given time.
00:11:43.680
That really nicely covers what our MVP would look like.
00:11:50.720
So, if we start to layer in some of the features we talked about initially, let's imagine we've built the MVP, the client loves it, and comes back to us.
00:11:57.040
Now would be a great time to make the system handle special events.
00:12:03.680
This could include extended hours for a promotion or being closed on a holiday like July 4th.
00:12:10.080
How would you add that modeling into our current solution?
00:12:17.440
I'm glad we decided to put this off earlier because this is kind of the gnarly part.
00:12:24.240
Previously, we had the Schedule table that just had a single row in it, which feels a little weird.
00:12:30.080
Now I think we could add a start and end date columns to it.
00:12:35.920
This way, we would have multiple rows in this table, and a particular schedule would only be active during a specific time period.
00:12:44.320
One nice aspect of this is that it allows for setting up schedules ahead of time. For example, we could have a winter schedule and a summer schedule.
00:12:50.480
The admin could go in and set these at the beginning of the year, saying what the hours are for winter, and what they will be for summer without having to make changes now.
00:12:56.160
That nicely covers a common use case for gyms that wasn't talked about in the initial requirements—the scheduling over large blocks of time.
00:13:05.760
Could we talk through how an admin would go in and close the gym for July 4th?
00:13:12.160
I think of a holiday as being like a micro version of a winter and summer schedule.
00:13:20.320
I guess an admin would go to the admin panel. We already have a summer schedule set that goes from June 21st to September 21st.
00:13:27.200
They would then have to end that schedule early on July 3rd, create a new schedule that's only for July 4th where the gym is closed,
00:13:34.720
and then start another schedule from July 5th through September 21st. That schedule would need to be the same as the summer schedule.
00:13:43.120
I feel like that might be a little error-prone for admins that would have to recreate this old schedule.
00:13:50.080
It is somewhat clunky. Maybe I could add a cloning button to copy the other half.
00:13:56.320
The cloning button would save time, but still, it's a lot of work to ensure our models support the scheduling.
00:14:03.040
I liked what you said before, where you mentioned how we handle schedules for different parts of the year.
00:14:09.760
It seems there's a logical separation we're not accounting for.
00:14:15.760
You mean that a schedule and a holiday are similar but not exactly the same?
00:14:21.760
Yes, they feel different to me.
00:14:27.040
Now, going back to visualization mode, I previously saw a calendar where one big event covers the whole summer.
00:14:33.040
Then, when adding an event in the middle, I would just break it into two and put a new one in.
00:14:39.200
But I need to think of it as having one big event that covers the summer and overlaying a holiday on top.
00:14:46.080
What if I model it this way? I could have a table that represents holidays as a separate entity, while keeping the schedules as previously described.
00:14:53.920
Now, when looking up availability on July 4th, we check the holidays table for any applicable overrides.
00:15:02.240
If there are holidays today, then the holiday schedule applies. If we're on July 3rd, there are no holidays, and we fall back to the current active schedule.
00:15:09.760
That feels like a more elegant solution, especially in terms of UI.
00:15:16.000
With this method, holidays are distinguished from schedules that administrators enter into the system.
00:15:22.240
I think we only have one feature left from our initial prompt, which is to support multiple locations.
00:15:30.560
If you were going to modify our existing database table diagram?
00:15:36.720
I guess the obvious addition is a Locations table now that we have multiple gyms.
00:15:43.680
I probably want an association to schedules since schedules are now per location. They don't all share the same schedule.
00:15:50.720
I think I would want to implement validations on the schedules table to ensure there is only one active schedule at a time.
00:15:57.680
With multiple locations, we'll need to scope that validation.
00:16:04.440
Also, I would need to add testing around that because it could introduce bugs.
00:16:11.360
There could also be an association to holidays, but I’m not sure if we have different holidays at different gyms.
00:16:18.640
That seems a little bit weird. However, the promotions might be different.
00:16:25.840
I could see different promotions targeting different groups of people at different gyms.
00:16:32.240
It seems like our solution expanded nicely out of our flexible scheduling system.
00:16:39.240
I think that's all we need to add—just the Locations table.
00:16:46.720
That confirms we made the right choice in the previous question—our architecture is now very expandable.
00:16:52.640
Great! I’ve gone through all the questions I had for you. Do you have any questions for me?
00:16:59.760
Yeah, I'm curious about the next steps for me after this.
00:17:05.760
That's a good question. Usually, there are two more steps after this.
00:17:11.520
The first being a code review. You'll receive a link to a GitHub project with an open PR.
00:17:17.680
The project is based on one of thoughtbot's internal projects, and you'll be asked to leave feedback and questions.
00:17:24.440
Try to review it the way you would approach any normal pull request.
00:17:32.000
After that, we have a pairing interview. You'll come in—we try to do them on Fridays.
00:17:39.680
Thoughtbot has internal time where we work on investment projects.
00:17:46.000
You'll pair with someone in the morning, have lunch with the team, and then pair with someone else in the afternoon.
00:17:53.440
Does that mean I might end up pairing on Factory Bot?
00:18:01.200
Yeah, a lot of our Friday projects, which are often open source, are born out of ideas we started on Fridays.
00:18:08.240
It's a very real possibility. It’s also very cool.
00:18:15.840
I'm curious; you mentioned earlier there’s a pull request review phase.
00:18:22.560
I've not seen that in interviews before. Is there anything I should watch out for?
00:18:29.080
No, similar to this interview where we want it to be discussion-based, we’re just looking for how you might approach these problems.
00:18:35.760
During the code review, we also want to see what you look for and how you communicate your feedback.
00:18:41.680
Code reviews are an important part of development, and we’re curious how you approach them.
00:18:48.640
I like that you emphasize team collaboration and how that works.
00:18:54.080
Yeah, it’s really important at thoughtbot too. Do you have any other questions?
00:19:01.520
Could you walk me through what a week in the life of an average thoughtbot developer is like?
00:19:06.800
Sure! From Monday to Thursday, I work on client work.
00:19:12.560
What that means for me right now is that I'll pair in the morning with another thoughtbot developer.
00:19:18.440
After lunch, I'll continue whatever we're pairing on by myself.
00:19:24.880
Around three o'clock, we take a coffee walk, which usually for me doesn't involve coffee.
00:19:32.400
It's just an excuse to go outside and get some fresh air. I find that when I take time away from the computer, everything sorts itself out.
00:19:38.960
When I return, all my problems seem fixed.
00:19:45.680
On Fridays, I've been working on my RailsConf talk.
00:19:52.000
Congratulations! What’s the topic?
00:19:59.120
We're discussing our interview process, where we've put a lot of work into making it more collaborative, closer to the work that you might actually be doing.
00:20:06.880
We're hoping that it's useful to others.
00:20:13.680
I have to say it’s been one of the more enjoyable interviews I've done, so I'm glad you're going to share that.
00:20:19.920
Thank you; it's great to hear that feedback. Good luck!
00:20:27.680
I think with that, we're all set.
00:20:34.560
Thanks for having me here.
00:20:39.040
Thanks so much for coming in.
00:20:46.160
Now that Joël's gone, it's probably a good time to fill out our interview rubric while it's still fresh in my mind.
00:20:54.080
I'm a big fan of this rubric; it helps me put different parts of the interview into perspective.
00:20:59.680
Okay, all these questions are asking me to identify what level I think Joël might be at—expert, practitioner, apprentice.
00:21:07.520
For the first question, was the candidate able to talk through different strategies for integrating onto a new project?
00:21:12.320
Joël had a lot of great techniques for getting to know a codebase.
00:21:18.720
He didn't discuss enhancements he might want to make, like fixing bugs in onboarding docs or fixing test warnings.
00:21:24.880
However, I didn't prompt him for that after he finished talking about getting to know the codebase.
00:21:31.360
So for this question, I think he's probably a practitioner.
00:21:39.760
Was the candidate able to define a project product and justify their decisions?
00:21:46.080
I really liked how Joël answered this question.
00:21:52.960
He talked through the features he would keep and why, along with how deployment affects the MVP.
00:21:59.760
That’s very important, and all candidates mention this, so I think he’s definitely an expert here.
00:22:06.720
Was Joël able to model complex objects in a domain?
00:22:14.800
He quickly proposed a good solution for our MVP.
00:22:21.040
Joël had two approaches and used his real-world experience to define which way he would go.
00:22:27.760
He also showed a solid approach to the scheduling component.
00:22:34.720
While his initial solution was a bit clunky, when we talked it over, he refined it to a better fit. I'm going to classify him as a practitioner.
00:22:42.080
For the last question, was the candidate able to talk through the pros and cons of their technical solution?
00:22:48.880
Joël did well here too.
00:22:56.080
When asked how an admin would enter a holiday, he could quickly identify the disadvantages of his solution.
00:23:02.640
Even if he had a bit of difficulty coming up with a more elegant solution, I think Joël is also an expert in this aspect.
00:23:09.200
Overall, Joël did really well in this interview, and I think we should consider hiring him or at least bringing him in for a code review.
00:23:14.960
I’m going to give him a call.
00:23:22.080
Bringing these elements together, I’m excited!
00:23:27.680
Hi Joël!
00:23:35.680
After our interview, I felt really good about how you did.
00:23:41.440
I would love to have you come in for a code review.
00:23:47.520
Okay, perfect!
00:23:53.040
So I think with that, we are all set.
00:23:59.200
I hope this has been helpful in seeing how we do things here at thoughtbot.
00:24:04.400
If you think this is a better way to interview, you should try going through it yourself.
00:24:10.320
You can apply by going to thoughtbot.com/jobs.
00:24:16.000
Feel free to reach out to me or Joël.
00:24:23.920
I don't have a prominent social media presence, but Joël’s Twitter is on the screen.
00:24:30.880
Thank you so much, everyone!