Coding Interview Patterns Module 2 – Interview toolkits in five languages
Choosing your interview language
Python, JavaScript, TypeScript, Java, C++ and Go compared for coding rounds: library gaps, integer traps, platform versions and when to switch languages.
What you will learn
- Compare Python, JavaScript/TypeScript, Java, C++ and Go for coding rounds
- Check which versions and libraries a platform offers before relying on a feature
- Decide when to switch language for an online assessment
Before you start
On this page
Most coding rounds let you pick your language from a list, and any of the five this track uses (Python, JavaScript or TypeScript, Java, C++ and Go) can solve the problems they set. The differences lie elsewhere: how much you have to type, which data structures come ready-made, which mistakes pass without an error, and which version the platform really runs. This lesson compares the five on those points, runs two of the differences as code, and ends with what to check on a platform and when a change of language during an online assessment is worth it.
Pick the language you write correctly under pressure
Choose the language in which you make the fewest mistakes while a clock runs and someone watches. Usually that is the one you have used most: you write a loop, a custom sort and a dictionary lookup without thinking about the syntax, you know where its heap and its queue live, and its error messages tell you at once what went wrong. A solution that is five lines longer costs less time than one bug you cannot find.
When you know two languages about equally well, these reasons can tip the choice:
- Short code. Python’s built-ins and standard library (sorting with a key,
collections.Counter, slicing, integers of any size) keep many solutions to a few lines, so there is less to type, explain and check. - Sorted maps and sets. Java and C++ ship them; Python, JavaScript and Go do not. A problem such as “the first free slot after time t, while bookings are added and cancelled” is much shorter where one exists.
- The role. If the job means writing one language every day, solving the round in it shows the skill the job needs, as long as the round offers it.
The round’s own list settles the rest. Meta’s public hiring page, for example, says that its AI-native coding interview supports Python, Java, TypeScript, C++, C#, Kotlin, Swift, Rust and Go. TypeScript is on that list; plain JavaScript is not.
Not affiliated
Based on public information about Meta. MySmartCoPilot is not affiliated with Meta, and Meta’s real interview formats may differ from what this lesson describes.
If you cannot decide between two languages, run a short trial instead of guessing. Take four practice problems of similar difficulty that you have not seen, solve two in each language with a timer running, and write down the minutes and the bugs you had to fix. Give each language its own problems: a problem you have just solved goes faster the second time, whatever the language. Choose the language with fewer bugs, even when its solutions are longer.
Timer Time each attempt of your trial: one problem in one language at a time.What each standard library gives you
A coding round leans on a small set of data structures. All five languages have a hash map and a set: dict and
set in Python, Map and Set in JavaScript, HashMap and HashSet in Java, std::unordered_map and
std::unordered_set in C++, and in Go the built-in map, which also serves as a set when its values are bool.
TypeScript counts as JavaScript here: its handbook says that TypeScript never changes how JavaScript code behaves when
it runs and provides no runtime libraries of its own, so its gaps are JavaScript’s gaps. Heaps (priority queues) and
sorted maps are where the five part ways:
- Python: a heap in
heapq, smallest item first (Python 3.14 adds functions for the largest first); no sorted map or set. - JavaScript and TypeScript: no heap; no sorted map or set (
MapandSetkeep the order of insertion). - Java: a heap in
PriorityQueue, least element first; sortedTreeMapandTreeSet. - C++: a heap in
std::priority_queue, largest element first; sortedstd::mapandstd::set. - Go: a heap in
container/heap, smallest first, once you write five methods; no sorted map or set.
Both gaps change how you write a solution. Without a heap, a JavaScript solution sorts, which is fine when it happens
once, or carries a short heap of its own; the JavaScript toolkit lesson of this module writes one. Without a sorted
map, a Python, JavaScript or Go solution needs another idea: a heap whose deleted entries are skipped when they reach
the top works when you only ever need the smallest key, and a binary search works on a sorted list that no longer
changes. Python’s bisect module can keep a list sorted as you insert, but its documentation warns that each
insertion is a slow O(n) step. And Go’s heap costs typing before it works at all: container/heap provides the
algorithm, and you provide a type with the five methods Len, Less, Swap, Push and Pop.
One problem in two languages
Return the three highest scores, highest first, or all of them when there are fewer than three. Python has a function for exactly this; JavaScript has no heap, so the usual way is to sort a copy from high to low.
Python · top_three.py
import heapq
def top_three(scores):
"""The three highest scores, highest first (fewer when there are fewer)."""
return heapq.nlargest(3, scores)
print(top_three([72, 100, 9, 85, 100, 64]))
print(top_three([40, 7]))
print(top_three([]))
# The mistake: heapq keeps the smallest item first, so three pops give the lowest three.
heap = [72, 100, 9, 85, 100, 64]
heapq.heapify(heap)
print([heapq.heappop(heap) for _ in range(3)]) Output
[100, 100, 85] [40, 7] [] [9, 64, 72]
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 top_three.py
JavaScript · top_three.mjs
function topThree(scores) {
// No heap is built in: copy, sort from high to low, keep the first three.
return [...scores].sort((a, b) => b - a).slice(0, 3);
}
console.log(JSON.stringify(topThree([72, 100, 9, 85, 100, 64])));
console.log(JSON.stringify(topThree([40, 7])));
console.log(JSON.stringify(topThree([])));
// The mistake: with no comparator, sort() compares the numbers as text.
console.log(JSON.stringify([72, 100, 9, 85, 100, 64].sort().reverse().slice(0, 3))); Output
[100,100,85] [40,7] [] [9,85,72]
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node top_three.mjs
Runs on this device, in your browser. The first run of each language downloads it: Python (about 13.5 MB) or JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
Both treat the edge cases alike: two scores give two, and no scores give an empty list. The last line of each program shows the mistake its language invites, and neither raises an error:
- Python’s
heapqkeeps the smallest item at the front, so three pops give the three lowest scores,[9, 64, 72].heapq.nlargestis the call to remember; its documentation says it returns the same as sorting in reverse and keeping the first n. - JavaScript’s
sort()without a comparator turns the numbers into strings and compares those, so"100"comes before"64"and"9"comes last. Reversed, the “top three” is[9, 85, 72]. Always pass a comparator, such as(a, b) => b - afor high to low.
Java, C++ and Go offer the same two ways, sorting a copy or keeping a small heap, and there the trap is the heap’s
direction: C++’s std::priority_queue gives the largest item first, while Java’s and Go’s heaps give the smallest.
Integers: the gap that hides best
A problem may say that values go up to and ask for the answer modulo . Two ordinary calculations show where each language stands: the number of pairs among 100,000 items, , which is about five billion, and the product of two numbers just below the modulus, about , before its remainder is taken.
Python · big_numbers.py
MOD = 1_000_000_007
def low_32_bits(x):
"""What a 32-bit int keeps of x: its low 32 bits, read as a signed number."""
x &= (1 << 32) - 1
return x - (1 << 32) if x >= 1 << 31 else x
n = 100_000
print("pairs of n items: ", n * (n - 1) // 2)
print("with 32-bit ints: ", low_32_bits(n * (n - 1)) // 2)
a = b = MOD - 1
print("a * b: ", a * b)
print("a * b % MOD: ", a * b % MOD) Output
pairs of n items: 4999950000 with 32-bit ints: 704982704 a * b: 1000000012000000036 a * b % MOD: 1
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 big_numbers.py
JavaScript · big_numbers.mjs
const MOD = 1000000007;
const n = 100000;
console.log("pairs of n items: ", n * (n - 1) / 2);
const a = MOD - 1;
const b = MOD - 1;
console.log("a * b: ", a * b);
console.log("a * b % MOD: ", (a * b) % MOD);
console.log("a * b is safe: ", Number.isSafeInteger(a * b));
// BigInt has no size limit, but it cannot be mixed with Number: convert every operand.
const exact = (BigInt(a) * BigInt(b)) % BigInt(MOD);
console.log("with BigInt: ", String(exact)); Output
pairs of n items: 4999950000 a * b: 1000000012000000000 a * b % MOD: 999999972 a * b is safe: false with BigInt: 1
Recorded with Node.js 24.21.0 on macOS 26 arm64. To run it yourself: mise exec node@24.21.0 -- node big_numbers.mjs
Runs on this device, in your browser. The first run of each language downloads it: Python (about 13.5 MB) or JavaScript (about 0.6 MB), which is kept for the next runs.
Your run, in this browser
- Python is exact at every step, because its integers have unlimited precision: 4999950000 pairs, and a remainder of 1.
- JavaScript gets the pair count right, since it is far below (about
), the largest safe integer: up to there, a Number holds every integer exactly. The
product is above it, so it is rounded to
1000000012000000000instead of1000000012000000036, and the remainder comes out as 999999972 instead of 1. Nothing warns you;Number.isSafeIntegersays false only when you ask. BigInt values have no size limit, so the product stays exact, but arithmetic cannot mix them with Numbers (it throws aTypeError), which is why the last line converts every operand. - Java keeps an
intresult in 32 bits: when the true value does not fit, the language specification keeps its low 32 bits and reports nothing. The Python functionlow_32_bitsdoes the same, so the second line is whatn * (n - 1) / 2gives withintvariables: 704982704, positive, plausible and wrong. Makenalong(64 bits), or write(long) n * (n - 1) / 2. Storing the result in alongis too late, because the multiplication of twointvalues already happened in 32 bits. - Go makes
int64 bits wide on 64-bit machines, so both results fit there. Its sized types such asint32wrap around the way Java’sintdoes, and the language specification says that overflow never causes a run-time panic, so a wrong result is just as quiet. - C++ promises nothing: when a signed integer result is out of range, the behaviour is undefined, and the program
may print a wrong number or something stranger. Use
long long, which the standard makes at least 64 bits wide.
Even 64 bits run out. fits below , about , but a product of three such numbers does not. Take the remainder after every multiplication, in every language. With JavaScript Numbers even that is not enough, because the product of two remainders can reach about and so pass by far. Multiply them as BigInt values instead, as the last line of the JavaScript example does.
Check versions and libraries before you rely on them
The lesson on coding round formats probes a platform with a few lines of code. One check comes even earlier, on paper: list the newer features your usual code relies on, find the version that introduced each one, and compare them with the platform’s environment page. Here is that check as a program, with the versions that HackerRank’s execution environment page lists:
# Versions one platform's environment page lists, and features with the first version that has each.
listed = {"Java": "21.0.4", "Go": "v1.26.4", "Node.js": "v20.15.1", "Python": "3.14.2"}
features = [
("Java", "21", "list.getLast() and list.reversed()"),
("Java", "22", "_ for a variable you never use"),
("Java", "25", "void main() with no class around it"),
("Go", "1.21", "the min and max built-ins"),
("Go", "1.22", "for i := range n"),
("Go", "1.27", "methods with their own type parameters"),
("Node.js", "21", "Object.groupBy()"),
("Python", "3.12", "itertools.batched()"),
]
def version(text):
"""'v1.26.4' -> (1, 26, 4). Tuples compare number by number."""
return tuple(int(part) for part in text.removeprefix("v").split("."))
for language, first, feature in features:
ok = version(listed[language]) >= version(first)
print(f"{'yes' if ok else 'no':3} {language} {first}+: {feature}")
# As text, "v1.26.4" sorts before "v1.9", because the character "2" sorts before "9".
print("v1.26.4" >= "v1.9", version("v1.26.4") >= version("v1.9")) Output
yes Java 21+: list.getLast() and list.reversed() no Java 22+: _ for a variable you never use no Java 25+: void main() with no class around it yes Go 1.21+: the min and max built-ins yes Go 1.22+: for i := range n no Go 1.27+: methods with their own type parameters no Node.js 21+: Object.groupBy() yes Python 3.12+: itertools.batched() False True
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 will_it_run.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
Not affiliated
Based on public information about HackerRank. MySmartCoPilot is not affiliated with HackerRank, and HackerRank’s real environments may differ from what this lesson describes.
Each “no” breaks a solution. Java and Go refuse to compile it, so no test runs at all, and JavaScript throws a
TypeError whenever the missing function is called.
- Java 21.0.4 has sequenced collections (JEP 431), with methods such as
getLast()andreversed(). It does not have unnamed variables written_(standard from JDK 22, JEP 456), or compact source files, wherevoid main()stands without a class around it (standard from JDK 25, JEP 512). JDK 21 had early forms of both only as preview features, which a compiler accepts only when it is started with--enable-preview(JEP 445 shows how). - Go v1.26.4 has
minandmax(Go 1.21) andfor i := range n(Go 1.22), but not methods that declare their own type parameters, which arrived in Go 1.27. - Node.js v20.15.1 has no
Object.groupBy(), which MDN’s compatibility data lists from Node.js 21. HackerRank’s page lists TypeScript 5.6.2 running on that Node.js, and because TypeScript adds no runtime library, it lacks the same built-ins.
The last line of the output shows why the program turns versions into tuples of numbers. Compared as text,
"v1.26.4" sorts before "v1.9", because the character 2 sorts before 9; as tuples, (1, 26, 4) is rightly the
later version. The same trap makes "3.14.2" >= "3.9" false in Python.
For C++, look at the compiler as well as the standard. HackerRank’s page offers a C++20 option built with G++ 8.3.0
and a C++23 option built with G++ 14.2.0. GCC’s standard library supports the ranges library from GCC 10.1 and
std::format from GCC 13.1, so code that calls std::ranges::sort compiles with the option labelled C++23 and fails
with the one labelled C++20.
Installed libraries need the same check, and environment pages list them too. HackerRank’s standard list for Python 3 includes requests, and its machine-learning list adds NumPy and pandas, but neither list has sortedcontainers, a third-party package of sorted lists, sets and dicts. Do not count on importing it there: a solution whose import fails scores nothing, however good the rest is. In a practice test, a probe like this one gives the answer in a second:
import importlib.util
# Three standard-library modules, then two packages that someone has to install.
for name in ["heapq", "bisect", "collections", "sortedcontainers", "numpy"]:
found = importlib.util.find_spec(name) is not None
print(f"{name:16} {'available' if found else 'not installed here'}") Output
heapq available bisect available collections available sortedcontainers not installed here numpy not installed here
Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 can_i_import.py
Runs on this device, in your browser. The first run downloads Python (about 13.5 MB), which is kept for the next runs.
Your run, in this browser
importlib.util.find_spec returns None when Python finds no module by that name, so the probe needs no try around
an import. Here the three standard-library modules are found and the two packages are not. Give it top-level names
only: for a dotted name such as numpy.linalg it first imports the parent package, and that import raises
ModuleNotFoundError when the package is missing.
When to switch language for an online assessment
Choose the language before the assessment starts, from the platform’s list and versions, and plan to use it throughout. Switching halfway costs more than it seems: you rewrite what you had, and you meet a different set of traps with less time left. The diagram puts the whole decision on one page.
Choosing a language for an online assessment
Text description of the diagram
The diagram reads from top to bottom.
- Before the round, pick your strongest language that the platform offers, in a version that runs your code.
- Then, for each problem, ask whether it needs something your language lacks. If it does not, stay with your language.
- If it does, ask whether the workaround is short. If it is, stay with your language and write the workaround.
- If the workaround is long, write that one problem in another language that the platform offers and you know well.
A switch is worth it in two situations:
- Your language is not offered, or its listed version lacks features you rely on. Then the decision comes before the round: practise the older forms on that version, or use your next-strongest language.
- One problem needs something your language lacks, and the workaround is long. Examples are a sorted set with
insertions and deletions in Python, JavaScript or Go, where C++ has
std::setand Java hasTreeSet, or exact arithmetic far beyond 64 bits, which Python does with ordinary integers. If the platform lets you pick a language for each problem and you write the other language well, write that one problem in it, then go back.
Speed alone is rarely a reason. Platforms set their time limits per language (HackerRank’s page lists 10 seconds for Python 3, 4 for Java and Go, and 2 for C++), and no language rescues an algorithm of the wrong complexity, so check the complexity before you blame the language. Shorter code in a language you seldom use is not a reason either.
The exercise below practises the version check on Java, whose versions are written in two styles.
Key takeaways
- Pick the language you write correctly under pressure. Short code, sorted maps and the role’s language only decide between languages you know equally well, and only among those the round offers.
- Heaps and sorted maps differ most: JavaScript and TypeScript have no heap, Python, JavaScript and Go have no sorted map, and Go’s heap needs five methods before it works.
- Integers fail silently: JavaScript rounds above , Java and Go wrap around, and in C++ signed overflow is undefined behaviour. Only Python’s ordinary integers never overflow.
- Compare the features you use with the platform’s listed versions as numbers, not as text, and probe its libraries in a practice test.
- Choose the language before the assessment, and switch for one problem only when a missing structure would cost more than writing that problem in another language you know well.
Exercise
Exercise · Easy · Python
Read the Java versions a platform lists
Environment pages write Java versions in the styles of different eras. HackerRank's page, for example, lists Sun Java 1.7.0_80, OpenJDK 8u472 and OpenJDK 21.0.4. JEP 223 describes both styles: before JDK 9 the major version was the second number of 1.N.0_U, and JDK 7u60 or JDK 7 Update 60 named the same release as 1.7.0_60; from JDK 9 on, the major version is the first number. JEP 322 later renamed that number the feature release, the name this exercise uses.
Write two functions in java_versions.py:
feature_release(listed)takes the text a page shows and returns the feature release as anint.supports(listed, needed)returnsTruewhen that Java is feature releaseneededor newer, andFalseotherwise.
feature_release("Sun Java 1.7.0_80") # 7
feature_release("OpenJDK 8u472") # 8
feature_release("OpenJDK 21.0.4") # 21
supports("OpenJDK 21.0.4", 21) # True: sequenced collections are standard in 21
supports("OpenJDK 21.0.4", 25) # False: compact source files need 25
The text before the version can be any words without digits (Sun Java , OpenJDK , JVM: ) or nothing at all, and an update can be written in the short or the long style (8u472, 7 Update 60).
Starter code · java_versions.py
def feature_release(listed):
"""The Java feature release of a version as a platform lists it: 'OpenJDK 8u472' -> 8."""
# Replace this line with your code.
return 0
def supports(listed, needed):
"""True when the listed Java is feature release `needed` or newer."""
# Replace this line with your code.
return False The sample tests · test_java_versions.py
from java_versions import feature_release, supports
def test_old_style():
"""an old-style version: 1.7.0_80 is Java 7"""
assert feature_release("Sun Java 1.7.0_80") == 7
def test_old_style_after_a_label():
"""an old-style version after a label: 1.8.0_121 is Java 8"""
assert feature_release("JVM: 1.8.0_121") == 8
def test_update_short_name():
"""the short name of an update release: 8u472 is Java 8"""
assert feature_release("OpenJDK 8u472") == 8
def test_update_long_name():
"""the long name of an update release: JDK 7 Update 60 is Java 7"""
assert feature_release("JDK 7 Update 60") == 7
def test_new_style():
"""a new-style version: the first number is the feature release"""
assert feature_release("OpenJDK 21.0.4") == 21
def test_not_the_largest_number():
"""the feature release is the first number, not the largest"""
assert feature_release("OpenJDK 11.0.25") == 11
def test_bare_number():
"""a version with no words around it"""
assert feature_release("25") == 25
def test_supports_its_own_release():
"""a feature of the very release the platform runs"""
assert supports("OpenJDK 21.0.4", 21) is True
def test_supports_a_later_feature():
"""a feature of a later release"""
assert supports("OpenJDK 21.0.4", 25) is False
def test_supports_old_style():
"""1.8.0_472 is Java 8, so it has what Java 8 added"""
assert supports("OpenJDK 1.8.0_472", 8) is True
def test_supports_two_digit_release():
"""release 10 is newer than release 9, although "10" sorts before "9" as text"""
assert supports("Java 10.0.2", 9) is True A hint
Collect every run of digits in the text: re.findall(r"\d+", listed) returns them in order, as strings. Then let the first number decide which of them is the feature release.
Results of the sample tests
| Test | Result | Details |
|---|
What your code printed
The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.
Check yourself
8 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.
References
- Execution environment (HackerRank)
- Hiring process (frequently asked questions) (Meta)
- heapq: heap queue algorithm (Python Software Foundation)
- bisect: array bisection algorithm (Python Software Foundation)
- Built-in types: numeric types (Python Software Foundation)
- The Python Standard Library (Python Software Foundation)
- importlib.util.find_spec() (Python Software Foundation)
- itertools.batched() (Python Software Foundation)
- Python Sorted Containers (Sorted Containers project)
- Array.prototype.sort() (MDN Web Docs)
- Number.MAX_SAFE_INTEGER (MDN Web Docs)
- BigInt (MDN Web Docs)
- Standard built-in objects (MDN Web Docs)
- Object.groupBy() (browser compatibility) (MDN Web Docs)
- ECMAScript language specification: the Number and BigInt types (Ecma International (TC39))
- TypeScript for the New Programmer (Microsoft (TypeScript))
- Java SE 25 API: package java.util (Oracle)
- Java SE 25 API: PriorityQueue (Oracle)
- Java SE 25 API: TreeMap (Oracle)
- The Java Language Specification, Java SE 25: integral types and values (4.2) (Oracle)
- The Java Language Specification, Java SE 25: multiplication operator (15.17.1) (Oracle)
- JEP 431: Sequenced Collections (OpenJDK)
- JEP 456: Unnamed Variables & Patterns (OpenJDK)
- JEP 512: Compact Source Files and Instance Main Methods (OpenJDK)
- JEP 445: Unnamed Classes and Instance Main Methods (Preview) (OpenJDK)
- JEP 223: New Version-String Scheme (OpenJDK)
- JEP 322: Time-Based Release Versioning (OpenJDK)
- Working Draft, Programming Languages: C++ (N4950) (ISO/IEC JTC1/SC22/WG21)
- libstdc++ implementation status (GNU Project (GCC))
- Package heap (container/heap) (The Go Authors)
- Standard library packages (The Go Authors)
- The Go Programming Language Specification (The Go Authors)
- Effective Go: maps (The Go Authors)
- Go FAQ: the size of an int on a 64-bit machine (The Go Authors)
- Go 1.21 release notes (The Go Authors)
- Go 1.22 release notes (The Go Authors)
- Go 1.27 release notes (The Go Authors)
Related tools
Report a problem with this lesson
Kept only in this browser. Your Learn progress