What they're testing
Whether you reason about allocation cost, and know how far the compiler already fixes it for you.
The short answer~30 seconds
Immutability allows safe sharing across threads without synchronisation, caching of the hash, and the string pool. It's also a security property: if String were mutable, a file path argument could be changed after it was validated and before it was used. StringBuilder is a mutable character buffer for repeated appends — every + on a String creates a new object.
The long answer
The detail worth getting right for the current era: a + b in a single expression is NOT slow — the compiler lowers it to StringConcatFactory (since Java 9, via invokedynamic), often faster than a hand-written StringBuilder. The problem appears only when concatenating INSIDE A LOOP: each iteration allocates a fresh builder and recopies the whole string, making it O(n²).
The string pool is also often misdescribed. Literals are interned automatically and have lived in the heap since Java 7 (they were in PermGen before). Runtime-built strings aren't interned, so new String("a") == "a" is false. Calling intern() by hand is rarely worth it, and on an application with many unique strings it backfires.
// O(n²): mỗi vòng sao chép lại toàn bộ chuỗi đã có
String s = "";
for (var row : rows) s += row.name() + ",";
// O(n): một bộ đệm, mở rộng khi cần
var sb = new StringBuilder();
for (var row : rows) sb.append(row.name()).append(',');
// Từ Java 8: rõ ràng hơn cả hai cách trên
String s = rows.stream().map(Row::name).collect(joining(","));What they'll ask next
?StringBuilder versus StringBuffer?
StringBuffer synchronises every method, StringBuilder doesn't. Use StringBuilder essentially always, because a string buffer is rarely shared between threads — and when it is, per-method synchronisation isn't enough for correctness anyway.
These lose points
- Saying "always use StringBuilder,
+is always slow". Untrue since Java 9, and an experienced Java interviewer will catch it.