Summary
It was a rigorous yet enjoyable interview experience. The technical rounds focused heavily on problem-solving, memory management, and understanding of computer architecture. System design concepts like indexing, sharding, and caching were explored in detail. I was selected for the role.
Full Experience
Round 1 (DSA + Problem Solving)
Question: Given a binary grid with exactly two islands (groups of 1s), find the minimum number of 0s that must be flipped to 1s to connect the two islands.
I have provided the code I wrote in the interview below
Show Code
#include <climits>
#include <cmath>
#include <cstdio>
#include <iterator>
#include <queue>
#include <vector>
#include <iostream>
#include <algorithm>
#include <limits>
#include <bits/stdc++.h>
using namespace std;
vector<pair<int,int>>direction={{-1,0},{0,-1},{0,1},{1,0}};
bool insideBoundary(int x,int y,int height,int width){
return (x>=0 and y>=0 and x<height and y<width);
}
int minDistance(int height,int width,vector<vector<int>>&grid){
queue<pair<int,int>> multiSourceBfs;
vector<vector<int>>dist(height,vector<int>(width,INT_MAX));
pair<int,int>source={-1,-1};
for(int row=0;row<height;row++){
for(int col=0;col<width;col++){
if(grid[row][col]==1){
source={row,col};
break;
}
}
}
queue<pair<int,int>> bfs;
bfs.push(source);
while(!bfs.empty()){
pair<int,int> node= bfs.front();
bfs.pop();
if(dist[node.first][node.second]<INT_MAX) continue;
dist[node.first][node.second]=0;
multiSourceBfs.push({node.first,node.second});
for(auto dir:direction){
int nx=node.first+dir.first,ny=node.second+dir.second;
if(insideBoundary(nx,ny,height,width) and grid[nx][ny]==1){
bfs.push({nx,ny});
}
}
}
while(!multiSourceBfs.empty()){
pair<int,int> node= multiSourceBfs.front();
multiSourceBfs.pop();
if(grid[node.first][node.second]==1 and dist[node.first][node.second]>0) return dist[node.first][node.second]-1;
for(auto dir:direction){
int nx=node.first+dir.first,ny=node.second+dir.second;
if(insideBoundary(nx,ny,height,width) and dist[nx][ny]>dist[node.first][node.second]+1){
dist[nx][ny]=dist[node.first][node.second]+1;
multiSourceBfs.push({nx,ny});
}
}
}
return -1;
}
int main() {
int height, width;
cin>>height>>width;
vector<vector<int>>grid(height,vector<int>(width,0));
for(int row=0;row<height;row++){
for(int col=0;col<width;col++){
cin>>grid[row][col];
}
}
int ans=minDistance(height,width,grid);
cout<<"Ans: "<<ans<<endl;
return 0;
}
Q2: Is vector memory contiguous? Why? How? Q3: Difference between pass-by-value and pass-by-reference. Q4: Threads, cache types (L1, L2, L3), why L1 cache is fast, what is its size, and why don’t we increase it? Q5: Indexes in databases — why not use multiple indexes, what is partitioning, and what is sharding?
Round 2 (DSA + OOP)
Given multiple orders with statuses, identify completed and cancelled orders.
Completed orders have gone through all stages (placed, processed, shipped, delivered).
Cancelled orders can have cancelled after any stage.
I have provided the code I wrote in the interview below
Show Code
#include <cmath>
#include <cstdio>
#include <unordered_map>
#include <vector>
#include <iostream>
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
struct order{
int order_id;
int customer_id;
string status;
order(int order_id,int customer_id,string status): order_id(order_id),customer_id(customer_id),status(status){}
};
class markCompletedOrder{
unordered_map<string,int> statusToStatusCode={
{"cancelled",0},
{"placed",1},
{"processed",2},
{"shipped",3},
{"delivered",4}
};
vector<order>orders;
unordered_map<int,set<int>>orderStatusmap; // key=>order_id, value: set<status_code>
vector<int>cancelled,completed;
void CountCompletedOrder(){
for(auto ord:orders){
if(statusToStatusCode.find(ord.status)==statusToStatusCode.end()){
cout<<"[Error] : invalid status code"<<endl;
return;
}
orderStatusmap[ord.order_id].insert(statusToStatusCode[ord.status]);
}
for(auto val:orderStatusmap){
set<int>allStatus=val.second;
if(*allStatus.begin()==0){
cancelled.push_back(val.first);
continue;
}
if(allStatus.size()==statusToStatusCode.size()-1){
completed.push_back(val.first);
}
}
}
public:
markCompletedOrder(vector<order>&orders){
this->orders=orders;
CountCompletedOrder();
}
int getCompletedOrder(){
return completed.size();
}
int getCancelledOrder(){
return cancelled.size();
}
vector<int>completedOrder(){
return completed;
}
};
int main() {
int countOrders;
cin>>countOrders;
vector<order>orders;
for(int i=0;i<countOrders;i++){
int order_id,customer_id;
string status;
cin>>order_id>>customer_id>>status;
orders.push_back(order(order_id,customer_id,status));
}
markCompletedOrder *completed= new markCompletedOrder(orders);
cout<<completed->getCompletedOrder()<<endl;
cout<<"completed order ids are: ";
for(auto it:completed->completedOrder()){
cout<<it<<" ";
}
cout<<endl;
return 0;
}
Round 3 (HR)
Mostly standard HR questions:
- Why Tower Research?
- Walk me through your projects
- Internship experience at MakeMyTrip
- Any offers in hand?
Interview Questions (10)
Given a binary grid with exactly two islands (groups of 1s), find the minimum number of 0s that must be flipped to 1s to connect the two islands.
Is vector memory contiguous? Why? How?
Difference between pass-by-value and pass-by-reference.
Threads, cache types (L1, L2, L3), why L1 cache is fast, what is its size, and why don’t we increase it?
Indexes in databases — why not use multiple indexes, what is partitioning, and what is sharding?
Given multiple orders with statuses, identify completed and cancelled orders. Completed orders have gone through all stages (placed, processed, shipped, delivered). Cancelled orders can have cancelled after any stage.
Why Tower Research?
Walk me through your projects
Internship experience at MakeMyTrip
Any offers in hand?