Software engineer interviews follow a familiar pattern at most companies: a recruiter call, one or two coding rounds, a system design round for mid-level and senior roles, and a behavioral round. Below are 20 software engineer interview questions with answers, grouped by round. Every code sample was tested against a brute-force version on thousands of random inputs before publishing.
What each round tests
| Round | Typical format | What they're judging |
|---|---|---|
| Recruiter screen | 20 to 30 minutes on the phone | Background, motivation, salary range, logistics |
| Coding | 45 to 60 minutes in a shared editor | Problem solving, clean code, testing, talking while you work |
| CS fundamentals | Mixed into coding or a separate round | Whether you understand the systems you use |
| System design | 45 to 60 minutes on a whiteboard or doc | Trade-offs, scale, and clear communication |
| Behavioral | 30 to 45 minutes | Ownership, collaboration, how you handle failure |
New graduate interviews are mostly coding and behavioral. Senior interviews add more system design and expect deeper answers about past projects. For the recruiter call, see our phone screen interview questions.
Coding questions
In every coding round, say your approach before you type, state the time and space complexity, and test with a small example at the end. Our Big O cheat sheet covers the complexity part.
1. Two sum: return the indices of two numbers that add up to a target
Store each number's index in a hash map. For each new number, check whether its complement is already in the map.
def two_sum(nums, target):
seen = {}
for i, x in enumerate(nums):
if target - x in seen:
return [seen[target - x], i]
seen[x] = i
return []
print(two_sum([2, 7, 11, 15], 9)) # [0, 1]
O(n) time and O(n) space. The brute-force version checks every pair in O(n²), and interviewers usually want you to mention it first and then improve it.
2. Valid parentheses: check that every bracket is closed in the right order
Push opening brackets onto a stack. On a closing bracket, the top of the stack must be its matching opener.
def is_valid(s):
pairs = {")": "(", "]": "[", "}": "{"}
stack = []
for ch in s:
if ch in pairs:
if not stack or stack.pop() != pairs[ch]:
return False
else:
stack.append(ch)
return not stack
print(is_valid("([]{})"), is_valid("(]")) # True False
O(n) time and O(n) space. The last line matters: a string like "((" leaves items on the stack and isn't valid.
3. Merge overlapping intervals
Sort by start time, then either extend the last merged interval or start a new one.
def merge_intervals(intervals):
merged = []
for start, end in sorted(intervals):
if merged and start <= merged[-1][1]:
merged[-1][1] = max(merged[-1][1], end)
else:
merged.append([start, end])
return merged
print(merge_intervals([[1, 3], [2, 6], [8, 10], [15, 18]]))
# [[1, 6], [8, 10], [15, 18]]
O(n log n) time because of the sort. Ask whether touching intervals such as [1, 2] and [2, 3] should merge. This version merges them.
4. Reverse a linked list
Walk the list once and point each node back at the previous one.
class ListNode:
def __init__(self, val, next=None):
self.val = val
self.next = next
def reverse_list(head):
prev = None
while head:
head.next, prev, head = prev, head, head.next
return prev
O(n) time and O(1) extra space. If the multiple assignment looks too clever for the interviewer, write it as three lines with a temporary variable. Clear beats short.
5. Return the k most frequent elements
Count with a hash map, then take the k largest counts with a heap.
from collections import Counter
import heapq
def top_k_frequent(nums, k):
counts = Counter(nums)
return [x for x, _ in heapq.nlargest(k, counts.items(), key=lambda p: p[1])]
print(top_k_frequent([1, 1, 1, 2, 2, 3], 2)) # [1, 2]
O(n log k) time. A follow-up is bucket sort by frequency, which gets O(n).
6. Design an LRU cache with O(1) get and put
You need fast lookup and fast reordering by recent use. A hash map plus a doubly linked list does both. In Python, OrderedDict is exactly that combination.
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.capacity = capacity
self.data = OrderedDict()
def get(self, key):
if key not in self.data:
return -1
self.data.move_to_end(key)
return self.data[key]
def put(self, key, value):
if key in self.data:
self.data.move_to_end(key)
self.data[key] = value
if len(self.data) > self.capacity:
self.data.popitem(last=False)
Some interviewers will ask you to build the linked list yourself. Explain the structure first: the map points to list nodes, the most recent node sits at one end, and you evict from the other end.
7. Shortest path in a grid with walls
Breadth-first search finds the shortest path when every step costs the same.
from collections import deque
def shortest_path(grid):
rows, cols = len(grid), len(grid[0])
if grid[0][0] or grid[rows - 1][cols - 1]:
return -1
queue = deque([(0, 0, 0)])
seen = {(0, 0)}
while queue:
r, c, steps = queue.popleft()
if (r, c) == (rows - 1, cols - 1):
return steps
for dr, dc in ((1, 0), (-1, 0), (0, 1), (0, -1)):
nr, nc = r + dr, c + dc
if 0 <= nr < rows and 0 <= nc < cols and not grid[nr][nc] and (nr, nc) not in seen:
seen.add((nr, nc))
queue.append((nr, nc, steps + 1))
return -1
print(shortest_path([[0, 0, 0], [1, 1, 0], [0, 0, 0]])) # 4
O(rows × cols) time and space. Mark cells as seen when you add them to the queue, not when you remove them, or the same cell gets queued many times.
8. Find the first bad version
Versions 1 to n are good up to some point and bad after it. Binary search finds the first bad one in O(log n) checks.
def first_bad_version(n, is_bad):
lo, hi = 1, n
while lo < hi:
mid = (lo + hi) // 2
if is_bad(mid):
hi = mid
else:
lo = mid + 1
return lo
The pattern applies to any yes or no question that flips once, which comes up a lot. For a list of problems that cover these patterns, see the Blind 75.
CS fundamentals questions
9. What is the difference between a process and a thread?
A process is a running program with its own memory space. Threads run inside a process and share its memory. Threads are cheaper to create and switch between and can share data directly, but that sharing is why you need locks and why race conditions happen. Processes are isolated, so a crash in one doesn't take down the others.
10. What is the difference between TCP and UDP?
TCP sets up a connection and guarantees ordered, reliable delivery with retransmission and flow control. UDP sends independent packets with no delivery or ordering guarantee and less overhead. Use TCP for web pages, APIs, and file transfer. UDP suits live voice, video, and games, where a late packet is useless anyway. Our computer networking interview questions go further.
11. What happens when you type a URL into a browser and press Enter?
The browser resolves the domain to an IP address through DNS, opens a TCP connection, and does a TLS handshake for HTTPS. It sends an HTTP request, and the server, often behind a load balancer, returns a response. The browser parses the HTML, requests the CSS, JavaScript, and images it references, and renders the page. Go deeper on whichever part the interviewer picks.
12. How does a hash table work, and what is its time complexity?
A hash function maps each key to a bucket in an array. Lookups, inserts, and deletes are O(1) on average. When two keys land in the same bucket, the table handles the collision by chaining or by probing another slot, and it resizes when it gets too full. The worst case is O(n) if many keys collide.
13. When would you choose a SQL database over a NoSQL one?
Choose SQL when the data is relational, you need joins and transactions, and the schema is fairly stable: orders, payments, user accounts. Choose a document or key-value store when access patterns are simple, the data shape varies, or you need to scale writes across many machines. Many systems use both. The answer interviewers want is the trade-off, not a winner. Our REST API interview questions cover the API layer that usually sits on top.
System design questions
14. Design a URL shortener
Clarify requirements first: how many new links a day, how many reads, whether links expire, whether custom aliases are allowed. Then cover the API (create and redirect), how you generate short codes (a counter encoded in base 62, or a random code with a uniqueness check), storage (a key-value store from code to URL), and a cache for popular links, since reads far outnumber writes. Finish with analytics and abuse prevention if time allows. We walk through the whole design in our system design guide.
15. Design a rate limiter
Start with where it runs (at the API gateway, per user or per API key) and what happens when a client goes over the limit (HTTP 429 with a retry time). A token bucket is the common choice: each client has a bucket that refills at a fixed rate and holds a maximum number of tokens, and each request uses one. It allows short bursts while enforcing an average rate. With several servers, keep the counters in a shared store such as Redis so every server sees the same count. For more practice, see our system design interview questions.
Behavioral questions
Use a clear structure for each story: the situation, what you did, and the result, with numbers where you have them.
16. Tell me about yourself
Give a two-minute version of your career that ends with why you want this role. Mention one or two projects with concrete results. Our guide to tell me about yourself has examples.
17. Tell me about a hard bug you fixed
Sample answer: "Our checkout service started timing out a few times a day with no pattern. I added request IDs to the logs and found every timeout came from one database query that only ran when a cart had more than 50 items. The query was missing an index on the join column. I added the index, the slow query dropped from about 4 seconds to under 50 milliseconds, and I added an alert on that query's latency so we'd catch it earlier next time."
18. Tell me about a disagreement with a teammate
Sample answer: "A teammate wanted to rewrite our notification service in a new framework, and I thought the risk was too high before a launch. Instead of arguing in the meeting, I suggested we each write down the cost and the risk. We agreed to fix the two worst problems in the current code before the launch and plan the rewrite for the next quarter. The launch went out on time, and we did the rewrite two months later with a proper test plan."
19. Tell me about a project that failed
Pick a real failure where you owned part of it. Explain what went wrong, what you'd do differently, and what you changed afterward. Interviewers are checking for honesty and learning, not a perfect record.
20. Why do you want to work here?
Connect something specific about the company's product or engineering work to your own experience. "I've used your API for two years and I'd like to work on the platform side" beats "you're a great company."
Questions to ask the interviewer
- What does a typical week look like for someone on this team?
- How is the work planned, and who decides priorities?
- How do code review and deployment work here?
- What would success look like in the first six months?
- What's the hardest technical problem the team is working on?
See questions to ask at the end of an interview for more.
How to prepare
- Pick one language and use it for every practice problem. Python is the most common choice because the code is short. Our Python interview questions cover the language itself.
- Practice by pattern, not by count: hash maps, two pointers, sliding window, binary search, BFS and DFS, heaps, and dynamic programming.
- Solve problems out loud with a timer. A correct silent solution scores lower than a clear spoken one.
- Practice in the editor you'll use. Many companies use CoderPad, which has a free sandbox.
- Prepare five stories from your work that you can adapt to most behavioral questions.
- For mid-level and senior roles, do at least a few full system design practice sessions with someone asking follow-up questions.
Practice coding interviews out loud
YesToTheOffer transcribes your answers so you can review how you explained your solution, with coding help from screenshots at 0.2x. 30 free minutes, no subscription.



