Design a single- and multi-threaded web crawler
Company: Anthropic
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Overview: This question evaluates skills in web crawling, URL parsing and fragment sanitization, graph traversal for deduplication, and concurrent programming for thread-safe crawling, and it falls under the Coding & Algorithms domain.
Read the full Anthropic Software Engineer interview experience this question came from
Part 1: Single-Threaded Web Crawler
Constraints
- 0 <= len(web) <= 10^4
- 0 <= total number of links across all pages <= 5 * 10^4
- All URLs are absolute and start with `http://` or `https://`
- Only fragment stripping is allowed; no other URL normalization may be applied
- The link graph may contain cycles
Examples
Input: ('http://news.example.com/a/index.html#top', {'http://news.example.com/a/index.html': ['http://news.example.com/b#section', 'http://other.example.com/x', 'http://news.example.com/c', 'http://news.example.com/b#other'], 'http://news.example.com/b': ['http://news.example.com/c#frag', 'http://news.example.com/a/index.html#again'], 'http://news.example.com/c': ['http://news.example.com/c#self']})
Expected Output: ['http://news.example.com/a/index.html', 'http://news.example.com/b', 'http://news.example.com/c']
Explanation: The crawler starts at the fragment-free URL `http://news.example.com/a/index.html`, ignores the external hostname, removes fragments before deduplication, and reaches pages a, b, and c.
Input: ('https://a.com/home', {'https://a.com/home': ['https://a.com/about#team', 'https://b.com/out', 'https://a.com/about#company'], 'https://a.com/about': ['https://a.com/home#top', 'https://a.com/about#self']})
Expected Output: ['https://a.com/about', 'https://a.com/home']
Explanation: Only URLs on hostname `a.com` are crawled. The two fragment variants of the about page collapse into one visited URL.
Hints
- Strip the fragment from every URL as soon as you read it, before deduplication.
- A DFS or BFS with a `visited` set is enough once you can extract the hostname.
Part 2: Multi-Threaded Web Crawler
Constraints
- 0 <= len(web) <= 10^4
- 0 <= total number of links across all pages <= 5 * 10^4
- All URLs are absolute and start with `http://` or `https://`
- Only fragment stripping is allowed; no other URL normalization may be applied
- The link graph may contain cycles
- The design must be safe under concurrent crawling (see the language note above)
Approach
Time complexity: O((V + E) · L)
Space complexity: O(V · L)
Hints
- Mark a URL as visited *before* handing it to a worker, not after you crawl it. That single ordering is what stops two workers racing onto the same page.
- A thread-safe work queue is the natural way to hand pages to workers — be ready to say how you would size the pool and decide the crawl is finished, which is what the interviewer is probing.
- Language note: Java and C++ can spawn real threads here. The Python sandbox runs single-threaded (thread creation is disabled), so write a correct sequential traversal in Python and describe the locking design in words — the grader compares the final sorted list, which is the same either way.