Back to News & Insights
JavaScript September 16, 2026 · 5 min read

JavaScript and TypeScript Interview Questions Explained With Real Production Examples, Part 2: Algorithms

Part one of this series covered scope, closures, promises, the event loop, and TypeScript's type...

JavaScript and TypeScript Interview Questions Explained With Real Production Examples, Part 2: Algorithms

Part one of this series covered scope, closures, promises, the event loop, and TypeScript's type system. This part covers the four data structure and algorithm concepts that come up constantly in interviews, and constantly in real code, if you know where to look for them.

Same approach as before: a plain definition first, for anyone just here to check their understanding, then a real example, not a toy one.

An array is an ordered collection you access by position, or index. A Set stores a collection of values with no duplicates allowed, and its main job is answering "have I seen this before" efficiently. A Map stores key-value pairs, and its main job is answering "given this key, what's the value" efficiently.

The three get confused because they can all technically "hold a list of things," but they answer completely different questions.

Use this when you genuinely care about sequence, or need to iterate in a specific order.

This is the shape of a bulk selection feature, checking a batch of rows in a table to apply a status update to all of them at once. The question you're asking is always some version of "is this one selected," and a Set answers that in constant time instead of scanning an array on every check.

Anywhere you'd otherwise write array.find(item => item.id === someId) inside a loop, a Map built once up front turns repeated linear scans into repeated constant time lookups.

Say your backend receives a list of email addresses during a bulk import, a CSV of contacts someone's uploading into their account:

You need to flag which ones are duplicated before importing. A Set gives you a clean way to track what's already been seen while walking the list exactly once:

This is a different shape of problem from the classic two sum pattern I covered in an earlier post on production JavaScript patterns, even though both lean on a hash-based structure. Two sum is about finding a relationship between two different values that together satisfy some condition. This is simpler: just tracking whether a single value has shown up before. Same underlying idea, a hash-based structure turning repeated scans into constant time checks, applied to a narrower question. The same pattern covers duplicate user IDs, duplicate product SKUs, and duplicate database records just as directly.

Big O describes how the amount of work a piece of code does grows as its input grows. It's not a measurement of actual speed; it's a description of the growth curve, which matters more than the raw number once your data gets large enough.

Here's the version that actually shows up in production, not the whiteboard version. Suppose you have a list of users and a separate list of profiles, and for every user you need to find their matching profile:

At 100 users and 100 profiles, this does roughly 10,000 comparisons in the worst case, .find() scanning the whole profiles array for every single user. That's O(n²), quadratic, because the work grows with the product of both list sizes. At 100,000 users and 100,000 profiles, that's roughly ten billion comparisons, the kind of thing that turns a fast endpoint into a timeout with no code change other than more data showing up.

The fix is the same Map pattern from the section above, built once, ahead of time:

Building the map is O(n). Every lookup afterward is constant time. Total cost: O(n), not O(n²). Same result, a completely different growth curve once real data volume shows up. This is the actual reason Big O gets asked about in interviews, not to test whether you can recite notation, but to see whether you notice a nested nested nested loop before it ships and becomes a production incident.

The handful worth actually knowing by shape, not by memorized name: constant time regardless of input size, logarithmic where doubling the input barely adds work, linear where work grows directly with input, linearithmic which is what most efficient sorting algorithms cost, and quadratic, which is the one to watch for, since it's the one that quietly turns fine into broken as data grows.

Binary search finds a value in a sorted collection by repeatedly cutting the remaining search space in half, instead of checking every element in order.

Looking for 600, you don't start at the front and check each one in sequence. You check the middle, 400. 600 is bigger, so everything to the left of 400 is eliminated in one comparison; no need to ever look at it. What's left is 500, 600, 700. Check the middle again: 600. Found it in two comparisons instead of six.

Want to discuss this further?

Book a free strategy call with our team to see how these insights apply to your specific business goals.

Book a consultation