Go read this repo to get context for the overall project: https://gist.github.com/airbnb-robot/af6e9068639733bff79d4e3773a8d1dc
There are 3 pull requests: 1, 2, 3
They are in increasing order of complexity and difficulty.
You get a GitHub repo with 3 pull requests. What they don't tell you is that you score "points" for making comments on various issues about the code. Apparently I got a few points below the cutoff for senior software engineer. I got all the low-hanging fruit in the easier pull requests, but I ran out of time on the bigger pull request.
For this interview, start with pull request 3 and make as many comments about the architecture as you can. Apparently the last pull request is worth the most points.
Pull request 1:
This pull request is to fix the wrong type of consistency being sent through the API. The two types are "EVENTUAL" and "STRONG", but someone wrote "WEAK" and "STRONG", which caused a bug. This pull request fixes the bug.
Things to note:
Pull request 2:
For this PR, we add a DAO layer to fetch listings data from the listing service and host data from the hosts service. In order to do so, we first need to issue service calls to those services and then transform the raw responses into our internal DAO objects for related processing.
x: datetime = None should actually be x: Optional[datetime] = None.Pull request 3:
Atlantis has told us that we're calling their API too frequently and they have a batch endpoint that they'd like for us to use instead. To get the status of many reservations and take advantage of this, we will start batching up our calls to Atlantis to make this work without changing our external API. We plan to use a job queue for registrations and listings. Once the queue is large enough or after enough time has passed, we'll pick a bunch of items off this queue.
list(set(registration_numbers)) instead of a list(registration_numbers)This interview was highly structured. The interviewer began talking a lot, and I started asking questions about what he was saying. He got a little confused or frustrated, and then he told me he will just paste the question. His English was also pretty bad.
I asked a lot of questions like:
He told me not to worry about any of that and just answer the 4 questions.
He was very interested in my data schema.
Cassandra and similar databases are just a waste. You don't need the write throughput.
The main question is SQL vs Non-Relational. He said the traffic is about 1 million group chats per year, assume 20 messages per group chat. That's 5500 messages / day, which is 228 messages / hour.
SQL can definitely handle that. BUT you don't need the strong consistency. It's probably to have high availability and easier horizontal scalability, so I went with DynamoDB.
My interviewer had ABSOLUTELY NO IDEA how DynamoDB worked. He didn't know about partition keys, sort keys, or secondary indices. I basically wrote my data schema AS IF it were SQL, which felt strange.
He asked me to walk through what happens in my system for each of the 4 workflows.
Group chat - easy.
Just create an entry in your group_chat table and corresponding entries in your chat_user table.
Create an inbox and load the top 10 group chats.
Simple - when the user logs in, you just query the top 10 most recently updated chats.
Consider this schema
group_chat
id: INT PK
created_at: datetime
last_modified_at: datetime (idx)
[Can also use a DB trigger to update last_modified_at.]
chat_user
id: INT PK
user_id: INT (idx, FK references user.id, ON UPDATE CASCADE, ON DELETE CASCADE)
group_chat_id: INT (idx, FK references group_chat.id, ON UPDATE CASCADE, ON DELETE CASCADE)
created_at: datetime
message
id: INT PK
sender_id: INT (idx, FK references user.id, ON UPDATE CASCADE, ON DELETE CASCADE)
message: varchar(500)
created_at: datetime
Whenever you write a message, you should use a producer-consumer model. The consumer should update the last_modified_at timestamp when you write a message in that group chat.
Send a message in the group chat.
I asked him whether we expect to send the message to the users who are online, or whether it should just show up next time the user refreshes their page. He said we want to push it.
Simple - I immediately said there were two paths:
He told me to ignore the second path. It was strange, because that one is pretty important.
For #1, do the following
User ----message----> [Chat Server] ---message---> Kafka ---message---> Consumer
The consumer (1) Writes the message to the message table, (2) Updates the group_chat table, and (3) delivers the message to the other online users (he said to ignore this) using at-least-once-delivery.
Show messages of a group chat
This is an easy query when you click a group chat. It just loads the most recent messages.
Follow up:
What if we want to create groups of users and refer back to the existing groups whenever the same group makes another reservation?
Simple.
New Tables:
Group:
Id INT PK
signature: text (idx)
created_at: datetime
group_member:
Id INT PK
user_id INT (idx) fk references ...
group_id: INT (idx), fk references group.id
created_at: datetime
Sort the user_ids and make a key out of the concatenated user_ids. This will be the Group.signature
E.g. if users 1, 2, 8 are in the group, then the key is "1,2,8"
If you want to see if users 2, 8, 1 have ever formed a group before, then you look for the key
"1,2,8"
Then change the chat_member table to reference groups instead of users.
Follow Up 2:
How do you deliver the messages to users who are actively online.
Go look at any system design for WhatsApp. Just use Redis + chat servers + messaging queues.
Follow Up 3:
How do you scale the system if you're creating 1,000,000 group chats per day?
DynamoDB horizontally scales REALLY WELL. Etc. etc.
Talk about a big project you were a part of.
Why were you chosen to lead it?
What were the steps you chose to implement it and why?
Talk about the other teams you worked with.
Talk about implementation details.
How long did it take, how many people did you lead, and what were the challenges/
How did you define milestones and distribute work?
How do you delegate work and make people successful vs. managing the overall timeline?
What challenges did you have?
What did you learn?
What compromises did you have to make with the product manager's vision?
What issues did you have with other teams?
How did you maintain high quality, especially during the rollout?
(Testing, Monitoring, alerting, rollout strategy)
I talked about leading an international payments project where I worked with payment service providers, legal teams, privacy teams, other engineering teams etc. and mentored a few engineers on my team.
I talked about how I like to divide up project work on projects that I lead. I said that I like to ask individual engineers if there are any specific opportunities that they want during the project. I also ask their managers if there are opportunities that they need to address or any areas where they could show signals since it could help in their performance reviews.
For my project, I talked about how I led an international payments project. I led a team of 4 and was also helping mentor a senior engineer. Our manager said he had botched a previous project that had a bad launch. Apparently he didn’t anticipate certain workflows when getting requirements or designing his last project, so I talked about how I made sure he got the opportunity to design some of our reconciliation workflows for the billing and payments engines.
For a mistake that I made, I talked about how I designed the database for the requirements that I got from the PM and from my partner teams. After we launched, our customers complained about how slow data access was, and apparently one of the workflows we missed involved business reporting. I had asked the other teams to review my data model, but what I should have done is ask what queries they will need to run and what those queries will be used for. Ultimately, other teams had been doing scatter-gather queries over all the shards to access data. I rectified this by proposing a few ideas, discussing tradeoffs, and then favoring a data warehouse given our needs and future scale.
There's obviously way more detail in there, but I'm not going to type out everything.
Hiring manager feedback - D.C. said I communicated very clearly, but that I have no sense of accountability or humility and that I spoke poorly of coworkers and treated them like "low performers" (his words, not mine).
He also apparently spoke against me in the onsite debrief and didn't want me to join even at the G8 (~Software Engineer II) level. That is crazy. I have never had an issue in behavioral/eng. experience interviews before. This feels malicious.
You are given an array like [5, 4, 3, 2, 1, 3, 4, 0, 3, 4]
Part 1:
Print a terrain where each number represents the height of a column at that index.
+
++ + +
+++ ++ ++
++++ ++ ++
+++++++ ++
++++++++++ <--- base layerPart 2:
Imagine we drop a certain amount of water at a certain column. The water can flow in whichever direction makes sense. Print the terrain after all the water has fallen.
dumpWater(terrain, waterAmount=8, column=1)
Should render
+
++WWWW+ +
+++WW++ ++
++++W++ ++
+++++++W++
++++++++++ <--- base layer