[Go to site: main page, start]

0% found this document useful (0 votes)
5 views11 pages

Core Java Java8 Interview Essentials

This document serves as a comprehensive guide for Java developers with 3-10 years of experience preparing for interviews on Core Java, Java 8, and concurrency. It covers essential concepts such as JVM, OOP principles, exceptions, generics, collections, functional programming features, and concurrency constructs. Additionally, it includes sample interview questions and answers to aid in preparation.

Uploaded by

Ramesh Thammu
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views11 pages

Core Java Java8 Interview Essentials

This document serves as a comprehensive guide for Java developers with 3-10 years of experience preparing for interviews on Core Java, Java 8, and concurrency. It covers essential concepts such as JVM, OOP principles, exceptions, generics, collections, functional programming features, and concurrency constructs. Additionally, it includes sample interview questions and answers to aid in preparation.

Uploaded by

Ramesh Thammu
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Core Java & Java 8 Interview Essentials

Target audience: 3–10 years experienced Java developers preparing for interviews focused on Core Java,
Java 8, and concurrency.
This PDF is structured as a concise but deep revision guide, with short explanations and focused code
examples.
1. Core Java Concepts
Core Java concepts form the foundation for writing correct, maintainable, and performant Java applications.
Interviewers often test your mental model of how Java code executes in the JVM.

1.1 JVM, JDK, JRE


JVM (Java Virtual Machine) is the runtime responsible for executing compiled Java bytecode. It provides
services such as class loading, bytecode verification, JIT compilation, and garbage collection.
JRE (Java Runtime Environment) bundles the JVM and core libraries required to run Java applications, while
JDK (Java Development Kit) adds compilers and development tools needed to develop, compile, and debug
Java programs.

• JVM: specification + concrete implementations (HotSpot, OpenJ9).


• JRE: JVM + core Java class libraries (java.* packages).
• JDK: JRE + javac, javadoc, jdb, and other developer tools.

1.2 Class loading and memory areas


Class loaders load bytecode into the JVM on demand. The Bootstrap, Extension/Platform, and Application
class loaders form a delegation hierarchy where parent loaders are consulted first before attempting to load a
class.
At runtime, the JVM divides memory into areas such as the heap (object instances), method area /
metaspace (class metadata), Java stacks (frames per thread), native method stacks, and the program
counter.

1.3 OOP principles in Java


Java is an object-oriented language supporting encapsulation, inheritance, polymorphism, and abstraction.
Interviewers usually expect you to illustrate these principles with simple class designs and code.
Encapsulation means bundling state and behavior and restricting direct access to internal representation via
access modifiers (private, protected, public, package-private).
class BankAccount {
private double balance;

public BankAccount(double balance) {


[Link] = balance;
}

public void deposit(double amount) {


if (amount <= 0) throw new IllegalArgumentException("amount must be positive");
balance += amount;
}

public double getBalance() {


return balance;
}
}
Inheritance allows a class to acquire properties and behavior of another class using the extends keyword,
enabling code reuse and polymorphism.
class Animal {
public void speak() {
[Link]("Some sound");
}
}

class Dog extends Animal {


@Override
public void speak() {
[Link]("Woof");
}
}
Polymorphism lets the same interface or superclass reference point to different concrete implementations,
with behavior determined at runtime via dynamic dispatch.
Animal a1 = new Dog();
Animal a2 = new Animal();

[Link](); // Woof
[Link](); // Some sound
Abstraction focuses on exposing essential behavior while hiding implementation details, commonly
implemented through abstract classes and interfaces.
interface PaymentProcessor {
void pay(double amount);
}

class CreditCardProcessor implements PaymentProcessor {


@Override
public void pay(double amount) {
// concrete implementation
}
}
1.4 Exceptions
Exceptions represent abnormal conditions that disrupt normal program flow. Java categorizes them into
checked exceptions, unchecked exceptions (runtime), and errors.

• Checked exceptions extend Exception (but not RuntimeException) and must be declared or handled.
• Unchecked exceptions extend RuntimeException and represent programming errors (null dereferences,
illegal arguments, etc.).
• Errors extend Error and represent serious problems (OutOfMemoryError, StackOverflowError).
try {
[Link]([Link]("[Link]"));
} catch (IOException e) {
// handle or rethrow
}
Best practice is to catch exceptions at boundaries (e.g., controllers), preserve root causes, and avoid
swallowing exceptions silently.

1.5 Generics
Generics provide compile-time type safety for collections and other containers by allowing parameterization of
types, reducing casts and ClassCastException.
List<String> names = new ArrayList<>();
[Link]("Alice");
String first = [Link](0); // no cast needed
Java implements generics using type erasure, meaning generic type parameters are removed at compile time
and replaced with their bounds or Object at runtime.

• You cannot use primitive types as type arguments (use wrappers like Integer).
• No generic array creation (e.g., new List[] is illegal).
• Use wildcards (? extends T, ? super T) for flexible APIs.
public static void printAll(List<? extends Number> nums) {
for (Number n : nums) {
[Link](n);
}
}

1.6 Collections basics


The Java Collections Framework provides interfaces (List, Set, Map, Queue) and implementations (ArrayList,
LinkedList, HashSet, TreeSet, HashMap, ConcurrentHashMap, etc.) for storing and manipulating groups of
objects.

• List: ordered, allows duplicates (ArrayList, LinkedList).


• Set: no duplicates, may be unordered (HashSet) or sorted (TreeSet).
• Map: key–value pairs (HashMap, LinkedHashMap, TreeMap).
Map<String, Integer> wordCount = new HashMap<>();
[Link]("java", 1);
[Link]("java", 1, Integer::sum);
Choose collection implementations based on complexity characteristics: HashMap and HashSet offer
average O(1) operations, while TreeMap and TreeSet maintain sorted order with O(log n) operations.
2. Java 8 Essentials
Java 8 introduced functional-style programming features like lambdas, method references, the Streams API,
Optional, and default methods. These are central to modern Java interview questions.

2.1 Functional interfaces and lambdas


A functional interface is an interface with exactly one abstract method, such as Runnable, Callable,
Comparator, and the [Link] package types like Function, Predicate, and Consumer.
@FunctionalInterface
interface Calculator {
int apply(int a, int b);
}

Calculator add = (a, b) -> a + b;


int result = [Link](2, 3); // 5
Lambdas provide a concise syntax for implementing functional interfaces, capturing effectively final variables
from the enclosing scope.

• (arg1, arg2) -> expression


• (arg1, arg2) -> { // statements }
• Use method references for even more concise code when existing methods match the functional
interface signature.

2.2 Method references


Method references are shorthand for lambdas that call existing methods, using the :: operator. Common
forms include static, instance, and constructor references.

• Static: ClassName::staticMethod
• Instance: instanceRef::instanceMethod
• Constructor: ClassName::new
List<String> names = [Link]("bob", "alice");
[Link](String::compareToIgnoreCase);

Supplier<List<String>> listSupplier = ArrayList::new;

2.3 Streams API basics


Streams represent sequences of elements supporting functional-style operations such as map, filter, reduce,
and collect. They are lazy, can be finite or infinite, and do not store data themselves.
List<String> names = [Link]("Alice", "Bob", "Charlie");
List<String> upper = [Link]()
.filter(n -> [Link]() > 3)
.map(String::toUpperCase)
.collect([Link]());
Intermediate operations (filter, map, sorted) return a new stream and are lazy, while terminal operations
(forEach, collect, reduce, count) trigger processing and close the stream.

2.4 Common stream operations


• map: transforms each element.
• filter: keeps elements matching a Predicate.
• flatMap: flattens nested structures (e.g., List>).
• sorted: sorts elements with natural order or a Comparator.
• distinct: removes duplicates based on equals/hashCode.
• limit / skip: truncates or skips elements.
int sum = [Link](1, 10)
.filter(i -> i % 2 == 0)
.sum();
Use Collectors for common reductions: toList, toSet, joining, groupingBy, partitioningBy, summingInt, and
more.
Map<Boolean, List<Integer>> partitioned = [Link](1, 10)
.boxed()
.collect([Link](i -> i % 2 == 0));

2.5 Optional
Optional is a container object that may or may not contain a non-null value. It was introduced to make the
absence of a value explicit and reduce NullPointerException.
Optional<String> maybeName = findName();
[Link](n -> [Link]([Link]()));

String name = [Link]("default");

• Use Optional as a return type to model absence, not for fields or parameters in most cases.
• Avoid calling get() without checking presence; prefer orElse, orElseGet, orElseThrow.
• Optional supports map, flatMap, filter for functional-style chaining.
3. Concurrency Essentials
Java concurrency is a core topic for backend and enterprise interviews. Modern Java favors higher-level
concurrency constructs from [Link] over manually managing threads.

3.1 Threads and Runnable


A thread is a lightweight unit of execution. In Java, you can create threads by extending Thread or, preferably,
by passing a Runnable or Callable to an ExecutorService.
class Task implements Runnable {
@Override
public void run() {
[Link]("Running in " + [Link]().getName());
}
}

Thread t = new Thread(new Task());


[Link]();
Manual thread management becomes hard to scale and tune. ExecutorService abstracts thread management
and provides a flexible way to submit tasks and manage pools.

3.2 ExecutorService basics


ExecutorService decouples task submission from execution, internally managing a pool of worker threads.
Use factory methods on Executors or custom ThreadPoolExecutor instances with explicit configuration.
ExecutorService executor = [Link](4);
Future<Integer> future = [Link](() -> {
// some computation
return 42;
});
Integer value = [Link]();
[Link]();

• newFixedThreadPool: fixed number of threads, suitable for CPU-bound workloads.


• newCachedThreadPool: dynamically sized, good for short-lived tasks, but must be used carefully.
• newScheduledThreadPool: supports delayed and periodic execution.

3.3 Synchronization and locks


When multiple threads access shared mutable state, you must ensure visibility and atomicity. The
synchronized keyword and higher-level locks provide mutual exclusion and memory visibility guarantees.
class Counter {
private int value;

public synchronized void increment() {


value++;
}

public synchronized int get() {


return value;
}
}
ReentrantLock from [Link] offers more flexible locking features than synchronized,
including tryLock, lockInterruptibly, and fair locks.
Lock lock = new ReentrantLock();
int[] count = {0};

void increment() {
[Link]();
try {
count[0]++;
} finally {
[Link]();
}
}

• Use synchronized for simple, intrinsic locking tied to an object monitor.


• Use ReentrantLock when you need timed, interruptible, or fair locking.
• Always release locks in a finally block to avoid deadlocks.

3.4 Volatile and atomic classes


The volatile keyword ensures changes to a variable are visible across threads and prevents certain instruction
reordering, but it does not make compound actions atomic.
volatile boolean running = true;

void stop() {
running = false;
}
For atomic operations on single variables, use AtomicInteger, AtomicLong, and other atomic classes from
[Link].
AtomicInteger counter = new AtomicInteger();
int newValue = [Link]();
3.5 CompletableFuture basics
CompletableFuture represents a future result of an asynchronous computation and supports a rich, fluent API
for composing dependent tasks without deeply nested callbacks.
CompletableFuture<Integer> future = [Link](() -> {
// simulate long-running task
return 42;
});

CompletableFuture<String> result = future


.thenApply(v -> "Result: " + v)
.exceptionally(ex -> "Error: " + [Link]());

[Link]([Link]());

• thenApply / thenApplyAsync: transform result synchronously/asynchronously.


• thenCompose: flatten dependent futures.
• allOf / anyOf: combine multiple futures.
• handle / exceptionally: centralized error handling.
4. Top Java Interview Questions and Answers (Sample)
This section provides representative Java and Java 8 interview questions with concise answers. Extend this
set up to 100 questions as needed for your preparation.
1. What is the difference between JDK, JRE, and JVM?
JVM is the runtime that executes bytecode. JRE bundles the JVM and core libraries required to run Java
applications. JDK includes the JRE plus development tools like the compiler, debugger, and documentation
generator.
2. Explain the main differences between an abstract class and an interface in Java.
Abstract classes can have state, constructors, and both abstract and concrete methods; a class can extend
only one abstract class. Interfaces primarily define contracts, support multiple inheritance of type, and from
Java 8 can contain default and static methods.
3. What is the difference between == and equals() for objects?
== compares reference equality (whether two references point to the same object), while equals() is meant to
compare logical equality and can be overridden to compare object contents.
4. What are checked and unchecked exceptions?
Checked exceptions must be declared in method signatures or handled with try-catch; they represent
recoverable conditions. Unchecked exceptions extend RuntimeException and typically indicate programming
errors that may not be recoverable.
5. What is the difference between ArrayList and LinkedList?
ArrayList is backed by a dynamic array, providing fast random access and good cache locality, while
insertions/removals in the middle are costly. LinkedList is a doubly linked list with cheaper insertions/removals
at arbitrary positions but slower random access.
6. How does HashMap work internally?
HashMap stores key–value pairs in buckets based on the key's hashCode. On lookup, it computes the hash,
finds the bucket, then uses equals() to resolve collisions among entries in the same bucket.
7. What is immutability in Java and why is String immutable?
An immutable object cannot change its state after construction. String is immutable to ensure security,
caching, and safe sharing across threads, and because it is heavily used as keys in collections and in class
loading.
8. What is a functional interface?
A functional interface is an interface with exactly one abstract method, used as the target for lambda
expressions and method references. Examples include Runnable, Callable, Supplier, Consumer, and
Predicate.
9. How do map, filter, and reduce work in streams?
map transforms each element using a Function, filter keeps elements matching a Predicate, and reduce
combines elements into a single result using an associative accumulation function and optional identity.
10. What is Optional and when would you use it?
Optional is a container that may or may not hold a non-null value. It is used as a return type to model absence
explicitly, avoid returning null, and encourage callers to handle the empty case.
11. Explain the difference between parallelStream() and stream().
stream() processes elements sequentially in a single thread, while parallelStream() attempts to process
elements in parallel using the common ForkJoinPool, which can improve performance for CPU-bound,
stateless operations on large data sets.
12. What is the happens-before relationship in the Java Memory Model?
Happens-before is a guarantee that memory writes by one specific statement are visible to another specific
statement. It is established by actions like unlocking a monitor before another thread locks it, or writing to a
volatile variable before another thread reads it.
13. What is the difference between synchronized and ReentrantLock?
synchronized is a language-level construct tied to an object's intrinsic lock, simpler and easier to use.
ReentrantLock is a more flexible explicit lock with features like fairness, tryLock, and lockInterruptibly, but
requires manual locking and unlocking.
14. How does CompletableFuture help avoid callback hell?
CompletableFuture supports a fluent API for composing asynchronous stages (thenApply, thenCompose,
thenAccept) and combining multiple futures (allOf, anyOf), avoiding deeply nested callbacks and improving
readability.
15. What is the difference between final, finally, and finalize()?
final is a keyword used with variables, methods, and classes to prevent modification or inheritance. finally is a
block in exception handling that always executes. finalize() is a method called by the garbage collector before
reclaiming an object's memory (now deprecated).
Extend this Q&A; list up to 100 questions by covering additional topics such as: serialization, reflection,
ClassLoader mechanics, design patterns, memory leaks, GC tuning, NIO, Java 8 date/time API, streams
performance, and advanced concurrency.

You might also like