Here are the top 25 interview questions for Java and related technologies, tailored for senior Java engineers. Each question is accompanied by a thorough answer and relevant examples where applicable.
1. What are the new features introduced in Java 8?
Answer:
Java 8 introduced several significant features:
- Lambda Expressions: Enable you to treat functionality as a method argument, or pass a block of code around.
List<String> names = Arrays.asList("John", "Jane", "Adam", "Eve");
names.forEach(name -> System.out.println(name));
- Stream API: Provides a way to process sequences of elements.
List<String> names = Arrays.asList("John", "Jane", "Adam", "Eve");
long count = names.stream().filter(name -> name.startsWith("A")).count();
System.out.println(count); // Outputs 1
- Default Methods: Allow the addition of new methods to interfaces without breaking existing implementations.
interface MyInterface {
default void newMethod() {
System.out.println("New default method");
}
}
- Optional Class: Helps to avoid null checks and NullPointerException.
Optional<String> optional = Optional.ofNullable(null);
System.out.println(optional.isPresent()); // Outputs false
2. Explain the differences between HashMap
and ConcurrentHashMap
in Java.
Answer:
- HashMap: Not thread-safe. Multiple threads can access and modify the HashMap concurrently, which can cause inconsistent state.
Map<String, String> map = new HashMap<>();
map.put("key1", "value1");
- ConcurrentHashMap: Thread-safe. Designed for concurrent access without locking the entire map.
Map<String, String> map = new ConcurrentHashMap<>();
map.put("key1", "value1");
3. What are the different types of memory areas allocated by JVM?
Answer:
- Heap: Stores objects. Managed by the Garbage Collector.
- Stack: Stores method call frames and local variables.
- Metaspace: Stores class metadata. Introduced in Java 8, replacing PermGen.
- PC Registers: Store the address of the current instruction.
- Native Method Stack: For native method calls.
4. Explain the concept of Garbage Collection in Java.
Answer:
Garbage Collection (GC) is the process of automatically freeing memory by deleting objects that are no longer reachable in the program.
- Serial GC: Single-threaded.
- Parallel GC: Multi-threaded.
- CMS (Concurrent Mark-Sweep) GC: Tries to minimize pause times.
- G1 (Garbage First) GC: Designed for applications with large heaps.
5. What are Java annotations, and how are they used?
Answer:
Annotations provide metadata about the code and can be applied to classes, methods, variables, etc.
- @Override: Indicates that a method is overriding a superclass method.
@Override
public void myMethod() {
// Implementation
}
- @Deprecated: Marks a method or class as deprecated.
@Deprecated
public void oldMethod() {
// Old implementation
}
6. Explain the use of the volatile
keyword in Java.
Answer:
The volatile
keyword ensures visibility of changes to variables across threads.
private volatile boolean running = true;
When a variable is declared volatile, reads and writes to that variable are directly from and to the main memory.
7. What is the difference between Comparable
and Comparator
?
Answer:
- Comparable: Used to define the natural ordering of objects. It is implemented by the class whose instances are to be ordered.
public class Person implements Comparable<Person> {
private String name;
public int compareTo(Person p) {
return this.name.compareTo(p.name);
}
}
- Comparator: Used to define an external ordering of objects. It can be implemented in a separate class.
public class NameComparator implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
8. What is the use of the transient
keyword?
Answer:
The transient
keyword in Java is used to indicate that a field should not be serialized.
public class MyClass implements Serializable {
private transient int myTransientField;
}
9. Explain the difference between ==
and equals()
in Java.
Answer:
==
checks for reference equality.equals()
checks for value equality.
String a = new String("test");
String b = new String("test");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
10. What is a Java ClassLoader?
Answer:
A ClassLoader in Java is responsible for dynamically loading Java classes into the JVM.
- Bootstrap ClassLoader: Loads core Java libraries.
- Extension ClassLoader: Loads classes from the extension directories.
- System/Application ClassLoader: Loads classes from the application classpath.
11. Explain the purpose of the final
keyword in Java.
Answer:
- Final Variable: Its value cannot be changed once assigned.
final int MAX = 100;
- Final Method: Cannot be overridden by subclasses.
public final void myMethod() {
// Implementation
}
- Final Class: Cannot be subclassed.
public final class MyClass {
// Implementation
}
12. Describe the Java Memory Model (JMM).
Answer:
The JMM defines how threads interact through memory and what behaviors are legal in concurrent execution.
- Happens-Before Relationship: Guarantees that memory writes by one specific statement are visible to another specific statement.
- Volatile Variables: Provide visibility guarantees.
- Atomicity: Operations like read and write on volatile variables are atomic.
13. What is the purpose of the synchronized
keyword?
Answer:
The synchronized
keyword is used to control access to a block of code or method by multiple threads, ensuring that only one thread can execute the block at a time.
- Synchronized Method:
public synchronized void syncMethod() {
// synchronized code
}
- Synchronized Block:
public void syncBlock() {
synchronized(this) {
// synchronized code
}
}
14. Explain the concept of immutability in Java.
Answer:
An immutable object is one whose state cannot be changed after it is created. The String class in Java is an example of an immutable class.
- To create an immutable class:
- Declare the class as
final
. - Make all fields
private
andfinal
. - Provide only getter methods.
- No setter methods.
15. What are design patterns? Give examples of a few commonly used design patterns in Java.
Answer:
Design patterns are typical solutions to common problems in software design. Examples include:
- Singleton Pattern: Ensures a class has only one instance.
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
- Factory Pattern: Defines an interface for creating an object, but lets subclasses alter the type of objects that will be created.
public class ShapeFactory {
public Shape getShape(String shapeType) {
if(shapeType == null){
return null;
}
if(shapeType.equalsIgnoreCase("CIRCLE")){
return new Circle();
} else if(shapeType.equalsIgnoreCase("RECTANGLE")){
return new Rectangle();
}
return null;
}
}
16. What is dependency injection and how is it implemented in Spring?
Answer:
Dependency injection (DI) is a design pattern used to implement IoC (Inversion of Control), allowing the creation of dependent objects outside of a class and providing those objects to a class in different ways.
- Constructor Injection:
@Service
public class MyService {
private final MyRepository repository;
@Autowired
public MyService(MyRepository repository) {
this.repository = repository;
}
}
- Setter Injection:
@Service
public class MyService {
private MyRepository repository;
@Autowired
public void setRepository(MyRepository repository) {
this.repository = repository;
}
}
17. Explain the difference between ArrayList
and LinkedList
.
Answer:
- ArrayList: Uses a dynamic array to store elements. Provides fast random access but slow insertion/deletion (except at the end).
List<String> arrayList = new ArrayList<>();
- LinkedList: Uses a doubly linked list to store elements. Provides fast insertion/deletion but slow random access.
List<String> linkedList
= new LinkedList<>();
18. What is the purpose of the try-with-resources
statement in Java?
Answer:
The try-with-resources
statement ensures that each resource is closed at the end of the statement.
try (BufferedReader br = new BufferedReader(new FileReader("path/to/file.txt"))) {
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
19. Explain the concept of method overloading and method overriding.
Answer:
- Method Overloading: Same method name but different parameters within the same class.
public void display(int a) {}
public void display(String a) {}
- Method Overriding: Subclass provides a specific implementation of a method already defined in its superclass.
@Override
public void display() {
// Implementation
}
20. What is a thread pool and how is it implemented in Java?
Answer:
A thread pool manages a pool of worker threads, reducing the overhead of creating and destroying threads.
ExecutorService executor = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executor.submit(() -> {
// Task implementation
});
}
executor.shutdown();
21. What are microservices and how does Spring Boot support them?
Answer:
Microservices are a style of software architecture that involves breaking down a large application into smaller, independent services.
- Spring Boot: Provides embedded servers, which allow microservices to run independently.
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
22. Explain the concept of RESTful web services and how they are implemented in Spring.
Answer:
RESTful web services follow the REST architecture, which uses standard HTTP methods and is stateless.
- Spring MVC:
@RestController
@RequestMapping("/api")
public class MyController {
@GetMapping("/greet")
public String greet() {
return "Hello, World!";
}
}
23. What is the difference between StringBuilder
and StringBuffer
?
Answer:
- StringBuilder: Not thread-safe but faster, used for single-threaded environments.
StringBuilder sb = new StringBuilder();
sb.append("Hello");
- StringBuffer: Thread-safe, used for multi-threaded environments.
StringBuffer sb = new StringBuffer();
sb.append("Hello");
24. What is the purpose of the ScheduledExecutorService
?
Answer:
The ScheduledExecutorService
is used to schedule tasks to run after a delay or to execute periodically.
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(() -> {
// Task implementation
}, 0, 1, TimeUnit.SECONDS);
25. Explain the different types of class loaders in Java.
Answer:
- Bootstrap ClassLoader: Loads the core Java libraries.
- Extension ClassLoader: Loads classes from the extension directories.
- System/Application ClassLoader: Loads classes from the application classpath.
These questions cover a wide range of topics essential for a senior Java engineer, providing a comprehensive overview of both fundamental and advanced concepts in Java and its related technologies.