Interview guides · Bandwidth
Bandwidth Software Engineer Interview Guide
Bandwidth Software Engineer interview guide: 3 reported rounds, SIP and SMS routing, coding, Linux and behavioral questions, plus a 7-day plan.
The 60-second brief
Bandwidth, as candidates describe it, runs communications infrastructure that carries voice and messaging traffic for enterprise customers. The work reported for this role touches 911 emergency services, SMS routing, and PSTN and SIP signaling. Candidates describe the codebase as a mix of older monolithic systems and newer distributed, cloud-based services. A Software Engineer in this loop builds and maintains services in that environment: finding bottlenecks, refactoring older code, adding API features, turning product requirements into technical specifications, reviewing code, writing unit tests and, in some teams, taking part in an on-call rotation.
This guide is for engineers interviewing for the Software Engineer role at Bandwidth. It walks through the three reported rounds, the technical, coding and behavioral questions candidates report, and the stack named in the role requirements candidates describe: Python, Java or PHP (with Perl also mentioned for scripting), SQL and NoSQL databases, SIP and PSTN networking, Linux and LAMP administration, and AWS, Docker and Kubernetes as extras. It ends with a seven-day plan that uses all of it.
Candidates report three stages over roughly 3-5 weeks: a Recruiter Call, Technical Screenings, and an Onsite/Virtual Loop with peer developers and hiring managers. Some teams reportedly run the rounds on a single day and others spread them out.
Focus areas
- Coding interviews (whiteboard/problem solving)
- Data structures & algorithms
- Linux
Overview
The reported questions split into two kinds of preparation. Half are telecom-flavoured: explain the difference between SIP and PSTN signaling, design a system for high-volume SMS routing, implement a simple least-cost routing algorithm, troubleshoot network latency across a distributed system. The other half are ordinary computer-science staples: traverse a binary tree, find the most frequent element in an array, and state the time complexity of what you wrote. You need both. A candidate who has only drilled tree and hash-map problems will have nothing to say about signaling, and a candidate who knows telephony but cannot write a clean traversal on a whiteboard will struggle in a coding screen.
A theme runs through the technical and behavioral questions alike: older systems meeting newer ones. Candidates report questions on integrating REST APIs with legacy systems, on Linux sysadmin work and LAMP stacks, on a legacy system that was hard to maintain, and on redesigning a module of an older system for performance. Prepare one or two real stories where you changed code that was hard to change, and be ready to explain the technical mechanics (tests around existing behavior, seams, incremental replacement, rollback) as well as the people side.
Preparation should also cover logistics and communication. Candidates are advised to think aloud during whiteboard and coding sessions, to learn the basics of SIP, SMS and emergency services before the first call, and to ask about the team's legacy systems and modernization plans at the end. Some candidates report being asked early for a list of five references, former managers included, so contact those people before you need them. The plan at the bottom of this page puts each of these into a day.
The Bandwidth interview process
These are the three stages candidates describe, in the order they report them. Content and weight vary by team, so treat the preparation under each stage as a checklist rather than a script.
Recruiter Call
Candidates report the process opening with a call with a recruiter about your background and your interest in the company. Treat it as the one conversation where your own story, location and logistics matter most; the technical material comes later. Some candidates also report being asked early in the process for a list of five references that includes former managers, so have those people briefed before the question arrives.
What to demonstrate
- How your background connects to the role described to candidates: services, APIs, Linux, databases, older codebases
- Your interest in the company and its communications work
- Practical fit such as location and whether the role is hybrid, remote or based in a hub
How to prepare
- Write a short career account that links one real project to high-volume traffic, API work, Linux administration or legacy code, whichever you can back with detail.
- Learn the vocabulary before the call: what SIP signaling does, what the PSTN is, and why SMS routing and emergency calling put reliability first.
- Contact up to five former managers and colleagues now, tell them what the role is and what you would like them to say.
- Ask the recruiter which rounds follow, whether they run on one day, and whether the posting is remote, hybrid or tied to a hub such as Raleigh, NC or Denver, CO.
Technical Screenings
Candidates describe technical screenings that may include coding challenges, conceptual discussions or both. This guide covers both kinds of reported question: the coding set (binary tree traversal, the most frequent element in an array, least-cost routing, explaining complexity) and the conceptual set (SIP versus PSTN signaling, REST integration with legacy systems, network latency troubleshooting, Linux and LAMP experience). It does not claim which one a particular screen uses. Candidates are advised to talk through their reasoning aloud, so practise speaking while you write code.
What to demonstrate
- Working code and clear reasoning in a coding challenge
- Conceptual understanding when the screen is a discussion rather than code
- Your ability to state and justify the complexity of the solution you just wrote
How to prepare
- Write binary tree traversal recursively, iteratively with an explicit stack, and breadth-first with a queue, and say the time and space cost of each.
- Solve the most-frequent-element problem with a hash map, then discuss ties, an empty array and what changes when the data is streamed.
- Explain SIP versus PSTN signaling aloud in under a minute, then again with a call-setup example, until both versions sound natural.
- Rehearse a two-part answer for Linux and LAMP experience: what you owned, then one incident you diagnosed with real commands.
Onsite/Virtual Loop
The final stage is reported as an onsite or virtual loop made of several sessions with team members, including peer developers and hiring managers. Candidates describe the later rounds as bringing deeper behavioral and system design conversations, and some teams run them on one day. Design scenarios candidates report across the process include redesigning a module of a legacy system for better performance and designing a service that handles concurrent call routing. Expect to switch between design thinking and personal stories.
What to demonstrate
- Design reasoning: breaking a large problem into components and justifying each choice
- Behavioral conversations with peers and hiring managers about teamwork, disagreement and communication
- Collaboration across several different people in one loop
How to prepare
- Work through the high-volume SMS routing design end to end: ingestion, queueing, routing decision, delivery, retries and what you do when a downstream carrier is down.
- Outline a concurrent call routing service and a legacy-module redesign, including how you would roll out the change safely.
- Build a bank of five behavioral stories (stakeholder explanation, legacy system, competing deadlines, feedback, pressure) and rehearse each in a structure of situation, your decisions, result.
- Write three questions about the team's legacy systems and modernization plans to ask at the end of each session.
Where candidates lose points
Answering the binary tree traversal with only a recursive version and no complexity
Write pre-order, in-order and post-order recursively, then iteratively with an explicit stack, and add a breadth-first version with a queue. Say O(n) time and the space cost (O(h) for depth-first, O(w) for breadth-first), and mention a skewed tree where recursion depth reaches n.
Treating SIP and PSTN as interchangeable buzzwords, or reciting definitions with no call flow
Prepare a plain two-sentence contrast (IP-based signaling to set up and tear down sessions versus the traditional telephone network and its own signaling) and a short walk through how a call crosses between the two. Learn the basics of SMS and emergency calling too, since candidates are advised to know them.
Starting the SMS routing design with component names and no scope, then ignoring failure handling
Ask for volume, latency and delivery guarantees first. Then cover queueing and backpressure, a routing decision such as least cost with a fallback route, idempotent retries so a message is not sent twice, and what happens when a downstream route is unavailable.
A legacy-system story that ends with "so we rewrote it", or that blames the original authors
Tell the incremental version: tests around existing behavior first, small changes behind flags, measured results, and respect for the constraints the old code was built under. Be ready to explain when you chose not to rewrite.
Behavioral answers told in the first person plural, with vague claims about Linux or LAMP experience
Say "I" for what you decided and "the team" for what was shared. Only claim tools you can answer follow-up commands about, and brief your references early so a request for five names does not stall the process.
Questions & practice
Write a function to traverse a binary tree.
Medium · Coding & Algorithms
Approach
- Ask which order is wanted (preorder, inorder, postorder or level order) and what the output should be, then write the recursive depth-first version: visit, recurse left, recurse right, reordered for each variant. Every version is O(n) time and O(h) extra space for the call stack.
- Flag the depth problem: h equals n on a skewed tree, and CPython's default recursion limit is about 1000, so a deep tree needs an iterative version with an explicit stack.
- Iterative inorder: push the current node and walk left until null, then pop, visit, and move to the popped node's right child; repeat while the stack is non-empty or the current node is not null. Iterative preorder pushes the right child before the left so the left is processed first.
- Level order: BFS with a queue (collections.deque in Python), recording the queue length at the start of each level when the answer must be grouped by level. Space is O(w), where w is the widest level.
- Test the edges aloud: empty tree (return an empty list), a single node, a tree that is all left children, and duplicate values. Mention Morris traversal as the O(1)-extra-space option that temporarily rewires right pointers and restores them.
Follow-up
- Write postorder iteratively. How do you know when a node's right subtree is finished?
- How would you use an inorder traversal to check whether the tree is a valid binary search tree?
- Return the nodes level by level, alternating left-to-right and right-to-left on each level.
How would you implement a simple least-cost routing algorithm?
Medium · Coding & Algorithms
Approach
- Clarify which problem is meant. In telecom, least-cost routing usually means choosing the cheapest carrier route for a dialed number from a rate table keyed by number prefix; the graph reading means the cheapest path through a weighted network. Say which one you are solving, or outline both.
- Rate-table version: store prefixes in a digit trie where each node keeps its carrier routes sorted by cost. Walk the dialed E.164 number digit by digit and remember the deepest node that has routes (longest-prefix match). Lookup is O(L) with L at most 15 digits, and the result is the cheapest route plus an ordered fallback list.
- Graph version: run Dijkstra with a min-heap from the source, in O((V + E) log V) with a binary heap, and keep a predecessor map so the path can be rebuilt. It requires non-negative costs; Bellman-Ford handles negative weights in O(VE).
- Edge cases: no matching prefix (reject, or use a default route), equal costs (break ties on a stated rule such as route quality or a stable carrier order), carriers marked down or over capacity (skip them and fall through to the next), and rates that carry effective dates.
- Production details: rate tables change while lookups run, so build a new trie and swap the reference atomically instead of mutating the live one, and cache results per prefix if the table is large.
Follow-up
- The cheapest carrier has a poor completion rate on a destination. How would you add a quality threshold without losing the cost ordering?
- Rates for thousands of prefixes change every day. How do you load them without blocking live lookups?
- If the routes form a graph and a link's cost can change mid-run, what happens to Dijkstra's guarantees?
Given an array of integers, how would you find the most frequent element?
Medium · Coding & Algorithms
Approach
- Default answer: one pass with a hash map from value to count, tracking the best value and its count as you go. That is O(n) time and O(k) extra space for k distinct values (average case, since hash lookups degrade under heavy collisions).
- Settle the ambiguous cases before coding: an empty array (raise, or return None), and ties (the first value to reach the top count, the smallest value, or all tied values). In Python, Counter(nums).most_common(1) breaks ties by the order values were first seen.
- Alternative when memory is tight: sort in place and scan runs of equal values, which is O(n log n) time and O(1) extra space beyond the sort, but it mutates or copies the input.
- Do not reach for Boyer-Moore voting unless a majority element (more than n/2 occurrences) is guaranteed. Without that guarantee it can return a value that is not the mode, so it needs a second counting pass to verify.
- If the values have a small known range (for example 0..1000), a fixed-size count array replaces the hash map and gives true O(n) time with O(range) space.
Follow-up
- Return the k most frequent elements. What is the cost with a size-k heap versus bucket sort by frequency?
- The input is a stream too large to hold the counts in memory. How do you find approximate heavy hitters (Misra-Gries or Count-Min Sketch)?
- How does your answer change if you must return every value tied for the highest count?
Can you explain the time complexity of your proposed solution?
Medium · Coding & Algorithms
Approach
- Name the input-size variables first (n elements, k distinct values, h tree height, L digits) and state the result in those variables, not only in n.
- Derive it from the code: sequential blocks add, nested loops over the same input multiply, and constants and lower-order terms drop. A single counting pass over n items with O(1) average hash operations is O(n); sorting first makes it O(n log n).
- State space separately, and include the recursion stack and the output. A recursive tree traversal is O(n) time but O(h) stack, which is O(n) on a skewed tree.
- Name the hidden costs: hash maps are O(1) on average but O(n) in the worst case, dynamic-array append is amortized O(1), Python slicing copies k elements, list membership is O(n), and repeated string concatenation in a loop can turn O(n) into O(n^2).
- For recursive divide-and-conquer, write the recurrence and solve it: T(n) = 2T(n/2) + O(n) gives O(n log n) by the master theorem. If asked whether you can do better, cite the lower bound: comparison sorting is Omega(n log n).
Follow-up
- Is there a faster solution, and what would it cost in memory?
- What is the worst case for your hash-based solution, and what input would trigger it?
- Your solution is O(n) but slower than an O(n log n) one on real data. How can that happen?
Replace offset paging on the resource feed with keyset
Easy · keyset pagination · composite index · sort order
resource holds resource_id, tenant_id, owner_user_id, title, body_ref, version, status ('draft','active','archived','deleted'), created_at, updated_at, deleted_at, with an index on (tenant_id, status, updated_at DESC, resource_id DESC). The listing endpoint returns active resources for one tenant, newest update first, 50 per page, today with LIMIT 50 OFFSET n. Tenants reach page 400 and rows are created while they read. Write the keyset query, define what the cursor carries and how it is encoded, and say which part of the index each predicate uses. Assume PostgreSQL 16.
Approach
- Name the two failures separately. OFFSET 20000 makes the server produce and discard 20,000 rows, so page cost grows with depth rather than with page size. Independently, any write that changes how many rows sort above the offset moves the window between two fetches, and the direction decides which anomaly you get: an insert lands at the head of updated_at DESC and pushes already-returned rows down past the boundary, so they are returned a second time; a delete above the offset, or a row whose updated_at is bumped above the cursor, pulls rows up and one is never returned at all. Nothing in the response reveals either.
- Write the seek: WHERE tenant_id = $1 AND status = 'active' AND (updated_at, resource_id) < ($2, $3) ORDER BY updated_at DESC, resource_id DESC LIMIT 50. The row-value comparison is one index range rather than a disjunction, and both columns are NOT NULL, which is what makes that comparison well defined.
- Map each predicate onto the index: tenant_id and status are equality on the leading columns, (updated_at, resource_id) is the range, and the ORDER BY matches the index order so no Sort node appears and the scan stops after 50 rows. The DESC in the definition only matters for mixed directions — a plain ascending btree on the same columns is read backwards for this query.
- Put both sort columns in the cursor and nothing the client can tamper with into another tenant: base64 of (updated_at, resource_id), validated server-side, with tenant_id taken from the principal.
Follow-up
- The client asks for 'jump to page 400'. What do you offer instead, and what does the honest version cost?
- Sort order becomes user-selectable across four columns. How many indexes is that, and which would you refuse to add?
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 SIP and PSTN signaling.
Medium · Technical & Domain Knowledge
Approach
- Open with the architectural split: the PSTN is circuit-switched, carrying voice on dedicated 64 kbps TDM channels (DS0), while SIP (RFC 3261) is an application-layer protocol that sets up sessions over IP and leaves the media to RTP on separate ports.
- Describe PSTN signaling as SS7: out-of-band common-channel signaling, with ISUP messages driving a call (IAM to set up, ACM when the far end is alerted, ANM on answer, REL and RLC to tear down).
- Walk the SIP equivalent as text request/response, much like HTTP: INVITE, 100 Trying, 180 Ringing (or 183 Session Progress for early media), 200 OK, ACK, and BYE to hang up. Codecs and media addresses are negotiated with SDP offer/answer inside those messages.
- Explain where the two meet: a media gateway converts RTP to TDM, a signaling gateway translates SIP to ISUP (SIP-I/SIP-T can carry the ISUP payload), and failure reasons are mapped between Q.850 cause codes and SIP response codes (RFC 3398 defines a mapping).
- Close with the practical consequences: SIP runs over UDP, TCP or TLS (5060/5061 by convention), has to deal with NAT traversal and separate signaling and media paths, and both networks address phones with E.164 numbers.
Follow-up
- A SIP call to a PSTN number fails with a 503 or a 404. Which ISUP release causes could that have come from, and how would you find out which?
- Why does SIP keep media off the signaling path, and what problem does that create behind NAT?
- What is early media, and why would a caller hear a ringback tone or an announcement before a 200 OK?
How would you design a system to handle high-volume SMS routing?
Medium · Technical & Domain Knowledge
Approach
- Fix the requirements first: messages per second at peak, accept latency versus delivery latency, whether per-conversation ordering matters, and what the sender is told (a message id at accept time, then status callbacks). Then split the system into an accept path and a delivery path.
- Accept path: an API validates the numbers (E.164), works out the encoding and segment count (GSM-7 fits 160 characters in one segment and 153 per segment when concatenated; UCS-2 fits 70 and 67), stores the message with an idempotency key, and writes it to a durable queue before it returns.
- Routing: look up the destination number (including number-portability data, since a ported number's carrier differs from its prefix's), pick a route, then hand off to per-carrier workers that hold the carrier connections (such as SMPP binds) and enforce per-carrier and per-sender rate limits with token buckets.
- Delivery state: correlate carrier delivery receipts back to the message through the carrier's message id, move each message through accepted, queued, sent, delivered or failed, and push status webhooks with retries. Retry with exponential backoff and fail over to a second route on retryable errors only.
- Trade-offs to state: the queue gives at-least-once delivery, so deduplicate on the message id. Partitioning on the (from, to) pair keeps a conversation in order but one busy pair can make a hot partition. Backpressure from a slow carrier must stay on that carrier's workers and not stall every route.
Follow-up
- A carrier starts throttling and its queue backs up. What stops that from delaying messages bound for other carriers?
- How do you avoid sending the same message twice when a worker crashes after the carrier accepted it but before you recorded that?
- How do you handle an inbound STOP reply so later sends to that number are blocked?
What are the common challenges when integrating REST APIs with legacy systems?
Medium · Technical & Domain Knowledge
Approach
- Data-model mismatch: legacy systems often expose fixed-width records, XML/SOAP or stored procedures with their own codes and encodings. Put an adapter (an anti-corruption layer) between them and the REST resources so legacy shapes never leak into the public contract.
- Timing mismatch: a slow or batch-driven backend does not fit a synchronous HTTP call. Return 202 Accepted with a status resource for long work, set explicit timeouts on every legacy call, and add a circuit breaker so a stalled backend does not exhaust the API's threads or connection pool.
- Retries and partial failure: the legacy side may have no idempotency, so an Idempotency-Key header plus a stored request record stops a client retry from applying twice. Say plainly what happens when step two of a multi-step legacy update fails (compensating action, or a reconciliation job).
- Errors and semantics: map legacy error codes onto a small set of HTTP statuses and a stable error body, and keep 4xx (caller's fault, do not retry) apart from 5xx and 503 (retry with backoff).
- Migration safety: characterization tests that pin the legacy system's current behaviour, contract tests on the new API, versioning (/v1 or a header), and a strangler-fig rollout that moves one endpoint at a time behind the same facade.
Follow-up
- The legacy system allows only a small number of concurrent connections. How do you protect it when API traffic spikes?
- A client times out, retries, and the original request completes anyway. How does your design make that safe?
- How would you retire the legacy path for one endpoint without breaking clients still on the old behaviour?
How do you approach troubleshooting a network latency issue in a distributed environment?
Medium · Technical & Domain Knowledge
Approach
- Define the symptom precisely before forming a theory: which percentile moved (p50 and p99 point to different causes), which endpoints, hosts, regions or clients are affected, and what changed around the start time (deploys, config, traffic, infrastructure).
- Split the request into phases. Distributed tracing shows which span grew; from a client, curl -w with time_namelookup, time_connect, time_appconnect, time_starttransfer and time_total separates DNS, TCP connect, TLS, server time and transfer.
- If the time sits between hosts, check the network layer: mtr or ping for RTT and packet loss, ss -ti for per-connection RTT and retransmits, tcpdump or Wireshark for retransmissions and resets. On Linux the minimum TCP retransmission timeout is 200 ms, so a little loss can produce latency spikes of that order.
- If the time sits inside a service, look at queueing rather than the wire: connection-pool or thread-pool exhaustion, GC pauses, lock contention, a slow downstream dependency, or CPU throttling, and compare server-side handling time with what the client measured.
- Confirm the cause by changing one thing (drain a host, roll back, route around a link) and watching the same percentile recover, then add the missing metric or alert so the next occurrence is found faster.
Follow-up
- Only p99 is up and p50 is flat. Which causes does that point to, and which does it rule out?
- The server reports 5 ms handling time but clients see 300 ms. Where do you look next?
- How would you tell whether a new deploy caused the latency or only coincided with a traffic increase?
Suggested practice checklist
The plan follows the three reported rounds: domain vocabulary and recruiter logistics first, then coding, routing design and systems troubleshooting, then behavioral stories and a final mixed run-through.
Day 1 — Domain vocabulary and recruiter-call logistics
- Write a one-page glossary covering SIP signaling, the PSTN, SMS routing and emergency calling, then practise the SIP versus PSTN contrast aloud.
- Write your career account in a form you can say aloud, linking one project to API work, Linux or legacy code.
- Contact five former managers or colleagues who could serve as references and note their current details.
Deliverable: A one-page glossary, a written career account, and a reference list with a confirmation from each person.
Day 2 — Tree traversal, frequency counting and complexity
- Implement pre-order, in-order and post-order traversal recursively and iteratively, plus breadth-first, and write the complexity of each beside the code.
- Solve the most-frequent-element problem with a hash map, then handle ties and an empty array, and state the complexity.
- Explain aloud the time and space complexity of both solutions as if you had just written them in front of someone.
Deliverable: Working code for the traversals and for the frequency problem, each with a written complexity statement and a note on its edge cases.
Day 3 — Routing: least-cost algorithm and SMS design
- Implement a simple least-cost routing function over a rate table, then extend it with a fallback route and tie-breaking.
- Outline the high-volume SMS routing design on one page: ingestion, queue, routing decision, delivery, retries and downstream failure.
- Do the database practice on keyset paging to refresh SQL, since SQL and NoSQL experience is listed in the requirements candidates describe.
Deliverable: A tested routing function, a one-page SMS routing design diagram, and a finished keyset-paging query.
Day 4 — Systems: Linux, legacy integration and latency
- Write a numbered troubleshooting sequence for a network latency problem in a distributed environment, with the command or metric you would use at each step.
- List the challenges of integrating a REST API with a legacy system (retries and idempotency, data formats, error mapping, versioning) with one mitigation for each.
- Prepare your Linux and LAMP answer: what you owned, three commands you reach for, and one incident told in order.
Deliverable: A latency runbook, a challenges-and-mitigations table for legacy REST integration, and a spoken-ready Linux and LAMP answer.
Day 5 — Behavioral stories, part one
- Write the stakeholder-explanation story: the impact, the plain-language cause, the options, and the decision you needed.
- Write the legacy-system story with the safety steps (tests, flags, rollback) and measured outcome.
- Write the constructive-feedback story with the specific habit you changed and the evidence afterwards.
Deliverable: Three written stories, each with situation, your decisions, and result, ready to be spoken in a few sentences per part.
Day 6 — Behavioral stories, part two, and parsing
- Write the competing-deadlines story with your ranking method and the trade-off you negotiated, including how you told stakeholders.
- Write the high-pressure team story naming what you personally did for the team.
- List the parsing edge cases you handle, with the real bug that taught you one of them.
Deliverable: Two more written stories and a parsing edge-case checklist tied to one real example.
Day 7 — Mixed run-through
- Answer aloud, in sequence, one domain question, one coding question and two behavioral questions, recording yourself.
- Review the recording for stories told as "we" and answers with no complexity or failure handling, and redo those.
- Do the tenant-cap practice question as extra database practice and write three questions to ask the team about legacy systems and modernization.
Deliverable: A recorded mixed run-through with a list of fixes applied, a worked answer to the tenant-cap practice question, and three written questions for the team.
Behavioral stories for Bandwidth
Candidates report behavioral conversations about working in a team, handling disagreements and explaining technical ideas to non-technical partners, and some of the reported scenarios concern technical debt, shifting priorities and missed deadlines. For this role, prepare stories that show you changing difficult older code safely, explaining a technical issue in business terms, and staying useful when pressure is high. Each story should name your own decisions and the result.
- Tell me about a time you had to persuade a team member to adopt your technical approach.
Describe your experience with Linux sysadmin tasks and managing LAMP stacks.
Medium · Technical & Domain Knowledge
Approach
- Name one real environment and your part in it: Linux distribution, Apache or nginx with PHP, MySQL or MariaDB, and what you personally owned, such as patching, deploys, backups, monitoring or incident response. If you have not run LAMP itself, say so and describe the closest stack you operated.
- Show the toolkit with a reason for each tool: systemctl and journalctl for services and logs, df -h and df -i for full disks and exhausted inodes, top, vmstat and iostat to separate CPU, memory and disk pressure, ss for sockets, and cron plus logrotate for housekeeping.
- Cover LAMP failure modes you have actually fixed: Apache workers exhausted (MaxRequestWorkers, or php-fpm pm.max_children), slow MySQL queries found through the slow query log and EXPLAIN, a missing index, swapping from an oversized configuration, a full /var.
- Add operational hygiene: key-based SSH, least-privilege sudo, scheduled patching with a rollback path, backups you have restored at least once, and configuration kept in version control.
- Close with one incident told in order: the symptom, what you measured, the change you made, and the result in numbers you genuinely observed.
Follow-up
- A disk reports 100 percent full but du accounts for far less space. What do you check?
- Apache starts returning 503 errors under load. What is your diagnostic sequence?
- How do you patch a production web server without downtime?
How do you handle edge cases when parsing complex data structures?
Medium · Coding & Algorithms
Approach
- Open with the checklist you actually apply: empty or null input, a missing field, a wrong type, duplicate keys, a trailing delimiter, stray whitespace, a byte-order mark or non-UTF-8 bytes, numbers beyond integer range, and deeply nested structures.
- Describe the layers: tokenise or use an existing parser, validate against a schema or explicit rules, then convert to typed objects. Reject bad data at the boundary with an error that says where (line, field) and why, instead of passing it inward.
- Anchor it in a real parser you wrote or maintained, such as a log format, a CSV or JSON feed, a config file or a protocol message, and name the specific bug that taught you a case, for example a quoted comma or a field that was sometimes a list.
- Say how you proved it: a table of malformed inputs as unit tests, property-based or fuzz tests, and a corpus of real samples. For large inputs, stream instead of loading everything, and use an explicit stack or a depth limit instead of unbounded recursion.
- State your policy: strict rejection versus tolerate-and-log, and which you chose for which data and why.
Follow-up
- A recursive parser crashes with a stack overflow on a hostile payload. How do you fix it?
- Strict or lenient for a partner feed that is occasionally malformed?
- How do you test a parser when you cannot see every input it will receive?
Tell me about a time you had to explain a complex technical issue to a non-technical stakeholder.
Medium · Behavioral & Leadership
Approach
- Choose an issue with real consequences and a listener who had a decision to make, such as a product manager weighing technical debt, an operations lead after an outage, or a support team facing a migration. The story fails if nobody had anything to decide.
- Structure what you said: impact in their terms first (customer effect, deadline, cost), the cause in one plain sentence or analogy, two or three options with trade-offs, then your recommendation and the decision you needed from them.
- Show the translation work: which jargon you dropped, which analogy you used, and what you refused to oversimplify, such as stating uncertainty and what evidence would change your recommendation.
- Show that it landed: you asked them to restate the plan, or they made the decision, and say what happened next. Avoid a story where you wrote a clear explanation but never learned whether it worked.
Follow-up
- What did they push back on, and how did you respond?
- How would you explain the same issue to an executive versus a support agent?
- What would you change about how you communicated it?
Describe a situation where you had to work with a legacy system that was difficult to maintain.
Medium · Behavioral & Leadership
Approach
- Describe the system honestly: language, size, missing tests or documentation, and what made it hard to maintain, such as tight coupling, hidden state or fragile deploys. Do not disparage the people who built it; describe constraints.
- Give your first move: make it safe to change. Write characterization tests that pin the behavior you must keep, add logging or metrics around the area, and establish a deploy-and-rollback path before touching logic.
- Explain the incremental strategy: find seams, extract one module behind an interface, route a slice of traffic to the new code (a strangler approach) behind a feature flag, and compare old and new outputs in shadow mode, rather than a big-bang rewrite.
- Show the judgement call: when you refactored, when you left code alone, and how you justified the cost to product with evidence. Report the outcome you actually measured, such as incidents, deploy frequency or response time.
- If the story involved integration, mention the boundary you built, for example a REST wrapper or translation layer that kept the old interface stable for its callers.
Follow-up
- How did you decide between refactoring and rewriting?
- How did you keep behavior identical when there were no existing tests?
- What did you deliberately leave alone, and why?
How do you prioritize tasks when you are juggling multiple competing deadlines?
Medium · Behavioral & Leadership
Approach
- Show a method, not a mood: list every commitment with owner and due date, estimate effort, rank by user or customer impact and cost of delay, and mark dependencies and what is blocked on whom.
- Say where production incidents and security fixes sit in that order, then deadlines tied to outside commitments, then everything else. Use a real example in which two or three deadlines collided and say what you ranked first.
- Show negotiation: you raised the conflict early, offered options (cut scope, move a date, add help), and got agreement in writing instead of silently missing one.
- Include what you deferred or declined and what it cost, then the result and what you changed about the way you plan afterwards.
Follow-up
- Two managers each say their task is the top priority. What do you do?
- Describe a deadline you missed and how you communicated it.
- How do you handle a production interrupt in the middle of planned work?
Give an example of a time you received constructive feedback and how you acted on it.
Medium · Behavioral & Leadership
Approach
- Pick feedback that stung or required real change, on something like terse code review comments, estimates that slipped, or unclear status updates. A disguised strength ("I work too hard") sinks the story.
- Report what was said, who said it and your first reaction, then how you made sure you understood it, for example by asking for a specific example.
- Describe concrete changes with a mechanism behind them: a checklist, a design-review step earlier in the work, pairing, a template for status updates. A promise to try harder is not a change.
- Give evidence it worked: the next review, a follow-up comment from the same person, or a measurable change. Close with how you now ask for feedback.
Follow-up
- What if you had disagreed with the feedback?
- How do you give constructive feedback to a peer?
- What feedback are you working on right now?
How do you contribute to a positive team culture during high-pressure projects?
Medium · Behavioral & Leadership
Approach
- Define positive culture by behaviors under pressure rather than adjectives: a named owner and calm written updates during an incident or crunch, no blame, shared load, and protected focus time for teammates.
- Pick one high-pressure project and say precisely what you did: took unglamorous work, paired with a newer teammate on the hard part, kept stakeholders informed so engineers were not interrupted, ran a short blameless review afterwards. Code reviews and on-call are natural settings.
- Include a moment of tension, such as a stressed teammate or a disagreement over approach, and how you handled it respectfully while keeping the decision moving.
- Show what lasted: a runbook, a retro action, a changed rotation or review rule. Avoid saying you are a team player and avoid a hero story where you did everything alone.
Follow-up
- A teammate is struggling during a crunch. What do you do?
- How do you handle a technical disagreement when time is short?
- What did the team change afterwards because of how that project went?