Concurrent Web Crawler Reachability
Reported by candidates from Temporal's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The Temporal OA reported in October 2025 dresses a plain graph traversal up in production-crawler language. Don't let the concurrency talk spook you. The judge is deterministic, so you're really doing reachability from a start node over a graph of up to 100000 pages and 300000 links. Map each page to its outgoing list, walk from startUrl with a visited set, skip unknown links, then sort the result. If the wording rattles you mid-assessment, StealthCoder is the invisible safety net that reads the problem and hands you a working solution. Most candidates won't need it here, but it's nice to have.
The problem
A production crawler fetches many discovered pages concurrently while ensuring that each known page is fetched at most once. For this deterministic judge adapter, pages[i] identifies a known page and outgoing[i] contains the links found after fetching it. Starting at startUrl, return every reachable known page in lexicographic order. Ignore links that do not occur in pages. The result must be independent of worker completion order. In a production discussion, explain how an atomic visited set and a bounded worker queue prevent duplicate fetches and unbounded concurrency. Function crawlReachable(startUrl: String, pages: String[], outgoing: String[][]) → String[] Examples Example 1 startUrl = "a" pages = ["a","b","c","d"] outgoing = [["b","c"],["d"],["d"],[]] return = ["a","b","c","d"] Both branches reach d, but it is returned once. Example 2 startUrl = "home" pages = ["home","about","orphan"] outgoing = [["about","external"],[],["home"]] return = ["about","home"] Unknown external is ignored and orphan is not reachable. Example 3 startUrl = "solo" pages = ["solo"] outgoing = [["solo"]] return = ["solo"] A self-link does not duplicate the page. Constraints 1 <= pages.length == outgoing.length <= 100000. Page identifiers are unique non-empty strings, and startUrl occurs in pages. The total number of links is at most 300000.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is that concurrency is a distraction. Build a hash map from page to its index or links, then run BFS or DFS from startUrl. The visited set is your 'fetch at most once' guarantee. Only enqueue a link if it exists in the map and isn't visited yet. At the end, sort the visited pages lexicographically, which makes the output independent of worker order. Brute force dies on size. Rescanning the pages array for every link is O(n * links), which is far too slow at 300000 links, so the hash map is mandatory. Prefer iterative traversal over recursion, since a long chain of 100000 pages can overflow the stack. Watch self-links and cycles, and remember the start page is included. If you blank on the setup during the live OA, StealthCoder can supply the traversal skeleton while you check edge cases.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Concurrent Web Crawler Reachability cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Temporal's OA.
Temporal reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Concurrent Web Crawler Reachability FAQ
What's the actual trick in the Temporal crawler problem?+
It's graph reachability. Put pages into a hash map, traverse from startUrl with a visited set, ignore links not in the map, then sort the visited pages. The atomic visited set and worker queue talk is only background for a discussion, not code you write.
Do I need to write multithreaded code?+
No. The problem calls it a deterministic judge adapter, and the function is a plain crawlReachable returning a sorted string array. Single-threaded BFS or DFS is correct. Just be ready to explain how an atomic visited set prevents duplicate fetches if asked.
What complexity should I hit with 100000 pages and 300000 links?+
Linear in pages plus links for the traversal, then O(k log k) to sort the k reachable pages. Anything that scans the pages array per link will time out. A hash map lookup per link keeps it fast enough.
What edge cases break most solutions?+
Self-links, cycles, links to unknown pages, and an unreachable orphan page. Also don't forget to include startUrl itself in the output. Mark pages visited when you enqueue them, not when you pop them, so duplicates never pile up in the queue.
How do I prepare for this in 48 hours?+
Practice BFS and DFS on adjacency lists with string keys until it's automatic. Write one iterative version to avoid stack overflow on deep chains. Then rehearse a two-sentence explanation of atomic visited sets and bounded queues, since the prompt invites that discussion.