My Interview Experience at Juspay, 6 Interview Rounds | Tree of Space | Juspay
My journey through one of the toughest campus interview processes, what each round tested, why I think I fell short, and the lessons every aspiring software engineer should know.

Few weeks ago, Juspay visited our campus (IIIT Nagpur), for SDE Intern position, 40k stipend + 27 LPA PPO.
Here is the detailed Hiring process:
Round 1 - Aptitude (Online)
• Participants - approx. 350
• Time - 60 mins
• 16 MCQ Questions
• Topics - CS, System, Maths, Physics
Round 2 - Online Assessment (DSA Round)
• Participants - approx. 83
• Time - 90 mins
• 3 DSA Questions
• Topics - Tree, Graph, Sliding Window
• Approx 50 student shortlisted in this round
Round 3 - Hackathon Part A (Hacker Earth) Tree of Space
• Participants - 50
• Time - 180 mins
• Tree of Space (very famous problem of Juspay) - Implement 3 functions: Lock, Unlock and Upgrade
• Topics - Tree, Graph, OOP
• Below a detailed solution of Tree of Space problem.
Round 4 - Elimination Round [NEW!] (GMeet)
• Interviewer - ADITYA KUMAR 🧠🐐
• Participants - 30
• Time - 60-120 mins
• Interview - Resume, Projects, Experience, CS Fundamentals, 1 Coding Question (DSA/CP)
• Topics (For coding question) - I was asked a CP Question, first attempt passed 13 testcase but left 2, then interviewer gave me some hints and then I fix the code. It was held on Google Docs and Vs Code.
Round 5 - Hackathon Part B (Slack + GMeet) | optimise Tree of space and make it thread safe.
• Interviewer - SANDEEP S J💡💯
• Participants - 15
• Time - 8 hours
• i) Explaining the complete approach of Part A and deriving time and space complexities. Some derivations like no. of a leaf node of a m-ary tree of height h.
ii) Improving time and space complexities.
iii) Making the solution thread-safe by introducing locking mechanisms. I wasn’t allowed to lock the entire tree or use any atomic variables. I used Mutex, but it kills concurrency, you have to do it with logical approach, so if other thread processing a node of tree, other nodes know the result and their threads do not have to wait for that thread. A detailed solution given below.
• Topics - Parallel Computing, Threading, locking, lock and test.
Round 6 - Technical Interview (GMeet)
• Interviewer - Piyush Banka🫡
• Participants - 6
• Time - 20 mins
• Interview/Discussion
• Topics - Puzzle / Problem solving
• Problem Statement - I was asked to find the relation in height of a binary tree and number of nodes, (to prove h = log (N) ) without using any mathematical formula, just logically. I was not able to answer it, I was thinking in one direction, GP : 1 + 2 + 4 + ...... = N but he was not asking about it.
A logical solution is given below.
After this round, 2 students got selected for the offline round and both got the offer!
Number of leaf nodes in m-ary Tree:
Solution of Part A hackathon | Tree of Space:
#include <bits/stdc++.h>
using namespace std;
struct Node{
string name;
Node* parent;
bool isLocked;
int lockedBy;
unordered_set<Node*> lockedDescendants;
Node(string n, Node* p){
name = n;
parent = p;
isLocked = false;
lockedBy = -1;
}
};
class Tree{
Node* root;
unordered_map<string, Node*> nodeMap;
public:
Tree(vector<string>nodes, int m){
int n = nodes.size();
root = new Node(nodes[0], nullptr);
nodeMap[nodes[0]] = root;
queue<Node*>q;
q.push(root);
int index = 1;
while(!q.empty() && index<n){
Node* curr = q.front();
q.pop();
for(int i=0; i<m && index<n; i++){
Node* child = new Node(nodes[index], curr);
nodeMap[nodes[index]] = child;
q.push(child);
index++;
}
}
}
bool lock(string name, int id){
Node * node = nodeMap[name];
if(node->isLocked || !node->lockedDescendants.empty()) return false;
Node* curr = node->parent;
while(curr){
if(curr->isLocked) return false;
curr = curr->parent;
}
curr = node->parent;
while(curr){
curr->lockedDescendants.insert(node);
curr = curr->parent;
}
node->isLocked = true;
node->lockedBy = id;
return true;
}
bool unlock(string name, int id){
Node* node = nodeMap[name];
if(!node->isLocked || node-> lockedBy != id) return false;
Node* curr = node-> parent;
while (curr) {
curr->lockedDescendants.erase(node);
curr = curr->parent;
}
node->isLocked = false;
node->lockedBy = -1;
return true;
}
bool upgrade(string name, int id){
Node* node = nodeMap[name];
if(node->isLocked || node->lockedDescendants.empty()) return false;
for(Node* desc : node->lockedDescendants){
if(desc-> lockedBy != id) return false;
}
Node* curr = node->parent;
while(curr){
if(curr->isLocked) return false;
curr = curr->parent;
}
unordered_set<Node*> descToUnlock = node->lockedDescendants;
for(Node* desc: descToUnlock){
unlock(desc->name, id);
}
lock(name, id);
return true;
}
};
int main(){
int m,n,q;
cin>>n>>m>>q;
vector<string> nodes(n);
for(int i=0; i<n; i++){
cin>> nodes[i];
}
Tree tree(nodes, m);
for(int i=0; i<q; i++){
int type, id;
string name;
cin>>type>>name>>id;
bool result=false;
if(type==1) result = tree.lock(name, id);
else if(type==2) result = tree.unlock(name, id);
else if(type==3) result = tree.upgrade(name, id);
if(result) cout<<"true \n";
else cout<<"false \n";
}
return 0;
}
Solution of Part B hackathon | Tree of Space | Thread space and optimised part A :
#include <bits/stdc++.h>
using namespace std;
struct Node{
string name;
Node* parent;
bool isLocked;
int lockedBy;
unordered_set<Node*> lockedDescendants;
Node(string n, Node* p){
name = n;
parent = p;
isLocked = false;
lockedBy = -1;
}
};
class Tree{
Node* root;
unordered_map<string, Node*> nodeMap;
public:
Tree(vector<string>nodes, int m){
int n = nodes.size();
root = new Node(nodes[0], nullptr);
nodeMap[nodes[0]] = root;
queue<Node*>q;
q.push(root);
int index = 1;
while(!q.empty() && index<n){
Node* curr = q.front();
q.pop();
for(int i=0; i<m && index<n; i++){
Node* child = new Node(nodes[index], curr);
nodeMap[nodes[index]] = child;
q.push(child);
index++;
}
}
}
bool lock(string name, int id){
Node * node = nodeMap[name];
if(node->isLocked || !node->lockedDescendants.empty()) return false;
Node* curr = node->parent;
while(curr){
if(curr->isLocked) return false;
curr = curr->parent;
}
curr = node->parent;
while(curr){
curr->lockedDescendants.insert(node);
curr = curr->parent;
}
node->isLocked = true;
node->lockedBy = id;
return true;
}
bool unlock(string name, int id){
Node* node = nodeMap[name];
if(!node->isLocked || node-> lockedBy != id) return false;
Node* curr = node-> parent;
while (curr) {
curr->lockedDescendants.erase(node);
curr = curr->parent;
}
node->isLocked = false;
node->lockedBy = -1;
return true;
}
bool upgrade(string name, int id){
Node* node = nodeMap[name];
if(node->isLocked || node->lockedDescendants.empty()) return false;
for(Node* desc : node->lockedDescendants){
if(desc-> lockedBy != id) return false;
}
unordered_set<Node*> descToUnlock = node->lockedDescendants;
for(Node* desc: descToUnlock){
Node* par = dec->parent;
desc->isLocked = false;
desc->lockedBy = -1;
while(par != node){
if(par->lockedDescendants.empty()) break;
par->lockedDescendants.clear();
par = par->parent;
}
par->lockedDescendants.clear();
}
Node* par = node->parent;
while(par){
for(Node* desc: descToUnlock) par->lockedDescendants.erase(desc);
par = par->parent;
}
lock(name, id);
return true;
}
};
int main(){
int m,n,q;
cin>>n>>m>>q;
vector<string> nodes(n);
for(int i=0; i<n; i++){
cin>> nodes[i];
}
Tree tree(nodes, m);
for(int i=0; i<q; i++){
int type, id;
string name;
cin>>type>>name>>id;
bool result=false;
if(type==1) result = tree.lock(name, id);
else if(type==2) result = tree.unlock(name, id);
else if(type==3) result = tree.upgrade(name, id);
if(result) cout<<"true \n";
else cout<<"false \n";
}
return 0;
}
struct Node{
string name;
Node* parent;
int isLocked;
int sibLock;
int lockedBy;
unordered_set<Node*> lockedDescendants;
Node(string n, Node* p){
name = n;
parent = p;
isLocked = false;
lockedBy = -1;
}
};
bool lock(string name, int id){
Node * node = nodeMap[name];
node->isLocked++;
if(node->isLocked > 1 || !node->lockedDescendants.empty() || sibLock){
node->isLocked--;
return false;
}
Node* curr = node->parent;
while(curr){
curr->lockedDescendants.insert(node);
if(curr->isLocked >0 ){
Node* curr2 = node->parent;
while(curr2 != curr){
curr2->lockedDescendants.erase(node);
curr2 = curr2->parent;
}
curr->lockedDescendants.erase(node);
node->isLocked--;
return false;
}
curr = curr->parent;
}
node->lockedBy = id;
return true;
}
Solution of System round:
height of a binary tree logically



