PracHub
QuestionsCoachesLearningGuidesInterview Prep
|Home/Coding & Algorithms/Meta

Implement BFS-based maze solver

Last updated: Mar 29, 2026

Quick Overview

This question evaluates grid traversal and shortest-path competencies, specifically breadth-first search for finding minimum steps in a 2D maze, along with correct array traversal and output formatting for printing the maze.

  • medium
  • Meta
  • Coding & Algorithms
  • Software Engineer

Implement BFS-based maze solver

Company: Meta

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Onsite

# Maze Printing and BFS Solver You are given a 2D grid representing a maze. Each cell of the grid is one of: - `'#'` – wall (cannot be passed) - `'.'` – empty path (can be passed) - `'S'` – start position (exactly one in the grid) - `'E'` – exit position (exactly one in the grid) This is an **AI-enabled coding** exercise: you are handed an existing source tree, and the work is delivered as a sequence of staged tests — you first fix a bug in the provided code, then extend it with additional functionality. You will complete two related tasks below. ### Constraints & Assumptions - $1 \le R, C \le 200$, where $R$ is the number of rows and $C$ the number of columns (at most $200 \times 200 = 40{,}000$ cells). - The grid always contains **exactly one** `'S'` and **exactly one** `'E'`. - Movement (Task 2) is restricted to the **4 orthogonal directions** (up, down, left, right) — no diagonals. - Only `'#'` blocks movement; `'.'`, `'S'`, and `'E'` are all passable. - Read all of the provided source files before writing code, so you understand the existing data representation and helpers rather than guessing. ### Clarifying Questions to Ask - Is a "step" counted as a **move/edge** or as a **cell visited**? (The Task 2 example pins this down — confirm the convention before coding.) - Are diagonal moves ever allowed, or strictly the 4 orthogonal directions? - Can the path pass **through** the `'S'` and `'E'` cells — i.e. are they passable like `'.'`, or special? - Are rows guaranteed to all have the same length (a true rectangular grid), or could the input be ragged? - For Task 1, is a single trailing newline after the final row acceptable, or must the output end with **no** trailing newline at all? - When no path exists in Task 2, what exactly should be returned (the spec says `-1`)? --- ## Task 1 – Correctly Print the Maze You are given a function with the following conceptual behavior: - Input: a 2D array `grid` of characters with `R` rows and `C` columns. - Output: print a textual representation of the maze to standard output. Requirements: - Print the maze row by row from top to bottom. - Within each row, print cells from left to right without extra spaces. - After each row, print a newline character. - Do not print an extra blank line at the end. Example input grid (shown here as a matrix): - Row 0: `['#', '#', '#', '#']` - Row 1: `['#', 'S', '.', '#']` - Row 2: `['#', '.', 'E', '#']` - Row 3: `['#', '#', '#', '#']` Expected output to stdout: ``` #### #S.# #.E# #### ``` The existing implementation has a bug and prints the maze incorrectly (for example, transposed rows/columns, missing newlines, or extra spaces). Describe how you would implement or fix the printing logic to satisfy the above specification. ```hint Where to start Map each described symptom to one specific code mistake: a **transposed** grid means the loops iterate `grid[c][r]` instead of `grid[r][c]`; **extra spaces** come from a separator (e.g. printing with a space delimiter); an **extra blank line** comes from emitting a newline *per cell* or after the last row. ``` ```hint Make the bug structurally impossible The space and blank-line symptoms both come from how the row's characters are glued together and how rows are separated. Ask yourself: if a single row were already one string before you printed anything, could a stray space ever appear between two cells? What separator between rows gives exactly one newline after each row and none after the last? ``` --- ## Task 2 – Find the Shortest Path Using BFS Implement a function with the following behavior: - Input: the same 2D character grid. - Output: the length of the shortest path (in number of steps) from `'S'` to `'E'`, moving only in 4 directions (up, down, left, right) and only through cells that are not walls (`'#'`). If there is no path, return `-1`. More formally: - You start on the cell containing `'S'`. - In one move, you may move to an adjacent cell (up, down, left, or right) that is within bounds and not a wall. - Reaching the cell containing `'E'` ends the path. - The path length is the number of moves taken. Example: Using the previous 4×4 grid: ``` #### #S.# #.E# #### ``` One valid shortest path is: - (1,1) `'S'` → (2,1) `'.'` → (2,2) `'E'` The shortest path length is 2, so the function should return 2. You may be asked to implement this in stages (first only detect reachability, then return distance, then optionally reconstruct the actual path), but the final requirement is to return the shortest path length. State the algorithm you would use (time and space complexity) and how you would implement it robustly for the given constraints. ```hint Which algorithm All moves cost the same (1 step), so this is an **unweighted shortest-path** problem on an implicit grid graph. Think about which traversal explores cells in non-decreasing distance order — that property is what makes the first arrival at `'E'` optimal. ``` ```hint Mechanics What data structure makes you process cells in the order they were discovered, and which cell should be the very first one you process? When you reach a neighbor for the first time, what has to happen *before* it goes back into that structure so you never count the same cell twice? And once you touch `'E'`, can you stop immediately, or do you need to keep going? ``` ```hint Two things the tests are watching for (1) When you decide whether a neighbor is enterable, are you listing the one character that blocks movement, or the one character that allows it? Which framing keeps `'S'` and `'E'` walkable? Re-read the passability rule in the constraints. (2) Trace the example by hand and pin down what distance the start cell should carry, and the order in which you do the bounds check versus the grid lookup — does the count you get for the 4×4 grid match the stated answer? ``` ### What a Strong Answer Covers ```premium-lock What a Strong Answer Covers ``` ### Follow-up Questions - How would you **reconstruct the actual path** of cells (not just its length), and how does that change your bookkeeping? - What changes if cells have **non-uniform costs** (e.g. some cells cost more to enter), or if there are 0-cost "teleport" cells? - How would you adapt this to find the shortest path that visits **multiple targets**, or to a **multi-source** BFS from several start cells at once? - At much larger scale, would an **A\*** heuristic (e.g. Manhattan distance) help, and what does it change about the asymptotic bound versus the constant factor? - Can you reduce auxiliary space below $O(R \cdot C)$, and what would you trade away to do so?

Quick Answer: This question evaluates grid traversal and shortest-path competencies, specifically breadth-first search for finding minimum steps in a 2D maze, along with correct array traversal and output formatting for printing the maze.

Solution

### Overview This is a two-part "AI-enabled coding" problem: first fix a broken maze-printer, then implement a shortest-path solver. Both parts share the same grid model, so I'll fix the data representation and helpers once, then build on them. The shortest-path part is a textbook **BFS on an unweighted grid** — BFS is optimal here because every move has unit cost, so the first time BFS reaches `E` it has reached it via a minimum number of moves. A note on approach (this matters for this specific interview): the task is delivered as a sequence of staged tests, and the winning move is to **read all the source files first** before touching anything, then make small, verifiable changes. I structure the answer the same way — clarify the contract, fix Task 1 cleanly, then layer the solver in the stages the interviewer asks for (reachability → distance → path reconstruction). --- ### Clarifying questions (state these up front) - **Diagonal moves?** No — the prompt says 4 directions only. Confirm, because a `dirs` array with 8 entries is the single most common silent bug. - **Is the path length counted in moves (edges) or cells visited?** The example fixes this: `S → . → E` is **2**, i.e. number of *moves/edges*, which equals (cells on path − 1). So distance to `S` itself is 0. - **Can `S` equal `E`?** The spec says exactly one of each, so they're distinct; the answer would be 0 if they coincided. - **Can you walk *through* `S`/`E` cells?** Yes — `S` and `E` are passable; only `'#'` is blocked. Don't accidentally treat anything other than `'#'` as a wall. - **Are rows guaranteed equal length (rectangular grid)?** The constraints (`R × C`) imply yes. The BFS below uses per-row column bounds anyway, so it stays correct even if rows turn out ragged — that's cheap insurance, not a behavior the spec requires. --- ## Task 1 — Print the maze correctly ### What the bug usually is The prompt hints the existing code "transposes rows/columns, misses newlines, or adds extra spaces." Each maps to a specific mistake: | Symptom | Root cause | |---|---| | Transposed output | Outer loop iterates columns and inner iterates rows — `grid[c][r]` instead of `grid[r][c]` | | Extra spaces between cells | Using `print(*row)` / joining with `' '` / `cout << cell << ' '` | | Extra blank line at the end | Printing `'\n'` *after every cell* or appending a trailing newline after the last row | | Missing newlines | Forgetting to emit a line break between rows | ### Correct contract - Outer loop over rows `0..R-1`, inner loop over columns `0..C-1`. - Emit each cell with **no separator**. - Emit a newline **after** each row. - "No extra blank line at the end" is satisfied by `'\n'`-terminated rows: `####\n#S.#\n#.E#\n####\n`. A single trailing `\n` after the last row is correct and standard; what you must avoid is an *empty* extra line (a second `\n` or a blank `print()`). If the spec is strict about no trailing newline at all, join rows with `'\n'` and print once with no terminator. ### Robust implementation Build each row as a single string and print once per row. This is both correct-by-construction (no per-cell separator can sneak in) and far faster than per-character I/O, which matters at the max size of $200 \times 200 = 40{,}000$ cells. ```python def print_maze(grid): # grid: List[List[str]] (or List[str]); R rows, C cols out = [] for row in grid: out.append("".join(row)) # no separators, preserves left->right order print("\n".join(out)) # newline BETWEEN rows; print() adds one final \n ``` - `"".join(row)` guarantees no extra spaces and correct left-to-right order. - `"\n".join(out)` puts a newline *between* rows; the single trailing `\n` from `print` is the conventional line terminator. To emit **zero** trailing newline, use `sys.stdout.write("\n".join(out))`. - If `grid` is a list of strings already, `"".join(row)` still works (and is a no-op concatenation). C++ equivalent, building the whole buffer to avoid per-char flush overhead: ```cpp void printMaze(const vector<string>& grid) { string out; for (size_t r = 0; r < grid.size(); ++r) { out += grid[r]; // row already has no separators if (r + 1 < grid.size()) out += '\n'; } cout << out << '\n'; // final terminator; drop this line for no trailing \n } ``` **Complexity:** $O(R \cdot C)$ time, $O(R \cdot C)$ extra space for the buffer (or $O(C)$ if you print row-by-row). --- ## Task 2 — Shortest path with BFS ### Why BFS (and not DFS or Dijkstra) The graph is implicit: nodes are passable cells, edges connect 4-adjacent passable cells, **all edge weights are 1**. On an unweighted graph, BFS explores cells in non-decreasing order of distance from the source, so the first time it dequeues (or, with an early-exit optimization, *enqueues*) `E`, that distance is the minimum. DFS would find *a* path but not necessarily the shortest. Dijkstra/A\* would also work but are overkill — BFS is strictly simpler and asymptotically optimal here. (A\* with a Manhattan-distance heuristic is the natural follow-up if asked to speed up large grids; it explores fewer cells but doesn't change worst-case bounds.) ### Algorithm 1. Scan the grid to locate `S` (and `E`, or just detect `E` during traversal). 2. BFS from `S`: a queue of cells plus a `visited` (or distance) structure. 3. Track distance per layer. Mark cells visited **when you enqueue them**, not when you dequeue — see the note below; both are $O(RC)$, but enqueue-marking avoids redundant queue churn. 4. Return the distance when `E` is reached; return `-1` if the queue empties first. ### Implementation (returns shortest distance) ```python from collections import deque def shortest_path(grid): if not grid or not grid[0]: return -1 R = len(grid) # 1) Find start. (We can also find E here, but detecting on arrival is enough.) start = None for r in range(R): for c in range(len(grid[r])): if grid[r][c] == 'S': start = (r, c) break if start: break if start is None: return -1 sr, sc = start visited = {start} # set keyed by (row, col): no width assumption q = deque([(sr, sc, 0)]) # (row, col, distance_from_S) DIRS = ((-1, 0), (1, 0), (0, -1), (0, 1)) # up, down, left, right — 4 only while q: r, c, d = q.popleft() if grid[r][c] == 'E': # reached the exit return d for dr, dc in DIRS: nr, nc = r + dr, c + dc if 0 <= nr < R and 0 <= nc < len(grid[nr]) \ and (nr, nc) not in visited \ and grid[nr][nc] != '#': # only '#' is blocked; S/E/'.' are passable visited.add((nr, nc)) # mark on ENQUEUE q.append((nr, nc, d + 1)) return -1 # queue drained, E never reached ``` Key correctness points baked in: - **Bounds check before grid access**, in the order `0 <= nr < R and 0 <= nc < len(grid[nr])` *then* `grid[nr][nc]` — short-circuiting avoids an index error. Using `len(grid[nr])` (the *target row's* width) rather than a single width read from row 0 means a ragged grid neither throws nor under-explores; on a rectangular grid it's identical work. (If you prefer a 2D `visited` matrix, size each row to its own length — `[[False] * len(grid[r]) for r in range(R)]` — for the same reason; a `set` of `(r, c)` sidesteps the issue entirely.) - **Wall test is `!= '#'`**, not `== '.'`. If you only allow `'.'`, you'd refuse to step onto `E` (and onto `S`), making every maze unsolvable — a classic trap. - **Visited-on-enqueue** keeps each cell enqueued exactly once. - **Early return on dequeuing `E`** gives the minimum distance because BFS dequeues in distance order. (You may also early-exit the moment you *enqueue* `E` and return `d+1`; both are correct, the enqueue version saves one layer of churn.) ### A note on visited-on-enqueue vs. visited-on-dequeue Both are correct and both run in $O(RC)$ — neither blows up. The reason BFS stays linear regardless of *when* you mark is that each undirected edge is relaxed a constant number of times: with mark-on-dequeue, a cell can be enqueued once per incoming edge (at most 4 times on a 4-neighbor grid), so total enqueues are bounded by $O(4 \cdot RC) = O(RC)$. The penalty of mark-on-dequeue is therefore only a constant-factor increase in queue size and some duplicate dequeues that get skipped, **not** a change in complexity class. The reason to still prefer mark-on-enqueue is purely to avoid that constant-factor redundant work, not to escape any super-linear behavior. ### Complexity Let $N = R \cdot C$ be the number of cells. - **Time:** $O(N)$. Each cell is enqueued at most once (mark-on-enqueue), and each performs a constant number of neighbor checks (4). The constant doesn't appear in the bound. The initial scan for `S` is also $O(N)$. At the max $200 \times 200$, that's $40{,}000$ cells — trivial. - **Space:** $O(N)$ for the `visited` set/matrix and the queue (which holds at most one BFS frontier, $O(N)$ in the worst case, e.g. an open grid). You can shave the `visited` structure by mutating the grid in place (mark visited cells as `'#'`), trading clarity and input-immutability for $O(1)$ extra space beyond the queue. I'd only do that if explicitly asked to minimize memory and told mutating the input is OK. --- ### Staging the implementation (how the interview unfolds) The problem is explicitly delivered in stages. Here's how each builds on the last with minimal changes: **Stage A — reachability (boolean).** Same BFS, but instead of carrying a distance, just return `True` on reaching `E`, `False` if the queue empties. Drop the `d` field. **Stage B — shortest distance.** Add the distance counter as above (the code shown). The cleanest way is either the `(r, c, d)` tuple, or a separate `dist` map initialized to `-1`/absent where `dist[(nr, nc)] = dist[(r, c)] + 1` — the map form doubles as `visited` (a cell is unvisited iff it's absent) and makes Stage C free: ```python def shortest_path_with_dist_map(grid): R = len(grid) start = next((r, c) for r in range(R) for c in range(len(grid[r])) if grid[r][c] == 'S') sr, sc = start dist = {start: 0} # membership == visited; value == distance from S q = deque([start]) while q: r, c = q.popleft() if grid[r][c] == 'E': return dist[(r, c)] for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)): nr, nc = r + dr, c + dc if 0 <= nr < R and 0 <= nc < len(grid[nr]) \ and (nr, nc) not in dist and grid[nr][nc] != '#': dist[(nr, nc)] = dist[(r, c)] + 1 q.append((nr, nc)) return -1 ``` **Stage C — reconstruct the actual path.** Keep a `parent[(r,c)] = (pr,pc)` map (set when you enqueue a neighbor). On reaching `E`, walk parents back to `S` and reverse: ```python def shortest_path_cells(grid): R = len(grid) start = next((r, c) for r in range(R) for c in range(len(grid[r])) if grid[r][c] == 'S') parent = {start: None} q = deque([start]) end = None while q: r, c = q.popleft() if grid[r][c] == 'E': end = (r, c) break for dr, dc in ((-1, 0), (1, 0), (0, -1), (0, 1)): nr, nc = r + dr, c + dc if 0 <= nr < R and 0 <= nc < len(grid[nr]) \ and (nr, nc) not in parent and grid[nr][nc] != '#': parent[(nr, nc)] = (r, c) q.append((nr, nc)) if end is None: return [] # no path path = [] cur = end while cur is not None: path.append(cur) cur = parent[cur] path.reverse() return path # cells from S to E; len(path) - 1 == distance ``` This composes cleanly: `parent` subsumes `visited` (membership = visited), and the reconstructed `path` length minus one equals the distance from Stage B — a good built-in consistency check to mention. If asked for a fourth stage, I'd clarify the exact deliverable before coding — common extensions are returning all shortest paths, handling weighted/teleport cells (switch to Dijkstra/0-1 BFS), or multi-source BFS — but I wouldn't guess; I'd confirm the contract first, the same discipline that made the earlier stages clean. --- ### Edge cases and validation (call these out) - **`S` and `E` adjacent** → returns 1. **`S == E`** (if ever allowed) → 0. - **`E` walled off / no path** → BFS drains the queue → returns `-1` (Stage A: `False`, Stage C: `[]`). - **`E` completely surrounded by `#`**, or `S` surrounded by `#` → `-1`. - **$1 \times 1$, $1 \times C$, $R \times 1$ grids** → bounds checks handle the degenerate cases; no off-by-one. - **Whole grid passable (open field)** → worst case for queue size; still $O(N)$. - **Don't hardcode 4 directions inline with a typo** — use one `DIRS` constant so up/down/left/right stay consistent across stages. - **Off-by-one in distance**: validate against the given example (`S → . → E` must yield **2**, not 1 or 3). Distance to `S` is `0`, so each move adds exactly 1. - **Ragged rows** (not expected given the `R × C` spec, but free to support): the per-row `len(grid[nr])` column bound means a short or long row is handled without an index error and without skipping reachable cells. ### Quick test set to verify ```python g1 = [list("####"), list("#S.#"), list("#.E#"), list("####")] # expect 2 g2 = [list("S#E")] # expect -1 (wall blocks) g3 = [list("SE")] # expect 1 (adjacent) g4 = [list("S.E")] # expect 2 g5 = [list("#S#"), list("###"), list("#E#")] # expect -1 (S boxed in) ``` These cover the happy path, blocked path, adjacency, a straight corridor, and an isolated start — enough to catch the wall-test, bounds, and off-by-one bugs simultaneously. --- ### Why this answer is interview-strong (summary) - **Task 1**: fixed by building rows as separator-free strings and joining with `'\n'`, which makes the transpose / extra-space / extra-blank-line bugs structurally impossible. - **Task 2**: BFS is provably optimal on this unit-cost grid; $O(RC)$ time and space, comfortably within the $200 \times 200$ bound. - The two load-bearing correctness details an interviewer is watching for: **wall test is `!= '#'`** (so you can step onto `S`/`E`) and **mark visited on enqueue** (so you avoid constant-factor redundant queue churn — BFS is $O(RC)$ either way, this just trims the constant). - Cleanly staged from reachability → distance → path, with a `parent`/`dist` map that lets each stage reuse the previous one's bookkeeping, and per-row column bounds so the same code is robust to any input shape.

Related Interview Questions

  • Validate Sorted Order Under a Custom Alphabet - Meta (medium)
  • Palindrome After Deleting at Most One Character - Meta (medium)
  • Find Shortest Unique Prefixes - Meta (medium)
  • Compute Exclusive Execution Times - Meta (medium)
  • Solve Tree Columns And Maze Variants - Meta (medium)
|Home/Coding & Algorithms/Meta

Implement BFS-based maze solver

Meta logo
Meta
Dec 7, 2025, 12:00 AM
mediumSoftware EngineerOnsiteCoding & Algorithms
28
0

Maze Printing and BFS Solver

You are given a 2D grid representing a maze. Each cell of the grid is one of:

  • '#' – wall (cannot be passed)
  • '.' – empty path (can be passed)
  • 'S' – start position (exactly one in the grid)
  • 'E' – exit position (exactly one in the grid)

This is an AI-enabled coding exercise: you are handed an existing source tree, and the work is delivered as a sequence of staged tests — you first fix a bug in the provided code, then extend it with additional functionality. You will complete two related tasks below.

Constraints & Assumptions

  • 1≤R,C≤2001 \le R, C \le 2001≤R,C≤200 , where RRR is the number of rows and CCC the number of columns (at most 200×200=40,000200 \times 200 = 40{,}000200×200=40,000 cells).
  • The grid always contains exactly one 'S' and exactly one 'E' .
  • Movement (Task 2) is restricted to the 4 orthogonal directions (up, down, left, right) — no diagonals.
  • Only '#' blocks movement; '.' , 'S' , and 'E' are all passable.
  • Read all of the provided source files before writing code, so you understand the existing data representation and helpers rather than guessing.

Clarifying Questions to Ask

  • Is a "step" counted as a move/edge or as a cell visited ? (The Task 2 example pins this down — confirm the convention before coding.)
  • Are diagonal moves ever allowed, or strictly the 4 orthogonal directions?
  • Can the path pass through the 'S' and 'E' cells — i.e. are they passable like '.' , or special?
  • Are rows guaranteed to all have the same length (a true rectangular grid), or could the input be ragged?
  • For Task 1, is a single trailing newline after the final row acceptable, or must the output end with no trailing newline at all?
  • When no path exists in Task 2, what exactly should be returned (the spec says -1 )?

Task 1 – Correctly Print the Maze

You are given a function with the following conceptual behavior:

  • Input: a 2D array grid of characters with R rows and C columns.
  • Output: print a textual representation of the maze to standard output.

Requirements:

  • Print the maze row by row from top to bottom.
  • Within each row, print cells from left to right without extra spaces.
  • After each row, print a newline character.
  • Do not print an extra blank line at the end.

Example input grid (shown here as a matrix):

  • Row 0: ['#', '#', '#', '#']
  • Row 1: ['#', 'S', '.', '#']
  • Row 2: ['#', '.', 'E', '#']
  • Row 3: ['#', '#', '#', '#']

Expected output to stdout:

####
#S.#
#.E#
####

The existing implementation has a bug and prints the maze incorrectly (for example, transposed rows/columns, missing newlines, or extra spaces). Describe how you would implement or fix the printing logic to satisfy the above specification.

Task 2 – Find the Shortest Path Using BFS

Implement a function with the following behavior:

  • Input: the same 2D character grid.
  • Output: the length of the shortest path (in number of steps) from 'S' to 'E' , moving only in 4 directions (up, down, left, right) and only through cells that are not walls ( '#' ). If there is no path, return -1 .

More formally:

  • You start on the cell containing 'S' .
  • In one move, you may move to an adjacent cell (up, down, left, or right) that is within bounds and not a wall.
  • Reaching the cell containing 'E' ends the path.
  • The path length is the number of moves taken.

Example:

Using the previous 4×4 grid:

####
#S.#
#.E#
####

One valid shortest path is:

  • (1,1) 'S' → (2,1) '.' → (2,2) 'E'

The shortest path length is 2, so the function should return 2.

You may be asked to implement this in stages (first only detect reachability, then return distance, then optionally reconstruct the actual path), but the final requirement is to return the shortest path length.

State the algorithm you would use (time and space complexity) and how you would implement it robustly for the given constraints.

What a Strong Answer Covers Premium

Follow-up Questions

  • How would you reconstruct the actual path of cells (not just its length), and how does that change your bookkeeping?
  • What changes if cells have non-uniform costs (e.g. some cells cost more to enter), or if there are 0-cost "teleport" cells?
  • How would you adapt this to find the shortest path that visits multiple targets , or to a multi-source BFS from several start cells at once?
  • At much larger scale, would an A* heuristic (e.g. Manhattan distance) help, and what does it change about the asymptotic bound versus the constant factor?
  • Can you reduce auxiliary space below O(R⋅C)O(R \cdot C)O(R⋅C) , and what would you trade away to do so?

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...

Browse More Questions

More Coding & Algorithms•More Meta•More Software Engineer•Meta Software Engineer•Meta Coding & Algorithms•Software Engineer Coding & Algorithms
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
  • AI Coding 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.