Microsoft SDE Intern Interview Experience
💼 LTIMindtree Interview Experience (On-Campus) | Fresher | 2026
Salesforce SMTS | Interview Experience | Rejected
JPMC | SDE2 (Associate) - Java Backend - Interview Experience + Compensation
Microsoft - SDE2 - Coding Round
tesco interview experience
Summary
This post details a system design interview experience at Tesco, where I was tasked with building a real-time analytics dashboard backend service that integrates data from multiple disparate internal services, handles various data formats and reliability issues, and provides an aggregated API endpoint.
Full Experience
You're developing a backend service for a real-time analytics dashboard that tracks user interactions across an e-commerce platform. Your service needs to:
- Process incoming event data from multiple sources
- Perform aggregation operations
- Provide API endpoints for the frontend dashboard with summarized data (given below)
Core Requirements:
Your service needs to fetch and combine data from three internal data sources:
- User Activity Service: Tracks page views, clicks, and session data
- Transaction Service: Tracks purchases, cart additions, and checkout events
- Inventory Service: Tracks product stock levels and alerts
Note that each service has different response characteristics, data formats, and reliability issues:
/**
* Fetches recent user activity data
* Returns detailed user interaction events
* High volume data, occasionally returns partial results
* ~150ms average response time with occasional spikes
*/
async function fetchUserActivity(timeWindow) {
return new Promise((resolve, reject) => {
const delay = 100 + Math.random() * 100; // 100-200ms
setTimeout(() => {
if (Math.random() < 0.15) {
// Sometimes returns partial data with an error flag
resolve({
events: generateRandomEvents(Math.floor(Math.random() * 10) + 5),
complete: false,
error: "Service degraded, partial data returned"
});
} else if (Math.random() < 0.05) {
// Occasionally fails completely
reject(new Error("User activity service temporarily unavailable"));
} else {
resolve({
events: generateRandomEvents(Math.floor(Math.random() * 20) + 10),
complete: true
});
}
}, delay);
});
function generateRandomEvents(count) {
const events = [];
const eventTypes = ["page_view", "click", "scroll", "search"];
for (let i = 0; i < count; i++) {
events.push({
eventId: `evt-${Math.random().toString(36).substring(2, 10)}`,
userId: `user-${Math.floor(Math.random() * 1000)}`,
type: eventTypes[Math.floor(Math.random() * eventTypes.length)],
timestamp: Date.now() - Math.floor(Math.random() * 60000),
data: {
page: Math.random() < 0.5 ? "/products" : "/checkout",
duration: Math.floor(Math.random() * 300)
}
});
}
return events;
}
}
/**
-
Fetches recent transaction data
-
Returns financial transaction information
-
Slower but fairly reliable service
-
Data format differs from user activity
*/
async function fetchTransactions(timeWindow) {
return new Promise((resolve, reject) => {
const delay = 200 + Math.random() * 150; // 200-350ms
setTimeout(() => {
if (Math.random() < 0.08) {
reject(new Error("Transaction service unavailable"));
} else {
const transactions = [];
const count = Math.floor(Math.random() * 8) + 2;
for (let i = 0; i < count; i++) {
transactions.push({
transactionId: `tx-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`,
customerData: {
id: `user-${Math.floor(Math.random() * 1000)}`,
},
amount: +(Math.random() * 200 + 10).toFixed(2),
status: Math.random() < 0.9 ? "completed" : "pending",
items: Math.floor(Math.random() * 5) + 1,
createdAt: new Date(Date.now() - Math.floor(Math.random() * 3600000)).toISOString()
});
}
resolve({
data: transactions,
meta: {
total: transactions.length,
timeframe: timeWindow
}
});
}
}, delay);
});
}
/**
-
Fetches inventory status updates
-
Returns stock level alerts and changes
Fast but returns data in a completely different structure */ async function fetchInventoryAlerts(urgencyLevel = "all") { return new Promise((resolve, reject) => { const delay = 50 + Math.random() * 100; // 50-150ms setTimeout(() => { if (Math.random() < 0.1) { reject(new Error("Inventory service connection refused")); } else { // Returns XML-like string that needs parsing const alertCount = Math.floor(Math.random() * 5); let xmlResponse =
<inventory-alerts generated="${new Date().toISOString()}" count="${alertCount}">;for (let i = 0; i < alertCount; i++) { const productId = Math.floor(Math.random() * 1000); const currentStock = Math.floor(Math.random() * 10); const threshold = 5; const urgency = currentStock < 2 ? "high" : "medium"; if (urgencyLevel === "all" || urgencyLevel === urgency) { xmlResponse += ` <alert type="stock" urgency="${urgency}"> <product id="${productId}" /> <current-stock>${currentStock}</current-stock> <threshold>${threshold}</threshold> <location warehouse="${Math.floor(Math.random() * 5) + 1}" /> </alert> `; } } xmlResponse += '</inventory-alerts>'; resolve(xmlResponse); } }, delay);}); }
Task:
Create an Express.js API endpoint that:
- Implements a GET /api/dashboard endpoint that accepts a timeWindow query parameter (e.g., "15m", "1h", "24h")
- Fetches data from all three services concurrently
- Handles the different response formats, error scenarios, and partial data
- Aggregates the data into a unified dashboard response
- Implements proper timeout handling (maximum 300ms total response time)
Sample response :
{
"dashboard": {
"timeWindow": "15m", // or whatever was requested
"summary": {
"activeUsers": 42,
"revenueTotal": 1234.56,
"conversionRate": 2.7,
"inventoryAlerts": 3
},
"details": {
"userActivity": {
// Processed user activity data
"complete": true|false,
// Additional details
},
"transactions": {
// Processed transaction data
// Additional details
},
"inventory": {
// Processed inventory data
// Additional details
}
},
"status": {
"servicesResponded": ["userActivity", "transactions", "inventory"],
"servicesFailed": [],
"responseTime": 298
}
}
}
Interview Questions (1)
You're developing a backend service for a real-time analytics dashboard that tracks user interactions across an e-commerce platform. Your service needs to:
- Process incoming event data from multiple sources
- Perform aggregation operations
- Provide API endpoints for the frontend dashboard with summarized data (given below)
Core Requirements:
Your service needs to fetch and combine data from three internal data sources:
- User Activity Service: Tracks page views, clicks, and session data
- Transaction Service: Tracks purchases, cart additions, and checkout events
- Inventory Service: Tracks product stock levels and alerts
Note that each service has different response characteristics, data formats, and reliability issues:
/**
* Fetches recent user activity data
* Returns detailed user interaction events
* High volume data, occasionally returns partial results
* ~150ms average response time with occasional spikes
*/
async function fetchUserActivity(timeWindow) {
return new Promise((resolve, reject) => {
const delay = 100 + Math.random() * 100; // 100-200ms
setTimeout(() => {
if (Math.random() < 0.15) {
// Sometimes returns partial data with an error flag
resolve({
events: generateRandomEvents(Math.floor(Math.random() * 10) + 5),
complete: false,
error: "Service degraded, partial data returned"
});
} else if (Math.random() < 0.05) {
// Occasionally fails completely
reject(new Error("User activity service temporarily unavailable"));
} else {
resolve({
events: generateRandomEvents(Math.floor(Math.random() * 20) + 10),
complete: true
});
}
}, delay);
});
function generateRandomEvents(count) {
const events = [];
const eventTypes = ["page_view", "click", "scroll", "search"];
for (let i = 0; i < count; i++) {
events.push({
eventId: `evt-${Math.random().toString(36).substring(2, 10)}`,
userId: `user-${Math.floor(Math.random() * 1000)}`,
type: eventTypes[Math.floor(Math.random() * eventTypes.length)],
timestamp: Date.now() - Math.floor(Math.random() * 60000),
data: {
page: Math.random() < 0.5 ? "/products" : "/checkout",
duration: Math.floor(Math.random() * 300)
}
});
}
return events;
}
}
/**
-
Fetches recent transaction data
-
Returns financial transaction information
-
Slower but fairly reliable service
-
Data format differs from user activity
*/
async function fetchTransactions(timeWindow) {
return new Promise((resolve, reject) => {
const delay = 200 + Math.random() * 150; // 200-350ms
setTimeout(() => {
if (Math.random() < 0.08) {
reject(new Error("Transaction service unavailable"));
}
else {
const transactions = [];
const count = Math.floor(Math.random() * 8) + 2;
for (let i = 0; i < count; i++) {
transactions.push({
transactionId: `tx-${Date.now()}-${Math.random().toString(36).substring(2, 7)}`,
customerData: {
id: `user-${Math.floor(Math.random() * 1000)}`,
},
amount: +(Math.random() * 200 + 10).toFixed(2),
status: Math.random() < 0.9 ? "completed" : "pending",
items: Math.floor(Math.random() * 5) + 1,
createdAt: new Date(Date.now() - Math.floor(Math.random() * 3600000)).toISOString()
});
}
resolve({
data: transactions,
meta: {
total: transactions.length,
timeframe: timeWindow
}
});
}
}, delay);
});
}
/**
-
Fetches inventory status updates
-
Returns stock level alerts and changes
Fast but returns data in a completely different structure */ async function fetchInventoryAlerts(urgencyLevel = "all") { return new Promise((resolve, reject) => { const delay = 50 + Math.random() * 100; // 50-150ms setTimeout(() => { if (Math.random() < 0.1) { reject(new Error("Inventory service connection refused")); } else { // Returns XML-like string that needs parsing const alertCount = Math.floor(Math.random() * 5); let xmlResponse =
<inventory-alerts generated="${new Date().toISOString()}" count="${alertCount}">;for (let i = 0; i < alertCount; i++) { const productId = Math.floor(Math.random() * 1000); const currentStock = Math.floor(Math.random() * 10); const threshold = 5; const urgency = currentStock < 2 ? "high" : "medium"; if (urgencyLevel === "all" || urgencyLevel === urgency) { xmlResponse += ` <alert type="stock" urgency="${urgency}"> <product id="${productId}" /> <current-stock>${currentStock}</current-stock> <threshold>${threshold}</threshold> <location warehouse="${Math.floor(Math.random() * 5) + 1}" /> </alert> `; } } xmlResponse += '</inventory-alerts>'; resolve(xmlResponse); } }, delay);}); }
Task:
Create an Express.js API endpoint that:
- Implements a GET /api/dashboard endpoint that accepts a timeWindow query parameter (e.g., "15m", "1h", "24h")
- Fetches data from all three services concurrently
- Handles the different response formats, error scenarios, and partial data
- Aggregates the data into a unified dashboard response
- Implements proper timeout handling (maximum 300ms total response time)
Sample response :
{
"dashboard": {
"timeWindow": "15m", // or whatever was requested
"summary": {
"activeUsers": 42,
"revenueTotal": 1234.56,
"conversionRate": 2.7,
"inventoryAlerts": 3
},
"details": {
"userActivity": {
// Processed user activity data
"complete": true|false,
// Additional details
},
"transactions": {
// Processed transaction data
// Additional details
},
"inventory": {
// Processed inventory data
// Additional details
}
},
"status": {
"servicesResponded": ["userActivity", "transactions", "inventory"],
"servicesFailed": [],
"responseTime": 298
}
}
}