Interview guides · AppViewX
AppViewX Software Engineer Interview Guide
AppViewX Software Engineer interview guide: the five reported rounds, coding, Java, Linux and networking questions, and a 7-day plan.
The 60-second brief
AppViewX makes software that automates and orchestrates network and security operations. Candidates describe a platform that deals with enterprise digital identities, certificates and application delivery infrastructure. A Software Engineer is described as working on that platform's orchestration engine or on individual automation modules, writing code that plugs into varied network environments, designing APIs, and working alongside product and QA teams from the first requirement through to deployment.
This guide is for candidates interviewing for a Software Engineer position at AppViewX. It covers the five reported stages, the coding, Java, OOP, Linux, networking, design and puzzle questions candidates report, the Group Discussion and managerial stages, and a seven-day schedule that sequences all of it. Java is the language the role description favours; Python and C++ are also listed, so the code examples and drills here are written to transfer across them.
Candidates report five stages over roughly four to six weeks: an Online Assessment, Technical Interviews, a Group Discussion, Managerial Interviews and the Final Offer. The technical stage is described as discussion-heavy, with whiteboarding and live troubleshooting.
Focus areas
- Data Structures & Algorithms (DSA)
- Java
- Arrays
Overview
The product handles network and security operations: certificates, identities and application delivery. That explains why the reported questions mix two worlds. One half is ordinary software-engineering ground: arrays, strings, object-oriented design, Java concurrency, a custom immutable list. The other half is systems knowledge: the OSI model, ARP, routers versus switches, SFTP, why one user can reach a site while another cannot, and what to do when an application on a Linux server slows down. A candidate who prepares only LeetCode-style coding leaves half the reported question set untouched.
The reported requirements are Java (favoured), a grasp of data structures and algorithms, networking basics including OSI, TCP/IP and DNS, SQL and DBMS knowledge, and comfort in a Linux environment. Spring Boot, cloud or virtualization exposure and some security or identity-management background are listed as extras. Prepare the must-haves to the point where you can explain them aloud, and learn enough about certificates, encryption and ports to talk about them without bluffing.
Candidates describe the technical stage as discussion-heavy: whiteboarding a solution, explaining the architecture behind projects on your resume, and working through a broken-system scenario live. That favours rehearsal out loud. For each reported question, practise saying the clarifying question, the approach, the complexity, the edge cases and one alternative, in that order. Reported puzzles (the snail and the well, the jugs, the mislabelled boxes, the clock hands) belong in the same routine: state the reasoning and check it against a small case.
Two stages are about people rather than code: a Group Discussion that candidates say looks at working in a team and putting ideas across, and Managerial Interviews. Prepare two or three project stories in which you can explain why you made each technical choice, and practise explaining a technical decision to someone outside engineering. The seven-day plan below puts coding first, systems knowledge in the middle and these conversation stages at the end.
The AppViewX interview process
These are the five stages candidates describe, in the order they report them. Only brief descriptions are reported for each, so the preparation advice below is built from the reported question types rather than from claims about any single stage.
Online Assessment
Candidates report that the process begins with an online assessment of technical capability. The format is not described in more detail, so prepare for the full range of fundamentals the loop reports instead of betting on one question type. Treat it as a stage where you answer alone, with no one to talk the problem through with, so your clarifying questions have to be settled in your own head before you write.
What to demonstrate
- Technical capability, which is the purpose candidates give for this stage
- Your fundamentals in the language you choose to answer in
How to prepare
- Write the minimum-and-maximum and first-repeating-character solutions in your main language without autocomplete, each with an empty input and a single-element input handled.
- Revise language basics you can state precisely: mutable versus immutable collections, variable scope, and the difference between run-time and compile-time polymorphism.
- Practise reading a short problem statement and writing down your assumptions about duplicates, empty input and case before you code.
Technical Interviews
Candidates describe several technical interviews that are discussion-heavy: you may be asked to whiteboard a solution, explain the architectural choices behind projects on your resume, or troubleshoot a live scenario. Expect to move between code, Java and OOP, Linux and networking in one sitting. Approach it as a conversation: ask clarifying questions first, think aloud, give the complexity, and say plainly when you do not know something and how you would find out.
What to demonstrate
- Data structures and algorithms, with complexity stated for each solution
- Java and object-oriented fundamentals, including concurrency and memory management
- Networking and Linux troubleshooting reasoning on a broken-system scenario
- How clearly you explain the reasoning behind your own project decisions
How to prepare
- Rehearse whiteboard-style answers to the reported coding questions: array scan, first repeating character, Fibonacci sum under a limit, and the custom immutable ArrayList that forbids duplicates.
- Prepare a Java concurrency answer that goes beyond the keyword synchronized: visibility versus atomicity, locks, atomics, concurrent collections and executors.
- Build a repeatable troubleshooting sequence for a slow application on a Linux server and for one user being unable to reach a site that works for someone else.
- For every project on your resume, write down why you chose the language, data store and structure, and what you would change.
Group Discussion
Candidates report a Group Discussion stage that looks at how well you work within a team and put your ideas across. No topics are reported, so preparation is about contribution quality rather than content. Plan to listen first, make points that build on what others said, and keep your language plain enough that a non-engineer in the group could follow it.
What to demonstrate
- Ability to work within a team, which is the reported purpose of the stage
- Clarity when articulating an idea to other candidates
How to prepare
- Run a mock discussion with two or three friends on a technical trade-off, for example SQL versus a document store for a given workload, and give each person a turn to summarise the group's position.
- Practise a three-part structure for every contribution: your position, one reason, and one question or concession to the previous speaker.
- Practise explaining a technical concept such as a certificate, a cache or a thread pool in everyday words, since candidates are told to expect cross-functional communication.
Managerial Interviews
Candidates report managerial interviews that look at how you fit into a collaborative team. The role description stresses ownership from conception to deployment and working with product and QA colleagues, and candidates are advised to be ready to discuss past projects and your part in them. Bring concrete stories with your own decisions in them, not a team summary.
What to demonstrate
- Your role and decisions in past projects
- Communication of technical choices to non-technical stakeholders
- Honesty about gaps in your knowledge and how you would close them
How to prepare
- Write two project stories as situation, your decision, the alternative you rejected, and the result, and say each aloud until it flows.
- Prepare an example of working with a QA or product colleague where a requirement changed or a defect surfaced late.
- Prepare a true example of not knowing something and how you found out, since candidates are told not to bluff.
Final Offer
Candidates describe the final stage as the offer, received after the earlier rounds are completed successfully. No further assessment is reported for it. Treat it as the point to confirm next steps with the recruiter and to prepare for the conversation about terms.
What to demonstrate
- Successful completion of every earlier stage, the only condition candidates describe
- Your own questions about the role, the team and the next steps
How to prepare
- Keep the recruiter informed and ask about your status between stages, as candidates are advised to do.
- Research the market range for your location and seniority from sources you trust before any offer conversation, and write down your own priorities.
- Prepare questions about which part of the platform you would work on, such as the orchestration engine or an automation module.
Where candidates lose points
Starting to code the first-repeating-character question without defining what first repeating means.
Ask which reading is meant: the character whose second occurrence comes earliest, or the first character in the string that occurs again anywhere. For the first reading, one pass with a HashSet is enough. For the second, count frequencies first and scan again. Say the complexity, O(n) time, and state what the answer is when no character repeats.
Answering the Java concurrency question with the keyword synchronized and nothing else.
Separate atomicity from visibility, and name volatile, locks, atomics, concurrent collections and executors with one use case each. Be ready to explain a deadlock and how to read a thread dump, and tie the answer to a piece of your own code.
Answering the slow Linux application question by guessing, for example blaming memory straight away.
Work down a fixed sequence: load and CPU with top, memory and swap with free and vmstat, disk with iostat, network connections with ss, and then application level evidence such as a thread dump or garbage-collection log. State what each result would rule in or out before moving on.
Reciting the OSI layers or the router-versus-switch difference as a memorised list.
Attach a function, a data unit and a protocol to each layer and trace one request through them. Place the switch at layer 2, forwarding by MAC address, and the router at layer 3, forwarding by IP address between networks, and explain where ARP sits between the two.
Giving a puzzle answer, or a single group-discussion remark, with the result but no reasoning.
For the snail question, say that it reaches the top during a day's climb, so the last night's slip never happens, and then check the count against a small well. For the jug and box questions, list each state or deduction aloud. In the Group Discussion, state a position, give a reason, and build on the previous speaker.
Questions & practice
Write a program to find the minimum and maximum values in an array.
Medium · Technical Fundamentals & Programming
Approach
- Clarify first: what to return for an empty array (throw, return null or an Optional) and whether values can be negative. Initialise both min and max from the first element, not from 0, so all-negative input still works.
- Single pass: compare each element against both running values. O(n) time, O(1) extra space, about 2(n-1) comparisons.
- Pairwise trick if asked to cut comparisons: take elements two at a time, compare the pair with each other, then compare the smaller with min and the larger with max. That is 3 comparisons per 2 elements, about 3n/2 in total; handle an odd length by seeding min and max from the first element.
- Sorting first gives the answer at both ends but costs O(n log n) and changes or copies the array, so name it only to reject it.
- Edge cases to test aloud: one element (min equals max), all equal values, Integer.MIN_VALUE and Integer.MAX_VALUE present, and a null array.
Follow-up
- How would you find the second largest value in one pass?
- How many comparisons does the pairwise version need exactly, and why is that the lower bound?
- How would you find the k-th smallest without sorting (quickselect, average O(n))?
Implement a function to find the first repeating character in a string.
Medium · Technical Fundamentals & Programming
Approach
- Clarify the definition, because two readings give different answers: the character whose second occurrence comes earliest, or the earliest character in the string that occurs more than once. For "abba" the first reading returns 'b' and the second returns 'a'.
- Earliest second occurrence: scan left to right with a HashSet (or a boolean[256] for ASCII); return the first character already in the set. O(n) time, O(k) space for an alphabet of size k.
- Earliest character that repeats anywhere: first pass counts frequencies in a map or int array, second pass returns the first character with count above 1. Still O(n) time.
- The brute-force double loop is O(n^2); mention it only as the baseline. For lowercase letters only, a 26-bit int bitmask replaces the set in O(1) space.
- Edge cases: empty string or no repeat (return a sentinel or null and say which), case sensitivity, spaces and punctuation, and in Java characters outside the BMP, which take two chars, so iterate codePoints() if full Unicode matters.
Follow-up
- How would you change it to return the first non-repeating character?
- What if the characters arrive as a stream and you must answer after each one?
- Which reading of 'first repeating' did you code, and how would the output differ on "abba"?
How often do the hour and minute hands of a clock coincide in a single day?
Medium · Problem-Solving & Puzzles
Approach
- Relative speed: the minute hand moves 6 degrees per minute and the hour hand 0.5, so the minute hand gains 5.5 degrees per minute and laps the hour hand every 360 / 5.5 = 720/11 minutes, about 65.45 minutes.
- In 12 hours (720 minutes) that is 720 / (720/11) = 11 coincidences, not 12, because there is no overlap between 11:00 and 12:00 apart from 12:00 itself. A full day therefore has 22.
- State the boundary convention: counting from 00:00 up to but not including the next midnight gives 22 (00:00 and 12:00 included).
- As code: the k-th coincidence is at 720k/11 minutes after midnight for k = 0 to 21; convert each to hh:mm:ss to list them (about 1:05:27, 2:10:55, and so on). Use exact fractions or integer arithmetic in seconds to avoid floating-point drift.
- Sanity check: the first one after 12:00 must fall a little after 1:05, since the hour hand has moved on by then; that matches 65.45 minutes.
Follow-up
- How many times a day are the hands at right angles? (44: two per relative lap.)
- How many times a day do they point in exactly opposite directions?
- When do the hour, minute and second hands all coincide?
How would you implement a custom ArrayList that is immutable and forbids duplicates?
Medium · Design & Scenario-Based Thinking
Approach
- Clarify the contract: on a duplicate, throw or silently drop? Is null allowed? Does insertion order matter? Immutability here means no structural change after construction.
- Use composition, not inheritance from ArrayList: a final class extending AbstractList<E> that overrides only get(int) and size(). AbstractList's add, set and remove already throw UnsupportedOperationException, and its iterators inherit that. Subclassing ArrayList means overriding every mutator, and later JDKs keep adding new ones (addFirst and addLast arrived in Java 21).
- Construction: defensively copy the input into a private final Object[] while a HashSet checks for duplicates. That is O(n) expected time, and copying ensures a later change to the caller's collection cannot leak in. Keep the set as a field too if contains should run in O(1) instead of O(n).
- Explain why the library shortcuts fall short: Collections.unmodifiableList is a read-only view, so changes to the underlying list still show through. List.copyOf is truly unmodifiable but still allows duplicates.
- Limits: the immutability is shallow, so a mutable element whose equals or hashCode changes can break the no-duplicates rule; prefer immutable element types. With final fields and no escaping this during construction, the object is safely published to other threads without locks.
Follow-up
- How would you support adding an element, and what does each add cost?
- Is your list thread-safe, and why does the final keyword matter for that?
- How would you enforce the no-duplicates rule if elements are mutable?
Write the update path that detects a concurrent edit
Medium · optimistic concurrency · transactional outbox · audit history
resource carries version INT NOT NULL DEFAULT 1. resource_revision holds revision_id, resource_id, version, actor_user_id, change_kind, patch JSONB, request_id, created_at with UNIQUE (resource_id, version). outbox_event holds aggregate_type, aggregate_id, aggregate_version, event_type, payload, status. A PUT carries the version the client read. Write the exact statements for the single transaction that applies the edit, records the revision and enqueues 'resource.updated', and give the handler's branch on zero affected rows. Then say what PostgreSQL 16 does under READ COMMITTED when two of these updates hit one row at once.
Approach
- One transaction, three writes, no network call inside it: UPDATE resource SET title = $3, version = version + 1, updated_at = now() WHERE resource_id = $1 AND tenant_id = $4 AND version = $2; then INSERT the resource_revision row at version $2 + 1; then INSERT the outbox_event row at the same aggregate_version. The event goes to a table rather than a broker because no transaction spans both.
- Branch on the affected-row count before doing anything else. Zero has three causes — stale version, wrong tenant, row gone — so re-read once and map to 409 carrying the current version, or 404 for an id outside the caller's tenant, which also stops the endpoint confirming that another tenant's id exists.
- State the engine behaviour instead of assuming it. Under READ COMMITTED the second UPDATE blocks on the row lock, and when the first commits PostgreSQL re-evaluates the WHERE clause against the newly committed row, so the version predicate now fails and the statement reports zero rows. Under REPEATABLE READ the identical collision raises SQLSTATE 40001 instead, so the handler must fold both shapes into one conflict response.
- Keep UNIQUE (resource_id, version) even though the predicate already serialises writers. It is what makes a lost update unwritable if any other path ever reaches the revision table, and it converts a logic bug into 23505 rather than into a silently missing history row.
Follow-up
- A client sends the version it read ten minutes ago and the resource has moved three versions. What is in your 409 so it can resolve the conflict without a full re-fetch?
- Two editors, two disjoint fields, no overlap. Does your answer still refuse the second write, and should it?
Hold a per-tenant active cap against concurrent creates
Hard · write skew · isolation levels · constraints
A tenant on the standard plan may hold at most 50 resources with status='active'. The create handler runs SELECT count(*) FROM resource WHERE tenant_id = $1 AND status = 'active', compares to 50, then inserts. Two creates arrive 3 ms apart on different instances and the tenant lands at 51. Name the anomaly, say whether PostgreSQL 16 READ COMMITTED or REPEATABLE READ prevents it and why, then give an implementation that holds the cap at READ COMMITTED with the exact statements. Finally, say what changes when the cap is 'at most one running export per tenant' on job_run.
Approach
- Name it: write skew. The two transactions read an overlapping set and write disjoint rows, so there is no row-level conflict for the engine to detect and each commit is individually legal.
- Rule out the levels precisely. READ COMMITTED takes a fresh snapshot per statement and takes no lock on the counted rows, so both see 49. PostgreSQL's REPEATABLE READ is snapshot isolation: it removes non-repeatable reads and phantoms within the snapshot but still admits write skew, because the anomaly is not a re-read of a changed row, it is a read of a set that a concurrent transaction invalidates. Only SERIALIZABLE closes it, by tracking the read dependency and aborting one transaction with SQLSTATE 40001 — a guarantee that exists only if the application re-runs the whole transaction from the read.
- Convert the set predicate into a single-row conflict: keep tenant.active_resource_count and run UPDATE tenant SET active_resource_count = active_resource_count + 1 WHERE tenant_id = $1 AND active_resource_count < 50 in the same transaction as the INSERT. Zero affected rows is the cap, returned as 409. The row lock serialises the decision at any isolation level, and contention is bounded to one tenant's row — which is also the fair-scheduling unit, unlike a global counter that would convoy every tenant behind one row.
- State the cost you just took on: a counter is a second source of truth that can drift, so every path that changes status must adjust it inside the same transaction, and a periodic reconciliation has to exist, with resource_revision as the authority for what the count should have been.
Follow-up
- A resource moves from archived back to active. Which statements change, and what breaks if the counter update and the status change land in different transactions?
- The cap becomes plan-dependent and a plan can change mid-month. Where does the number 50 live, and who reads it?
Explain the difference between List and Tuple, or Local and Global variables.
Medium · Technical Fundamentals & Programming
Approach
- List vs tuple in Python: a list is mutable (append, insert, pop, item assignment), a tuple is immutable once built. Because of that, a tuple is hashable when all its elements are hashable, so it can be a dict key or set member and a list cannot.
- Practical consequences: tuples are slightly smaller in memory and fit fixed records such as (host, port) and multiple return values; lists fit collections that grow or get sorted in place. Immutability is shallow: a tuple holding a list still lets that list change, and then hashing the tuple raises TypeError.
- Local vs global: Python resolves names by LEGB (Local, Enclosing, Global, Built-in). Any assignment to a name inside a function makes it local for the whole function body, so reading it before the assignment raises UnboundLocalError.
- To rebind a module-level name inside a function, declare it with global; for an enclosing function's variable use nonlocal. Mutating a global object (appending to a global list) needs no declaration because the name is not rebound.
- If you answer in Java terms: Java has no true globals; the nearest equivalent is a static field, and local variables live on the thread's stack, which is why they are thread-confined while shared static state is not.
Follow-up
- What happens if you use a tuple that contains a list as a dictionary key?
- Why does a mutable default argument such as def f(x=[]) keep its contents between calls?
- When would you pick a namedtuple or a frozen dataclass over a plain tuple?
Explain the core pillars of OOPS (Inheritance, Polymorphism, Abstraction, Encapsulation).
Medium · Technical Fundamentals & Programming
Approach
- Encapsulation: keep fields private and change state only through methods that enforce invariants, for example a BankAccount whose withdraw method refuses to go negative. The point is protecting invariants, not just writing getters and setters.
- Abstraction: expose what an object does and hide how, through interfaces and abstract classes. Callers depend on a CertificateStore interface, not on whether it is backed by a file or a database.
- Inheritance: an is-a relationship that reuses and specialises behaviour through extends. In Java a class extends one class but can implement many interfaces. Prefer composition when the relationship is really has-a, and respect Liskov substitution (a Square that breaks a Rectangle's setWidth contract is the classic violation).
- Polymorphism: compile-time (method overloading, picked by the declared argument types) vs run-time (method overriding, picked by the object's actual class through dynamic dispatch). Static, private and final methods are not overridden; a static method with the same signature in a subclass only hides the parent's.
- Tie each pillar to one short code example rather than a definition list, and finish with how they combine: an interface (abstraction) with several implementations (polymorphism) whose state is private (encapsulation).
Follow-up
- What is the difference between an abstract class and an interface since Java 8 added default methods?
- Can you override a static method in Java, and what happens if you try?
- When would you choose composition over inheritance in your own code?
Explain the OSI Model layers and their specific functions.
Medium · Networking & System Domain
Approach
- Name the seven layers bottom-up with their unit and an example. 1 Physical: bits on the wire or radio. 2 Data Link: frames, MAC addresses, Ethernet, switches, CRC error detection. 3 Network: packets, IP addressing and routing, routers. 4 Transport: segments, TCP and UDP, ports, reliability and flow control.
- 5 Session: setting up and tearing down sessions between applications. 6 Presentation: encoding, serialisation, compression and encryption. 7 Application: protocols the program speaks, such as HTTP, DNS, SMTP and SSH.
- Map it onto TCP/IP, which is what real stacks implement: Link, Internet, Transport, Application, with OSI layers 5-7 folded into Application. Say plainly that TLS does not sit cleanly in one OSI layer; it runs above TCP and below HTTP.
- Walk one HTTPS request through the stack: DNS resolves the name, TCP three-way handshake on port 443, TLS handshake and certificate validation, HTTP request, IP routing hop by hop, ARP for the next-hop MAC, Ethernet frames on the wire.
- Use the layers as a troubleshooting map: link lights and cabling, then IP and gateway, then port reachability, then TLS and the application response.
Follow-up
- At which layer does a load balancer work, and what does an L7 balancer see that an L4 one cannot?
- Where does ARP fit, given that it links layer 2 and layer 3 addresses?
- Which layer does a TLS certificate error belong to, and how would you confirm it?
Describe the difference between a router and a switch.
Medium · Networking & System Domain
Approach
- A switch works at layer 2: it forwards Ethernet frames by MAC address inside one local network. It learns which MAC sits on which port from source addresses and floods frames whose destination it has not learned yet.
- A router works at layer 3: it forwards IP packets between different networks using a routing table with longest-prefix match, decrements TTL and rewrites the layer-2 header at every hop.
- Domains: each switch port is its own collision domain, but all ports (in one VLAN) share a broadcast domain; a router separates broadcast domains. Home routers also bundle NAT, DHCP and a switch, which is why the two get confused.
- How a host chooses: it compares the destination IP against its own subnet mask. Same subnet means ARP for the host and send through the switch; different subnet means send to the default gateway (the router).
- Mention layer-3 switches and VLANs as the blurred middle: switches that route between VLANs in hardware.
Follow-up
- What does a switch do with a frame for a MAC address it has never seen?
- How does a hub differ from a switch?
- Why can two hosts on different VLANs on the same switch not talk without a router?
What is ARP protocol, and why is it used?
Medium · Networking & System Domain
Approach
- ARP (Address Resolution Protocol) maps an IPv4 address to a MAC address on the local network. IP decides where a packet goes logically; Ethernet still needs the hardware address of the next hop to deliver the frame.
- Sequence: check the ARP cache (ip neigh or arp -a); on a miss, broadcast a request to ff:ff:ff:ff:ff:ff asking who has that IP; the owner replies unicast with its MAC; the sender caches the answer for a limited time.
- For a destination on another subnet, the host resolves the default gateway's MAC, not the remote server's. This detail separates a memorised answer from an understood one.
- Security: ARP has no authentication, so ARP spoofing or poisoning lets an attacker claim the gateway's IP and sit in the middle. Mitigations include dynamic ARP inspection on switches, static entries for critical hosts, and encryption such as TLS so intercepted traffic is unreadable.
- Related points: gratuitous ARP announces or updates a mapping (used in failover), and IPv6 replaces ARP with Neighbor Discovery (NDP).
Follow-up
- Why does a host ARP for the gateway rather than the remote server?
- How would you detect ARP spoofing on a network?
- What replaces ARP in IPv6?
Explain the role of SFTP and SFB in secure communications.
Medium · Networking & System Domain
Approach
- SFTP is the SSH File Transfer Protocol: a subsystem of SSH, normally on port 22. Commands and file data are encrypted on one connection, which makes it simpler to pass through firewalls than plain FTP with its separate data channel.
- Separate it from FTPS (FTP over TLS, ports 21 or 990, X.509 certificates) and from SCP (copying over SSH without SFTP's file-management operations). Confusing SFTP with FTPS is the common mistake.
- Security mechanics: the server proves its identity with a host key the client checks against known_hosts, which stops man-in-the-middle attacks; the user authenticates with a password or, better, a public key; SSH provides confidentiality and integrity for the whole session.
- SFB is not a standard protocol acronym, so ask what is meant instead of guessing. If it means Skype for Business, explain that it signals over SIP on TLS and carries media over SRTP, and that both depend on valid certificates.
- Close with a scenario: automated file drops between servers over SFTP with key-based accounts, restricted to a chroot directory, keys rotated and host keys pinned.
Follow-up
- How does SFTP differ from FTPS in authentication and firewall behaviour?
- What does the known_hosts check protect against, and what happens if a server's host key changes?
- How would you automate SFTP transfers without storing a password in a script?
A snail climbs 3 feet during the day and slips 2 feet at night. If the well is 30 feet deep, how long until it
Medium · Problem-Solving & Puzzles
A snail climbs 3 feet during the day and slips 2 feet at night. If the well is 30 feet deep, how long until it reaches the top?
Approach
- The net gain is 1 foot per day-night cycle, but on the final day the snail climbs out and never slips back. Counting 30/1 = 30 days is the trap.
- After 27 full days and nights it is at 27 feet. On day 28 it climbs 3 feet to reach 30 and is out, so the answer is 28 days.
- State the assumption out loud: reaching the rim exactly counts as getting out.
- Generalise: with climb c, slip s and depth D greater than c, days = ceil((D - c) / (c - s)) + 1. Here ceil(27/1) + 1 = 28. If D is at most c it takes 1 day; if c is at most s and D is greater than c, it never gets out.
- Check the formula with a tiny case by hand (a 4-foot well takes 2 days) or a short simulation loop before trusting it.
Follow-up
- What if the well is only 3 feet deep?
- What if the snail slips 3 feet each night?
- Write the simulation and show it agrees with the closed-form formula.
How can you measure exactly four liters of water using a three-liter and a five-liter jug?
Medium · Problem-Solving & Puzzles
Approach
- Shortest route, starting from the 5-litre jug: fill the 5 (5,0), pour into the 3 (2,3), empty the 3 (2,0), pour the 2 into the 3 (0,2), fill the 5 (5,2), top up the 3, which takes 1 litre, leaving 4 in the 5. Six operations.
- The other route, starting from the 3-litre jug: fill 3, pour into 5; fill 3 again, pour until 5 is full, leaving 1 in the 3; empty 5; move the 1 across; fill 3 and pour, giving 4. It works but takes more steps.
- Why it is solvable: with jugs a and b, a target t can be measured exactly when t is a multiple of gcd(a, b) and t is at most max(a, b). gcd(3, 5) = 1, so 4 is reachable.
- To solve it as code, run BFS over states (x, y) with six moves: fill either jug, empty either jug, pour either way. There are at most (a+1)(b+1) states (24 here), and BFS returns the shortest sequence.
- Narrate the state pair after every move so the listener can check each step.
Follow-up
- Can you measure 4 litres with a 6-litre and a 9-litre jug? Why not?
- Write the BFS and say how you would rebuild the sequence of moves.
- What is the time and space complexity of that BFS in terms of the jug sizes?
You have three boxes that are wrongly labeled; you have one chance to label them perfectly—how do you do it?
Medium · Problem-Solving & Puzzles
Approach
- Set it up: three boxes labelled Apples, Oranges and Mixed, and every label is wrong. You may take one fruit from one box, then relabel all three correctly.
- Draw from the box labelled Mixed. It cannot be mixed, so the fruit you draw tells you what it holds; say it is an apple, so that box is Apples.
- The box labelled Oranges cannot hold oranges (its label is wrong) and cannot be apples (already placed), so it is Mixed. The box labelled Apples gets Oranges. The case where you draw an orange is symmetric.
- Explain why other choices fail: drawing an orange from the box labelled Apples leaves it either Oranges or Mixed, so one draw does not settle it.
- The structure underneath: 'all labels wrong' means the labelling is a derangement, and three items have exactly two derangements. One draw from the Mixed box picks between them.
Follow-up
- Why does drawing from the box labelled Apples not work?
- What if you were told only that at least one label is wrong?
- How does the reasoning change with four boxes and one draw?
Design a web crawler that operates within limited memory constraints.
Medium · Design & Scenario-Based Thinking
Approach
- Components: a seed list, a URL frontier, fetchers, a parser and link extractor, a URL normaliser, a seen-URL filter, robots.txt and per-host politeness, and a store for fetched pages. Fix scope first: number of pages, single machine or several, and whether freshness (re-crawling) matters.
- Memory pressure lives in the frontier and the seen-set. Keep the frontier on disk as segmented append-only files, with only a small in-memory buffer at the head and tail. Normalise URLs (lowercase scheme and host, strip fragments, resolve relative paths) before deduplicating.
- For the seen-set, use a Bloom filter: no false negatives, and a false positive only skips a URL that was never crawled. At a 1% false-positive rate it needs about 9.6 bits per URL with 7 hash functions, so 100 million URLs fit in about 120 MB. Alternatively, keep 64-bit URL hashes in a sorted on-disk file and merge in batches.
- Politeness and ordering: one queue per host with a minimum delay between requests to that host (the Mercator front-queue/back-queue layout), BFS with a depth limit, and robots.txt cached per host with an expiry.
- Stream page bodies rather than buffering them whole, cap page size, and detect duplicate content with a hash or SimHash fingerprint. Guard against spider traps with URL length limits, depth limits and per-host page caps.
Follow-up
- How does the crawler resume after a crash without re-crawling everything?
- How would you split the crawl across several machines without two of them fetching the same host?
- What does a Bloom filter false positive cost you here, and how would you size it for a lower rate?
How would you design an elevator system?
Medium · Design & Scenario-Based Thinking
Approach
- Clarify scope: number of elevators and floors, whether this is object design or the scheduling algorithm, capacity limits, and special modes such as maintenance or fire service.
- Classes: an ElevatorController (dispatcher), Elevator (current floor, direction, state enum IDLE, MOVING_UP, MOVING_DOWN, DOORS_OPEN, OUT_OF_SERVICE), Request split into hall calls (floor plus direction) and car calls (destination floor), plus Door and Button. The State pattern suits the elevator's modes and the Strategy pattern the dispatch policy.
- Per-car scheduling with the LOOK variant of SCAN: keep the up stops and down stops in two sorted sets (TreeSet), serve stops in the current direction, and reverse only when nothing remains ahead. Plain first-come-first-served makes the car zigzag; nearest-first can starve far floors.
- Dispatching a hall call: estimate each car's arrival time, prefer a car already moving toward the floor in the requested direction, then the nearest idle car, then the car with the shortest remaining route.
- Concurrency and edge cases: requests arrive from many buttons at once, so feed them into a thread-safe queue consumed by one controller loop (or lock each elevator's stop sets). Handle a request for the floor the car is already on, a full car skipping hall calls, and a car taken out of service mid-route whose stops must be reassigned.
Follow-up
- How do you stop requests at the far floors from being starved?
- How would you test the scheduler without real hardware?
- How would you change dispatching for morning rush hour, when most trips start at the lobby?
Explain how you would rectify a connectivity issue where one user can access a website but another cannot.
Medium · Design & Scenario-Based Thinking
Approach
- Find the difference between the two users before touching anything: same network or not, same browser, same device type, and the exact error (DNS failure, timeout, connection refused, certificate warning, HTTP 403 or 5xx). Each error points at a different layer.
- Name resolution on the failing machine: nslookup or dig the hostname and compare the IP with the working user's. Look for a stale DNS cache, a hosts-file entry, a different resolver, or VPN split DNS. If the site loads by IP but not by name, it is DNS.
- Path and port: curl -v https://host shows where it stops (TCP connect, TLS handshake or HTTP response). traceroute and ping help, but many networks block ICMP. Check proxy settings, local firewall, and IPv6 vs IPv4: one machine may prefer a broken AAAA record.
- TLS-specific causes: a wrong system clock, a missing root or intermediate certificate in that client's trust store, or a corporate proxy that intercepts TLS. The certificate error text says which.
- Server-side causes: IP or geo blocking, a WAF or rate limit, or a load balancer with one unhealthy backend that only some users are pinned to. Confirm the fix by repeating the original failing request from the same machine.
Follow-up
- It works in an incognito window but not in the normal one. What does that tell you?
- It works on mobile data but not on the office Wi-Fi. Where do you look next?
- Only users on one ISP fail. What would you check on the server side?
How would you troubleshoot a slow-running application on a Linux server?
Medium · Networking & System Domain
Approach
- Define slow before touching the box: high latency or low throughput, every request or some, since when, and what changed (deploy, traffic, data size). Get one reproducible slow request if possible.
- Check host resources with the USE method (utilisation, saturation, errors). uptime for load average (on Linux it also counts tasks in uninterruptible I/O sleep), top for us, sy, wa and st CPU time, vmstat 1 for the run queue and swap activity (si/so), iostat -x for disk await and %util, free -m for memory, df -h for full disks.
- Look for errors the kernel already logged: dmesg for OOM-killer events and disk errors, ss -s for connection counts and TIME_WAIT build-up, ulimit -n with lsof for file-descriptor exhaustion.
- Then narrow to the process: pidstat or top -H -p PID for hot threads, strace -p to see the syscall it blocks on, perf top for CPU hot spots. For a JVM, take several jstack thread dumps a few seconds apart to spot locked or waiting threads, and jstat -gcutil to check for long or frequent GC.
- Finally check dependencies, since the application is often waiting on something else: slow database queries, DNS resolution, downstream HTTP calls. Confirm the fix with the same measurement you started from.
Follow-up
- Load average is high but CPU usage is low. What does that point to?
- One Java thread pins a core at 100%. How do you find it in a thread dump?
- The slowdown appears only under peak traffic. What would you look at differently?
Suggested practice checklist
The plan starts with coding and language fundamentals, moves through Java concurrency, networking and Linux troubleshooting, then puzzles and discussion practice, and ends with your project stories and a full run-through. Each day names the reported questions it practises.
Day 1 — Arrays, strings and Fibonacci in code
- Write the minimum-and-maximum function in Java and Python in a single pass, then test it on an empty array, one element and all-equal values.
- Write the first-repeating-character function using a HashSet, then write the variant that returns the first character occurring more than once, and compare the complexity.
- Write the function that prints the sum of the Fibonacci series under a given number, iteratively, and decide what happens for a limit of 0 or 1.
Deliverable: Three working, tested functions (min/max, first repeating character, Fibonacci sum) with a list of the edge cases each handles.
Day 2 — Language and OOP fundamentals
- Write a one-page answer on List versus Tuple (mutability, hashability, typical use) and on local versus global variables, with a short code example of each.
- Explain Inheritance, Polymorphism, Abstraction and Encapsulation with one Java class hierarchy, and mark where run-time polymorphism (overriding) differs from compile-time polymorphism (overloading).
- Say each answer aloud once, without notes, and note where you hesitate.
Deliverable: A written answer with a code example for each of the two fundamentals questions, plus a list of the points where your spoken version stalled.
Day 3 — Java concurrency and the immutable list
- Write a counter shared by several threads, show the lost update, and fix it three ways: synchronized, AtomicInteger and LongAdder.
- Write a producer-consumer pair on a BlockingQueue and a small deadlock, then fix the deadlock with consistent lock ordering.
- Implement an immutable list class that forbids duplicates: a final class, a defensive copy on construction, no mutators, and a decision on equality.
Deliverable: A runnable concurrency demo with three counter fixes and a deadlock fix, the immutable list class with tests, and a short spoken answer to the concurrency question.
Day 4 — Networking fundamentals and connectivity faults
- Draw the OSI layers with a function, a data unit and an example protocol each, then trace one HTTPS request through them.
- Write the router-versus-switch comparison (layer, address type, forwarding table, broadcast domain) and explain ARP: who asks, who answers, and the ARP cache.
- Look up SFTP and clarify what SFB refers to in the SFTP question, then write when you would pick SFTP for a transfer.
- Write a checklist for one user reaching a website while another cannot: DNS, IP and gateway, firewall or proxy, certificate, browser or account state.
Deliverable: A one-page networking reference and a connectivity-fault checklist you can recite in order.
Day 5 — Linux troubleshooting and design scenarios
- Write a slow-application runbook with the command for each step (top, free, vmstat, iostat, ss, thread dump) and what each result rules out.
- Outline a web crawler under limited memory: a disk-backed URL frontier, a Bloom filter or hashed set for visited URLs, per-host politeness and what you drop when memory is short.
- Model an elevator system as classes and a state machine, with request handling, direction scheduling and what happens with multiple cars.
Deliverable: A slow-server runbook, a crawler outline with its memory trade-offs, and an elevator class diagram.
Day 6 — Puzzles and group discussion
- Solve the snail-and-well, the three-liter and five-liter jug, and the mislabelled boxes puzzles, and write down the reasoning plus a check on a smaller case.
- Work out how often the clock hands coincide in a day, and show the relative-speed equation behind it.
- Hold a mock group discussion with two or three friends on a technical trade-off, and have each person summarise the group's position at the end.
Deliverable: Written reasoning for all four puzzles and notes on how your contributions went in the mock discussion.
Day 7 — Project stories and a full run-through
- Write two project stories with your decision, the rejected alternative and the outcome, and practise explaining one of them to a non-engineer.
- Do a spoken pass through one question from each area: coding, Java concurrency, OSI or ARP, Linux troubleshooting and a puzzle.
- List two questions to ask the recruiter about the process and the team.
Deliverable: Two written project stories, a list of your three weakest answers from the run-through, and your questions for the recruiter.
Behavioural preparation
Candidates describe the Group Discussion and Managerial Interviews as covering teamwork, how clearly you put ideas across, and your part in past projects. Role descriptions mention ownership from requirement to deployment and working with product and QA colleagues. Prepare stories in which your own decision is visible and the result is checkable.
- Walk through a project on your resume and explain why you chose its language, data store and structure over the alternatives.
- Tell me about a time you had to explain a technical decision to someone outside engineering.
- Describe a time you did not know the answer to a technical question and how you found it.
- Tell me about a time you disagreed with a teammate about a design and how it was resolved.
- Describe a defect that QA found late in your work: what caused it and what you changed afterwards.
How do you handle concurrency in Java?
Medium · Technical Fundamentals & Programming
Approach
- The question sits among the behavioral prompts but is a technical one, so answer it technically and anchor it in your own work. Start with the model: threads share the heap, and the three problems are atomicity (a count++ is a read, an add and a write), visibility (one thread's write may not be seen by another) and ordering. The Java Memory Model defines happens-before edges that fix visibility and ordering.
- Walk up the toolbox. volatile gives visibility and ordering for a single variable, not atomicity. synchronized and ReentrantLock give mutual exclusion plus visibility; ReentrantLock adds tryLock with a timeout, interruptible locking, and Condition objects. AtomicInteger and AtomicReference use compare-and-swap, and LongAdder reduces contention for hot counters. Prefer immutability and thread confinement first, since shared state you never mutate needs no lock.
- Cover the higher level: use an ExecutorService with a bounded pool and queue rather than creating threads by hand, Callable and Future or CompletableFuture for results, and BlockingQueue for producer-consumer. Size the pool by workload: near the core count for CPU-bound tasks and larger for I/O-bound ones. Shut executors down, and never swallow InterruptedException; restore the interrupt flag or propagate it.
- Name the hazards and the fix for each: check-then-act races (use putIfAbsent, compute or merge on ConcurrentHashMap, not get followed by put), deadlock (acquire locks in one global order, or use tryLock with a timeout), double-checked locking that needs a volatile field, and iterating a non-thread-safe collection while it is modified. Say how you would find a hang: take a thread dump with jstack and read the lock owners.
- Close with one real example from your projects: what was shared, what protected it, why you chose that tool, and how you tested it, for instance a stress test with many threads. If you have no such example, say so and describe a small one you have built; do not bluff.
Follow-up
- Why is count++ on a volatile int still unsafe, and what would you replace it with?
- ConcurrentHashMap is thread-safe, so why can get followed by put still lose an update?
- A service is hung. How do you confirm it is a deadlock from a running JVM, and how do you stop it recurring?
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?
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?