Interview guides · Allied Globetech
Allied Globetech Software Engineer Interview Guide
Allied Globetech Software Engineer interview guide: reported Java, API, XML vs JSON and HTTPS questions, the three-stage loop and a 7-day prep plan.
The 60-second brief
Candidates describe Software Engineer work at Allied Globetech through its stack: Java development, Kafka-based messaging and API management, with Apigee named as the API gateway and management tool and cloud platforms listed as a plus. Reported day-to-day work includes writing and testing code, taking part in code reviews, working with cross-functional teams, troubleshooting an Apigee configuration and tuning a Java application. Nothing reported describes the company's end products, so this guide stays with the engineering topics candidates actually name.
This guide is for candidates interviewing for the Software Engineer role at Allied Globetech, particularly those whose experience is in Java, web APIs or message streaming. It covers the five fundamentals questions candidates report (the Java main method, what an API is, XML versus JSON, HTTP versus HTTPS, and the mechanisms behind HTTPS), the three reported stages, and a seven-day plan. Candidates report that the technical stage leans toward architecture, security and language fundamentals rather than algorithm puzzles, so the plan spends its time there.
Candidates report three stages: an introduction that reviews your background and education, a technical round on Java, web protocols and security, and a final business-level discussion with leadership. Many candidates report finishing the whole loop in a single day.
Focus areas
- Java
- Kafka
- Apigee (API Gateway/Management)
Overview
The reported technical topics are narrow and foundational. Under Java, candidates mention object-oriented basics, method signatures and class structure. Under web protocols, they mention how data moves across the web, with the emphasis on security and data formats. Less common areas are distributed systems, real-time data pipelines and cloud security configuration. All five reported questions sit in the fundamentals group, so the preparation task is to give an answer with a definition, the mechanism underneath it and an example, rather than a one-line label.
The stack that candidates list (Java, Kafka, Apigee, HTTPS, API management) hangs together, and it helps to see how. A Java service exposes an API over HTTPS, the payloads are usually JSON or XML, an API gateway such as Apigee typically sits in front to handle authentication and rate limits, and Kafka carries events between services asynchronously. If you can trace one request through that chain and say what could go wrong at each hop, each fundamentals question becomes a short tour of a system you already understand.
The first stage is reported to review your background and education, and the last is a business-level discussion with leadership. Candidates also describe the role as translating business goals into technical tasks and owning work from conception to deployment. Prepare a concise account of your path and two project stories where you can state the technical choice, the reason for it and the effect on users or the business. The plan below gives the technical days first and the story days last.
Where to focus your preparation
Candidates describe three stages, from introductions through a technical round to a leadership discussion. No per-stage format, duration or question assignment is reported, so ask your recruiter which stages share a day and whether you will write code.
Preparation focus
This block covers the whole reported loop rather than one interview. Candidates report an opening stage that reviews your background and education, a technical stage where Java core concepts and web protocol security and data formats come up, and a closing business-level conversation with leadership. Many loops are reported to fit into one day, which means the stages can arrive back to back. Approach it by splitting your time: speak the five reported fundamentals answers until they are fluent, have a short spoken account of your background ready, and bring two stories that connect a technical decision to a business result. Confirm the sequence and whether code will be written before you finalise your schedule.
What to demonstrate
- Java core concepts such as method signatures, class structure and the main method
- Web protocol knowledge, with emphasis on HTTPS security and data formats such as XML and JSON
- How clearly you present your background, education and motivation in the opening stage
- How you connect your technical work to business outcomes in the final discussion
How to prepare
- Answer the five reported questions aloud: the void return type of main, what an API is, XML versus JSON, HTTP versus HTTPS, and the mechanisms that make HTTPS more secure
- Write a short spoken account of your background, education and why this role, and rehearse it until it sounds natural rather than recited
- Prepare two project stories that each name a technical choice, the reason you made it and the result for users or the business
- Ask your recruiter for the stage order, whether coding is expected and what each stage covers
Where candidates lose points
Reciting public static void main as a memorised line without saying what each keyword is for
Give each part a reason (reachable by the launcher, runs before any object exists, no return value consumed) and add the exit-code story with System.exit and uncaught exceptions. Run a few wrong variants on Day 1 so you can describe the real launcher error.
Answering the HTTPS questions with only "it is encrypted" and no mechanism
Name the sequence: client hello, server certificate and signature, key exchange, session keys, record protection. Say which step gives authentication, which gives forward secrecy and which gives integrity.
Defining an API as "a way for systems to connect" with no request, status code or contract in the answer
Walk through one call with a method, URL, body and response code, then contrast synchronous REST with asynchronous Kafka messaging and say how a gateway such as Apigee fits in front.
Comparing XML and JSON only as "JSON is newer and simpler"
Bring concrete differences: schema and namespaces, comments, array handling, dates, number precision and XXE. Keep one real serialisation bug in your pocket, such as a single-element list collapsing into an object.
Rambling through background and education in the opening stage with no link to why this role or to business results
Write a short spoken account in three beats: where you started, the work that shaped you, why this role. Tie each project story to an effect on users or the business.
Questions & practice
Identify the heaviest tenants in a five-minute window under memory pressure
Medium · top-k · heavy hitters · streaming
The edge service handles about 3,000 requests per second across roughly 50,000 tenants, peaking near 9,000. Expose the 50 heaviest tenants by request count over the trailing five minutes so limits can be tightened before one tenant's backfill starves the fleet. You may not retain five minutes of raw records. Give the exact solution and its memory, then the bounded-memory approximation with its error stated as a formula, and say which you would ship and at what tenant cardinality that choice changes.
Approach
- Do the exact version first, because it is affordable at this cardinality: a ring of 300 one-second counters per tenant, advanced lazily, is 1,200 bytes of counters per tenant and roughly 60 to 90 MB for 50,000 tenants with overhead. Carry a running total and subtract the bucket you overwrite so a window read is O(1) rather than 300 adds.
- Extract the top 50 with a size-k min-heap over the tenant sums: O(d log k) for d tenants, against O(d log d) to sort them all. Maintaining the heap continuously instead of on query requires a tenant-to-heap-index map, because incrementing a count already inside the heap means sifting from a known position, and without that map you rebuild the heap on every request.
- State the approximation precisely rather than gesturing at sketches. Misra-Gries with m counters retains every item whose true count exceeds N/(m+1), and each retained count underestimates the truth by at most N/(m+1). With m = 1,000 and N = 900,000 requests in the window the error is roughly 900 requests, which is fine for spotting a tenant sending 50,000 and useless for ranking two tenants 200 apart.
- Say what breaks when the window slides: Misra-Gries and Space-Saving are insert-only and cannot be decremented as records age out. The workable construction is one summary per sub-window, say ten seconds, with 30 summaries merged at query time, and the merged error is the sum of the per-summary errors, so the bound degrades linearly in the number of sub-windows.
Follow-up
- The heaviest tenant is heavy because of one export job rather than user traffic. Should the limiter treat those as the same tenant?
- Two tenants sit tied at the boundary of the top 50. Does your answer flap, and does the flapping matter?
Collapse a redelivered event batch into per-aggregate high-water marks
Easy · hashing · at-least-once · aggregation
You drain a batch of up to 5,000,000 events, each (aggregate_id BIGINT, aggregate_version INT, event_type, payload). The log guarantees order within one aggregate only; the batch merges 64 partitions, and a relay failover has redelivered a range, so an older version for an aggregate can appear after a newer one. Given a map of last_applied_version per aggregate, produce the events worth applying, at most one per (aggregate_id, version), plus the count discarded. Target O(n) time. State the memory for 2,000,000 distinct aggregates and what you do when it does not fit.
Approach
- One pass, one hash map from aggregate_id to the highest version kept, and a discard counter. An event whose version is at or below last_applied_version for its aggregate is dropped without further work, which is the whole reason the event carries its version rather than a delta. O(n) expected time, O(d) space in distinct aggregates.
- Keep the maximum, never the last occurrence. The redelivered range means the final appearance of an aggregate in the batch can be an older version than one seen earlier in the same batch, so last-wins applies stale state over newer state and the projection regresses with no error anywhere.
- Cost the memory instead of calling it large: an 8-byte key plus a 4-byte version is 12 bytes of payload, and an open-addressed table held at a 0.7 load factor costs roughly 17 bytes per entry before per-slot metadata, so 2,000,000 aggregates is tens of megabytes in a native layout and several times that in a runtime that boxes both key and value.
- If the distinct set exceeds memory, partition on hash(aggregate_id) mod P and reduce each partition independently. Every event for one aggregate hashes to the same partition, so the per-partition result is exact and the merge is concatenation rather than a second reduction.
Follow-up
- The payload is a patch rather than a snapshot, so applying only the highest version loses the intermediate changes. What changes in your reduction?
- How do you detect that version 7 arrived while version 6 was never delivered, and what should the consumer do about the gap?
Track a rolling failure rate per destination for circuit decisions
Easy · sliding window · ring buffer · circuit breaker
The egress service delivers about 1,500 webhooks per second across roughly 40,000 destinations, each call bounded by a 10 second timeout. Maintain, per destination, the failure rate over the trailing 60 seconds so a caller can ask before dispatch whether the circuit should open. Attempts arrive as (destination_id, finished_at_ms, outcome). Requirement: amortised O(1) per attempt, with total memory bounded by the destination count rather than by traffic. Give the structure, its exact memory, and the rule that stops a destination with three attempts from opening a circuit.
Approach
- Name the exact-deque version and then reject it as the default. Holding timestamps and advancing a tail pointer past anything older than now minus 60 seconds is a correct two-pointer window at amortised O(1) per attempt, but its memory tracks in-window traffic, so one destination in a retry storm holds hundreds of thousands of entries while thousands of quiet destinations hold none.
- Use a ring of 60 one-second buckets per destination, each bucket a pair of counters for attempts and failures. On an attempt, advance the ring by the elapsed whole seconds, zeroing at most min(elapsed, 60) buckets, then increment the head. That is amortised O(1) with a fixed footprint per destination.
- State the footprint: 60 buckets times two 4-byte counters is 480 bytes of payload per destination, so 40,000 destinations is roughly 20 to 25 MB with per-entry overhead, bounded by the catalogue rather than by the rate. The cost is granularity, since the oldest bucket ages out in whole seconds, which is far tighter than the decision needs.
- Require a minimum sample before the circuit may open. A destination with three attempts and three failures reads as 100 percent and is not evidence; a floor of roughly 20 attempts in the window makes the ratio meaningful, and below that floor use a run of consecutive failures as the trigger instead.
Follow-up
- The fleet is 30 instances and each sees roughly a thirtieth of a destination's traffic. Where does the rate actually live, and what does a per-instance answer get wrong?
- A destination answers in 9.5 seconds and succeeds. It is not failing but it is consuming your per-destination concurrency. What signal should open the circuit here?
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?
Stop tag and share joins from fanning out a page
Medium · join fan-out · semi-joins · many-to-many
resource_tag is (resource_id, tag_id) with PK (resource_id, tag_id); resource_share is (resource_id, shared_with_user_id, permission). The tagged-and-shared listing inner-joins resource to both, filters tenant_id, tag_id = ANY($2) and shared_with_user_id = $3, orders by updated_at DESC and takes 50. Pages come back with fewer than 50 distinct resources and the total in the header is far too high. Explain the row multiplication, rewrite both the page query and the count query so each is correct, and name the index each one needs. PostgreSQL 16.
Approach
- Do the arithmetic against the predicates that are actually there. An inner join emits one row per matching child row, and both joins are filtered: tag_id = ANY($2) admits only the requested tags, shared_with_user_id = $3 admits one user's share rows. So a resource holding three of the requested tags and shared with $3 once yields three rows, not one — the multiplier is its count of matching tags times its share rows for that single user, and that second factor is 1 unless the table admits duplicate (resource_id, shared_with_user_id) pairs. LIMIT 50 then limits rows rather than resources, and COUNT(*) counts pairs — the header is the product, not the population.
- Reject DISTINCT as the fix. It deduplicates after the product has been built, so the planner must materialise and sort the fanned-out set before the LIMIT can apply, and it leaves any SUM or AVG in the same select list wrong.
- Rewrite both filters as semi-joins, keeping resource as the only row source: AND EXISTS (SELECT 1 FROM resource_tag rt WHERE rt.resource_id = r.resource_id AND rt.tag_id = ANY($2)) and the same shape against resource_share. A semi-join stops at the first match per resource and preserves the driving index order, so ORDER BY updated_at DESC, resource_id DESC LIMIT 50 still stops after 50 rows.
- Count with the same predicates and no join at all: SELECT count(*) FROM resource r WHERE r.tenant_id = $1 AND r.status = 'active' AND EXISTS (...) AND EXISTS (...). Nothing multiplies a resource, so the number is the population.
Follow-up
- The filter changes from 'any of these tags' to 'all of these tags'. Rewrite it and state what it costs relative to the ANY form.
- A resource can be shared with the same user twice under different permissions. Does your count change, and should it?
What is the significance of the void return type in the main method of a Java Class?
Medium · Technical Fundamentals and Web Concepts
Approach
- State the entry-point contract: the launcher looks up public static void main(String[] args) by exact signature. It is static so the JVM can call it without creating an instance, and public so the launcher can reach it.
- Explain why it is void: the JVM never reads a value back from main. The process exit status comes from the runtime, so main has nothing to return, unlike C's int main.
- Show how a program does report an exit code: System.exit(int), where non-zero means failure by convention. If main returns normally, the JVM waits for every non-daemon thread to finish and then exits with 0. An uncaught exception in main makes the standard launcher exit with 1.
- Cover the edge cases. A main declared to return int compiles, but the launcher rejects it with an error saying main must return void. Overloaded main methods are legal but never used as the entry point. Since JDK 25 (instance main methods, JEP 512), main can be a parameterless instance method, but it is still void.
Follow-up
- How would you make a batch job signal failure to the shell or scheduler that started it?
- What happens to a running non-daemon thread when main returns, and how does System.exit change that?
- What runs when System.exit is called (shutdown hooks), and what does Runtime.halt skip?
Can you explain what an API is and how it facilitates communication between services?
Medium · Technical Fundamentals and Web Concepts
Approach
- Define an API as a contract: the operations a provider exposes, their inputs and outputs, and their error cases. The caller depends on the contract, not on how the provider implements it, so either side can change internally without breaking the other.
- Walk through an HTTP/REST call between two services: a resource URL, a method (GET, POST, PUT, PATCH, DELETE), headers for auth and content type, a JSON body, and status codes (2xx success, 4xx caller error, 5xx provider error). The caller branches on those codes.
- Cover failure handling. GET, PUT and DELETE are idempotent by definition and POST is not, so a POST that may be retried after a timeout needs an idempotency key. Add timeouts, bounded retries with backoff, and versioning (in the path or a header) so old clients keep working.
- Contrast synchronous calls with asynchronous messaging such as Kafka. A request/response API couples the caller to the provider's availability and latency. Publishing an event decouples them, but you lose the immediate answer and have to handle ordering and duplicate delivery.
- Explain where a gateway such as Apigee sits: in front of the services, handling authentication (API keys, OAuth tokens), rate limits and quotas, routing, request transformation and analytics, so each backend does not re-implement them.
Follow-up
- A caller times out on a POST that actually succeeded. How do you stop the retry from creating a duplicate?
- When would you put an event on a Kafka topic instead of calling another service's API directly?
- How would you introduce a breaking change to a response field without breaking existing clients?
What are XML and JSON, and how do they differ in terms of data serialization?
Medium · Technical Fundamentals and Web Concepts
Approach
- Define both as text formats for serialising structured data. XML is markup: nested elements, attributes, namespaces, comments and mixed content, validated with DTD or XSD. JSON has six value types (object, array, string, number, boolean, null) and is validated with JSON Schema.
- Compare them on serialisation. XML is more verbose (closing tags) and every value is text unless a schema assigns a type. JSON has native numbers, booleans and arrays but no comments and no date type, so dates travel as agreed strings such as ISO 8601. XML can carry metadata in attributes; JSON has no equivalent.
- Name the tooling in Java: Jackson or Gson for JSON; JAXB, Jackson's XML module, or the DOM, SAX and StAX parsers for XML. DOM loads the whole tree into memory, while SAX and StAX stream it, which matters for large payloads.
- Name the conversion traps you would check when debugging a JSON-to-XML mismatch: a single repeated XML element turning into a JSON object instead of an array, null versus a missing field versus an empty element, number precision (JavaScript parsers lose integers above 2^53), date formats, and character encoding.
- Mention security. XML parsers that resolve external entities are open to XXE and entity-expansion attacks such as billion laughs, so disable DTDs and external entities on the parser factory. JSON has no entity mechanism, but deserialising into polymorphic types needs care.
Follow-up
- A service sends XML and its consumer expects JSON, and a list field sometimes arrives as an object. How do you find and fix this?
- When is XML still the better choice (SOAP contracts, signed documents, document markup), and when would you choose a binary format such as Avro or Protobuf?
- How do you configure a Java XML parser to be safe against XXE?
What is the fundamental difference between HTTP and HTTPS?
Medium · Technical Fundamentals and Web Concepts
Approach
- Say it in one line: HTTPS is HTTP sent over TLS. Methods, headers and status codes are identical; what changes is the transport. It defaults to port 443 rather than 80, and the URL scheme is https.
- Name the three properties TLS adds. Confidentiality: traffic is encrypted. Integrity: AEAD ciphers detect tampering. Server authentication: the certificate must chain to a trusted CA and match the hostname.
- Walk through a TLS 1.3 handshake. The ClientHello carries supported ciphers and an ECDHE key share. The server replies with its key share, its certificate, a CertificateVerify signature proving it holds the private key, and Finished. Both sides derive symmetric keys, so a full handshake takes one round trip (TLS 1.2 took two).
- Say what HTTPS hides and what it does not. The path, query string, headers and body are encrypted. The IP addresses, the SNI hostname (unless Encrypted Client Hello is used), DNS lookups, and traffic sizes and timing are still visible to an observer.
- Mention deployment details: redirect HTTP to HTTPS and send HSTS so browsers stop trying plain HTTP, and know where TLS terminates (load balancer, API gateway or the service itself) and whether the hop behind it is encrypted too.
Follow-up
- Walk me through the handshake when a client connects to an HTTPS-secured API. Where exactly does the certificate get checked?
- If TLS terminates at the gateway, is the traffic between the gateway and the backend still protected?
- What does mutual TLS add, and when would you use it between services?
What specific mechanisms make more secure than standard?
Medium · Technical Fundamentals and Web Concepts
Approach
- Read the question as asking what makes HTTPS more secure than plain HTTP, and answer mechanism by mechanism rather than repeating 'it is encrypted'.
- Authentication through PKI: the server presents an X.509 certificate signed by a CA in the client's trust store. The client checks the chain, the expiry date and that the hostname matches the certificate's Subject Alternative Name, and the server proves it holds the private key by signing the handshake. This is what stops a man-in-the-middle from impersonating the server.
- Key exchange with forward secrecy: ephemeral (EC)DHE keys mean a later leak of the server's private key cannot decrypt recorded sessions. TLS 1.3 removed static RSA key exchange for that reason. Asymmetric cryptography is used only for authentication and key agreement; bulk data uses fast symmetric keys.
- Confidentiality and integrity together: AEAD ciphers such as AES-GCM and ChaCha20-Poly1305 encrypt each record and add an authentication tag, so any modified or replayed record fails verification. The handshake transcript is also authenticated, which blocks downgrade attacks.
- Name the supporting controls and the limits. HSTS prevents SSL stripping, and Certificate Transparency logs expose wrongly issued certificates. HTTPS does not authenticate the client unless mutual TLS is used, does not protect data at rest or a compromised endpoint, and depends on every trusted CA.
Follow-up
- What is forward secrecy, and why did TLS 1.3 drop RSA key exchange?
- An attacker on the same Wi-Fi tries to intercept a login. Which step of HTTPS stops them, and what would the user see?
- For service-to-service calls through a gateway, how would you authenticate the client: mutual TLS, API keys or OAuth tokens, and why?
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 reported loop: Java and web-protocol fundamentals first, then the Kafka and Apigee stack the role lists, then the background and business stories, with a full run-through last.
Day 1 — Java entry point and class fundamentals
- Write a class with the classic main signature, then break it three ways (non-static, private, int return) and record the exact launcher error for each.
- Exit the program with System.exit(2), with a normal return and with an uncaught exception, and read the exit code in the shell each time.
- Write a spoken explanation of classes, interfaces, method signatures, overloading and overriding, and answer the main-method question aloud.
Deliverable: A short note listing each main variant with its exact error and exit code, plus a recorded spoken answer to the main-method question.
Day 2 — What an API is and how services talk
- Build or sketch a two-endpoint HTTP API and call it with curl, saving each request and response with its status code.
- Write the contract as a one-page spec covering inputs, outputs and error cases, then list one backward-compatible and one breaking change to it.
- Answer the API question aloud, covering REST, Kafka messaging and the role of an API gateway.
Deliverable: A one-page contract plus the saved curl transcripts and a spoken answer to the API question.
Day 3 — XML and JSON in practice
- Model one record with a list field in both XML and JSON and write the comparison table (schema, namespaces, comments, arrays, dates, number precision).
- Parse both in Java, JSON with Jackson or Gson and XML with a DOM or StAX parser, and turn off external entities in the XML parser.
- Reproduce the single-element-list bug when converting XML to JSON and fix it.
Deliverable: The comparison table, working parse code for both formats, and a written fix for the single-element-list bug.
Day 4 — HTTP, HTTPS and the TLS handshake
- Run openssl s_client against a public HTTPS host and annotate the certificate chain, protocol version and cipher.
- Compare curl -v against an http and an https URL and mark where the handshake happens.
- Write the TLS handshake steps from memory, then answer the HTTP versus HTTPS question and the HTTPS mechanisms question aloud.
Deliverable: Annotated openssl output, a from-memory handshake outline and spoken answers to both HTTPS questions.
Day 5 — Kafka and API gateway concepts
- Write a one-page Kafka note on topics, partitions, offsets, consumer groups and at-least-once delivery, and what each means for duplicates and ordering.
- Write an Apigee cheat sheet: what a proxy and a target are, and how authentication, quota and spike-limit policies apply, with a troubleshooting order for a request that fails.
Deliverable: A Kafka one-pager, an Apigee cheat sheet and working solutions to the two practice problems.
Day 6 — Background and business-impact stories
- Write and rehearse a short spoken account of your background, education and why this role.
- Pick two projects and write each as decision, reason, result, with the effect on users or the business stated.
Deliverable: A written background account and two decision-reason-result stories, with notes from the two practice rehearsals.
Day 7 — Full dry run
- Answer the five reported fundamentals questions back to back, aloud, without notes.
- Deliver your background account, then one project story, then answer a business-impact question as if speaking to a leader.
- Write two questions to ask the team about its current projects, such as how API changes are versioned or where Kafka is used instead of direct calls.
Deliverable: A recorded full run, a list of the answers that needed notes, and two written questions for the team.
Background, motivation and business impact
Candidates report that the opening stage reviews your background and education and that the final stage is a business-level conversation with leadership. Reported tips also mention explaining the reasons behind technical choices, being open to feedback and understanding how code affects the business. Prepare stories with a decision, a reason and a result you can state.
- Walk through your background and education, and explain why this role is your next step.
- Tell me about a technical choice you made and why you chose it over the alternatives.
- Describe a time a bug came from how data was serialised between two systems, and how you found it.
- Give an example of a task you owned from start to deployment and what changed for users or the business once it shipped.
- Describe feedback you received in a code review and what you changed because of it.
Ship under a deadline and bound the debt you chose
Medium · pagination · technical debt · tradeoffs
You have four days to ship a tenant-facing listing endpoint. The version you would defend uses keyset pagination over (tenant_id, status, updated_at DESC, resource_id DESC); the version you can finish uses LIMIT/OFFSET with no matching index. Describe a deadline call you actually made of this shape: what you shipped, what you knowingly deferred, how you bounded the damage with a mechanism rather than an intention, and the specific numeric condition that would force the follow-up. Name who you told and where you wrote it down.
Approach
- Name the deferred failure precisely instead of calling it slow. OFFSET n makes the database produce and discard n rows, so cost grows with page depth; without an index matching the sort, every matching row is read and sorted before the limit applies; and rows inserted between two page fetches shift across the boundary so items are skipped or repeated with nothing in the response to signal it.
- Bound the blast radius with something mechanical rather than a promise: cap maximum page depth, cap page size, restrict the endpoint to one internal caller, or keep it behind a flag. State which failure each cap removes and which it leaves standing.
- Attach a number to the trigger and wire it to an alarm: the first tenant crossing N resources, or the endpoint's p99 crossing its share of the 400 ms budget, so the debt announces itself instead of waiting to be remembered.
- Write it where the next engineer looks, which is the code and the ticket, not a chat message: what was deferred, why, the cap, and the trigger.
Follow-up
- At what page depth does the offset version breach your latency budget, given your page size and row counts?
- What breaks first when you switch to keyset pagination later, and what does a client holding an old page token see?
Estimate work you have never done and defend the range
Hard · estimation · backfills · expand-contract
You are asked to estimate a change you have never attempted: add a column to a 100-million-row table, populate it, move reads across, and drop the old shape. Give a range with the assumptions that generate it, including batch size, the signal your backfill throttles on, and wall-clock hours, and name the three unknowns that would move the number most. Then describe a real estimate you gave under comparable ignorance: how you expressed its uncertainty, what you committed to, and how wrong you turned out to be.
Approach
- Decompose into independently deployable steps before estimating anything: add the column nullable, write both shapes, backfill in batches, verify, move reads, stop writing the old shape, drop it. That is four deploys spread over days, and the calendar estimate is dominated by them rather than by the loop's runtime.
- Do the arithmetic aloud for the part that has arithmetic in it: batch size times number of batches times per-batch duration, at a write rate the primary can absorb alongside roughly 1.2k writes per second of production traffic. The loop is throttled by replication lag and lock waits, not by how fast it can issue statements.
- Price the schema step by its lock rather than its statement duration. In PostgreSQL an ALTER TABLE taking ACCESS EXCLUSIVE waits for every open transaction on that table while later queries queue behind it, so a millisecond change issued during a thirty-second analytics query stalls that table for thirty seconds. Adding a nullable column with a non-volatile default avoids a rewrite from version 11; a new index wants CREATE INDEX CONCURRENTLY, which cannot run inside a transaction block and leaves an invalid index behind if it fails.
- Express the answer as a range whose endpoints each trace to a stated assumption, then name the cheapest experiment that collapses it, which is almost always running one real batch against the real table and multiplying.
Follow-up
- How do you verify the backfill genuinely finished, given rows written by production traffic while it ran?
- Where does the backfill resume from after a worker is killed mid-batch, and what makes that resume point trustworthy?
Tell callers you do not own that their integration breaks
Medium · deprecation · compatibility · stakeholders
A field in a write endpoint's response must change shape. You own the endpoint; you do not own the four internal callers or the outbound webhook consumers who read it. Describe a deprecation you were responsible for: what you shipped first, how you established who was actually reading the field, the window you gave and what set its length, what you did about the consumer who never moved, and how you decided removal was safe. Name the signal you used, not the announcement you sent.
Approach
- Establish the reader set empirically rather than from a wiki of owners: per-field usage counters keyed by principal, or access logs attributed to a consumer. State the blind spot of whichever you pick, since a consumer that reads the field only on a monthly job will not appear in a week of logs.
- Ship additive first. Populate the new field alongside the old one so no reader is forced to move, which is also what keeps a rolling deploy safe, because old and new instances answer the same requests at the same time and a rollback must still find the old shape present.
- Set the window from the slowest legitimate consumer's release cadence, not from your calendar, and decide separately what to do for a consumer with no release process at all, such as an external webhook endpoint you can only email.
- Convert silence into evidence before you rely on it: a short, low-traffic removal window that makes a still-dependent consumer fail visibly and loudly while you are watching, rather than at three in the morning after you have moved on.
Follow-up
- How would you detect a consumer that reads the field only during a monthly export?
- One caller refuses to move and has a commercial relationship behind it. What changes in your plan and what does not?