Here is your structured, compressed, and high-yield technical handbook for Senior Java Interview Series β Part 5: Advanced String Interview Questions (50+ Questions) formatted strictly using our locked-in Style 1 (Flowchart-Style ASCII / Box Blocks), tables, and explicit decision flows.
Table of ContentsΒΆ
- Core String Concept Questions
- String Pool and Intern Questions
- StringBuilder and StringBuffer Questions
- JVM Internal Questions
- Garbage Collection and Memory Questions
- Scenario-Based Senior Questions
- Coding Questions
- Tricky Interview Questions
- Quick Revision
1. Core String Concept QuestionsΒΆ
Q1. Why is String immutable in Java?ΒΆ
Immutability guarantees that once constructed, state cannot mutate.
1. Security ParametersΒΆ
- Prevents mid-execution mutation of sensitive values (e.g., DB URLs, file paths, class loading targets).
url = "jdbc:mysql://localhost/bank"
ββ [Immutable] ββ> Value remains fixed across connection lifetime
ββ [Mutable Risk] ββ> Thread 2 could alter host mid-handshake to attacker domain
2. String Pool ReuseΒΆ
- Enables global instance sharing across the JVM without state corruption.
3. Inherent Lock-Free Thread SafetyΒΆ
- Multi-threaded read access requires zero synchronization overhead.
4. $O(1)$ HashCode CachingΒΆ
- Immutable state enables memoizing computed hash values inside
private int hash.
Follow-up: Why does declaring the class
finalsupport immutability?finalprevents subclassing. Withoutfinal, a malicious subclass could override mutators/accessors, introduce mutable fields, and break immutability guarantees.
Q2. Is String really 100% immutable?ΒΆ
- API Perspective: Yes. Public APIs expose zero mutator methods.
- JVM/Reflection Perspective: Historically, reflection could mutate
private final char[] value. Modern JDKs (Java 9+ Module System) encapsulatejava.langinternals, blocking reflection mutation unless explicitly forced via deep JVM args.
Q3. Difference between String Object and String Constant Pool?ΒΆ
| Feature | String Object (Heap) | String Constant Pool (SCP) |
|---|---|---|
| Storage Location | General Heap memory | Dedicated hash table inside Heap |
| Instantiation | Explicit via new String() | Implicit via Literals ("") or intern() |
| Deduplication | Distinct duplicate instances allowed | Holds single canonical instance per literal |
Q4. How many objects are created by String s = new String("Java")?ΒΆ
new String("Java") Allocation
ββ ["Java" Absent from SCP] ββ> Creates 2 objects (1 in SCP + 1 on Heap)
ββ ["Java" Present in SCP] ββ> Creates 1 object (1 on Heap)
Q5. How many objects are created by String s1 = "Java"; String s2 = "Java";?ΒΆ
Literal Execution Flow
ββ [s1 = "Java"] ββ> Creates 1 object in SCP
ββ [s2 = "Java"] ββ> Reuses existing SCP object (0 new objects)
- Total Objects Created: 1 (Both references point to identical SCP memory address).
Q6. Difference between == and equals()?ΒΆ
String Comparison Check
ββ [operator ==] ββ> Reference Equality Check (Compares memory addresses)
ββ [method equals()] ββ> Content Equality Check (Compares character sequences)
ExampleΒΆ
String a = new String("Java");
String b = new String("Java");
System.out.println(a == b); // false (Distinct Heap instances)
System.out.println(a.equals(b)); // true (Matching character content)
Q7. Why is String an ideal HashMap key?ΒΆ
- Immutable State: Hash code remains stable across life cycle.
- Cached Hash Code:
hashCode()is calculated once and memoized. - Thread Safety: Lock-free key operations across concurrent threads.
Q8. What happens internally when calling String.concat()?ΒΆ
s = "Java".concat("8")
ββ Step 1 ββ> Reads "Java" length (4) & "8" length (1)
ββ Step 2 ββ> Allocates new array buffer of size 5
ββ Step 3 ββ> Copies characters into new buffer
ββ Step 4 ββ> Instantiates & returns brand-new String object
- The original
"Java"string remains completely untouched in memory.
Q9. Why does String use HashCode Caching?ΒΆ
HashMap lookups recalculate hashCode() per call. Computing polynomial hashes for long strings is expensive ($O(N)$). String caches its computed value in hash on first invocation, enabling $O(1)$ fast lookups thereafter.
2. String Pool and Intern QuestionsΒΆ
Q10. What is String.intern()?ΒΆ
Returns the canonical reference from the SCP.
s1 = new String("Java"); s2 = s1.intern();
ββ ["Java" in SCP] ββ> Returns existing pooled reference to s2
ββ ["Java" Not in SCP] ββ> Adds s1 string to SCP + returns reference
Q11. Difference between String Pool and intern()?ΒΆ
| Attribute | String Constant Pool (SCP) | intern() Method |
|---|---|---|
| Type | Memory structure inside Heap | Instance method on String class |
| Management | JVM automatic management | Developer invoked explicitly |
| Purpose | Stores canonical literal instances | Retrieves or registers dynamic instances into SCP |
Q12. Should you always call intern() on dynamic inputs?ΒΆ
- No. Interning high-cardinality, unbounded runtime data (e.g., UUIDs, customer names) causes String Pool table bucket collisions and memory explosion.
- Rule: Intern strictly on finite, low-cardinality values (e.g., country codes
"US","IN", status codes"ACTIVE","SUCCESS").
Q13. Where is the String Constant Pool stored across Java versions?ΒΆ
SCP Storage Location
ββ [Java 6 and earlier] ββ> Stored in PermGen (Fixed size, high OOM risk)
ββ [Java 7+] ββ> Stored in Main Heap (Dynamically sized, GC-managed)
Q14. Why was the String Constant Pool moved from PermGen to Heap in Java 7?ΒΆ
- PermGen had fixed size constraints, leading to
java.lang.OutOfMemoryError: PermGen space. - Moving SCP to Heap allows strings to be collected during standard GC sweeps and dynamically scaled.
Q15. Can String Pool objects be garbage collected?ΒΆ
- Yes. From Java 7+, pooled strings without active strong references are eligible for collection during GC sweeps.
3. StringBuilder and StringBuffer QuestionsΒΆ
Q16. Why do we need StringBuilder?ΒΆ
String immutability causes loop concatenation anti-patterns (s += i) to allocate thousands of short-lived intermediate Heap objects. StringBuilder mutates an internal buffer without intermediate allocations.
Q17. Difference between StringBuilder and StringBuffer?ΒΆ
| Feature | StringBuilder | StringBuffer |
|---|---|---|
| Mutability | Mutable | Mutable |
| Thread Safety | Not Thread-Safe | Thread-Safe |
| Synchronization | Unsynchronized (Fast) | Synchronized methods (Slow) |
| Introduced In | Java 5 | Java 1.0 |
| Primary Scope | Local method variables | Shared multi-threaded mutation |
Q18. Why is StringBuilder faster than StringBuffer?ΒΆ
Append Execution Flow
ββ [StringBuilder] ββ> Direct array modification (Zero locking cost)
ββ [StringBuffer] ββ> Acquire Monitor Lock ββ> Modify array ββ> Release Lock
Q19. Is StringBuilder thread-safe?ΒΆ
- No. Simultaneous concurrent modifications by multiple threads corrupt internal
countpointers and array elements, resulting in corrupted output orArrayIndexOutOfBoundsException.
Q20. Is StringBuffer completely thread-safe in all scenarios?ΒΆ
- Individual method calls (e.g.,
.append()) are atomic and thread-safe. - Compound checks (e.g.,
if (sb.length() > 0) sb.deleteCharAt(0);) remain vulnerable to race conditions unless protected by client-side synchronization locks.
Q21. What is the default initial capacity of StringBuilder?ΒΆ
- Default Empty Constructor (
new StringBuilder()): 16 characters. - String Constructor (
new StringBuilder("Java")):str.length() + 16($4 + 16 = 20$).
Q22. How does StringBuilder dynamically increase capacity?ΒΆ
Capacity Exceeded Rule
ββ Standard Formula ββ> newCapacity = (oldCapacity * 2) + 2
ββ Insufficient Formula ββ> newCapacity = minimumRequiredCapacity
Q23. Does StringBuilder.append() allocate new objects?ΒΆ
- Normally No: Modifies elements directly inside the existing array.
- Exception: When capacity is exceeded, it allocates a new larger array and executes
System.arraycopy().
4. JVM Internal QuestionsΒΆ
Q24. Difference between Java 8 and Java 9 String implementations?ΒΆ
Internal Storage Shift
ββ [Java 8] ββ> char[] value (2 bytes / 16 bits per character unconditionally)
ββ [Java 9+] ββ> byte[] value + byte coder flag (Compact Strings optimization)
Q25. What are Compact Strings (JEP 254)?ΒΆ
Introduced in Java 9 to reduce string memory footprint. Since most application strings contain LATIN-1 characters requiring only 1 byte, storing them in 2-byte char[] arrays wasted 50% memory.
Q26. What is the coder field in Java 9+ String?ΒΆ
A byte field indicating array encoding:
coder Encoding Selection
ββ [LATIN1 (0)] ββ> Single-byte encoding (ISO-8859-1 / ASCII)
ββ [UTF16 (1)] ββ> Double-byte encoding (Unicode / Non-ASCII)
Q27. Why was char[] replaced with byte[]?ΒΆ
- Cuts string heap memory usage by up to 50% for LATIN-1 strings.
- Improves CPU cache-line efficiency due to higher data density.
Q28. How does String.equals() work internally?ΒΆ
s1.equals(s2) Execution Pipeline
ββ [Same Identity (this == obj)] ββ> Return true instantly (O(1))
ββ [Type / Length Mismatch] ββ> Return false instantly (O(1))
ββ [Matching Lengths] ββ> Compare byte[]/char[] elements value-by-value (O(N))
Q29. How does String.hashCode() calculate its value?ΒΆ
Formula:
$$h = \sum_{i=0}^{n-1} s[i] \cdot 31^{n-1-i}$$
Q30. Why use prime multiplier 31 in hash calculations?ΒΆ
- Prime Number Properties: Distributes hash codes evenly across table buckets, reducing collisions.
- CPU Optimization: $31 \cdot i$ is optimized by compiler to bitwise shifts and subtractions:
(i << 5) - i.
5. Garbage Collection and Memory QuestionsΒΆ
Q31. What is G1 GC String Deduplication?ΒΆ
A feature (-XX:+UseStringDeduplication) available with G1 GC. During GC sweeps, it identifies distinct Heap String instances containing identical character arrays and repoints both to a single shared byte[] array, collecting duplicate arrays.
Q32. Difference between String Constant Pool and G1 String Deduplication?ΒΆ
| Metric | String Constant Pool (SCP) | G1 String Deduplication |
|---|---|---|
| Scope | Compile-time literals & intern() calls | Dynamic runtime Heap String instances |
| Timing | Instantaneous upon creation/intern | Asynchronous during GC cycles |
| Target | Deduplicates String reference objects | Deduplicates underlying array storage (byte[]) |
Q33. When should G1 String Deduplication be enabled?ΒΆ
- Recommended: Memory-heavy applications containing large numbers of duplicate strings (e.g., repeated JSON payloads, cache structures).
- Not Recommended: Applications where strings are highly unique (e.g., cryptographically generated tokens, GUIDs), as inspection adds GC overhead without memory savings.
6. Scenario-Based Senior QuestionsΒΆ
Q34. Production JVM exhibits high memory usage dominated by String objects. How do you debug?ΒΆ
Production Debugging Pipeline
ββ Step 1 ββ> Capture Heap Dump (jmap / gcmd)
ββ Step 2 ββ> Analyze using Eclipse MAT or VisualVM (Inspect Dominator Tree & Duplicate Strings)
ββ Step 3 ββ> Identify source (e.g., unbounded interning, loop concatenation, duplicated JSONs)
ββ Step 4 ββ> Apply fix (Refactor to StringBuilder, apply bounded caching, or enable G1 String Deduplication)
Q35. Performance degrades during large payload generation (response += data). What is the issue and fix?ΒΆ
- Root Cause: Re-allocates intermediate
Stringobjects continuously inside the loop, overloading GC. - Fix: Replace
Stringconcatenation withStringBuilderinitialized with an estimated capacity:new StringBuilder(estimatedSize).
Q36. Should database primary key strings be interned using .intern()?ΒΆ
- No. Primary keys/UUIDs are high-cardinality, dynamic values. Interning millions of unique keys floods the String Pool table, causing bucket collisions and degraded performance.
Q37. A developer uses StringBuffer inside local method scopes. Should you approve?ΒΆ
- No. Local method variables are confined to a single thread's stack frame. Using
StringBufferadds unnecessary monitor locking overhead. Replace withStringBuilder.
Q38. API latency increased after switching from StringBuilder to StringBuffer. Why?ΒΆ
StringBufferenforces monitor lock acquisition/release overhead on every method invocation, adding CPU synchronization latency.
Q39. Why are immutable strings preferred in distributed microservices?ΒΆ
- Thread Safety: Lock-free concurrent sharing across worker threads.
- Key Stability: Immutable keys prevent cache corruption in distributed stores (e.g., Redis).
- Security Integrity: Guaranteed parameter stability across async execution pipelines.
7. Coding QuestionsΒΆ
Q40. What is the output of the following code?ΒΆ
String a = "Java";
String b = "Ja" + "va";
System.out.println(a == b);
- Output:
true - Reason: Compile-time constant folding evaluates
"Ja" + "va"directly to"Java", referencing the identical SCP instance.
Q41. What is the output of the following code?ΒΆ
String a = "Java";
String b = "Ja";
String c = b + "va";
System.out.println(a == c);
- Output:
false - Reason:
bis a variable, so concatenation occurs dynamically at runtime, creating a new Heap object.
Q42. Optimize the following string accumulation logic:ΒΆ
// Anti-Pattern
String result = "";
for (String value : list) {
result = result + value;
}
Optimized CodeΒΆ
StringBuilder sb = new StringBuilder();
for (String value : list) {
sb.append(value);
}
String result = sb.toString();
Q43. Reverse a String using built-in utilities:ΒΆ
public class StringUtil {
public static String reverse(String input) {
if (input == null) return null;
return new StringBuilder(input).reverse().toString();
}
}
8. Tricky Interview QuestionsΒΆ
Q44. Is String immutable because the class is declared final?ΒΆ
- No.
finalon the class level only prevents subclassing. Immutability is enforced because: - Internal storage array
valueisprivateandfinal. - No mutator methods are exposed.
- Defensive copying is used where applicable.
Q45. Can a final String field be modified using Reflection?ΒΆ
- In legacy Java versions (Java 8 and earlier), reflection could modify
private finalfields. From Java 9+ onward, the Module System restricts deep reflection access tojava.langinternals. Modifying immutable strings breaks JVM assumptions and leads to unpredictable bugs.
Q46. Is StringBuilder immutable?ΒΆ
- No.
StringBuilderis mutable; its contents mutate directly inside its internal character array.
Q47. Does string concatenation (+) always instantiate a StringBuilder?ΒΆ
String Concatenation Strategy
ββ [Compile-Time Constants ("a" + "b")] ββ> Constant Folding (No StringBuilder allocated)
ββ [Dynamic Variables (Java 8)] ββ> Compiler injects new StringBuilder()
ββ [Dynamic Variables (Java 9+)] ββ> Invokes StringConcatFactory (invokedynamic optimization)
Q48. How did string concatenation change in Java 9+?ΒΆ
Java 9 replaced static StringBuilder bytecode generation for concatenation with invokedynamic calling StringConcatFactory.makeConcatWithConstants(). This allows the JVM to change concatenation strategies without recompiling bytecode.
Q49. Why is String immutable while StringBuilder is mutable?ΒΆ
String: Designed for thread safety, global instance sharing, domain security, and key stability in hash tables.StringBuilder: Designed purely as a high-performance buffer for local string manipulation.
Q50. How do you implement a custom Immutable Class in Java?ΒΆ
- Declare the class as
final(prevents subclassing). - Declare all fields as
privateandfinal. - Initialize all fields via constructor (no setters).
- Perform defensive copying for any mutable object inputs and outputs.
Quick RevisionΒΆ
- Immutability Drivers: Security, SCP sharing, thread safety, cached hash codes.
- SCP Location: PermGen (Java 6) $\rightarrow$ Main Heap (Java 7+).
- Compact Strings (Java 9+): Swapped
char[]forbyte[]pluscoderflag (0 for LATIN-1, 1 for UTF-16), saving 50% memory. ==vs.equals():==compares reference addresses;.equals()compares character values.intern()Rule: Returns canonical SCP reference. Use on finite low-cardinality values only.StringBuildervsStringBuffer:StringBuilderis unsynchronized (fast);StringBufferis synchronized (slow).- G1 String Deduplication: Asynchronously merges duplicate
byte[]arrays on Heap during GC sweeps (-XX:+UseStringDeduplication). - Java 9 Concatenation: Uses
invokedynamicviaStringConcatFactoryinstead of hardcodedStringBuilderinstantiations.