Java Interview Guide - Core Concepts
Java Fundamentals
Collection Framework
Key Concepts: Thread safety, iterators, duplicates, ordered collections, key-value pairs
List Implementations
Vector
- Thread-safe with strong consistency
- 2x capacity expansion
Collections.synchronizedList()
requires manual synchronization for iterators
ArrayList
- Array-based implementation
- Inefficient head insertion, efficient tail insertion
- 1.5x capacity expansion
- Pre-specify capacity to reduce expansion overhead
- Uses
transient
for object array to avoid serializing empty slots
LinkedList
- Doubly-linked list implementation
- Slowest for middle insertions
- Use Iterator for traversal
remove(Integer)
removes element,remove(int)
removes by index
Iterator Safety
- Enhanced for-loop uses iterator internally
- Concurrent modification throws
ConcurrentModificationException
- Use iterator’s
remove()
method instead of collection’s
Map Implementations
Hashtable
- Thread-safe using
synchronized
- No null keys/values allowed
HashMap
- Not thread-safe, allows null keys/values
- Array + linked list structure
- Hash collision resolution via chaining
- Default capacity: 16, load factor: 0.75
- JDK 1.8: Converts to red-black tree when chain length > 8 and capacity > 64
- Multi-threading can cause infinite loops during rehashing
1 | // Hash calculation for efficient indexing |
LinkedHashMap
- HashMap + doubly-linked list
- Maintains insertion/access order
- Used for LRU cache implementation
TreeMap
- Red-black tree based
- O(log n) time complexity
- Sorted keys via Comparator/Comparable
I/O Models
Java I/O Hierarchy
- Base classes:
InputStream/Reader
,OutputStream/Writer
- Decorator pattern implementation
BIO (Blocking I/O)
- Synchronous blocking model
- One thread per connection
- Suitable for low-concurrency scenarios
- Thread pool provides natural rate limiting
NIO (Non-blocking I/O)
- I/O multiplexing model (not traditional NIO)
- Uses
select/epoll
system calls - Single thread monitors multiple file descriptors
- Core components: Buffer, Channel, Selector
AIO (Asynchronous I/O)
- Event-driven with callbacks
- Introduced in Java 7 as NIO.2
- Direct return without blocking
- Limited adoption in practice
Thread Pool
Thread Creation Methods
- Runnable interface
- Thread class
- Callable + FutureTask
- Thread pools (recommended)
Core Parameters
corePoolSize
: Core thread countmaximumPoolSize
: Maximum thread countkeepAliveTime
: Idle thread survival timeworkQueue
: Task queue (must be bounded)rejectedExecutionHandler
: Rejection policy
Execution Flow
- Create threads up to core size
- Queue tasks when core threads busy
- Expand to max size when queue full
- Apply rejection policy when max reached
- Shrink to core size after keepAliveTime
Optimal Thread Count
1 | Optimal Threads = CPU Cores × [1 + (I/O Time / CPU Time)] |
Best Practices
- Graceful shutdown
- Uncaught exception handling
- Separate pools for dependent tasks
- Proper rejection policy implementation
ThreadLocal
Use Cases
- Thread isolation with cross-method data sharing
- Database session management (Hibernate)
- Request context propagation (user ID, session)
- HTTP request instances
Implementation
1 | Thread → ThreadLocalMap<ThreadLocal, Object> → Entry(key, value) |
Memory Management
- Entry key uses weak reference
- Automatic cleanup of null keys
- Must use
private static final
modifiers
Best Practices
- Always call
remove()
in finally blocks - Handle thread pool reuse scenarios
- Use
afterExecute
hook for cleanup
JVM (Java Virtual Machine)
Memory Structure
Components
- Class Loader
- Runtime Data Area
- Execution Engine
- Native Interface
Runtime Data Areas
Thread-Shared
- Method Area: Class metadata, constants, static variables
- Heap: Object instances, string pool (JDK 7+)
Thread-Private
- VM Stack: Stack frames with local variables, operand stack
- Native Method Stack: For native method calls
- Program Counter: Current bytecode instruction pointer
Key Changes
- JDK 8: Metaspace replaced PermGen (uses native memory)
- JDK 7: String pool moved to heap for better GC efficiency
Class Loading
Process
- Loading: Read .class files, create Class objects
- Verification: Validate bytecode integrity
- Preparation: Allocate memory, set default values for static variables
- Resolution: Convert symbolic references to direct references
- Initialization: Execute static blocks and variable assignments
Class Loaders
- Bootstrap: JDK core classes
- Extension/Platform: JDK extensions
- Application: CLASSPATH classes
Parent Delegation
- Child loaders delegate to parent first
- Prevents duplicate loading
- Ensures class uniqueness and security
Custom Class Loaders
- Extend ClassLoader, override
findClass()
- Tomcat breaks delegation for web app isolation
Garbage Collection
Memory Regions
- Young Generation: Eden + Survivor (From/To)
- Old Generation: Long-lived objects
- Metaspace: Class metadata (JDK 8+)
GC Root Objects
- Local variables in method stacks
- Static variables in loaded classes
- JNI references in native stacks
- Active Java threads
Reference Types
- Strong: Never collected while referenced
- Soft: Collected before OOM
- Weak: Collected at next GC
- Phantom: For cleanup notification only
Collection Algorithms
- Young Generation: Copy algorithm (efficient, no fragmentation)
- Old Generation: Mark-Sweep or Mark-Compact
Garbage Collectors
Serial/Parallel
- Single/multi-threaded
- Suitable for small applications or batch processing
CMS (Concurrent Mark Sweep)
- Low-latency for old generation
- Concurrent collection with application threads
G1 (Garbage First)
- Region-based collection
- Predictable pause times
- Default in JDK 9+, suitable for large heaps (>8GB)
ZGC/Shenandoah
- Ultra-low latency (<10ms)
- Supports TB-scale heaps
- Ideal for cloud-native applications
Tuning Parameters
1 | # Heap sizing |
OOM Troubleshooting
- Generate heap dumps on OOM
- Analyze with MAT (Memory Analyzer Tool) or VisualVM
- Common causes: memory leaks, oversized objects, insufficient heap space
- Tune object promotion thresholds and GC parameters
Performance Optimization Tips
- Collections: Pre-size collections, use appropriate implementations
- Strings: Use StringBuilder for concatenation, intern frequently used strings
- Thread Pools: Tune core/max sizes based on workload characteristics
- GC: Choose appropriate collector, monitor GC logs, tune heap ratios
- Memory: Avoid memory leaks, use object pools for expensive objects