Interview guides · Bse Global
Bse Global Software Engineer Interview Guide
Bse Global Software Engineer interview guide: 3 reported rounds, 15 reported questions, ticketing system design and a 7-day prep plan.
The 60-second brief
Bse Global builds technology for sports, entertainment and live-event audiences. Candidates describe Software Engineer work on systems such as ticketing, streaming and fan engagement platforms, carried out alongside product managers, designers and other engineers. The reported responsibilities are writing and testing application code, taking part in code reviews, helping shape the design of new systems and features, and debugging problems as they surface.
This guide is for Software Engineer candidates. The requirements candidates describe are Java, Python or JavaScript, web frameworks and database work, algorithms, data structures and system design, and familiarity with Agile; cloud services, data analytics or machine learning, and DevOps are listed as extras. The experience level described is roughly 2-5 years. The guide covers all three reported stages and the fifteen reported questions, spanning databases, cloud experience, code quality, REST, data structures, ticket-sales and API design, microservices, performance diagnosis, two coding problems and three behavioral prompts.
Candidates report three stages over roughly 3-5 weeks: a Phone Screen, a Technical Assessment and In-Person Interviews. The final stage is described as several interviews covering technical skills and cultural fit.
Focus areas
- Software Engineering
- Interview Process
- Candidate Experience Management
Overview
The reported question set tells you where to spend time. Five questions are fundamentals that a working engineer should answer from experience: how relational and non-relational databases differ, cloud platforms you have used, how you keep code maintainable, what makes a REST API well designed, and how data-structure choices trade off. Three are design questions with a clear product flavour: handling real-time ticket sales for a major event, designing an API for a fan engagement platform, and what to weigh when splitting a system into microservices.
Two reported questions are diagnostic: how you would investigate user-facing performance problems, and how you would optimise an existing application. Both reward a fixed method (measure, locate the bottleneck, change one thing, measure again) over a list of tricks. Two are coding questions: finding the longest substring with no repeated characters, and a sorting or searching problem that you explain as you solve it. The remaining three are behavioral: a significant project challenge, handling team conflict, and what motivates you.
Because the role description mentions ticketing, streaming and fan engagement, it pays to rehearse the ticket-sales design until you can draw it from memory: inventory that cannot be oversold, a burst of traffic when sales open, temporary holds on seats, payment confirmation that survives retries, and what the user sees when a dependency is slow. The same reasoning carries over to the fan engagement API and the microservices question.
The reports do not say whether the Technical Assessment is live or done on your own time, and they do not say which questions belong to which stage. Prepare every category and pick one of the listed languages (Java, Python or JavaScript) as your coding language early, so the time you spend practising goes into problems rather than syntax.
The Bse Global interview process
These are the stages candidates describe, in the order they report them. The reports give a total span of about 3-5 weeks and do not publish per-stage durations or a fixed question list.
Phone Screen
Candidates describe the Phone Screen as an opening call about your background and how well you fit the Software Engineer role. No technical exercise is reported for it, so treat it as the place where your experience has to line up with the requirements candidates describe: one of Java, Python or JavaScript, web frameworks, database work, algorithms and system design, and Agile ways of working. Go in with two or three projects you can describe precisely, and with one honest sentence on why sports, entertainment and live events interest you.
What to demonstrate
- Your background as it relates to the Software Engineer role
- Fit between your experience and the listed requirements
- How clearly you describe work you have done
How to prepare
- Pick two or three projects and write down for each the problem, your own contribution, the stack (language, framework, database) and one measurable outcome.
- Map your experience against the listed requirements and note any gap, such as no cloud or DevOps exposure, with a truthful sentence about how you would close it.
- Prepare a specific reason for wanting this domain, for example a ticketing, streaming or audience-facing system you have used or built.
- Ask the recruiter what format the Technical Assessment takes and which language you may use.
Technical Assessment
Candidates describe the Technical Assessment as an evaluation of technical skills through coding challenges or assessments. The reports do not say whether it is live, timed online or take-home, so prepare for both: write working code in one language, and be ready to explain it aloud. The reported coding questions are the longest substring without repeated characters and a sorting or searching problem explained step by step; the reported fundamentals include database types, REST principles and data-structure trade-offs.
What to demonstrate
- Technical skill demonstrated through coding challenges or assessments
- Working code in a language you choose from those the role lists
- Reasoning about algorithm and data-structure trade-offs
How to prepare
- Solve the longest-unique-substring problem with a sliding window and a map of last-seen positions, then state O(n) time and the bound on extra space.
- Pick one sorting or searching problem (binary search on a rotated array, merging intervals, top-k) and practise explaining the brute force, the improvement and the edge cases aloud.
- Write short answers for the data-structure trade-offs question: array versus linked list, hash map versus balanced tree, heap versus sorted array.
- Practise writing code without autocomplete in your chosen language, including tests for empty and single-element input.
In-Person Interviews
Candidates describe In-Person Interviews as several interviews that cover technical skills and cultural fit. Prepare the design and diagnosis material here: real-time ticket sales for a major event, an API for a fan engagement platform, microservice trade-offs, finding the cause of user performance problems and optimising an existing application. Prepare behavioral stories too, since cultural fit is part of what is described: a significant project challenge, a team conflict and what motivates you.
What to demonstrate
- Technical skill across design, performance and coding topics
- Cultural fit, as candidates describe the stage
- Collaboration and communication, listed among the themes candidates mention
How to prepare
- Rehearse the ticket-sales design end to end: inventory, seat holds with expiry, a waiting room for the opening burst, idempotent purchase requests and payment reconciliation.
- Prepare a fixed performance method: reproduce, measure with metrics or a profiler, find the bottleneck, change one thing, measure again.
- Write four behavioral stories with your own role and a result in each, and be able to compress each to a short version.
- Prepare questions for the people you meet about how teams split work between product managers, designers and engineers.
Where candidates lose points
Designing ticket sales as plain CRUD and never saying how oversell is prevented
State the invariant first: a seat or ticket is sold at most once. Then show how you protect it, for example an atomic conditional update on inventory, a hold with an expiry, and an idempotent purchase request. Add a waiting room or queue for the moment sales open.
Submitting only the brute-force solution to the longest-unique-substring problem, or skipping edge cases
Say the O(n^2) or worse version, then move to a sliding window with a map from character to last index and move the left edge forward. Test with an empty string, one character, all identical characters and a repeat that sits before the current window.
Answering the performance questions with a list of fixes before measuring anything
Open with what you would collect: which users, which endpoints, since when, percentile latencies, and what changed. Locate the bottleneck (database query, network, memory, front end) with a profiler or traces, change one thing, and re-measure. Name a concrete example such as a missing index or an N+1 query.
Listing cloud product names when asked about experience
Describe one system you owned: what ran where, one trade-off you decided, and one problem in operation. Say clearly where your experience stops.
Behavioral stories that say the team did everything and end without a result or a lesson
Write each story with your own decision, the evidence behind it, a result you can state and one thing you would change. Practise the conflict story so that it is about the problem and its resolution, not the other person.
Questions & practice
What are the trade-offs between different data structures in algorithm design?
Medium · Technical / Domain Questions
Approach
- Frame the answer by access pattern, then compare costs. Dynamic arrays give O(1) indexing, amortised O(1) append and O(n) insertion in the middle, with good cache locality. Linked lists insert or delete in O(1) when you already hold the node, but access is O(n) and locality is poor, so arrays often win in practice.
- Hash maps give average O(1) lookup and insertion, with no ordering and extra memory per entry. The worst case on collisions is O(n), although Java 8+ HashMap turns large buckets into trees, giving O(log n). Balanced BSTs (Java TreeMap, a red-black tree) cost O(log n) per operation but give sorted iteration, range queries and floor/ceiling lookups.
- Heaps give O(1) peek at the minimum or maximum, O(log n) push and pop, and O(n) heapify. For top-k from n items, a size-k heap costs O(n log k), which beats sorting everything when k is much smaller than n.
- Mention the specialised structures and when each fits: stacks and queues for LIFO/FIFO processing and BFS, deques for sliding-window maximums, tries for prefix lookups in O(length of the key), and graph representations, where an adjacency list uses O(V + E) memory and an adjacency matrix O(V^2) but answers an edge lookup in O(1).
- Tie it to an example: a live leaderboard that needs updates, top-k and a user's rank calls for an ordered structure such as a balanced tree or skip list (a Redis sorted set does ZADD in O(log n)), not a hash map that you sort on every read.
Follow-up
- Design an LRU cache with O(1) get and put. Which structures do you combine, and why?
- When would a sorted array with binary search beat a hash map despite the worse asymptotic lookup?
- How does your choice change if the data no longer fits in memory?
Write a function to find the longest substring within a given string that contains only unique characters.
Medium · Coding / Algorithms
Approach
- Clarify the output (length or the substring itself), the character set (ASCII, or full Unicode) and the empty input, which returns 0 or an empty string. State the brute force: check every substring with a set, O(n^3), or O(n^2) if you extend each start incrementally.
- Use a sliding window with a map from character to last index seen. For each right index, if the character was last seen at an index >= left, move left to that index + 1. Then record the character's new index and update best = max(best, right - left + 1).
- Watch the main trap: left must never move backwards. On "abba", at the final 'a' the stored index 0 is below left = 2, so left stays at 2. Use the >= left check or left = max(left, last + 1). Keep the start index of the best window so you can return the substring.
- Complexity: O(n) time, because each index enters the window once and left only moves forward. Space is O(min(n, alphabet size)). For a known small alphabet, an int array of size 128 or 256 can replace the map.
- Test cases to say out loud: "" gives 0, "a" gives 1, "bbbbb" gives 1, "abcabcbb" gives 3 ("abc"), "pwwkew" gives 3 ("wke"), "abba" gives 2.
Follow-up
- Change it to the longest substring with at most k distinct characters.
- How do you handle Unicode correctly, for example characters outside the BMP in Java strings?
- Return every longest substring rather than one. What changes?
Solve a problem related to sorting or searching algorithms and explain your thought process.
Medium · Coding / Algorithms
Approach
- Clarify the input first: is it already sorted, how big is it, are there duplicates, and is it a static array or a stream? If the input is sorted, reach for binary search, O(log n). Say the loop invariant, compute mid as lo + (hi - lo) / 2 to avoid integer overflow in Java or C++, and know the lower-bound form that finds the first occurrence.
- Know the sorting trade-offs. Quicksort averages O(n log n), is O(n^2) in the worst case, sorts in place and is not stable. Merge sort is O(n log n) in every case and stable, but uses O(n) extra memory. Heapsort is O(n log n) in place but not stable. Insertion sort is O(n^2) but fast on small or nearly sorted input. Counting and radix sort run in O(n + k) for bounded integer keys.
- Know what your language does. Python's sort is Timsort (stable and adaptive). Java's Arrays.sort uses dual-pivot quicksort for primitives and TimSort for objects. JavaScript's Array.prototype.sort has been stable since ES2019 but compares values as strings by default, so numbers need a comparator such as (a, b) => a - b.
- Recognise the common variants: binary search on the answer when a predicate is monotonic (for example the minimum capacity that ships everything in d days), search in a rotated sorted array, and k-th largest with a size-k heap (O(n log k)) or quickselect (O(n) average, O(n^2) worst).
- Talk through the edge cases while coding: an empty array, a single element, all duplicates, a target smaller or larger than every element, and an off-by-one in the loop condition (lo < hi versus lo <= hi).
Follow-up
- The data does not fit in memory. How do you sort it? (external merge sort)
- Why does sort stability matter when you sort records by a second key?
- Find the first and last position of a target in a sorted array with duplicates in O(log n).
Find version gaps and relay lag with window functions
Medium · window functions · event tables · frame semantics
outbox_event holds event_id, aggregate_type, aggregate_id, aggregate_version, event_type, payload, status ('pending','published','dead'), attempts, created_at, published_at. A projection is missing rows and you must decide whether the relay skipped events or the consumer dropped them. Write three queries over the last seven days: one listing every aggregate_id whose published aggregate_version sequence has a hole, one giving per-day counts with a running total, and one returning the newest published event per aggregate. For each, say where the window function is evaluated relative to WHERE and LIMIT. PostgreSQL 16.
Approach
- Gaps: compute lead(aggregate_version) OVER (PARTITION BY aggregate_id ORDER BY aggregate_version) in a subquery, then filter next_version <> aggregate_version + 1 in the outer query. Window functions are evaluated after WHERE, GROUP BY and HAVING and before the outer ORDER BY and LIMIT, so the predicate cannot sit in the same WHERE clause and PostgreSQL 16 has no QUALIFY.
- Say what the seven-day filter does to the answer: it truncates every partition, so the first row per aggregate has no predecessor inside the window and a hole spanning the boundary is invisible. Widen the window, or join to resource.version as the authority for the true maximum.
- Running total: SELECT date_trunc('day', created_at) AS d, count() AS n, sum(count()) OVER (ORDER BY date_trunc('day', created_at) ROWS UNBOUNDED PRECEDING). An aggregate inside a window call is legal because grouping runs before windowing. The grouping key is unique per row here so ROWS and RANGE agree, but write the frame anyway — over ungrouped rows with tied timestamps the default RANGE frame pulls in every peer row and the total jumps.
- Newest per aggregate: DISTINCT ON (aggregate_id) ... ORDER BY aggregate_id, aggregate_version DESC is the cheap PostgreSQL-only form when an index matches that order; row_number() OVER (PARTITION BY aggregate_id ORDER BY aggregate_version DESC) = 1 is the portable form and needs a subquery for the same evaluation-order reason as the gap query.
Follow-up
- Relay failover redelivers events. Does a duplicate break the gap query, and how would you detect one from this table alone?
- Turn the gap check into a continuous monitor rather than a query someone runs after an incident. What does it watch?
Write the update path that detects a concurrent edit
Medium · optimistic concurrency · transactional outbox · audit history
resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.
Approach
- One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
- Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
- State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
- Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.
Follow-up
- A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
- Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?
What are some key differences between relational and non-relational databases?
Medium · Technical / Domain Questions
Approach
- Start with the data model: relational stores keep rows in tables with a fixed schema, foreign keys and joins. Name the non-relational families separately, because they differ from each other: key-value (Redis, DynamoDB), document (MongoDB), wide-column (Cassandra) and graph (Neo4j).
- Compare guarantees. Relational engines give ACID transactions across many rows and tables. Many NoSQL stores make a single item or partition atomic and offer tunable or eventual consistency: Cassandra sets a consistency level per query, and DynamoDB reads are eventually consistent unless you ask for strong reads. MongoDB has supported multi-document transactions since 4.0, but its schemas are still designed around single-document atomicity.
- Compare scaling and querying. A relational database usually scales up and adds read replicas, and sharding needs extra tooling such as Vitess or Citus. Key-value and wide-column stores partition by key from the start, so you design the tables around known access patterns, and a query that does not use the partition key is expensive. SQL handles ad hoc joins and reporting much better.
- Finish with a concrete split. I would keep orders, payments and seat inventory in a relational database because double-selling is unacceptable there. Data with a high write rate and a simple shape, such as activity feeds, session state or cached seat-map snapshots, can go in a key-value or wide-column store.
- Cover schema change: a relational migration (ALTER TABLE, backfill) is explicit and checked, while a document store makes code handle old and new shapes when it reads them. Schema-on-read is flexible, but every reader then has to cope with every shape.
Follow-up
- When would you pick a document store for a new feature, and what would make you regret it a year later?
- How does the CAP theorem apply when a network partition splits a Cassandra or DynamoDB cluster?
- How would you run a reporting query across data that lives in a NoSQL store?
How do you ensure code quality and maintainability?
Medium · Technical / Domain Questions
Approach
- Start with automated gates in CI so nobody has to remember them: a formatter and linter (Black or ruff for Python, ESLint and Prettier for JavaScript, Checkstyle or Spotless for Java), static types where the language allows them (TypeScript, mypy), and a build that fails on warnings you have agreed to enforce.
- Describe the test strategy as a pyramid. Write many fast unit tests that check behaviour rather than private implementation, integration tests at the real boundaries (database, HTTP clients, queues), and a few end-to-end tests for the main user paths. Treat coverage as a signal of untested code, not as a target to game.
- Explain how you run code review: small pull requests with one purpose each, a description of why the change exists, and review comments that cover naming, error handling, missing tests and hidden coupling, not formatting the linter already checks.
- Name the design habits that keep code easy to change: single-responsibility modules, clear interfaces, dependency injection so collaborators can be swapped in tests, and refactoring in small steps under existing tests instead of big rewrites.
- Back it with one real example: a change you made (a flaky test you removed, a module you split, a lint rule you introduced) and what got measurably better afterwards. Without an example the answer sounds like a list of slogans.
Follow-up
- A senior colleague's pull request works but is hard to read. What do you do?
- How do you decide whether to refactor now or ship and log the debt?
- What is your view on a hard coverage threshold in CI?
Can you explain the principles of RESTful API design?
Medium · Technical / Domain Questions
Approach
- Model resources as nouns with stable URIs (/events/{id}/tickets), not verbs (/getTickets). List Fielding's constraints briefly: client-server, stateless, cacheable, uniform interface, layered system, and optionally code on demand.
- Get the method semantics right. GET is safe and idempotent. PUT replaces the whole resource and is idempotent. DELETE is idempotent. POST creates a resource or triggers an action and is not idempotent. PATCH is a partial update and is not guaranteed to be idempotent.
- Use status codes precisely: 200, 201 with a Location header, 204 for an empty success, 400 for a malformed request, 401 when the caller is unauthenticated and 403 when it is authenticated but not allowed, 404, 409 for a state conflict, 422 for a validation failure, and 429 with Retry-After. Return one consistent error body (a code, a message and the field details).
- Explain statelessness: every request carries its own credentials (for example a bearer token), so any server instance can handle it and the service scales horizontally. Add HTTP caching with Cache-Control and ETag/If-None-Match (304 Not Modified), and optimistic concurrency with If-Match, which returns 412 Precondition Failed when the version is stale.
- Cover the practical parts: cursor pagination rather than offset for large or changing lists, filtering and sorting through query parameters, and versioning (/v1 in the path or a media-type header) with additive, backward-compatible changes. Say that HATEOAS is part of strict REST but most production APIs leave it out.
Follow-up
- How do you make a POST that charges money safe to retry after a timeout?
- When would you use PUT and when PATCH, and what does each do to a field the client omits?
- How would you remove a field without breaking existing mobile clients?
Design a system to handle real-time ticket sales for a major event.
Medium · System Design / Architecture
Approach
- Pin down the requirements first: reserved seating or general admission, the expected peak at on-sale, how long a seat stays held at checkout, and the hard rule that a seat is never sold twice. That rule needs strong consistency on inventory writes, while browsing can tolerate stale data.
- Absorb the surge before it reaches inventory. Serve event pages from a CDN, put buyers in a virtual waiting room that admits them at a controlled rate with signed admission tokens, and add per-user and per-IP rate limits plus bot checks on the hold endpoint.
- Make holds atomic. Use a conditional update such as UPDATE seats SET status='HELD', hold_id=?, expires_at=? WHERE seat_id=? AND (status='AVAILABLE' OR expires_at < now()), and treat 0 rows affected as a lost race. Another option is Redis SET with NX and a TTL as the hold, with the database as the record of truth. Expired holds release the seat automatically.
- Run checkout as a state machine: HELD, then PAYMENT_PENDING, then SOLD, or back to AVAILABLE. Call the payment provider with an idempotency key, confirm the sale and write the order in one transaction, and use a transactional outbox to publish ticket-issued events. A reconciliation job uses the provider's webhooks to fix a payment that succeeded after the hold expired.
- Scale the read path separately. Seat-map availability is read-heavy, so serve it from a cache and push changes over WebSocket or SSE. Partition inventory by event, and split one very large event by section so a single hot partition does not become the bottleneck.
Follow-up
- The payment succeeds but your confirm write fails. What state is the seat in, and how do you recover?
- How do you stop bots from taking the best seats while staying fair to real buyers?
- What changes if the event uses general admission with a fixed count instead of numbered seats?
How would you approach designing an API for a fan engagement platform?
Medium · System Design / Architecture
Approach
- Agree the scope before drawing anything. I would ask which features are in play (profiles, following teams or artists, comments, live polls, notifications), who the clients are (mobile, web, partners) and what has to update live during an event.
- Lay out the resources and their contracts: /users/{id}, /teams/{id}/followers, /events/{id}/polls, /polls/{id}/votes, /users/{id}/feed. Use cursor pagination for feeds and comments, one shared error schema, and OAuth 2.0 bearer tokens with scopes for authentication.
- Make writes safe to retry. Enforce one vote per fan with a unique constraint on (poll_id, user_id) and expose it as an idempotent PUT /polls/{id}/votes/me. Accept an Idempotency-Key header on the POST endpoints that create comments.
- Split request/response from live updates. Use REST for CRUD and WebSocket or Server-Sent Events to push scores and poll results during a live event. For high-volume counters, use sharded counters or periodic aggregation instead of locking one row.
- Cover operations: per-user rate limits that return 429 with Retry-After, caching of popular read endpoints, a choice between fan-out on write and fan-out on read for the feed (fan-out on write is cheap to read but expensive for accounts with huge followings), and additive versioning so old app builds keep working.
Follow-up
- A poll gets a huge vote spike in the last minute of a game. What breaks first and how do you protect it?
- Would you use GraphQL instead of REST for the mobile app? What do you gain and what do you lose?
- How would you deprecate a feed field that older app versions still read?
What considerations would you take into account when designing a microservices architecture?
Medium · System Design / Architecture
Approach
- Draw service boundaries around business capabilities (for example inventory, payments, users, notifications), give each service its own data, and never let one service read another's tables. Say that for a small team a modular monolith is often the better start, and that shared databases plus synchronous call chains produce a distributed monolith.
- Choose how services communicate: synchronous REST or gRPC when the caller needs an answer now, asynchronous messaging (Kafka, RabbitMQ, SQS) for events and decoupling. Every remote call needs a timeout, retries with exponential backoff and jitter, and a circuit breaker so one slow dependency does not exhaust everyone's threads.
- Handle data consistency without distributed ACID transactions. Use a saga, either choreographed through events or run by an orchestrator, with compensating actions. Publish events reliably with a transactional outbox. Make consumers idempotent, because most brokers deliver at least once.
- Name the operational cost: service discovery, an API gateway for authentication and routing, an independent CI/CD pipeline per service, containers and an orchestrator such as Kubernetes, and observability through distributed tracing (OpenTelemetry), correlation IDs, centralised logs and per-service metrics.
- Keep contracts compatible: change APIs additively, use consumer-driven contract tests (for example Pact), and deploy so old and new versions run side by side. Close with the trade-off: independent deploys and scaling in exchange for network latency, partial failures and more infrastructure.
Follow-up
- How would you split an existing monolith, and which piece would you extract first?
- An order must reserve inventory and charge a card in two different services. Walk through the failure cases.
- When would you advise a team not to adopt microservices?
Given a specific scenario with user performance issues, how would you diagnose the problem?
Medium · Problem-Solving / Case Studies
Approach
- Scope the symptom before touching anything: which users (region, device, browser, app version), which pages or endpoints, and since when. Line the start time up against deploys, config changes, traffic spikes and dependency incidents. Describe latency with percentiles (p50, p95, p99), not averages.
- Find the layer, from outside in. On the client, check real-user monitoring, Core Web Vitals, bundle size and long tasks. On the network and CDN, check DNS, TLS and the cache hit ratio. On the server, use APM traces to see where request time goes. In the database, check the slow query log, EXPLAIN ANALYZE, lock waits and connection pool saturation. Then check downstream services.
- Apply a method rather than guessing: USE (utilisation, saturation, errors) for CPU, memory, disk and pools, and RED (rate, errors, duration) for each service. Look for GC pauses, thread or connection pool exhaustion and queue build-up.
- Check the usual culprits: N+1 queries, a missing index after data growth, a cache stampede when a popular key expires, unbounded payloads or pagination, and a slow third-party call made inline.
- Reproduce it, form one hypothesis, change one thing and verify against the same metric. Roll back first if the problem lines up with a deploy. Afterwards, add an alert or SLO on the metric that would have caught it sooner.
Follow-up
- The p50 is fine but the p99 has tripled. What does that suggest, and where do you look?
- You cannot reproduce the slowness locally. How do you proceed?
- How would you tell a slow database apart from an exhausted connection pool waiting on the database?
Outline your approach to optimizing an existing application for better performance.
Medium · Problem-Solving / Case Studies
Approach
- Measure before changing anything. Record a baseline with a profiler or APM, agree a target metric (for example p95 latency on the checkout endpoint, or time to interactive), and rank hotspots by share of total time. Amdahl's law limits the gain: speeding up a part that takes 10% of the time can never save more than 10%.
- On the backend, check the database first: add or fix indexes and confirm the change with EXPLAIN, remove N+1 queries by batching or joining, select only the columns you need, and paginate. Then add caching (cache-aside with a TTL and a clear invalidation rule), connection pooling, and background jobs for work the user does not need to wait for.
- On the code itself, replace quadratic loops with hash lookups, cut allocations and serialisation inside hot loops, and run independent I/O calls concurrently instead of one after another.
- On the frontend, use code splitting and lazy loading, compress images and serve them at the right size, serve static assets from a CDN with long-lived cache headers, and reduce the number of round trips.
- Verify under realistic load with k6, JMeter or Locust, compare against the baseline, and set a performance budget in CI so the gain does not slowly regress. State the trade-offs: caching brings staleness, and denormalisation brings write complexity.
Follow-up
- You have three candidate optimisations and time for one. How do you choose?
- How do you show that a new cache is helping and not just adding complexity?
- An optimisation made the median faster but the p99 worse. What might explain that?
Edge instances grow 400 MB per hour until the nightly restart
Hard · memory leak · heap analysis · metric cardinality
Edge API instances start at 700 MB resident and grow about 400 MB/hour; a nightly rolling restart has hidden it for weeks. Growth continues unchanged when request rate halves overnight, p99 degrades in the last hours before an instance is recycled, and heap used immediately after a forced full GC rises monotonically. The service holds no product state. Name the discriminating measurement that separates the plausible causes, give the most likely cause, and give the fix and how you would verify it.
Approach
- Separate resident memory from live heap first, because they fail differently. Resident size can grow from fragmentation, native buffers or thread stacks while the heap is flat; heap used after a full GC rising monotonically is the measurement that says objects are reachable and not being released. You already have it, so this is retention, not fragmentation, and that closes off half the candidate list.
- Use the rate's independence from traffic as the discriminator. Growth that continues at half the request rate rules out per-request objects that are merely slow to collect and points at a structure that grows with distinct values observed rather than with call volume. Write the candidates that have that property: a metrics registry keyed on a high-cardinality label, an unevicted cache, an interner, a per-key lock map.
- Take two heap snapshots an hour apart and diff by retained size, reading the dominator tree, not by allocation count or instance count. Expect one root holding a map with millions of entries, then follow the reference chain to the code that inserts and never removes. Allocation profilers point at churn, which is the wrong signal here.
- The candidate that fits this service is an observability label carrying an identifier, such as a request path recorded before templating so that /v1/resources/48213 becomes its own metric series. That grows with distinct ids seen, is independent of rate, and explains the late p99 degradation, since GC cost rises with the size of the live set.
Follow-up
- Post-GC heap is now flat but resident size still creeps. What are you looking at, and does it matter?
- How would you have detected this before an OOM, given the nightly restart masked the trend?
Suggested practice checklist
The plan follows the three reported stages and the fifteen reported questions: coding first, then data and API design, ticket-sales design, performance diagnosis, behavioral stories, and a full rehearsal. Practice-library drills are attached where they match a day's topic.
Day 1 — Map the loop and choose your language
- Write out the three reported stages (Phone Screen, Technical Assessment, In-Person Interviews) and list which reported questions you could answer well today.
- Choose Java, Python or JavaScript as your coding language and set up a file where you can run code without help from autocomplete.
- Compare your experience with the listed requirements (web frameworks, database work, algorithms, system design, Agile) and mark each as strong or weak.
Deliverable: A one-page map of the loop with the weakest topics marked, and a runnable practice file in your chosen language.
Day 2 — Coding: sliding window, sorting and searching
- Solve the longest substring without repeated characters with a sliding window and a last-seen map, then test empty, single-character and all-identical input.
- Solve one sorting or searching problem (for example binary search on a rotated array) and say aloud the brute force, the improvement and the complexity.
- Write a half-page comparing array, linked list, hash map, balanced tree and heap by lookup, insert, ordered iteration and memory.
Deliverable: Two working solutions with complexity notes and one data-structure comparison sheet.
Day 3 — Data stores and API design
- Write a comparison of relational and non-relational databases with one example workload for each, covering transactions, schema change, joins and scaling.
- Write the principles of REST (resources, verbs, status codes, statelessness, pagination, versioning) and apply them to a fan engagement API with idempotency keys on any write.
Deliverable: A database comparison sheet, an outline of a fan engagement API with error cases, and the finished concurrent-edit drill.
Day 4 — System design: ticket sales and microservices
- Design real-time ticket sales for a major event on paper: inventory store, seat holds with expiry, a waiting room for the opening burst, payment step, and what happens if payment confirmation arrives twice.
- List the considerations for splitting into microservices: service boundaries, data ownership, synchronous versus queued calls, failure handling, tracing and deployment.
- State where you accept stale data (for example browsing counts) and where you need strong consistency (the purchase itself).
Deliverable: One annotated architecture diagram for ticket sales and a one-page microservices checklist.
Day 5 — Performance diagnosis and code quality
- Write your fixed diagnosis sequence for user performance problems: scope, metrics, traces, bottleneck, one change, re-measure.
- Write an optimisation plan for an existing application covering database queries, caching, payload size and concurrency, with the evidence you would need for each.
Deliverable: A diagnosis checklist, an optimisation plan, a completed memory-growth drill and a short code-quality answer.
Day 6 — Behavioral stories
- Write a cloud-experience answer around one system you ran, with the platform, a trade-off and an incident.
- Write the significant-challenge story and the team-conflict story, each with your own decision, evidence, result and lesson.
- Write a motivation answer backed by a real project, then say all four aloud.
Deliverable: Four written stories and spoken versions of each.
Day 7 — Full rehearsal
- Give your project walk-through as for the Phone Screen and refine it.
- Redo the ticket-sales design from a blank page and the unique-substring solution from memory, speaking throughout.
- Answer one behavioral prompt and one performance question back to back, then list what to fix.
Deliverable: A rehearsal run with a list of three fixes.
Behavioural preparation
Candidates describe the In-Person Interviews as covering technical skills and cultural fit, and the reported behavioral prompts cover a project challenge, team conflict and motivation, with cloud experience asked as a background question. Prepare stories where you made a decision, say what you did in the first person, and finish with a result and a lesson. The role works with product managers, designers and other engineers, so choose examples that involve them.
- How do you approach giving and receiving feedback?
- How do you handle changes in project scope or direction?
Describe your experience with cloud-based services. Which platforms have you worked with?
Medium · Technical / Domain Questions
Approach
- Choose one system you actually ran in the cloud and describe it as a request path: where the code ran (virtual machines, containers or functions), where data lived (managed relational database, object storage, cache), how background work was queued, and how a release reached production.
- State the platforms in one sentence, then move to the story. AWS and Google Cloud are the two the role lists as a plus; say which services you configured yourself and which were managed for you. If you have used only one platform, say so and explain how you would map the same building blocks onto another.
- Include one decision with a trade-off you can defend, such as managed versus self-hosted database, autoscaling versus fixed capacity, or a queue between two services, and say what you measured: cost, latency, or operational effort.
- Cover operating it: monitoring and alerts, access control with least-privilege roles and no secrets in code, and one incident or cost surprise with what you changed afterwards. Do not claim depth you lack; a smaller true answer holds up better than a long list of product names.
Follow-up
- Why did you pick that service over the alternative you considered?
- How would that setup cope if traffic jumped tenfold for a single evening?
- What did it cost, and how did you keep the bill predictable?
Describe a time when you faced a significant challenge in a project. How did you overcome it?
Medium · Behavioral / Leadership
Approach
- Pick a project where the challenge was genuinely hard and your decisions mattered, not one you observed. Open with the situation and the stake in two sentences: what was at risk and by when.
- Spend most of the time on your reasoning: the options you weighed, what evidence you gathered (logs, a prototype, a benchmark, a conversation with a user or product manager), and why you chose the path you did.
- Say what you personally did, in the first person, and name who else was involved and what they contributed. Answers that stay at the level of what the team did leave the listener unable to tell what you did.
- Close with a result you can state in numbers or observable terms (error rate, latency, delivery date, tickets closed), then one thing you would do differently. A story with no cost, mistake or lesson sounds rehearsed.
Follow-up
- What was the hardest decision, and what did you rule out?
- How did you know your fix caused the improvement?
- What would you do differently if the same situation came back?
How do you handle conflicts within a team?
Medium · Behavioral / Leadership
Approach
- Choose a real disagreement about substance, such as an API shape, a review comment, a scope cut or a deadline, rather than a personality clash. Describe the positions of both sides fairly, in a sentence each.
- Show the steps you took: you asked questions until you could restate the other view, moved the discussion from opinion to evidence (a quick prototype, a benchmark, the requirement from a product manager), and agreed who would make the call if evidence did not settle it.
- Describe the outcome and the working relationship after it. If you were wrong, say so; a story where you simply won teaches the listener little. If you disagreed and committed, show that you carried out the decision fully.
- Avoid blaming a named person, and avoid the answer that you do not have conflicts. Keep escalation to a manager as a step you took after direct conversation, with a reason for it.
Follow-up
- What if the other person still disagreed after seeing the evidence?
- Tell me about a time you changed your mind in a disagreement.
- How do you raise a concern in a code review without it turning personal?
What motivates you to perform well in your role?
Medium · Behavioral / Leadership
Approach
- Give a specific, honest driver rather than a slogan. Examples that work are seeing real users depend on something you shipped, solving problems under live load, improving a codebase so the next person moves faster, or learning a new area. Pick the one that is true for you.
- Back it with evidence from a past project: the moment you noticed you were most engaged, what you did that others might not have bothered with, and the result.
- Connect it to this role without inventing facts about the company: the role description mentions sports, entertainment and live events and ticketing, streaming or fan engagement systems, so say plainly if building products for audiences is part of what draws you.
- Be ready for the low side as well: what drains your motivation (for example unclear ownership or repeated rework) and what you do about it. Naming compensation or title alone as the driver gives the listener nothing to remember.
Follow-up
- Tell me about a time your motivation dropped and what you did.
- What kind of work do you find least engaging?
- How would the work on this team match what drives you?