PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates a candidate's competency in implementing robust HTTP-based crawling and traversal logic, including response parsing, retry and error handling, and termination detection.

  • hard
  • Ramp
  • Coding & Algorithms
  • Software Engineer

Find final URL by crawling until “congrats”

Company: Ramp

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Technical Screen

You are given a starting HTTP URL. Implement a function that repeatedly calls URLs returned by previous responses until you reach a response that indicates success. Behavior: - Make an HTTP GET request to a URL. - The response body can be one of: 1) A success marker (e.g., the body equals the string `"congrats"`). 2) A payload that contains a list of new URLs to call next (possibly alongside other fields/data). 3) Other data that does not contain any new URLs (a dead end). - Continue iterating/recursing through returned URLs until you find a URL whose response is `"congrats"`. Requirements: - Return only the final URL that produced the `"congrats"` response (you do NOT need to return the path of URLs taken). - Print/log each HTTP response you receive before deciding how to parse it and what to do next. - Handle error cases, especially HTTP 503 (Service Unavailable): implement reasonable retry behavior and error handling for malformed/unexpected response bodies. - The solution should be practical and focused on getting the core logic working first; coding style is not the priority. Clarify any assumptions you need (e.g., max retries, backoff strategy, cycle detection, concurrency).

Quick Answer: This question evaluates a candidate's competency in implementing robust HTTP-based crawling and traversal logic, including response parsing, retry and error handling, and termination detection.

You are given a starting URL and a simulated HTTP environment. Implement a function that keeps making GET requests until it finds a response body equal to the string "congrats". Simulation rules: - `web` maps each URL to either a single response body or a list of response bodies. - If `web[url]` is a list, each fetch of that URL returns the next item in the list. If the URL is fetched more times than the list length, keep returning the last item. - A response body can be: 1. The string "congrats" -> success. 2. A dictionary containing key `"urls"` with a list of next URLs to visit -> continue crawling. 3. Any other value -> dead end. 4. A dictionary `{"status": 503}` -> temporary failure; retry the same URL. Requirements and assumptions: - Return only the final URL whose response body is "congrats". - Print/log every response before deciding how to handle it. Printed output is not part of the return value. - Retry HTTP 503 immediately, up to `max_retries` extra times for that URL. - Use FIFO order (BFS) when exploring returned URLs, preserving the order in each `"urls"` list. - Use cycle detection so the same URL is not processed repeatedly through loops. - If a response is malformed or does not contain usable next URLs, treat it as a dead end. - If no URL leads to "congrats", return `None`.

Constraints

  • 0 <= len(web) <= 10^4
  • 0 <= max_retries <= 10
  • The total number of URLs across all `urls` lists is at most 2 * 10^4
  • Each URL in a `urls` list should be processed at most once, except for internal retries caused by HTTP 503

Examples

Input: ("http://start", {"http://start": {"urls": ["http://a", "http://b"], "meta": 1}, "http://a": {"message": "dead end"}, "http://b": "congrats"}, 2)

Expected Output: "http://b"

Explanation: Start returns two next URLs. `http://a` is a dead end, and `http://b` returns `congrats`, so the answer is that final URL.

Input: ("s", {"s": {"urls": ["r"]}, "r": [{"status": 503}, {"status": 503}, "congrats"]}, 2)

Expected Output: "r"

Explanation: URL `r` returns HTTP 503 twice, then succeeds on the third attempt. With `max_retries = 2`, this is allowed.

Input: ("u1", {"u1": {"urls": ["u2"]}, "u2": {"urls": ["u1", "u3"]}, "u3": {"info": "nothing here"}}, 1)

Expected Output: None

Explanation: The crawl contains a cycle between `u1` and `u2`, but no reachable response ever equals `congrats`.

Input: ("done", {"done": "congrats"}, 3)

Expected Output: "done"

Explanation: The starting URL already returns `congrats`, so it is immediately the answer.

Input: ("root", {"root": {"urls": ["bad", "slow"]}, "bad": [[1, 2, 3]], "slow": [{"status": 503}, {"status": 503}, {"status": 503}]}, 1)

Expected Output: None

Explanation: `bad` returns a malformed body (a list body, treated as a dead end). `slow` keeps returning 503 more times than allowed by `max_retries`, so no success is found.

Hints

  1. Model the crawl as a graph traversal: each URL is a node, and each `urls` list gives outgoing edges.
  2. Keep retry logic separate from your visited set: a 503 means retry the same URL, while cycle detection prevents revisiting URLs discovered through links.
Last updated: Apr 19, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Find User Airport at a Time - Ramp (medium)
  • Find an Exit in a URL Maze - Ramp (medium)
  • Implement a multi-level digital recipe manager - Ramp (medium)
  • Build a Wordle-style game in React - Ramp (medium)
  • Implement multi-level task manager APIs - Ramp (medium)