Tips :
The problem is divided into 4 parts, with each part extending the previous one.
| Part | Topic | Difficulty |
|---|---|---|
| Part 1 | Basic User → Account → Role Mapping | 🟢 Easy |
| Part 2 | Account Hierarchy & Role Inheritance | 🟡 Medium |
| Part 3 | Role Overrides & Deny Rules | 🟠 Medium |
| Part 4 | Role Dependencies, Caching & Edge Cases | 🔴 Hard |
Given a list of user-role assignments, implement:
getRolesForUserInAccount(userId, accountId)
Each assignment contains:
userIdaccountIdroleThe function should return all roles that the specified user has in the specified account. If there are no matching roles, return an empty list.
Assignments:
[
{ userId: "usr_1", accountId: "org_1", role: "admin" },
{ userId: "usr_1", accountId: "wksp_1", role: "developer" },
{ userId: "usr_1", accountId: "wksp_1", role: "analyst" }
]
Last updated Oct 4, 2026
Executions:
getRolesForUserInAccount("usr_1", "wksp_1")
→ ["developer", "analyst"]
getRolesForUserInAccount("usr_1", "org_1")
→ ["admin"]
Extend the previous problem to support account hierarchies. An account can have a parent account, and roles are inherited from parent accounts. A user inherits roles from their parent accounts. Roles inherited from parent accounts should be included, and a role should not appear more than once in the result. If no matching roles exist, return an empty list.
org_1
└── wksp_1
└── sbx_1
(This means: wksp_1 → org_1, sbx_1 → wksp_1, org_1 → null)
Accounts:
org_1 → null
wksp_1 → org_1
sbx_1 → wksp_1
sbx_2 → org_1
wksp_2 → null
User Role Assignments:
usr_1 → org_1 → admin
usr_1 → wksp_1 → developer
usr_1 → wksp_1 → analyst
usr_1 → sbx_1 → analyst
usr_2 → org_1 → developer
usr_3 → wksp_1 → analyst
usr_3 → wksp_1 → admin
usr_4 → wksp_2 → admin
Executions:
getRolesForUserInAccount("usr_1", "wksp_1")
→ ["admin", "developer", "analyst"]
getRolesForUserInAccount("usr_1", "sbx_1")
→ ["admin", "developer", "analyst"]
Extend the previous problem to support role inheritance with overrides and account-level role restrictions.
An account can:
Each user-role assignment can now contain:
userIdaccountIdroleeffect — either "allow" or "deny"A role assigned with "deny" should prevent that role from being inherited from any parent account.
The function should:
"allow" roles."deny" assignments (a deny overrides an inherited allow).Hierarchy:
org_1
└── wksp_1
└── sbx_1
User Role Assignments:
usr_1 → org_1 → admin → allow
usr_1 → org_1 → developer → allow
usr_1 → wksp_1 → analyst → allow
usr_1 → wksp_1 → developer → deny
usr_1 → sbx_1 → tester → allow
Executions:
getRolesForUserInAccount("usr_1", "org_1")
→ ["admin", "developer"]
getRolesForUserInAccount("usr_1", "wksp_1")
→ ["admin", "analyst"]
// developer is inherited from org_1, but explicitly denied at wksp_1.
getRolesForUserInAccount("usr_1", "sbx_1")
→ ["admin", "analyst", "tester"]
// developer remains denied for sbx_1 because the denial exists in its parent.
Design a production-ready role resolution system that supports account hierarchies, role inheritance, role dependencies, and caching.
Some roles automatically grant other roles.
{ "role": "admin", "inherits": ["developer", "analyst"] }
{ "role": "developer", "inherits": ["viewer"] }
{ "role": "analyst", "inherits": ["viewer"] }
{ "role": "viewer", "inherits": [] }
Therefore, admin implicitly provides: admin, developer, analyst, and viewer.
For getRolesForUserInAccount("usr_1", "sbx_1"), the system should:
sbx_1.Example execution based on Part 3's data + the above dependencies:
getRolesForUserInAccount("usr_1", "sbx_1")
→ ["admin", "analyst", "viewer", "tester"]
// developer is excluded because it was explicitly denied at wksp_1.
The role-resolution operation may be called thousands of times.
userId + accountId (e.g., usr_1:sbx_1).addRoleAssignment, removeRoleAssignment, updateAccountParent, updateRoleDefinition).org_1) must invalidate cached results for all descendant accounts of org_1.Your implementation must handle:
admin → developer and developer → admin). The implementation must not enter an infinite loop.General Instructions:
At a company like Stripe, we move a lot of money around. It is often important to know how much money an account has at a given time.
Implement a function that computes the account balances given a list of transactions.
Each transaction contains:
account_id — The account identifiertimestamp — The transaction timestampcurrency — The currency codeminor_unit — The transaction amount in minor units, such as cents for USDTransactions are provided in strictly increasing order of timestamp.
Requirement: Return the final balance of each account, excluding accounts whose final balance is zero.
account_id,timestamp,currency,minor_unit
acct_123,1,usd,800
acct_321,2,usd,100
acct_123,4,usd,-300
acct_321,5,usd,-300
acct_321,9,usd,-800
acct_321,10,usd,1000
acct_123: 500
acct_123 = 800 - 300 = 500acct_321 = 100 - 300 - 800 + 1000 = 0acct_321 is excluded because its final balance is zero.
Modify the solution so that an individual merchant balance can never go below zero.
For every transaction:
Requirement: Return the rejected transactions and the final balances.
acct_321,2,usd,100
acct_321,5,usd,-300
acct_321,9,usd,-800
acct_321,10,usd,1000
+100 -> 100 ✓ accepted-300 -> -200 ✗ rejected-800 -> -800 ✗ rejected+1000 -> 1100 ✓ acceptedFinal balance:
acct_321: 1100
// Complete the 'compute_account_balances' function below.
function compute_account_balances() {
// Your code here
}
function main() {
compute_account_balances();
}
O(N)O(A)Where:
N = number of transactionsA = number of unique accountsThe interviewer gave me a GitHub repo and asked me to open GitHub Issues for the issues present in the repo. There were around 3–4 issues that needed to be identified and documented.
The interviewer asked me to clone the repo locally, open it in VS Code, and start working on it. I preferred using JS since I’m more comfortable with it; I don’t have much experience with other languages.
This round was honestly quite hard, especially if you don’t have hands-on experience with GitHub and JavaScript-level coding. The expectations were kind of production-level.
I still had the repo locally that I cloned during the interview, so I’ve attached it here. It might be helpful for you all while preparing.
General Instructions:
Let's parse some JSON data.
(Note: If you're using a statically typed language such as Java, Kotlin, C#, C++, or Go, you may want to review how to handle dynamic/unstructured objects in JSON, though you may map it to structured objects if you prefer).
Your Task:
ride-simple.json.stdout.There are almost 500 points in the file, but we only need to see the first 10. This is GPS data of a bicycle trip to Stripe's Seattle office, encoded as GeoJSON.
The input is provided in a local file named: ride-simple.json
The JSON contains a GeoJSON object with GPS coordinates. The coordinates are available under the following path:
rideData.features[0].geometry.coordinates
Each coordinate is represented as an array containing two numbers:
[longitude, latitude]
Print the first 10 coordinate pairs to stdout.
Example:
First 10 coordinates
[-122.2851, 47.55126]
[-122.28531, 47.55126]
[-122.28535, 47.55126]
[-122.28565, 47.55126]
[-122.28575, 47.55126]
[-122.28598, 47.55126]
[-122.2862, 47.55126]
[-122.28631, 47.55126]
[-122.28687, 47.55127]
[-122.28767, 47.55127]
Note: The exact coordinates should be dynamically extracted from ride-simple.json rather than hardcoded.
'use strict';
const fs = require('fs');
try {
const rawData = fs.readFileSync('ride-simple.json');
const rideData = JSON.parse(rawData);
const coordinates = rideData.features[0].geometry.coordinates;
const firstTenCoordinates = coordinates.slice(0, 10);
console.log('First 10 coordinates');
for (const coord of firstTenCoordinates) {
console.log(coord);
}
} catch (error) {
console.log('Error processing JSON file:', error.message);
}
If using Node.js:
node output.js
A later version of this task removes the .slice(0, 10) limitation.
Before (Part 1):
const firstTenCoordinates = coordinates.slice(0, 10);
for (const coord of firstTenCoordinates) {
console.log(coord);
}
Updated Version (Part 2+):
for (const coord of coordinates) {
console.log(coord);
}
The updated version loops directly over the coordinates array and prints all ~500 points.
ride-simple.json.In the last round, I fumbled quite a bit and wasn’t able to solve more than 1.5 parts. The interviewer’s expectation was around 3 parts.
So, hoping for the best! 🤞


Waiting for this round 😬