0% found this document useful (0 votes)
3 views23 pages

Java 8 Interview Prep

The document is a comprehensive Java 8 Interview Preparation Guide designed for individuals with 2+ years of experience, covering over 100 questions and code examples from basic to advanced topics. It includes sections on Java 8 features like Lambda Expressions, Stream API, Optional Class, and more, along with explanations and interview tips. The guide aims to equip candidates with essential knowledge and practical coding challenges for Java 8 interviews.

Uploaded by

asif.hawkscode
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)
3 views23 pages

Java 8 Interview Prep

The document is a comprehensive Java 8 Interview Preparation Guide designed for individuals with 2+ years of experience, covering over 100 questions and code examples from basic to advanced topics. It includes sections on Java 8 features like Lambda Expressions, Stream API, Optional Class, and more, along with explanations and interview tips. The guide aims to equip candidates with essential knowledge and practical coding challenges for Java 8 interviews.

Uploaded by

asif.hawkscode
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

JAVA 8

Interview Preparation Guide

For 2+ Years Experience

Basic to Advanced | 100+ Questions | Code Examples

Complete with Explanations, Code Snippets & Interview Tips


Table of Contents
1. Java 8 Overview & New Features

2. Lambda Expressions

3. Functional Interfaces

4. Stream API

5. Optional Class

6. Default & Static Methods in Interfaces

7. Method References

8. Date & Time API ([Link])

9. Collections Enhancements

10. Concurrency Enhancements

11. Nashorn JavaScript Engine & Other Features

12. Java Core Concepts (OOP, Collections, Strings)

13. Exception Handling & Multithreading

14. Design Patterns & Best Practices

15. Coding Challenges & Output-Based Questions

16. Quick Revision Cheat Sheet

Java 8 Interview Prep Guide | Page 2


1. Java 8 Overview & New Features
Q: What are the major features introduced in Java 8?
A: Java 8 introduced several groundbreaking features: Lambda Expressions for functional-style programming,
Stream API for bulk data operations on collections, Functional Interfaces (with @FunctionalInterface
annotation), Default and Static methods in interfaces, Optional class to handle null safely, New Date/Time
API ([Link] package), Method References, Nashorn JavaScript Engine, and CompletableFuture for
asynchronous programming.

Q: Why was Java 8 considered a major release?


A: Java 8 was revolutionary because it brought functional programming paradigms to a traditionally
object-oriented language. It enabled writing more concise, readable, and maintainable code. The Stream API
allowed declarative data processing, and lambdas eliminated verbose anonymous inner classes. It was also the
first version to allow method bodies inside interfaces via default methods.

Q: What is the difference between JDK, JRE, and JVM?


A: JVM (Java Virtual Machine): Executes bytecode; platform-dependent. JRE (Java Runtime Environment):
JVM + core libraries; needed to run Java programs. JDK (Java Development Kit): JRE + development tools
(javac, debugger, etc.); needed to develop Java programs.
Interview Tip: Interviewers often start with Java 8 features as a warm-up. Be ready to list at least 5-6 key
features with brief explanations.

Java 8 Interview Prep Guide | Page 3


2. Lambda Expressions
Q: What is a Lambda Expression in Java 8?
A: A lambda expression is a concise way to represent an anonymous function (a method without a name). It
provides a clear and compact way to implement a single abstract method interface (functional interface).
Syntax: (parameters) -> expression or (parameters) -> { statements; }
// Before Java 8
Runnable r = new Runnable() {
public void run() {
[Link]("Hello");
}
};

// With Lambda
Runnable r = () -> [Link]("Hello");

Q: What are the rules for Lambda Expressions?


A: 1) A lambda can have zero, one, or multiple parameters. 2) Parameter types can be explicitly declared or
inferred. 3) Parentheses are optional for a single parameter with inferred type. 4) Curly braces are optional if the
body has a single statement. 5) A return keyword is optional if the body is a single expression. 6) Lambdas can
only be used where a functional interface is expected.
() -> 42 // No params, returns 42
(a) -> a * 2 // Single param
a -> a * 2 // Parentheses optional
(a, b) -> a + b // Multiple params
(String s) -> [Link]() // Explicit type

Q: What is the scope of a Lambda Expression? Can it access local variables?


A: Lambdas can access: 1) Local variables that are effectively final (not modified after initialization), 2)
Instance variables (via 'this' reference of the enclosing class), 3) Static variables. They cannot modify local
variables because lambdas capture values, not variables. 'this' inside a lambda refers to the enclosing class,
NOT the lambda itself.
int num = 10; // effectively final
Runnable r = () -> [Link](num); // OK
// num = 20; // Would cause compile error

Q: What is the difference between a Lambda Expression and an Anonymous Inner Class?
A: 1) Lambdas can only implement functional interfaces (single abstract method); anonymous classes can
implement any interface or extend a class. 2) 'this' in a lambda refers to the enclosing class; in an anonymous
class, it refers to the anonymous class instance. 3) Lambdas are more concise and don't generate a separate
.class file (they use invokedynamic). 4) Anonymous classes can have state (fields); lambdas cannot.
Interview Tip: When asked about lambdas, always mention 'effectively final' - it's a very common follow-up
question.

Java 8 Interview Prep Guide | Page 4


3. Functional Interfaces
Q: What is a Functional Interface?
A: A Functional Interface is an interface that contains exactly one abstract method (SAM - Single Abstract
Method). It can have any number of default or static methods. The @FunctionalInterface annotation is optional
but recommended as it provides compile-time checking.
@FunctionalInterface
public interface MyFunction {
int apply(int a, int b); // single abstract method
default void info() { } // allowed
static void util() { } // allowed
}

Q: What are the key built-in Functional Interfaces in [Link]?


A: Predicate<T> - Takes T, returns boolean (test method). Function<T,R> - Takes T, returns R (apply
method). Consumer<T> - Takes T, returns void (accept method). Supplier<T> - Takes nothing, returns T (get
method). UnaryOperator<T> - Takes T, returns T (extends Function). BinaryOperator<T> - Takes (T,T),
returns T (extends BiFunction). BiFunction<T,U,R> - Takes (T,U), returns R. BiPredicate<T,U> - Takes (T,U),
returns boolean.

Interface Method Input Output Example Use

Predicate<T> test(T) T boolean Filtering

Function<T,R> apply(T) T R Mapping/Transform

Consumer<T> accept(T) T void forEach

Supplier<T> get() None T Factory/Lazy init

UnaryOperator<T> apply(T) T T replaceAll

BinaryOperator<T> apply(T,T) T, T T reduce

Q: What is Predicate chaining?


A: Predicates can be composed using and(), or(), and negate() methods to build complex conditions.
Predicate startsWithA = s -> [Link]("A");
Predicate endsWithZ = s -> [Link]("Z");

Predicate combined = [Link](endsWithZ);


Predicate either = [Link](endsWithZ);
Predicate notA = [Link]();

Q: What is Function composition?


A: Functions can be chained using andThen() (apply this first, then the other) and compose() (apply the other
first, then this).
Function doubleIt = x -> x * 2;
Function addTen = x -> x + 10;

[Link](addTen).apply(5); // (5*2)+10 = 20
[Link](addTen).apply(5); // (5+10)*2 = 30

Interview Tip: Memorize the four core functional interfaces (Predicate, Function, Consumer, Supplier) with their
method names - this is almost always asked.

Java 8 Interview Prep Guide | Page 5


4. Stream API
Q: What is the Stream API in Java 8?
A: The Stream API ([Link]) provides a declarative way to process collections of data. A Stream is NOT
a data structure - it's a pipeline of operations on a data source. Streams support lazy evaluation, can be
sequential or parallel, and are designed for functional-style operations like filter, map, and reduce.

Q: What is the difference between Intermediate and Terminal operations?


A: Intermediate operations return a new Stream and are lazy (not executed until a terminal operation is
invoked). Examples: filter(), map(), sorted(), distinct(), peek(), flatMap(), limit(), skip(). Terminal operations
produce a result or side-effect and close the stream. Examples: collect(), forEach(), reduce(), count(), min(),
max(), anyMatch(), allMatch(), findFirst(), toArray().

Q: Explain lazy evaluation in Streams with an example.


A: Intermediate operations are not executed until a terminal operation is called. The Stream pipeline optimizes
execution by processing elements one at a time through the entire pipeline (vertical processing), not
horizontally.
List names = [Link]("Alice","Bob","Charlie","David");

// Nothing happens here - lazy!


Stream stream = [Link]()
.filter(n -> {
[Link]("Filtering: " + n);
return [Link]() > 3;
})
.map(String::toUpperCase);

// Terminal operation triggers execution


String first = [Link]().orElse("");
// Prints: Filtering: Alice (stops after first match!)

Q: What is the difference between map() and flatMap()?


A: map() transforms each element to exactly one element (1-to-1 mapping). flatMap() transforms each element
to zero or more elements and flattens the result into a single stream (1-to-many mapping). Use flatMap when
each element maps to a collection/stream that you want to merge.
// map: List -> Stream of lengths
[Link]().map(String::length); // [5, 3, 7]

// flatMap: List> -> flat Stream


List> nested = [Link](
[Link]("a","b"), [Link]("c","d")
);
[Link]()
.flatMap(Collection::stream) // ["a","b","c","d"]
.collect([Link]());

Q: What are the different ways to create a Stream?


A: 1) [Link]() or [Link](), 2) [Link](array), 3) [Link](values...), 4)
[Link](seed, unaryOperator), 5) [Link](supplier), 6) [Link](path), 7)
[Link](start, end) / rangeClosed().

Q: What is the Collectors class? Name important collectors.

Java 8 Interview Prep Guide | Page 6


A: Collectors is a utility class providing common reduction operations used with [Link](). Key collectors:
toList(), toSet(), toMap(), joining(), counting(), groupingBy(), partitioningBy(),
summarizingInt/Long/Double(), toUnmodifiableList(), reducing(), collectingAndThen().
// groupingBy
Map> byLength = [Link]()
.collect([Link](String::length));

// partitioningBy (boolean split)


Map> evenOdd = [Link]()
.collect([Link](n -> n % 2 == 0));

// joining
String csv = [Link]()
.collect([Link](", ", "[", "]"));

// toMap
Map nameLen = [Link]()
.collect([Link](n -> n, String::length));

Q: What is the difference between reduce() and collect()?


A: reduce() combines elements into a single immutable result using an associative function (e.g., sum,
product). It's best for aggregation operations. collect() is a mutable reduction - it accumulates results into a
mutable container (List, Set, Map, StringBuilder). Use collect() for building collections and reduce() for
computing single values.
// reduce - compute sum
int sum = [Link]().reduce(0, Integer::sum);

// collect - build a list


List result = [Link]([Link]());

Q: What are parallel Streams? When should you use them?


A: Parallel streams split the data source into multiple chunks and process them concurrently using the
ForkJoinPool. Use them when: the data set is large (10,000+ elements), operations are CPU-intensive and
stateless, and the source supports efficient splitting (ArrayList, arrays). Avoid when: operations have
side-effects, the data source is small, ordering matters, or using shared mutable state.
Interview Tip: Stream API is the MOST asked topic for Java 8 interviews. Practice writing stream pipelines for
common tasks: filtering, grouping, sorting, and aggregating.

Java 8 Interview Prep Guide | Page 7


5. Optional Class
Q: What is Optional in Java 8? Why was it introduced?
A: Optional<T> is a container object that may or may not contain a non-null value. It was introduced to: 1)
Reduce NullPointerExceptions, 2) Make API contracts clearer about nullable returns, 3) Encourage defensive
programming, 4) Provide a functional approach to handling absent values.

Q: How do you create an Optional?


Optional empty = [Link](); // empty
Optional of = [Link]("Hello"); // non-null value
Optional nullable = [Link](s); // null-safe

Q: What are the important methods of Optional?


A: isPresent() - checks if value exists. ifPresent(Consumer) - executes if value present. get() - returns value
(throws NoSuchElementException if empty). orElse(T) - returns value or default. orElseGet(Supplier) - returns
value or lazily computes default. orElseThrow(Supplier) - returns value or throws custom exception.
map(Function) - transforms value if present. flatMap(Function) - transforms and flattens Optional.
filter(Predicate) - returns Optional if value matches predicate.
Optional name = [Link](getName());

// Anti-pattern: DON'T do this


if ([Link]()) { return [Link](); }

// Good: Functional approach


String result = name
.filter(n -> [Link]() > 3)
.map(String::toUpperCase)
.orElse("DEFAULT");

Q: What is the difference between orElse() and orElseGet()?


A: orElse(T) always evaluates the default value, even if Optional has a value. orElseGet(Supplier) only
evaluates the Supplier when the Optional is empty. Use orElseGet() when the default computation is expensive.
// orElse - expensiveCall() is ALWAYS invoked
[Link](expensiveCall());

// orElseGet - expensiveCall() invoked ONLY if opt is empty


[Link](() -> expensiveCall());

Interview Tip: Common interview trap: Optional should NOT be used for method parameters or class fields -
only for return types. Know this!

Java 8 Interview Prep Guide | Page 8


6. Default & Static Methods in Interfaces
Q: What are Default Methods in interfaces?
A: Default methods (declared with the 'default' keyword) allow interfaces to have method implementations. They
were introduced to enable backward-compatible evolution of interfaces (e.g., adding stream() to Collection
without breaking all implementations). Classes can override default methods.
public interface Vehicle {
void start();
default void horn() {
[Link]("Beep!");
}
}

Q: What is the Diamond Problem with Default Methods? How does Java 8 resolve it?
A: If a class implements two interfaces with the same default method, it causes ambiguity (diamond problem).
Java resolves this by: 1) The implementing class MUST override the conflicting method. 2) The class can call a
specific interface's method using [Link](). 3) Class methods always take priority over
interface default methods.
interface A { default void greet() { [Link]("A"); } }
interface B { default void greet() { [Link]("B"); } }

class C implements A, B {
@Override
public void greet() {
[Link](); // explicitly choose A's version
}
}

Q: What are Static Methods in interfaces?


A: Java 8 allows static methods in interfaces. They belong to the interface itself (not inherited by implementing
classes). They are called using the interface name: [Link](). Use them for utility methods
related to the interface.

Java 8 Interview Prep Guide | Page 9


7. Method References
Q: What are Method References in Java 8?
A: Method references are shorthand notations for calling a method via a lambda. They use the :: operator.
There are four types:

Type Syntax Equivalent Lambda

Static method ClassName::staticMethod (args) -> [Link](args)

Instance method
(specific object) instance::method (args) -> [Link](args)

Instance method
(arbitrary object) ClassName::method (obj, args) -> [Link](args)

Constructor ClassName::new (args) -> new ClassName(args)

// Static method reference


[Link]().map(Integer::parseInt);

// Instance method (arbitrary object)


[Link]().map(String::toUpperCase);

// Constructor reference
[Link]().map(ArrayList::new);

Java 8 Interview Prep Guide | Page 10


8. Date & Time API ([Link])
Q: Why was a new Date/Time API introduced in Java 8?
A: The old [Link] and Calendar classes had many issues: they were mutable (not thread-safe), had
confusing month indexing (0-based), poor API design, and no timezone support in Date. The new [Link] API
(JSR-310, inspired by Joda-Time) is immutable, thread-safe, fluent, and comprehensive.

Q: What are the key classes in [Link]?


A: LocalDate - date without time (2024-01-15). LocalTime - time without date (14:30:00). LocalDateTime -
date + time without timezone. ZonedDateTime - date + time + timezone. Instant - machine timestamp (epoch
seconds). Duration - time-based amount (hours, minutes, seconds). Period - date-based amount (years,
months, days). DateTimeFormatter - parsing and formatting.
LocalDate today = [Link]();
LocalDate birthday = [Link](1995, [Link], 15);
Period age = [Link](birthday, today);

LocalDateTime now = [Link]();


String formatted = [Link](
[Link]("dd-MM-yyyy HH:mm"));

ZonedDateTime zoned = [Link]([Link]("Asia/Kolkata"));

Q: What is the difference between Duration and Period?


A: Duration measures time in seconds and nanoseconds (time-based: hours, minutes, seconds). Used with
LocalTime, LocalDateTime, Instant. Period measures time in years, months, and days (date-based). Used with
LocalDate, LocalDateTime.
Interview Tip: Always mention immutability and thread-safety when comparing old vs new Date API. These are
the primary advantages.

Java 8 Interview Prep Guide | Page 11


9. Collections Enhancements
Q: What new methods were added to Collections in Java 8?
A: [Link](Consumer) - iterate with lambda. [Link]() and parallelStream().
[Link](Predicate) - conditional removal. [Link](UnaryOperator) - transform all
elements. [Link](Comparator) - in-place sort. [Link](BiConsumer), [Link](),
[Link](), [Link](), [Link](), [Link](), [Link](),
[Link]().

Q: Explain [Link]() with an example.


A: computeIfAbsent() computes a value for a key only if the key is not already present (or mapped to null). It is
very useful for building maps of collections (multimap pattern).
Map> map = new HashMap<>();

// Old way
if (![Link]("fruits")) {
[Link]("fruits", new ArrayList<>());
}
[Link]("fruits").add("Apple");

// Java 8 way
[Link]("fruits", k -> new ArrayList<>())
.add("Apple");

Q: How does HashMap work internally? (Java 8 improvement)


A: In Java 8, HashMap was improved with treeification. When a bucket's linked list exceeds
TREEIFY_THRESHOLD (8) entries, it converts to a balanced Red-Black Tree, improving worst-case lookup
from O(n) to O(log n). When entries reduce below UNTREEIFY_THRESHOLD (6), it converts back to a linked
list. The initial capacity is 16 with a load factor of 0.75.

Java 8 Interview Prep Guide | Page 12


10. Concurrency Enhancements
Q: What is CompletableFuture in Java 8?
A: CompletableFuture is an enhancement to the Future interface that supports non-blocking, asynchronous
programming with callback-style operations. Unlike Future, it can be manually completed, chained, combined,
and composed. It supports both synchronous and asynchronous pipelines.
CompletableFuture future = CompletableFuture
.supplyAsync(() -> fetchDataFromDB()) // async
.thenApply(data -> transform(data)) // chain
.thenApply(String::toUpperCase) // chain
.exceptionally(ex -> "Error: " + ex); // error handling

// Combine two futures


CompletableFuture combined = future1
.thenCombine(future2, (a, b) -> a + b);

Q: What is the difference between thenApply() and thenCompose()?


A: thenApply(Function) transforms the result synchronously - equivalent to map(). Returns
CompletableFuture<R>. thenCompose(Function) chains another async operation - equivalent to flatMap().
Returns CompletableFuture<R> (flattens nested futures). Use thenCompose when the transformation itself
returns a CompletableFuture.

Q: What new features were added to ConcurrentHashMap in Java 8?


A: Java 8 added several bulk operations to ConcurrentHashMap: forEach(), search(), reduce() with
parallelism threshold, mappingCount() (returns long vs int from size()), newKeySet() for creating a concurrent
Set, and atomic operations like compute(), computeIfAbsent(), merge().

Java 8 Interview Prep Guide | Page 13


11. Nashorn & Other Java 8 Features
Q: What is the Nashorn JavaScript Engine?
A: Nashorn replaced the Rhino engine and provides a high-performance JavaScript runtime on the JVM. It
allows executing JavaScript from Java using [Link] API and provides better compliance with ECMAScript
5.1. Note: Nashorn was deprecated in Java 11 and removed in Java 15.

Q: What is the StringJoiner class?


A: StringJoiner ([Link]) constructs a sequence of characters separated by a delimiter, with optional prefix and
suffix. It's used internally by [Link]() and [Link]().
StringJoiner sj = new StringJoiner(", ", "[", "]");
[Link]("Apple").add("Banana").add("Cherry");
[Link](sj); // [Apple, Banana, Cherry]

// Or simply:
[Link]("-", "2024", "01", "15"); // 2024-01-15

Q: What are the improvements to the Comparator interface in Java 8?


A: Java 8 added many static and default methods: [Link](keyExtractor), thenComparing()
for secondary sort, reversed(), [Link](), [Link](),
[Link]() / nullsLast().
// Multi-level sort
[Link](
[Link](Employee::getDepartment)
.thenComparing(Employee::getSalary, [Link]())
.thenComparing(Employee::getName)
);

Java 8 Interview Prep Guide | Page 14


12. Java Core Concepts (OOP, Collections, Strings)
Object-Oriented Programming
Q: What are the four pillars of OOP?
A: Encapsulation: Bundling data (fields) and methods together; hiding internal state via access modifiers.
Inheritance: Creating new classes from existing ones (extends keyword); promotes code reuse.
Polymorphism: One interface, many forms - compile-time (method overloading) and runtime (method
overriding). Abstraction: Hiding implementation details; achieved through abstract classes and interfaces.

Q: What is the difference between Abstract Class and Interface (Java 8)?
Feature Abstract Class Interface (Java 8+)

Methods Abstract + concrete Abstract + default + static

Variables Any type Only public static final

Constructor Yes No

Multiple Inheritance No (single extends) Yes (multiple implements)

Access Modifiers Any public (methods), public static final (fields)

State Can hold state No instance state

String Handling
Q: Why are Strings immutable in Java?
A: 1) String Pool: Multiple references can share the same instance safely. 2) Security: Used in class loading,
network connections, DB URLs - mutation could cause security issues. 3) Thread Safety: Immutable objects
are inherently thread-safe. 4) Hashing: hashCode can be cached since the value never changes (HashMap
performance). 5) Class Loading: Used as arguments for loading classes; mutation could lead to loading wrong
classes.

Q: Explain String Pool and the difference between == and equals().


A: The String Pool (in the Heap from Java 7+) stores unique string literals. When you create a string literal, Java
checks the pool first. == compares references (memory addresses). equals() compares the actual character
content.
String s1 = "Hello"; // Pool
String s2 = "Hello"; // Same pool reference
String s3 = new String("Hello"); // New heap object

s1 == s2; // true (same pool ref)


s1 == s3; // false (different objects)
[Link](s3); // true (same content)

Collections Framework
Q: What is the difference between ArrayList and LinkedList?
A: ArrayList: Backed by dynamic array. O(1) random access, O(n) insertion/deletion in the middle. Good for
read-heavy operations. Uses contiguous memory (cache-friendly). LinkedList: Doubly-linked list. O(n) random
access, O(1) insertion/deletion at known position. Better for frequent insertions/deletions. Higher memory

Java 8 Interview Prep Guide | Page 15


overhead (node objects). In practice, ArrayList is preferred in most cases due to better cache locality.

Q: What is the difference between HashMap, TreeMap, and LinkedHashMap?


A: HashMap: O(1) average lookup, no ordering. TreeMap: O(log n) lookup, sorted by natural order or
Comparator (Red-Black tree). LinkedHashMap: O(1) lookup, maintains insertion order (or access order for
LRU cache).

Q: How does ConcurrentHashMap differ from synchronized HashMap and Hashtable?


A: Hashtable: Synchronized on entire map (single lock), no null keys/values. Legacy class.
[Link](HashMap): Wraps HashMap with synchronized methods (single lock).
ConcurrentHashMap: Uses bucket-level (segment) locking in Java 7 and CAS operations + synchronized
blocks on individual nodes in Java 8. Much better concurrent performance. Does not allow null keys/values.

Java 8 Interview Prep Guide | Page 16


13. Exception Handling & Multithreading
Exception Handling
Q: What is the difference between Checked and Unchecked Exceptions?
A: Checked Exceptions: Verified at compile time. Must be caught or declared with 'throws'. Extend Exception
(not RuntimeException). Example: IOException, SQLException. Unchecked Exceptions: Not checked at
compile time. Extend RuntimeException. Example: NullPointerException, ArrayIndexOutOfBoundsException.
Error: Serious problems not meant to be caught. Example: OutOfMemoryError, StackOverflowError.

Q: Explain try-with-resources. How does it work?


A: Introduced in Java 7, try-with-resources automatically closes resources that implement AutoCloseable.
Resources declared in the try() block are closed in reverse order of declaration after the try block finishes (even
if an exception occurs). Eliminates the need for finally blocks for resource cleanup.
try (BufferedReader br = new BufferedReader(
new FileReader("[Link]"));
PrintWriter pw = new PrintWriter("[Link]")) {
String line = [Link]();
[Link](line);
} // Both br and pw auto-closed here

Multithreading
Q: What are the different ways to create a thread in Java?
A: 1) Extend Thread class and override run(). 2) Implement Runnable interface and pass to Thread
constructor. 3) Implement Callable<V> and use with ExecutorService (returns a result). 4) Use Lambda with
Runnable (Java 8). 5) Use ExecutorService thread pool.

Q: What is the difference between synchronized and ReentrantLock?


A: synchronized: Built-in keyword, implicit locking/unlocking, non-interruptible, no timeout, non-fair.
ReentrantLock: Explicit lock/unlock, supports tryLock() with timeout, interruptible, supports fairness policy,
provides Condition objects for fine-grained wait/notify, can check if lock is held. Must be unlocked in finally
block.

Q: What is the difference between wait/notify and sleep?


A: wait() releases the lock, must be called inside synchronized block, woken by notify/notifyAll. It is defined in
Object class. sleep() does NOT release the lock, can be called anywhere, woken by timeout or interrupt. It is
defined in Thread class.

Q: What is a volatile variable?


A: The volatile keyword ensures that a variable's value is always read from and written to main memory (not
CPU cache). It guarantees visibility across threads but does NOT guarantee atomicity. Use for simple flags. For
compound operations (like i++), use AtomicInteger or synchronized.

Java 8 Interview Prep Guide | Page 17


14. Design Patterns & Best Practices
Q: Implement Singleton pattern (thread-safe, lazy).
// Bill Pugh Singleton (recommended)
public class Singleton {
private Singleton() { }
private static class Holder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return [Link];
}
}

// Enum Singleton (best - prevents reflection & serialization attacks)


public enum Singleton {
INSTANCE;
public void doSomething() { }
}

Q: What is the Builder Pattern? When do you use it?


A: Builder pattern separates the construction of a complex object from its representation. Use when: a class has
many optional parameters, you want immutable objects, or the constructor would have too many parameters
(telescoping constructor anti-pattern).
public class Person {
private final String name;
private final int age;
private final String email; // optional

private Person(Builder b) {
[Link] = [Link];
[Link] = [Link];
[Link] = [Link];
}
public static class Builder {
private final String name;
private final int age;
private String email = "";

public Builder(String name, int age) {


[Link] = name; [Link] = age;
}
public Builder email(String e) {
[Link] = e; return this;
}
public Person build() { return new Person(this); }
}
}

Q: What are SOLID principles?


A: S - Single Responsibility: A class should have only one reason to change. O - Open/Closed: Open for
extension, closed for modification. L - Liskov Substitution: Subtypes must be substitutable for their base
types. I - Interface Segregation: Prefer small, specific interfaces over large, general ones. D - Dependency
Inversion: Depend on abstractions, not concrete implementations.

Q: What is the Strategy Pattern? How does Java 8 simplify it?

Java 8 Interview Prep Guide | Page 18


A: Strategy pattern defines a family of algorithms and makes them interchangeable. In Java 8, functional
interfaces and lambdas eliminate the need for separate strategy classes.
// Before Java 8: separate classes for each strategy
// After Java 8: lambdas as strategies
List names = [Link]("Charlie","Alice","Bob");

// Strategy = Comparator (functional interface)


[Link]([Link]()); // strategy 1
[Link]([Link]()); // strategy 2
[Link]([Link](String::length)); // strategy 3

Java 8 Interview Prep Guide | Page 19


15. Coding Challenges & Output-Based Questions
Stream API Coding Questions
Q: Find the second highest number in a list using Streams.
List nums = [Link](5, 3, 9, 1, 9, 7, 3);

Optional secondHighest = [Link]()


.distinct()
.sorted([Link]())
.skip(1)
.findFirst();

[Link]([Link](-1)); // 7

Q: Group employees by department and find the highest salary in each.


Map> result = [Link]()
.collect([Link](
Employee::getDepartment,
[Link](
[Link](Employee::getSalary)
)
));

Q: Count the frequency of each character in a string.


String str = "programming";

Map freq = [Link]()


.mapToObj(c -> (char) c)
.collect([Link](
[Link](),
[Link]()
));
// {p=1, r=2, o=1, g=2, a=1, m=2, i=1, n=1}

Q: Find all duplicate elements in a list using Streams.


List nums = [Link](1, 2, 3, 2, 4, 1, 5);

Set duplicates = [Link]()


.filter(n -> [Link](nums, n) > 1)
.collect([Link]());
// [1, 2]

// More efficient approach:


Set seen = new HashSet<>();
Set dups = [Link]()
.filter(n -> ![Link](n))
.collect([Link]());

Q: Flatten a list of lists and find distinct elements, sorted.


List> nested = [Link](
[Link](1,2,3), [Link](3,4,5), [Link](5,6,7)
);

List result = [Link]()


.flatMap(Collection::stream)
.distinct()

Java 8 Interview Prep Guide | Page 20


.sorted()
.collect([Link]());
// [1, 2, 3, 4, 5, 6, 7]

Output-Based Questions
Q: What is the output?
String s1 = "Java";
String s2 = "Java";
String s3 = new String("Java");
[Link](s1 == s2); // true
[Link](s1 == s3); // false
[Link]([Link](s3)); // true
[Link]([Link]() == s1); // true

Q: What is the output?


List list = [Link](1, 2, 3, 4, 5);
[Link]()
.filter(n -> {
[Link]("filter: " + n);
return n % 2 == 0;
})
.map(n -> {
[Link]("map: " + n);
return n * 10;
})
.findFirst();

// Output:
// filter: 1
// filter: 2
// map: 2
// (short-circuits after finding first match)

Q: What is the output? (HashMap ordering)


Map map = new HashMap<>();
[Link]("A", 1);
[Link]("B", 2);
[Link]("A", 3); // overwrites
[Link]([Link]()); // 2
[Link]([Link]("A")); // 3

Q: What happens here?


Optional opt = [Link](null);
// Throws NullPointerException immediately!
// Use [Link](null) for potentially null values.

Java 8 Interview Prep Guide | Page 21


16. Quick Revision Cheat Sheet
Lambda Syntax Quick Reference
() -> expression // No parameters
x -> expression // Single parameter
(x, y) -> expression // Multiple parameters
(x, y) -> { statements; } // Multiple statements
(int x) -> x * 2 // Explicit types

Stream Operations Cheat Sheet


Operation Type Returns Example

filter() Intermediate Stream<T> [Link](x -> x > 5)

map() Intermediate Stream<R> [Link](String::length)

flatMap() Intermediate Stream<R> [Link](Collection::stream)

distinct() Intermediate Stream<T> [Link]()

sorted() Intermediate Stream<T> [Link]([Link]())

limit(n) Intermediate Stream<T> [Link](10)

skip(n) Intermediate Stream<T> [Link](5)

peek() Intermediate Stream<T> [Link]([Link]::println)

collect() Terminal R [Link]([Link]())

forEach() Terminal void [Link]([Link]::println)

reduce() Terminal Optional/T [Link](0, Integer::sum)

count() Terminal long [Link]()

anyMatch() Terminal boolean [Link](x -> x > 5)

findFirst() Terminal Optional<T> [Link]()

Key Collectors
[Link]() // List
[Link]() // Set
[Link](keyFn, valueFn) // Map
[Link](", ") // String concatenation
[Link](classifier) // Map>
[Link](predicate) // Map>
[Link]() // Long count
[Link](mapper) // IntSummaryStatistics

Top Interview Tips


1. Always explain WHY a feature was introduced, not just WHAT it does.
2. Practice writing Stream pipelines on paper/whiteboard - no IDE autocomplete in interviews!
3. Know the difference: map vs flatMap, orElse vs orElseGet, thenApply vs thenCompose.
4. Be ready to discuss internal workings: HashMap (treeification), String pool, JVM memory.
5. For 2+ year experience: expect design pattern questions and coding exercises.

Java 8 Interview Prep Guide | Page 22


6. When asked 'What Java 8 features do you use daily?' - mention Streams, lambdas, Optional, and the new
Date API.
7. Common coding tasks: grouping, sorting, finding duplicates, frequency counting with Streams.
8. Know when NOT to use: parallel streams (small data), Optional (as method parameters).
9. Practice explaining your code as you write it - communication matters as much as the solution.
10. Review equals/hashCode contract, immutability patterns, and exception handling best practices.

Best of luck with your interview!


Remember: Understanding concepts deeply > Memorizing answers

Java 8 Interview Prep Guide | Page 23

You might also like