Interview guides · airtel
airtel Software Engineer Interview Guide
Prepare for the airtel Software Engineer interview: 5 reported rounds, DSA, Core Java, networks and design questions, and a 7-day plan.
The 60-second brief
Candidates describe airtel as a telecommunications and digital services provider, with engineering work spread across units such as Airtel Digital, Airtel X Labs and Airtel Payments Bank, and consumer products including Wynk Music and Airtel Xstream. Candidates describe software engineers building backend microservices, real-time event pipelines, and web and mobile apps. The work they mention includes subscriber management, billing, payment gateways and network routing automation. The stack named for the role is Java with Spring Boot on the backend, Kafka for event streaming, Redis for caching, MySQL, PostgreSQL and MongoDB for storage, React on the web, and Kotlin or Swift on mobile.
This guide is for candidates interviewing for Software Engineer roles at airtel. Candidates mention levels from SDE-1 through SDE-2 and SDE-4. It covers the online assessment, the technical interviews, the low-level and high-level design stage, the techno-managerial discussion and the HR session. Backend candidates should concentrate on DSA, Core Java and concurrency, SQL, computer networks, operating systems and design. Candidates applying to web or mobile teams should also work through the React, JavaScript, Android and SwiftUI questions, which are reported for those specialisations. Every reported question has its own approach and possible follow-ups below.
Candidates report five stages: an Online Technical Assessment, Technical Interview Rounds, Design Evaluations, a Techno-Managerial Discussion and an HR Session. Reported timelines range from one to three weeks up to roughly four to six weeks, and weekend hiring drives can fit the technical rounds into a single day.
Focus areas
- Data Structures & Algorithms (DSA)
- Java (Core Java / OOP)
- Computer Networks (CN)
Overview
The day-to-day work candidates describe is backend services in Java and Spring Boot, with Kafka pipelines, Redis caches and relational databases behind them, plus React, Kotlin and Swift for teams that ship user-facing apps. The reported topic breakdown puts Data Structures & Algorithms first, followed by Core Java and OOP, Computer Networks, OOP concepts and general problem solving. For most backend candidates that means three areas: algorithm fluency, Java runtime internals you can explain mechanically, and enough networking to map protocols to layers and walk through a TLS handshake.
The 26 reported questions fall into five groups. Six are algorithm problems: level-order traversal, Dutch National Flag, maximum path sum in a binary tree, sorting a linked list, moving zeros, and permutations. Five are Core Java: HashMap internals, static versus dynamic polymorphism, garbage collection and G1GC, synchronized and volatile, and SOAP versus REST. Five are design: an LRU cache, a railway booking LLD in the style of IRCTC, a Wynk-like music streaming service, a web crawler, and background audio playback in a mobile app. Five cover networks and OS: OSI layers, HTTPS and TLS, hubs, switches and routers, processes versus threads, and IP addressing with NAT, BGP and OSPF. The last five are frontend and mobile questions for web or mobile specialisations.
Your level changes what to prepare. Candidates report that SDE-1 candidates are assessed mainly on DSA, core CS and low-level object-oriented design, and that high-level distributed design comes in from SDE-2 upward. The online assessment is described for entry and intermediate roles and includes quantitative aptitude along with coding, so fresh graduates should practise aptitude problems as well as code.
Candidates also report technical deep dives built around the projects and technologies on their resume, and several smaller reported prompts point at backend fundamentals: finding duplicate customer records with GROUP BY and HAVING, putting Redis caching in front of a Spring Boot service, SQL joins and transaction isolation levels. Prepare a two-minute career overview, and be ready to defend every framework on your resume down to how it behaves at runtime.
The airtel interview process
These five stages come from candidate reports, not from a published process. The reported overview also says the number of stages varies between two and four with the hiring route (campus, lateral or referral), and that stages may run virtually or as weekend hiring drives.
Online Technical Assessment
Candidates describe the Online Technical Assessment as the first screen, reported mainly for entry-level and intermediate roles. Candidates report that it tests three things under timed conditions: quantitative aptitude, computer science fundamentals and hands-on coding. Little more is reported about its content, so prepare each part separately. For aptitude, build speed on the common problem types. For fundamentals, a sensible general review covers OS, networking, DBMS and OOP basics, since the reported technical questions draw on several of those areas. For coding, get a correct solution submitted before polishing it, and test it on empty input, single elements and duplicates before you submit.
What to demonstrate
- Coding proficiency under timed conditions
- Quantitative aptitude
- Computer science fundamentals
How to prepare
- Solve the Dutch National Flag and move-zeros problems from memory in your chosen language, each in one pass with O(1) extra space
- Do timed sets of aptitude problems (percentages, ratios, time and work, probability) until the common types feel routine
- As general review, write one-line definitions for OS, networking and DBMS terms: deadlock conditions, paging, OSI layers, normal forms, ACID
- Practise level-order traversal and linked-list sorting until both compile and pass edge cases on the first run
Technical Interview Rounds
Candidates report that the Technical Interview Rounds cover algorithmic problem solving, core language fundamentals and the architecture of past projects. Reported tips say interviewers build deep dives around the technologies and patterns listed on your resume. Candidates can usually code in their preferred language, but Java is described as heavily used in airtel's backend systems, so backend candidates who choose Java should be ready for follow-ups on its runtime. Say your approach and its complexity out loud before you write code. Then write it cleanly and trace it on a small example. For the project part, prepare one system you built in enough detail to draw its components, its data flow and the bottleneck you fixed.
What to demonstrate
- Working, complexity-aware code for tree, array, linked-list and recursion problems
- Depth in core language mechanics, especially Java collections, the JVM and concurrency
- Ability to explain the architecture and trade-offs of projects on your resume
How to prepare
- Rehearse the maximum path sum, linked-list merge sort and permutations problems aloud, stating time and space complexity for each
- Write a one-page explanation of Java 8 HashMap (hashing, resize, treeify thresholds) and of synchronized versus volatile, then explain each without notes
- Pick two resume projects and write a component diagram, the data stores used, and one latency or reliability improvement with a number attached
- Review SQL joins, GROUP BY with HAVING, isolation levels, and Spring Boot basics: dependency injection, @Transactional proxies and @Cacheable backed by Redis
Design Evaluations
Candidates report Design Evaluations covering both low-level and high-level design, aimed at senior engineering levels. SDE-1 candidates report a focus on low-level object-oriented design, while SDE-2 and above get high-level distributed design. The reported design questions are the ones to practise for this stage: an LRU cache, a railway booking system LLD with seat locking, a music streaming service, a web crawler, and a mobile app with background audio. Reported tips recommend clarifying non-functional requirements (latency, throughput, availability) before drawing data models, and explaining single points of failure, consistency and cache invalidation for any distributed component you add. For LLD, name the classes, their relationships and the concurrency control. For HLD, size the read and write paths and say where Kafka or Redis fits and why.
What to demonstrate
- Low-level object-oriented design: entities, interfaces, design patterns and concurrency handling
- High-level design: service decomposition, caching, messaging, data partitioning and failure handling
- Clarifying requirements before committing to a design
How to prepare
- Write the IRCTC-style booking LLD as class definitions, including how two users trying to book the same seat are resolved
- Code an LRU cache with a HashMap and a doubly linked list, then explain the LinkedHashMap shortcut and how you would make it thread-safe
- Sketch the streaming service and the web crawler end to end, marking every single point of failure, how each recovers, and where Kafka partitions and consumer groups fit
- Review Factory, Singleton, Strategy and Observer with one concrete use of each inside these designs
Techno-Managerial Discussion
Candidates describe the Techno-Managerial Discussion as covering both the technical and the managerial sides of the role. Little more is reported about its format, so prepare for a mix of a technical walk-through of your work and questions about how you operate on a team. The reported preparation tips point at owning services, collaborating, and showing the business effect of engineering decisions such as lower latency or better reliability. Bring two or three stories with measurable outcomes, and be ready to go back into technical detail on any of them.
What to demonstrate
- The technical and managerial sides of the role, which candidates report the discussion covers
- Ownership of past systems, which the reported preparation tips stress
- Collaboration and the business impact of engineering work, also named in the reported tips
How to prepare
- Write three STAR stories: a latency or reliability improvement, a production incident you handled, and a disagreement about a technical decision
- Attach a number to each story (latency drop, error rate, users affected, time to recover)
- Prepare a short explanation of why you chose the stack in your main project and what you would change now
HR Session
Candidates describe the HR Session as the final stage, covering the offer and company culture. Candidates also say the work setup varies by team and location; the hubs they name are Gurgaon, Noida and Bengaluru, and the arrangement reported there is hybrid. Settle your location preference, notice period and level expectations before this conversation, and have a few questions ready about the team and product area you would join.
What to demonstrate
- The offer, which candidates report is discussed here
- Company culture, which candidates report the session covers
How to prepare
- Decide your preferred location among the reported hubs and how much hybrid flexibility you need
- Prepare questions about the team, whether it sits in a unit like Airtel Digital, Airtel X Labs or Airtel Payments Bank, and its on-call expectations
- Have a clear answer on notice period, joining date and the level you are targeting
Where candidates lose points
Advancing the middle pointer after swapping with the high end in the Dutch National Flag problem, or losing track of what each pointer guarantees.
Before coding any partition problem, write the invariants as comments: what is known to be left of low, between low and mid, and right of high. Then trace [2,0,1] and [2,2,0,0] by hand. The same discipline fixes the move-zeros write index and the slow and fast pointers in linked-list merge sort.
Describing Java HashMap as 'an array of linked lists' and stopping there, or confusing it with ConcurrentHashMap.
Java runtime knowledge is reported as heavily tested, so learn the mechanics with their numbers: power-of-two table, hash spreading, 0.75 load factor, doubling with the lo and hi split, treeify once a bin grows past 8 nodes when capacity is at least 64, untreeify at 6, and the Comparable-key caveat on O(log n). Prepare the same depth for G1 regions and pause targets, and for the visibility versus atomicity distinction between volatile and synchronized.
Drawing Kafka, Redis and a load balancer in the streaming or crawler design without saying what happens when each one fails or goes stale.
Reported tips warn against adding distributed components without covering single points of failure, consistency and cache invalidation. For each box you add, state its failure mode, what the user sees, and how it recovers. In the railway booking LLD, have an exact answer for two users holding the same seat: a conditional update or version check, a hold expiry, and an idempotent confirm.
Listing frameworks and projects on the resume that you cannot explain beneath the surface.
Candidates report deep dives built around whatever their resume cites. For every technology listed (Spring Boot, Kafka, Redis, React), prepare how you used it, one configuration decision you made, and one problem it caused. Remove anything you could not discuss for ten minutes.
Preparing only DSA and skipping networking and OS, then stumbling over OSI mapping, the TLS handshake or NAT.
Computer Networks appears in the reported topic breakdown, and five reported questions cover networks and OS. Spend a full study day on them: map protocols to layers, walk a TLS 1.2 handshake message by message and the TLS 1.3 change, subnet a /24 by hand, and explain a context switch and IPC options. These questions are short, so a vague answer stands out.
Questions & practice
Write an efficient algorithm to traverse a binary tree in level order and print nodes level by level.
Medium · Data Structures & Algorithms
Approach
- Use BFS with a queue. Start with the root (return nothing if it is null). At each iteration, read the current queue size k, then poll exactly k nodes and print or collect them. That snapshot of the queue size is what separates one level from the next.
- Enqueue left then right children of each polled node, skipping nulls. Each node is enqueued and dequeued once, so time is O(n) and space is O(w), where w is the maximum width (up to about n/2 for a complete tree).
- Alternatives worth naming: two queues swapped per level, a null sentinel marking the end of each level, or DFS that carries depth and appends into result[depth]. The DFS version uses O(h) stack and gives the same output.
- Edge cases: empty tree, a single node, and a fully skewed tree, where each level has one node and the queue never holds more than two.
Follow-up
- Print the levels in zigzag order, alternating direction each level.
- Return the right-side view or the bottom view of the tree.
- Return the average value of each level, and say what overflow risk the sum has.
Given an array containing 0s, 1s, and 2s, sort the array in linear time using constant space (Dutch National F
Medium · Data Structures & Algorithms
Given an array containing 0s, 1s, and 2s, sort the array in linear time using constant space (Dutch National Flag problem).
Approach
- Use three pointers: low = 0, mid = 0, high = n-1. Invariants: a[0..low) are 0s, a[low..mid) are 1s, a(high..n-1] are 2s, and a[mid..high] is unprocessed.
- While mid <= high: if a[mid] == 0, swap with a[low] and increment low and mid. If a[mid] == 1, increment mid. If a[mid] == 2, swap with a[high] and decrement high only, because the element swapped in from high has not been examined yet.
- One pass, O(n) time, O(1) space. A two-pass counting sort (count 0s, 1s, 2s, then overwrite) is also O(n) and O(1). Mention it, but the one-pass partition is what the question asks for.
- Test on empty, all one value, [2,0,1], [2,2,0,0] and [1,0]. The classic bug is advancing mid after swapping with high.
Follow-up
- Is this sort stable, and does that matter for plain integers?
- How does this three-way partition help quicksort on inputs with many duplicate keys?
- Generalise to k distinct values: what does it cost in passes or space?
Implement a function to find the maximum path sum in a binary tree.
Medium · Data Structures & Algorithms
Approach
- Do a post-order DFS that returns the best downward gain from a node: gain(node) = node.val + max(0, gain(left), gain(right)). Clamping a child's gain at 0 means a negative branch gets dropped.
- At each node, update a global best with node.val + max(0, gainLeft) + max(0, gainRight). That is the best path bending through this node. The return value can only extend one side, because a path cannot fork.
- Initialise best to the smallest integer (or the root's value), not 0, so a tree of all negative values returns its largest single node.
- O(n) time, O(h) recursion stack. A skewed tree with a very large n can overflow the Java stack, so mention an iterative post-order with an explicit stack as the fix.
Follow-up
- Return the nodes on the best path, not just the sum.
- Restrict paths to root-to-leaf: what changes in the recursion?
- What if node values can be large enough to overflow an int?
Given a unsorted singly linked list, write a function to sort it efficiently.
Medium · Data Structures & Algorithms
Approach
- Use merge sort, because linked lists allow O(1) splitting and merging but no random access. Find the middle with slow and fast pointers, starting fast at head.next so a two-node list splits into one and one, then cut the list at slow.next.
- Merge the two sorted halves with a dummy head node, linking the smaller node each time and appending the remainder. Using <= keeps the merge stable.
- Top-down recursion is O(n log n) time with O(log n) stack. A bottom-up merge sort, merging runs of size 1, 2, 4 and so on, gets O(1) extra space.
- Quicksort is a weaker fit: no random pivot access and degenerate behaviour on sorted input. Copying into an array, sorting and relinking works but costs O(n) memory. Edge cases: empty list, one node, all duplicates, already sorted.
Follow-up
- Write the bottom-up version with constant extra space.
- Merge k sorted linked lists: compare a min-heap approach with pairwise merging.
- How would you sort a doubly linked list, and does anything get easier?
Solve the problem of moving all zeros to the end of an array while maintaining the relative order of non-zero
Medium · Data Structures & Algorithms
Solve the problem of moving all zeros to the end of an array while maintaining the relative order of non-zero elements.
Approach
- Keep a write index w = 0. Scan with i; whenever a[i] != 0, swap a[i] with a[w] and increment w. The non-zero elements keep their relative order, and the zeros collect behind w.
- An equivalent two-phase version copies non-zeros forward to a[w++], then fills a[w..n-1] with zeros. Both are O(n) time and O(1) space.
- The swap version writes nothing on a prefix with no zeros if you only swap when i != w. Mention this if the follow-up is about minimising writes.
- Edge cases: no zeros, all zeros, a single element, and zeros already at the end.
Follow-up
- Minimise the number of array writes.
- Move zeros to the front instead, keeping order.
- Do the same for a singly linked list, or for any value matching a predicate.
Generate all permutations of a given string or array and analyze the time complexity.
Medium · Data Structures & Algorithms
Approach
- Backtrack with a used[] array and a current path. At depth d, try every unused element, mark it, recurse, then unmark. When the path length reaches n, record a copy.
- Alternatively, permute in place by swapping a[d] with each a[i] for i >= d, recursing on d+1, and swapping back. This needs no extra path array.
- Complexity: there are n! permutations, and copying each costs O(n), so O(n * n!) time. Recursion depth is O(n). The output size forces this bound, so say so rather than claiming something faster.
- Duplicates: sort first and skip a[i] when a[i] == a[i-1] and a[i-1] is unused. In the swap method, keep a per-level set of values already placed at position d. For a string, mention that string concatenation in Java creates new objects, so use a char array or StringBuilder.
Follow-up
- Generate only unique permutations when the input has duplicates.
- Find the k-th permutation in lexicographic order without generating the others.
- Implement next-permutation iteratively and give its complexity.
How does Garbage Collection function in Java, and why would an enterprise application choose the G1GC collecto
Medium · Core Java & Object-Oriented Programming
How does Garbage Collection function in Java, and why would an enterprise application choose the G1GC collector?
Approach
- GC reclaims objects that are unreachable from GC roots: thread stacks and local variables, static fields, JNI references. Reachability, not reference counting, is the criterion, which is why cycles are collected.
- Generational design: most objects die young. New objects go to Eden. Minor GCs copy survivors between survivor spaces and promote long-lived objects to the old generation, which is collected less often with mark, sweep and compact phases.
- G1 divides the heap into equal-sized regions, marks concurrently, and collects the regions with the most garbage first, within a pause-time target set by -XX:MaxGCPauseMillis. It runs young and mixed collections and treats very large objects as humongous regions. It has been the default collector since Java 9.
- Why an enterprise service picks it: large heaps with predictable, bounded pauses for latency-sensitive APIs, as opposed to Parallel GC, which maximises throughput but has longer stop-the-world pauses. For sub-millisecond pauses, ZGC and Shenandoah are the next step. Diagnose with GC logs (-Xlog:gc*) and heap dumps.
Follow-up
- Can a Java program leak memory? Give a concrete example.
- What triggers a Full GC under G1, and how would you prevent it?
- Why do teams often set -Xms equal to -Xmx in production?
Explain the concept of thread synchronization, the synchronized keyword, and volatile variables in concurrent
Medium · Core Java & Object-Oriented Programming
Explain the concept of thread synchronization, the synchronized keyword, and volatile variables in concurrent multi-threaded applications.
Approach
- Start with the problem: a race condition happens when threads read-modify-write shared state without coordination, as with count++. The critical section must be mutually exclusive, and its writes must become visible to other threads.
- synchronized acquires the object's monitor: this for instance methods, the Class object for static methods. It is reentrant. Releasing a monitor happens-before every later acquire of the same monitor, so it gives both atomicity and visibility.
- volatile gives visibility and ordering only: a write to a volatile field happens-before later reads of it, and reads are never served from a stale cached value. It does not make count++ atomic, so use AtomicInteger (CAS) or a lock for that.
- Mention the practical tools: double-checked locking needs a volatile instance field. wait/notify must be called while holding the monitor. ReentrantLock adds tryLock, timeouts and fairness. Deadlock is avoided by acquiring locks in a consistent global order.
Follow-up
- Why does a double-checked locking singleton break without volatile?
- Implement a bounded producer-consumer buffer with wait/notify or a BlockingQueue.
- When would you choose ReentrantLock over synchronized?
Describe the low-level object-oriented design (LLD) for a railway ticket booking system (e.g., IRCTC), includi
Medium · System Design & Architecture
Describe the low-level object-oriented design (LLD) for a railway ticket booking system (e.g., IRCTC), including entity relationships, concurrency handling, and seat locking mechanisms.
Approach
- Entities: Train, Station, Route (ordered stops with distances), Coach, Seat, TrainRun (a train on a date), Passenger, Booking (PNR, status, passengers), Payment and Quota. A seat's availability depends on the segment, because one seat can be sold Delhi to Agra and again Agra to Bhopal. Model occupancy per seat as a set or bitmask of route segments.
- Booking flow: search availability, then hold seats, then pay, then confirm. Give holds a status machine (AVAILABLE, HELD with an expiry, BOOKED) and release them when payment times out.
- Concurrency: prevent double booking with a conditional update (UPDATE seat_segment SET status='HELD' WHERE ... AND status='AVAILABLE', checking the affected row count), optimistic locking with a version column, or SELECT ... FOR UPDATE inside a transaction. With several app servers, use a Redis lock with an expiry and a fencing token, or rely on the database constraint as the final arbiter.
- Patterns: Strategy for seat allocation and fare calculation, State for booking status, Observer for SMS and email notifications. Waitlist and RAC sit in a queue per TrainRun and class, and cancellations promote the head of the queue. Make the confirm call idempotent with a client request id.
Follow-up
- Two users click the last seat at the same moment: walk through exactly what each sees.
- How does the design hold up when a Tatkal-style window opens and traffic spikes at one instant?
- How do you guarantee a held seat is released if the payment service never calls back?
Compare processes and threads, explaining how inter-process communication (IPC) and context switching operate
Medium · Computer Networks & Operating Systems
Compare processes and threads, explaining how inter-process communication (IPC) and context switching operate at the OS level.
Approach
- A process has its own virtual address space, file descriptor table and resources, so a crash stays isolated. Threads within a process share heap, code and open files, but each has its own stack, registers and program counter. Threads are cheaper to create and communicate through shared memory, at the cost of synchronisation bugs.
- IPC mechanisms: pipes and named pipes (byte streams), message queues, shared memory plus semaphores (fastest, but you handle synchronisation yourself), memory-mapped files, sockets (which also work across machines) and signals.
- Context switch: the kernel saves the running task's registers, program counter and stack pointer into its control block, the scheduler picks the next task, and its state is restored. A process switch also changes page tables, which can flush TLB entries and cool caches. A thread switch within one process skips that, so it is cheaper.
- Connect it to Java: platform threads map one-to-one to OS threads, so thousands of blocking threads mean heavy switching and stack memory. That is the motivation for thread pools and for virtual threads in Java 21.
Follow-up
- What does fork() do, and how does copy-on-write keep it cheap?
- Name the four conditions for deadlock and one way to break each.
- Why can adding more threads to a CPU-bound service reduce throughput?
Explain the concept of event looping, asynchronous callbacks, and scope hoisting in JavaScript.
Medium · Frontend & Mobile Development
Approach
- JavaScript runs on a single call stack. Asynchronous work (timers, network, I/O) is handed to the browser's Web APIs or Node's libuv. When it completes, a callback is queued.
- The event loop takes one macrotask (setTimeout, I/O callbacks, UI events), runs it to completion, then drains the entire microtask queue (promise reactions, queueMicrotask, MutationObserver) before rendering or taking the next macrotask. So console.log('a'); setTimeout(()=>log('b')); Promise.resolve().then(()=>log('c')); log('d') prints a, d, c, b.
- Hoisting: var declarations are hoisted and initialised to undefined. let, const and class are hoisted but stay in the temporal dead zone until their line runs, so earlier access throws a ReferenceError. Function declarations are hoisted with their body. Function expressions and arrow functions follow the hoisting of their variable.
- Tie this to closures: a for loop using var with setTimeout logs the final value n times because there is one shared binding. Using let creates a new binding per iteration and logs 0..n-1. async/await is syntax over promises, and the code after an await runs as a microtask.
Follow-up
- Predict the output of a snippet mixing setTimeout, promises and async/await.
- In Node, where do process.nextTick and setImmediate run relative to promises?
- How would you keep a long CPU-bound loop from freezing the UI?
Describe how to handle multidex support and optimize runtime class loading in large-scale Android applications
Medium · Frontend & Mobile Development
Describe how to handle multidex support and optimize runtime class loading in large-scale Android applications.
Approach
- Background: one DEX file can reference at most 65,536 methods. Large apps with many libraries exceed this and must split code across several DEX files.
- On minSdk 21 and above, ART supports multidex natively: all DEX files are compiled at install time, so enabling multiDexEnabled is enough. Below 21, the support library loads secondary DEX files at startup. That slows cold start and can cause ANRs, and classes needed during startup must be kept in the primary DEX.
- Shrink before you split: enable R8 to remove unused code and resources, drop or replace heavy dependencies, and inspect method counts with the APK Analyzer. Add keep rules for classes accessed through reflection, otherwise R8 removes them and they fail at runtime.
- For runtime class loading and startup cost, ship Baseline Profiles so hot code is precompiled, defer initialisation with the App Startup library or lazy injection, keep Application.onCreate light, and move rarely used features into dynamic feature modules. Measure cold start with Macrobenchmark before and after.
Follow-up
- How would you measure and break down cold-start time?
- A release build crashes with ClassNotFoundException but debug works: what do you check?
- When are dynamic feature modules worth their extra complexity?
Denormalise tenant onto revisions and backfill it live
Hard · denormalisation · online migration · backfill
resource_revision (revision_id, resource_id, version, actor_user_id, change_kind, patch, request_id, created_at) has 400M rows and no tenant column; tenant_id lives only on resource. Two reads need it: a tenant-scoped audit feed ordered by created_at DESC, and an offboarding purge. Both join back to resource today. Justify adding tenant_id to resource_revision against those two reads, name the anomaly the copy introduces and the constraint that prevents it, then give the ordered migration for a live table taking 1.2k writes/second — the lock each step takes, how the backfill is batched, and where each step stops being reversible. PostgreSQL 16.
Approach
- Justify from the access path rather than from taste. Without the column, the audit feed either scans resource_revision by created_at and discards other tenants' rows, or resolves the tenant's resource_ids first and probes with them — both proportional to the tenant's whole history rather than to one page. With (tenant_id, created_at DESC, revision_id DESC) it is a seek that stops at 50 rows, and the purge becomes a ranged delete instead of a join.
- Name the cost exactly: a second copy of a fact can disagree with the first. Make the disagreement unwritable rather than documented — add UNIQUE (resource_id, tenant_id) on resource so it can serve as a foreign-key target, then FOREIGN KEY (resource_id, tenant_id) REFERENCES resource (resource_id, tenant_id) on the revision table. A revision can then only ever carry its parent's tenant.
- Step one, expand: ALTER TABLE resource_revision ADD COLUMN tenant_id BIGINT NULL, with no default, so it is a catalogue change and no rewrite. It still needs ACCESS EXCLUSIVE for an instant, and that instant queues behind the longest open transaction on the table while every later query queues behind it — set lock_timeout to 2s and retry rather than wait.
- Step two, dual-write: deploy the writer that populates tenant_id on every new revision while reads still use the join. Reversible by redeploying the previous build, because nothing reads the column yet.
Follow-up
- The backfill is half finished and a rollback is required. What state is the table in, and what does the previous build do with a half-populated column?
- How do you verify the backfill actually finished, given rows are still being inserted while it runs?
Keep soft-deleted accounts from blocking re-registration
Easy · soft delete · unique constraints · engine differences
app_user holds user_id, tenant_id, email CITEXT, password_hash (NULL for SSO principals), email_verified_at, auth_version, status ('invited','active','suspended','deactivated'), created_at, updated_at, deleted_at. Two live accounts for one address inside a tenant must be impossible, but an address freed by a soft delete must be reusable, and the same tenant may delete and re-register it repeatedly. Write the uniqueness DDL for PostgreSQL 16, then the equivalent for MySQL 8 where partial indexes do not exist, and say what each permits once three deleted rows already hold that address.
Approach
- Start from what is actually unique: not (tenant_id, email), but (tenant_id, email) among live rows. PostgreSQL says that directly — CREATE UNIQUE INDEX app_user_live_email ON app_user (tenant_id, email) WHERE deleted_at IS NULL. A full constraint over the same two columns burns the address permanently the first time someone deletes an account.
- Keep case-insensitivity in the type or the index, never in the application: CITEXT as given, or UNIQUE (tenant_id, lower(email)) as an expression index where the extension is unavailable. A case-sensitive unique column is exactly how two accounts for one human appear.
- For MySQL 8 the predicate has to move inside the key: add a discriminator column that is a constant 0 while the row is live and is set to user_id on delete, with UNIQUE (tenant_id, email, deleted_marker). Live rows share the constant and still collide; deleted rows differ from each other and stop colliding.
- State the NULL variant and its dependency: leaving the marker NULL for deleted rows also works, because a unique index treats NULLs as distinct — true in MySQL, and true in PostgreSQL only under the default NULLS DISTINCT, which PostgreSQL 15 lets you reverse. Check the polarity against the three existing deleted rows: constant-on-live is what preserves the collision you want, and reversing it silently admits duplicate live accounts.
Follow-up
- A deleted account re-registers with the same address the next day. Do the old resource rows follow the new user_id, and how does the API keep the two principals apart?
- How do you honour an erasure request while resource_revision.actor_user_id still references this table?
Explain the internal working of HashMap in Java, including collision resolution and treeification in Java 8.
Medium · Core Java & Object-Oriented Programming
Approach
- Structure: an array of buckets (table) whose length is a power of two, default 16. The index is (n - 1) & hash, where hash spreads the key's hashCode as h ^ (h >>> 16) so that high bits affect low-bit indexing.
- Collisions: entries in the same bin form a linked list. In Java 8, treeifyBin runs when a bin grows past TREEIFY_THRESHOLD (8), on the insert that makes it 9 nodes, and converts it to a red-black tree only if the table has at least 64 buckets (MIN_TREEIFY_CAPACITY); otherwise the table resizes instead. A tree bin reverts to a list when a resize split leaves it with 6 or fewer nodes.
- The O(log n) worst-case lookup inside a tree bin holds when the colliding keys are Comparable. If they are not (and their hashes are equal), the tree cannot order them, so a lookup may still scan both subtrees.
- Resize: when size exceeds capacity * loadFactor (0.75 by default), capacity doubles. Java 8 splits each bin into a 'lo' list that stays at index i and a 'hi' list that moves to i + oldCap, based on one hash bit, and keeps their order. Contracts: equal keys need equal hashCodes, a mutated key becomes unreachable, one null key is allowed (hash 0), and HashMap is not thread-safe, so concurrent code uses ConcurrentHashMap.
Follow-up
- How does ConcurrentHashMap achieve thread safety in Java 8 without segments?
- What happens if every key returns the same hashCode, with and without Comparable keys?
- Why is the table length kept a power of two?
What is the difference between static and dynamic polymorphism, and how does method overriding work under the
Medium · Core Java & Object-Oriented Programming
What is the difference between static and dynamic polymorphism, and how does method overriding work under the hood in the JVM?
Approach
- Static polymorphism is method overloading. The compiler picks the overload from the static (declared) types of the arguments at compile time, using exact match, then widening, then boxing, then varargs.
- Dynamic polymorphism is method overriding. The call is bound at runtime by the actual class of the receiver object, so Animal a = new Dog(); a.speak() runs Dog.speak().
- Under the hood, the compiler emits invokevirtual (or invokeinterface). The JVM resolves it through the class's method table (vtable), where an overriding method occupies the same slot as the parent's. The JIT often devirtualises or inlines monomorphic call sites. Static, private and constructor calls use invokestatic or invokespecial and are not dispatched dynamically.
- Points to state: static methods are hidden, not overridden. Fields are not polymorphic. final and private methods cannot be overridden. Covariant return types are allowed and implemented with compiler-generated bridge methods.
Follow-up
- Which overload is chosen for print(null) when print(Object) and print(String) both exist?
- Why is calling an overridable method from a constructor risky?
- Can you override a static method? What happens with a reference of the parent type?
Compare SOAP versus REST web services, explaining when each protocol is appropriate for enterprise integration
Medium · Core Java & Object-Oriented Programming
Compare SOAP versus REST web services, explaining when each protocol is appropriate for enterprise integration.
Approach
- SOAP is a protocol: XML envelopes, a formal WSDL contract, and WS-* standards such as WS-Security for message-level signing and encryption and WS-ReliableMessaging. It can run over transports other than HTTP and typically sends everything as POST.
- REST is an architectural style over HTTP: resources addressed by URLs, standard verbs, status codes, stateless requests, and cacheable GET responses, usually with JSON payloads. Contracts are documented with OpenAPI.
- Choose SOAP when a partner system already exposes WSDL, or when strict contracts, message-level security or WS-* transactions are required, as in many banking and telecom back-office integrations. Choose REST for mobile and web clients, public APIs, and anywhere lighter payloads and HTTP caching matter.
- Cover reliability either way. In REST, GET, PUT and DELETE are idempotent and POST is not, so a payment or order POST needs an idempotency key so that a retry after a timeout does not apply twice.
Follow-up
- How would you version a REST API without breaking existing mobile clients?
- Where does gRPC fit compared with both?
- How do you secure a REST API between internal services: OAuth2 tokens, mTLS or both?
Design an LRU Cache using appropriate data structures to support $O(1)$ put and get operations.
Medium · System Design & Architecture
Approach
- Combine a HashMap from key to node with a doubly linked list ordered by recency. Use sentinel head and tail nodes so insertions and removals have no null checks.
- get(key): if the key is absent, return -1. Otherwise unlink the node, move it to the front and return its value. put(key, value): if the key exists, update the value and move it to the front. Otherwise insert at the front, and if size exceeds capacity, remove tail.prev and delete its key from the map. Every operation is O(1).
- Store the key in the node itself. Eviction needs it to remove the map entry, and forgetting this is a common bug.
- In Java, LinkedHashMap with accessOrder = true and an overridden removeEldestEntry gives the same behaviour. Mention it, but implement the explicit version if asked. Edge cases: capacity 1, updating an existing key (no eviction), and repeated gets of the same key.
Follow-up
- Make it thread-safe for heavy concurrent access without one global lock becoming the bottleneck.
- Change the eviction policy to LFU while keeping O(1) operations.
- Add per-entry TTL expiry: lazy on read, a background sweeper, or both?
How would you design a music streaming service (similar to Wynk Music) supporting random playback, offline dow
Medium · System Design & Architecture
How would you design a music streaming service (similar to Wynk Music) supporting random playback, offline downloads, and device synchronization?
Approach
- Clarify scope first: catalogue browsing, streaming, playlists with shuffle, offline downloads, and syncing playback across devices. Set targets for start-up latency and availability before drawing anything.
- Streaming path: audio is transcoded into several bitrates and segmented (HLS or DASH) in object storage behind a CDN. A playback service checks entitlement and returns short-lived signed URLs, and the client switches bitrate with network quality. Catalogue metadata lives in a database with a Redis cache for hot tracks and charts.
- Random playback: shuffle the queue with Fisher-Yates using a stored seed, so the order is reproducible on another device and 'previous' works. Offline downloads: store encrypted files with a DRM licence that has an expiry and a per-account device limit, renew the licence when the device comes online, and queue offline play events for upload.
- Device sync: a user-state service holds the current track, position and queue. Clients push updates and receive changes over a persistent connection or push notification. Resolve conflicts with last-writer-wins on server timestamps or a version counter. Play events go through Kafka to analytics and royalty counting.
Follow-up
- A popular artist releases an album at midnight: what saturates first, and what do you pre-warm?
- How do you count plays that happened offline, accurately and only once?
- Two devices change the queue at the same moment: which edit wins, and how does the user see it?
Walk through the high-level design (HLD) of a Web Crawler system, addressing deduplication, rate limiting, and
Medium · System Design & Architecture
Walk through the high-level design (HLD) of a Web Crawler system, addressing deduplication, rate limiting, and thread pool management.
Approach
- Components: seed URLs, a URL frontier, a fetcher pool, DNS and robots.txt caches, a parser that extracts and normalises links, a URL-seen check, a content-seen check, and storage for pages plus a link graph.
- Frontier and rate limiting: split it into a priority queue feeding per-host queues (the Mercator design). Each host has a next-allowed-fetch time, so politeness and robots.txt crawl delays are enforced per host rather than globally.
- Deduplication: normalise URLs (lowercase host, strip fragments, sort query parameters), then check a Bloom filter backed by a persistent store. A false positive only means a page is skipped. Detect duplicate content with a hash of the body, or SimHash for near-duplicates.
- Thread pool: a bounded ExecutorService, or async I/O, sized to network latency rather than CPU count, with a bounded work queue for backpressure. Across machines, assign hosts to workers by consistent hashing of the hostname so each host's politeness state lives in one place. Retry with exponential backoff, checkpoint the frontier, and cap depth or URLs per host to escape crawler traps.
Follow-up
- How large a Bloom filter do you need for a billion URLs at a 1% false-positive rate, and what does a false positive cost?
- How do you decide how often to recrawl a page?
- A worker dies mid-crawl: which URLs are lost and how do you recover them?
How do you design a mobile app interface for local media playback that maintains background audio playback whe
Medium · System Design & Architecture
How do you design a mobile app interface for local media playback that maintains background audio playback when navigating away from the screen?
Approach
- The key decision is that playback must not belong to the screen. On Android, run the player (ExoPlayer or Media3) inside a foreground service of type mediaPlayback with a media-style notification. The activity or fragment only binds to it through a MediaController and observes state through a ViewModel.
- Expose a MediaSession so the lock screen, notification, Bluetooth and headset buttons control playback. Request audio focus and pause or duck when another app or a call takes it. Pause when headphones are unplugged by handling the becoming-noisy broadcast.
- On iOS, set the AVAudioSession category to .playback, enable the Audio background mode, publish metadata through MPNowPlayingInfoCenter, and handle remote commands with MPRemoteCommandCenter. Keep the AVPlayer in an app-level object, not in the view.
- For local media, read tracks through MediaStore (with the media permission) or the iOS media library. Persist the current track and position so playback can resume after the process is killed.
Follow-up
- The OS kills the app process during playback: what does the user see, and how do you restore state?
- How do you handle a phone call arriving mid-track on each platform?
- How would the UI show progress without polling the player constantly?
Explain the seven layers of the OSI Model and map common internet protocols (TCP, UDP, HTTP, IP) to their resp
Medium · Computer Networks & Operating Systems
Explain the seven layers of the OSI Model and map common internet protocols (TCP, UDP, HTTP, IP) to their respective layers.
Approach
- List the layers from bottom to top with one job each: Physical (bits on the medium), Data Link (frames, MAC addressing), Network (IP addressing and routing), Transport (end-to-end delivery, ports), Session (dialogue control), Presentation (encoding, encryption) and Application (protocols the app uses).
- Mapping: HTTP, DNS, SMTP at layer 7; TLS is usually placed at layer 6, or described as sitting between transport and application; TCP and UDP at layer 4; IP and ICMP at layer 3; Ethernet and Wi-Fi framing at layer 2. ARP sits between layers 2 and 3.
- Contrast TCP and UDP: TCP is connection-oriented, with a three-way handshake, ordering, retransmission, and flow and congestion control. UDP is connectionless with no delivery guarantee and is used for DNS lookups, voice and video, and as the base for QUIC.
- Relate OSI to the four-layer TCP/IP model, which is what real stacks implement. A strong close is walking a single HTTPS request down the stack and back up.
Follow-up
- Walk through the TCP three-way handshake and connection teardown, including TIME_WAIT.
- Why does DNS mostly use UDP, and when does it switch to TCP?
- What is the difference between a layer 4 and a layer 7 load balancer?
What is the difference between HTTP and HTTPS, and how does the TLS/SSL handshake establish secure client-serv
Medium · Computer Networks & Operating Systems
What is the difference between HTTP and HTTPS, and how does the TLS/SSL handshake establish secure client-server communication?
Approach
- HTTPS is HTTP sent over TLS. It adds confidentiality (encryption), integrity (tamper detection) and server authentication (certificates). Plain HTTP exposes headers, cookies and bodies to anyone on the path.
- TLS 1.2 with ECDHE: ClientHello (cipher suites, client random). ServerHello (chosen suite, server random), followed by separate Certificate and ServerKeyExchange messages (the server's ECDHE share, signed with its certificate key) and ServerHelloDone. The client verifies the chain to a trusted CA and the hostname, then sends ClientKeyExchange carrying its own ECDHE public share.
- Both sides then compute the same premaster secret, derive the session keys from it and the two randoms, and each sends ChangeCipherSpec followed by an encrypted Finished message over the handshake transcript, which confirms nothing was tampered with. Asymmetric cryptography covers only authentication and key agreement; bulk data uses symmetric ciphers such as AES-GCM, and ephemeral Diffie-Hellman gives forward secrecy.
- TLS 1.3 cuts the handshake to one round trip, drops RSA key exchange and weak ciphers, and allows 0-RTT resumption, which can be replayed and so suits only idempotent requests.
Follow-up
- How does certificate pinning in a mobile app defend against a man-in-the-middle, and what is its operational risk?
- What does HSTS protect against?
- Where would you terminate TLS in a microservice deployment, and is internal traffic left in plaintext?
Describe the core functional differences between a Hub, a Switch, and a Router within campus and enterprise ne
Medium · Computer Networks & Operating Systems
Describe the core functional differences between a Hub, a Switch, and a Router within campus and enterprise networking setups.
Approach
- Hub (layer 1): repeats every incoming signal out of every other port. All devices share one collision domain and operate half duplex, so throughput collapses as devices are added.
- Switch (layer 2): learns which MAC address sits on which port from source addresses and forwards each frame only to the destination port, flooding unknown or broadcast frames. Each port is its own collision domain with full duplex. All ports remain one broadcast domain unless VLANs split them.
- Router (layer 3): forwards packets between different IP networks using a routing table, separates broadcast domains, and usually adds NAT, ACLs and DHCP relay. Layer 3 switches combine switching with routing between VLANs at hardware speed.
- In a campus or enterprise network, place them in the access, distribution and core tiers: access switches for end devices, VLANs per department, and routing at distribution or core to reach other subnets and the internet.
Follow-up
- What does a switch do with a frame for a MAC address it has not learned yet?
- How do two hosts on different VLANs communicate?
- How does a host find the MAC address of its default gateway?
Explain the principles of IP addressing, NAT (Network Address Translation), and dynamic routing protocols like
Medium · Computer Networks & Operating Systems
Explain the principles of IP addressing, NAT (Network Address Translation), and dynamic routing protocols like BGP and OSPF.
Approach
- IPv4 addresses are 32 bits, written in CIDR notation as address/prefix. A /24 gives 256 addresses (254 usable hosts), and a /26 gives 64 addresses (62 usable). Private ranges are 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16. IPv6 uses 128-bit addresses, which removes most of the reason for NAT.
- NAT (strictly PAT) rewrites a private source IP and port to a public IP and port and records the mapping in a translation table, so replies can be translated back. Inbound connections fail without port forwarding, which is why peer-to-peer apps use STUN and TURN. Carriers run carrier-grade NAT to share public IPv4 addresses across many subscribers.
- OSPF is a link-state interior gateway protocol. Routers flood link-state advertisements, each builds the same topology map, and each runs Dijkstra's shortest-path algorithm over link costs. Areas keep the flooding scope bounded.
- BGP is the path-vector protocol between autonomous systems, running over TCP port 179. It selects routes by policy and attributes such as AS_PATH and local preference rather than pure shortest distance. This is how networks exchange reachability on the internet.
Follow-up
- Split 192.168.10.0/24 into four equal subnets and give each range.
- Why is BGP policy-driven rather than shortest-path, and what is a route leak?
- How does a client behind two layers of NAT receive an incoming call or stream?
What is the difference between state and props in React, and when should you wrap components with memoization
Medium · Frontend & Mobile Development
What is the difference between state and props in React, and when should you wrap components with memoization mechanisms?
Approach
- Props are inputs that a parent passes in, and they are read-only inside the child. State is data a component owns and changes through useState or useReducer. Changing state schedules a re-render of that component and, by default, all its children. When siblings need the same data, lift the state to their common parent.
- React.memo skips re-rendering a component when a shallow comparison finds its props unchanged. useMemo caches an expensive computed value between renders. useCallback keeps a function's identity stable so a memoised child receiving it as a prop does not re-render.
- Use memoisation when the React DevTools Profiler shows a component that renders often, is expensive, and receives the same props: large lists, charts, heavy rows. Do not wrap everything, because comparisons cost time and wrong dependency arrays cause stale values.
- A common trap is passing an inline object or arrow function as a prop. It is a new reference every render, so React.memo never skips. Context changes re-render every consumer regardless of memo.
Follow-up
- Why does a memoised child still re-render when the parent passes style={{...}}?
- How do you stop a frequently changing Context from re-rendering the whole tree?
- Why do list items need stable keys, and what goes wrong when the index is used?
Develop a functional timer component in React featuring start, pause, and reset controls using functional hook
Medium · Frontend & Mobile Development
Develop a functional timer component in React featuring start, pause, and reset controls using functional hooks.
Approach
- State: elapsedMs and isRunning in useState. Refs: the interval id and the timestamp at which the current run started, kept in useRef so updating them does not re-render.
- start: if already running, return (this prevents double intervals). Record startRef = Date.now() - elapsedMs and start a setInterval that sets elapsedMs to Date.now() - startRef. Computing from timestamps avoids the drift you get from adding 1000 on each tick.
- pause: clearInterval, set isRunning to false, and keep elapsedMs. reset: clearInterval, set elapsedMs to 0 and isRunning to false. Add a useEffect cleanup that clears the interval on unmount to avoid leaks and updates after unmount.
- Format the display as mm:ss (or with centiseconds), and disable buttons by state. Mention that putting the logic in a custom useStopwatch hook makes it testable with fake timers.
Follow-up
- What happens to accuracy when the browser tab is in the background?
- Add lap times, and say where they live in state.
- How would you test this component with fake timers?
Discuss common architecture patterns (MVVM, VIPER) used in modern iOS application development with SwiftUI.
Medium · Frontend & Mobile Development
Approach
- SwiftUI is declarative: views are functions of state. MVVM fits it directly. The View observes an ObservableObject view model with @Published properties (or an @Observable class from iOS 17), and the view model calls services and exposes display-ready state.
- Ownership matters: @StateObject (or @State with @Observable) creates and owns the view model, @ObservedObject receives one from a parent, and @EnvironmentObject shares it down the tree. Using @ObservedObject for something the view creates causes the state to reset on re-render.
- VIPER (View, Interactor, Presenter, Entity, Router) was built for UIKit. It gives strict separation and testability for large teams, but brings heavy boilerplate. In SwiftUI the Router is awkward, because navigation is itself state (a NavigationStack path).
- Compare the trade-offs plainly: MVVM is light and natural for SwiftUI but view models can grow large. VIPER scales to large modules but slows small features. Coordinators or The Composable Architecture are other options. Pick based on team size, testing needs and how complex navigation is.
Follow-up
- What is the difference between @StateObject and @ObservedObject, and what bug does mixing them up cause?
- How do you handle navigation in MVVM with NavigationStack?
- How do you unit test a view model that calls async network code?
One log partition stops advancing while the others drain
Easy · poison message · head-of-line blocking · consumer lag
Search results for a subset of tenants are hours stale; the rest are current. The projection consumer reports lag of zero on 15 of 16 partitions and 400,000 on one. Its error rate is flat and its CPU is idle. outbox_event has no pending rows older than a second, so the relay has published everything it holds. Identify the mechanism, give the ordered checks, and state what you do in the first ten minutes versus what you change permanently.
Approach
- Read the lag distribution first. A slow consumer lags everywhere; zero on fifteen partitions and 400,000 on one is not throughput. Idle CPU on the stuck partition means the consumer is not advancing its offset at all, which points at one message it cannot get past rather than at a rate problem.
- Exonerate the producer before touching the consumer. No pending outbox rows older than a second means the relay published, so the event exists in the log. This separates never sent from sent and never applied, which are different code paths and usually different owners.
- Read the message at the stuck offset and the handler's log lines for its event_id. A flat error rate with no progress has two explanations and you must distinguish them: the handler is throwing and the retry loop is swallowing it, or the handler is blocking on something and never returning. Idle CPU with no error lines favours the second.
- Mitigate before diagnosing further. Move the offending event to a dead-letter store and commit the offset past it. Adding consumers does nothing here, because a partition is consumed by exactly one member of the group, and the blast radius is every aggregate hashed to that partition, not only the aggregate that produced the bad event.
Follow-up
- The dead-lettered event carried aggregate_version 7 and the projection had applied 6. What must the replay do differently if 8 and 9 landed in the meantime?
- How do you show staleness to the user while the partition is behind, given the API already returns the projection's watermark?
Suggested practice checklist
Each day targets one group of the reported questions in the order the loop reports them: online assessment coding first, then technical-round fundamentals and Spring Boot, then design with Kafka, then the managerial and HR conversations. The frontend and mobile questions sit on the last day for candidates applying to those teams.
Day 1 — Online assessment warm-up: array partitioning and aptitude
- Solve the Dutch National Flag problem and the move-zeros problem in your interview language, writing the pointer invariants as comments first
- Test both on empty, single-element, all-same and already-sorted inputs, and fix any failure
- Do a timed set of quantitative aptitude problems (percentages, ratios, time and work) and note which types slow you down
- As general fundamentals review, write one-line definitions for 15 OS, DBMS and networking terms
Deliverable: Two tested array solutions with their invariants, an aptitude error log, and a one-page fundamentals sheet.
Day 2 — Trees and linked lists
- Write level-order traversal with the queue-size snapshot, then extend it to zigzag order and bottom view
- Write maximum path sum with a global best and clamped child gains, and test it on a tree of all negative values
- Write linked-list merge sort with the slow and fast split, then the bottom-up version with constant extra space
- Say each solution's time and space complexity out loud before running it
Deliverable: Four working tree and list solutions with edge-case tests and a recorded complexity explanation for each.
Day 3 — Recursion and the LRU cache
- Write permutations with backtracking, then the unique-permutations variant for duplicate input, and explain the O(n * n!) bound
- Implement an LRU cache with a HashMap and a doubly linked list using sentinels, then the LinkedHashMap version
- Add a thread-safety layer to the LRU cache and explain the contention trade-off
- Write a GROUP BY and HAVING query that finds duplicate customer records across two tables
Deliverable: Permutation code for both variants, two LRU implementations plus a thread-safe wrapper, and one duplicate-detection SQL query.
Day 4 — Core Java, Spring Boot and web services
- Write a one-page HashMap internals sheet (hash spreading, resize split, treeify past 8 nodes at capacity 64, Comparable caveat) and explain overloading versus overriding with invokevirtual and the method table
- Outline G1 regions, mixed collections and pause targets, then write a race on count++ and fix it with synchronized and with AtomicInteger
- Compare SOAP and REST for one partner integration and one mobile API, including idempotency keys on POST
- Outline an answer to the reported Redis caching with Spring Boot prompt: DI and bean scopes; why @Transactional fails on self-invocation (the call skips the proxy); propagation and isolation; @Cacheable cache-aside on Redis with a TTL, @CacheEvict on update, and stampede protection (sync=true or a lock)
Deliverable: A Java internals sheet, a fixed concurrency example, a SOAP versus REST decision table, and a written Spring Boot and Redis caching outline.
Day 5 — Computer networks and operating systems
- Draw the OSI stack, map HTTP, TLS, TCP, UDP, IP, Ethernet and ARP onto it, and trace one HTTPS request through it
- Walk through the TLS 1.2 handshake message by message, including ClientKeyExchange, ChangeCipherSpec and Finished, then list what TLS 1.3 changes
- Subnet 192.168.10.0/24 into four ranges by hand, and explain NAT translation, OSPF and BGP in three sentences each
- Compare processes and threads, list five IPC mechanisms, and describe a context switch including the page-table change
Deliverable: An annotated OSI diagram, a handshake walk-through, a subnetting worksheet, and an OS comparison page.
Day 6 — Design evaluations: LLD, HLD and Kafka
- Write the railway booking LLD as classes and a seat-hold state machine, and resolve the case of two users booking the last seat
- Sketch the music streaming service (CDN delivery, seeded shuffle, offline licences, cross-device sync) and the web crawler (per-host frontier, Bloom filter dedup, bounded thread pool, host-based sharding)
- For each design, list every single point of failure and its recovery, and describe background audio playback on Android and iOS
- Review Kafka for the event pipelines in these designs: partitions and per-key ordering, consumer groups and rebalancing, at-least-once delivery with idempotent consumers, and consumer lag; then work the stalled-partition debugging drill
Deliverable: One LLD class diagram, two HLD diagrams with failure annotations, a mobile playback architecture note, and a one-page Kafka sheet.
Day 7 — Resume deep dive, techno-managerial and HR, plus the web and mobile track
- Write a two-minute career overview and three STAR stories with numbers: a latency or reliability win, an incident, and a lost design argument
- For each technology on your resume, write how you used it and one problem it caused
- If you are applying for web or mobile roles, answer the event loop, React memoisation, timer component, multidex and SwiftUI architecture questions out loud
- Decide your location preference, notice period and target level, and prepare three questions for the HR session
Deliverable: A recorded career overview, three written STAR stories, a resume technology sheet, spoken track answers where relevant, and an HR checklist.
Techno-managerial and HR conversations
No behavioral prompts are reported word for word for this loop. Candidates report a Techno-Managerial Discussion covering both technical and managerial aspects, and an HR Session about the offer and culture, and the reported tips stress ownership of services, collaboration and business impact. Rehearse stories that carry real technical detail and a measurable result, because the same conversation can switch back to how your system worked.
- Give a two-minute overview of your career and technical background, centred on your main projects and your own architectural contribution.
- Tell me about a time you reduced latency or improved reliability in a service you owned. What did you measure before and after?
- Describe a production incident you handled, from the first alert to the fix that stopped it from happening again.
- Tell me about a technical decision you disagreed with. What evidence did you bring, and what did you do once the decision was made?
- Describe a time you worked with product, QA or SRE colleagues to ship something under a deadline. What trade-off did you make?
Narrate an outage you owned from page to postmortem
Hard · incident response · blast radius · postmortems
Pick an incident you personally drove, ideally one where writes were affected rather than reads. In six to eight minutes: state the symptom as it first appeared on a dashboard, the blast radius you established before you knew the cause, the mitigation you applied and when, the mechanism you eventually proved, and the follow-up that would prevent a repeat. Bring numbers: error rate, tenants affected, minutes to mitigate, minutes to resolve. If you cannot name what you measured, choose a different incident.
Approach
- Open on the signal rather than the cause: which metric at which percentile moved, on which service, at what time, so the listener follows the same evidence you had rather than a conclusion you already reached.
- Separate mitigation from diagnosis out loud. State what you did to stop the bleeding (flag off, shed traffic, drain a lease, roll back a deploy) and say plainly that you did it before the mechanism was known, because those are two jobs with different deadlines.
- Establish blast radius in countable terms: how many tenants, how many writes, and crucially whether the effect was loss or only delay. An append-only revision table or a pending outbox row means the change survived and the projection was merely behind, which is a repair rather than a data-loss incident.
- Prove the mechanism instead of asserting it. Name the trace span that grew, the plan that flipped to a sequential scan, the lease that expired, plus one alternative you ruled out and the signal that stayed flat while you ruled it out.
Follow-up
- What would you do differently in the first five minutes, given the same dashboard and no more information?
- Which follow-up action did you deliberately not take, and why was dropping it the right call?
Unblock an engineer without taking the keyboard
Easy · mentoring · leases · at-least-once
A teammate has spent two days on a job handler that occasionally writes duplicate rows. They are certain the queue is delivering twice by mistake. You suspect a lease expiring under a slow handler, so the job is running concurrently with itself. Describe how you have unblocked someone in this position: what you asked before offering a hypothesis, what you showed them rather than told them, and what you left them owning. Then say what you would do if their theory turned out to be the right one.
Approach
- Ask before diagnosing, and ask for things answerable from data they already have: the attempt count on the job rows that produced duplicates, the handler's observed duration against its lease expiry, and whether the duplicate rows share a natural key that a unique constraint could have caught.
- Teach the shape rather than the answer. A lease cannot distinguish a dead worker from a slow one, so a handler that outruns its lease is running twice by design, and deploys deliver the other half by killing handlers mid-run on every rollout. Both of their candidate theories produce identical duplicate rows, which is why the evidence has to come from timings rather than from argument.
- Hand over a checklist they execute: a natural key on every write the handler performs so the second copy collides rather than appends, the record of intent written before any external effect, a lease heartbeat while running, and the metric that shows it working.
- Keep ownership with them deliberately. Pair on the first write, then step back; if you finish it yourself you have closed one ticket and left the same person stuck on the next redelivery.
Follow-up
- How would you distinguish a genuine double-delivery from a lease expiry using only the data already stored?
- Their handler calls an external endpoint before recording that it did. What do you tell them to change first?
Argue against a design, lose, and commit anyway
Medium · disagreement · service boundaries · decision records
Describe a design you argued against and lost. State the failure you predicted as a named mechanism, not a feeling about complexity: two services that would need one transaction, a projection with no rebuild path, a write path with no idempotency key. Say what evidence you brought, what the decision maker weighed instead, and what you did after the decision was made: what you instrumented, what you wrote down, and whether the prediction came true. Five minutes.
Approach
- State the prediction in falsifiable form up front: the mechanism, the condition that triggers it, and the observable outcome. A prediction that cannot be checked also cannot be credited to you later.
- Show the evidence you had at the time and label each piece honestly as measured, analogous, or intuition. Keeping the intuition is fine; disguising it as data is the thing that erodes your standing in the next argument.
- Represent the opposing case at full strength, including the constraint you did not control: a fixed date, a team boundary, or the fact that the decision was cheap to reverse and yours was not.
- Make disagree-and-commit concrete. Name the artefact you left behind so the prediction could be settled without you: the alert and its threshold, the counter on the dashboard, the decision note that recorded the trade-off and the condition that would revisit it.
Follow-up
- What threshold on that alert would have proved you right, and did anyone ever look at it?
- If the same proposal arrived tomorrow with the same deadline, would you argue it the same way?