Alright, before I begin my post I would like to thank the community for helping me get prepared for my interviews. Even though the outcome was not what I expected, I was very close on my coding and most likely failed behavior.
BS in CS, and MS in CS from US university, ~10 YOE.
Leetcode count: ~90 Easy, ~90 Medium, ~10 Hard.
A l g o e x p count: 80 total, 25 Easy, 45 Medium, 10 Hard/Very Hard.
E P I count: ~20 all Medium.
Preparation
I started my interview preparation in May, I was coming in with barely being able to do Easy, and some select few Mediums. I did most of my begining work on other algo websites, the video solutions helped me get a solid base. I started of by doing all of the Easy and most of the Mediums and then jumped into Leetcoding.
Throughout my prep I kept interviewing for other 3rd tier and FAANG companies, my target was my Facebook onsite and i did the others as pure free mock interview reviews. I also used a mock interview website which game me 1 free credit. I luckily got another fellow Facebook wannabe and I got an actual FB question that later appeared as my 1st interview question on my onsite, weirdly enough!
Recruiter
A recruiter reached out to me via email. We had a chat, where I mentioned i was due to have a FAANG OA soon, so she pushed me to the Phone Screen round without having me do an OA.
Phone Interview
I had my phone interview about 30 days into my prep. The interviewer was very nice, even though I was very nervous during the call he had patience with me.
My first question was 938. Range Sum of BST. I fumbled this a bit, but I managed to give a solution.
class Solution {
public:
int rangeSumBST(TreeNode* root, int low, int high) {
if (root == nullptr) {
return 0;
}
stack<TreeNode*> st;
TreeNode* curr = root;
int sum = 0;
while(curr || !st.empty()) {
while(curr) {
st.push(curr);
curr = curr->left;
}
curr = st.top();
st.pop();
if(curr->val >= low && curr->val <= high) {
sum += curr->val;
}
curr = curr->right;
}
return sum;
}
};My second question was 56. Merge Intervals, this one i did without any fumbling:
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
if (intervals.size() <= 1) {
return intervals;
}
sort(intervals.begin(), intervals.end(), [](const auto &a, const auto &b) {
return a[0] < b[0];
});
vector<vector<int>> merged = {{intervals[0]}};
for(int i = 1; i < intervals.size(); ++i) {
vector<int> lastMerged = merged.back();
if(lastMerged[1] >= intervals[i][0]) {
merged.pop_back();
merged.push_back({lastMerged[0], max(lastMerged[1], intervals[i][1])});
}
else {
merged.push_back(intervals[i]);
}
}
return merged;
}
};My recruiter called me by the end of the same day and told me to start prepping for my onsite. She gave me some links and access to some stuff that they do for prep, largely useless IMHO.
Virtual Onsite
1st Round: Coding
On my 1st round I could barely hold it together, I was extremely nervous and I honestly wanted to cancel everything because I was sure I would not be able to do anything.
My first interviewer was pretty unfriendly, BUT his questions were basic, lucky for me. First question was 1249. Minimum Remove to Make Valid Parentheses
I effortlessly wrote the solution, and it was something similar to:
class Solution {
public:
string minRemoveToMakeValid(string s) {
if(s.size() <= 1) {
return s;
}
int n = s.size();
vector<bool> ommit(n, false);
stack<int> st;
for(int i = 0; i < s.size(); ++i) {
if(s[i] != '(' && s[i] != ')') {
continue;
}
else if (s[i] == '(') {
st.push(i);
}
else if (st.empty()) {
ommit[i] = true;
}
else {
st.pop();
}
}
while(!st.empty()) {
ommit[st.top()] = true;
st.pop();
}
string res = "";
for(int i = 0; i < s.size(); ++i) {
if (ommit[i] == false) {
res.push_back(s[i]);
}
}
return res;
}
};My 2nd question was 46. Permutations. At this point, I couldn't believe my luck this was one of my best problems. I talked about different approaches, including building the array from scratch or destroiyng the input by doing swaps on the input array. We both agreed that the second approach was more space friendly and i went ahead and coded it up.
class Solution {
public:
vector<vector<int>> permute(vector<int>& nums) {
vector<vector<int>> res;
step(0, res, nums);
return res;
}
void step(int idx, vector<vector<int>>& res, vector<int>& nums) {
if(idx == nums.size()) {
res.push_back(nums);
return;
}
for(int i = idx; i < nums.size(); ++i) {
swap(nums[idx], nums[i]);
step(idx+1, res, nums);
swap(nums[idx], nums[i]);
}
}
};At this point we still had some time and he asked me 47. Permutations II. I gave a quick and dirty solution of replacing the combinations vector with a set, coded that really quick, it was like 30 seconds to do the replace. Then i went ahead and discussed the optimal approach, and coded most of it up until he stopped me and we went to Q/A.
class Solution {
public:
vector<vector<int>> permuteUnique(vector<int>& nums) {
unordered_map<int, int> m;
for(auto n: nums) {
m[n]++;
}
vector<pair<int, int>> nums;
for(auto p: m) {
nums.push_back(p);
}
vector<vector<int>> res;
step(0, m, res, nums);
return res;
}
void step(int idx, unordered_map<int, int> &m, vector<vector<int>> &res, vector<pair<int, int>>& nums) {
if(idx == nums.size()) {
res.push_back(nums);
return;
}
for(int i = idx; i < nums.size(); ++i) {
if(m[nums[i]] <= 0) {
continue;
}
swap(nums[i], nums[idx]);
m[nums[i]]--;
step(idx + 1, m, res, nums);
m[nums[i]]++;
swap(nums[i], nums[idx]);
}
}
};I thought I absolutely nailed this one, and I was finally getting my hopes up. 3 Mediums, one with 2 solutions, done and done.
2nd Round: Behavior
On this round I am not sure how i did.
I gave the best/honest answer I could think of. I was somewhat prepared to answer these questions because I interviewed with Amazon and I prepped for their LP. If you prepped for Amazon's LPs then you should be good to go on this round.
3rd Round: System Design
This round was my biggest fear, howerver I received a very basic question, I was tasked to design Google Drive. He called it Facedrive, LOL.
Lucky for me, I already did that question on Systems Expert, I did it a few times, and I did Dropbox from G r o k k i n g so I was super prepared and lucky to get this question. I discussed Database schema, broke down the data into metadata and block data, gave a synchronization between clients(tablet, etc) via queues. I wrote down the Synchronization API. I broke it down into API Servers, Blockdata Servers, Metadata Servers with a RR LB. I mentioned data deduplication via chunking and gave a detailed approach on how it would work.
I drove most of the discussion, I did some back of the envelope calculation that the interviewer agreed with. His only follow up was on the Synchronization aspect, and it's when I went ahead and wrote down the actual API calls, and also mentioned using a local offline mapping file on each device.
I thought that I nailed this round because I did most of the talking like they want you to do. I was intrerupted once for Synch but after doing it he was OK with it and we continued to Q/A.
4th Round: Coding Round
This is the round that I think killed my 3 months of work :(. I worked very hard but foolishly did not cover all the FB questions. I was preparing more of a generalistic approach so I could solve anything they threw at me, but I messed up because very few people can come up with an algorithm to a question that they never seen within <20min. 5min for Q/A, and 5min for intros, which leaves about 35min for 2 Mediums, or 1 Hard, 1 Medium :(.
My 1st question was 297. Serialize and Deserialize Binary Tree. I coded up a partial solution, but I did not manage get edge cases working, it looked like I nailed it but when he gave me a test input for an edge case my logic was not working right. However I did give the O(n) time and Space and he seemed content with that.
Since then I did solve the question and I could easily nail it in an interview, but unfortunately no one gives a ,,,
With 5min left he asked about 173. Binary Search Tree Iterator approach, not code. I gave the quick and dirty approach:
class BSTIterator {
vector<int> sorted;
vector<int>::iterator it;
public:
BSTIterator(TreeNode* root) {
inorder(root);
it = sorted.begin();
}
int next() {
if(!hasNext()) {
return -1;
}
int ret = *it;
it++;
return ret;
}
bool hasNext() {
if (it == sorted.end()) {
return false;
}
return true;
}
void inorder(TreeNode* root) {
if(root == nullptr) {
return;
}
inorder(root->left);
sorted.push_back(root->val);
inorder(root->right);
}
};I coded a lot of the approach up but time was almost up. Mentioned what we could do better, he asked about time and space and i gave that, and that was that, we then went on about Q/A.
5th Round: Behavior Round
My last round was another behavior round. It was more of the same, the person talked to me about 20min before starting the actual interview, I believe the person was warming me up so i could trust and get me more comfortable about discussing bad previous experiences about my past roles. Questions were very similar to:
Then follow ups on these two. We spent more than 1 hour (it was supposed to be 45min) on this interivew, we started it late after chit chatting for 20min or so, and the Q/A was extremely chit chatish.
After the onsite
I figured out that I could Graphql stalk the recruiting website, and I was inspecting the response pertaining to schedulrLoopStatus. My status went from PENDING_FEEDBACK to PENDING_DECISION. I was called within a few days, my rejectionReason was NULL and right after the call went to NOT_SELECTED.
Interviewer Debrief
My debrief was a joke, recruiter said that I was not selected. I asked if they could tell me if it was Coding or Behavior, or anything and they wouldn't budge. I asked if I failed more than one round, no response. I asked for any tips on what I could potentially improve and didn't get anything but a No.
My cooldown was 1 year, they mentioned that sometimes they tried 6 months as an experiment a few times but this time it will be a full 1 year.
Thoughts
I spend ~3 months targeting this particular company because of it being remote friendly. I am more upset about wasting all that time than not being selected. I am not even sure on what I should be working on. Since then I kept on Leetcoding, and doing System Design every day, so I suppose I am ready for another go at some other company. I still feel incredibly disappointed. I will not give up though, I plan on keep grinding until I finally make it.
The only thing that I would have done different would have been to start System Design prep earlier, and done more Leetcode company targetted question. Even though I can solve a lot of the problems that I see, I really cannot do new problems fast enough in the pressure of a fast paced coding interview. It is what it is.
To everyone reading, thank you for reading. I hope you found something helpful in this post and I wish you the best!