Java Interview Questions 2024

JAVA INTERVIEW QUESTIONS

10/25/20222 min read

  • What are the main features introduced in Java 17 (or the latest version in 2024)?
    The latest released Java version is 22 but latest LTS version is 21, however in 2024 the widely used version across software industry is Java 17.

  •  What is LTS version ?
    In the context of Java, LTS stands for Long-Term Support. An LTS release of Java is one that receives updates, including bug fixes, security patches, and performance improvements, for an extended period of time. This extended support period typically lasts for several years, providing stability and reliability for applications that require long-term maintenance.

Developers often prefer LTS releases for critical or enterprise applications because they offer a predictable support timeline, allowing organizations to plan their software maintenance and upgrades more effectively. It's worth noting that not all Java releases are LTS; some are considered feature releases and receive support for a shorter period.

For enterprises and businesses with applications that require long-term stability and support, choosing an LTS release of Java ensures they can receive updates and security fixes for an extended period, often several years, without needing to upgrade to a newer version frequently.

  • Java 17 features in detail

1. Sealed Classes (Preview Feature):

Sealed classes and interfaces restrict which classes can extend or implement them. They enhance code maintainability and reliability by controlling class inheritance more tightly.

Example:

public sealed interface Shape permits Circle, Rectangle {

double area();

}

public final class Circle implements Shape {

private final double radius;

public Circle(double radius) {

this.radius = radius;

}

@Override

public double area() {

return Math.PI radius radius;

}

}

public final class Rectangle implements Shape {

private final double length;

private final double width;

public Rectangle(double length, double width) {

this.length = length;

this.width = width;

}

@Override

public double area() {

return length * width;

}

}

2.Pattern Matching for Switch (Standard Feature):

Pattern matching for switch statements simplifies code by allowing pattern matching directly within switch statements.

Example:

Object obj = "Hello";

String result = switch (obj) {

case String s -> s.toUpperCase(); // Pattern matching

case Integer i && i > 0 -> "Positive integer"; // Pattern matching with condition

default -> "Unknown";

};

System.out.println(result); // Output: HELLO

3.Hidden Classes (Standard Feature):

Hidden classes are generated at runtime by the JVM and are intended for use by frameworks and libraries that need to generate classes dynamically.

Example:

import java.lang.invoke.MethodHandles;

import java.lang.invoke.MethodType;

public class HiddenClassesExample {

public static void main(String[] args) throws Throwable {

MethodHandles.Lookup lookup = MethodHandles.lookup();

Class<?> hiddenClass = lookup.defineHiddenClass(

new byte[]{}, true, MethodHandles.Lookup.ClassOption.NESTMATE);

System.out.println(hiddenClass.getName());

}

}

4.Deprecation of Applet API:

The Applet API, deprecated since Java 9, is officially marked for removal in Java 17. Applets are no longer supported in modern web browsers due to security concerns and the evolution of web technologies.

Example: Applets were typically embedded in HTML pages, but due to deprecation and removal, it's not advisable to provide an example for this feature.

5.JEP 382: New macOS Rendering Pipeline: macOS users benefit from a new rendering pipeline implementation, leveraging the Apple Metal framework for improved graphics performance and reduced resource consumption.

6.JEP 391: macOS/AArch64 Port: Java 17 includes experimental support for running on macOS systems using the ARM64 architecture (Apple Silicon), providing compatibility with the latest hardware from Apple.

7.Deprecation of RMI Activation: The RMI (Remote Method Invocation) Activation mechanism, which has been deprecated since Java 9, is now marked for removal. This feature was seldom used and is no longer considered essential for modern Java applications.

These are the main features introduced in Java 17. Each feature brings enhancements to the language, library, or runtime environment, improving developer productivity, code readability, performance, and security.

What are the major features introduced in Java 8?

  • Lambda Expressions

  • Stream API

  • Default Methods in Interfaces

  • Optional Class

  • Date and Time API (java.time package)

  • Nashorn JavaScript Engine

    Please Click here Java 8 to understand Java 8 features in details .

  • Explain Composition and Aggregation in details

    Composition and aggregation are both forms of association between classes in object-oriented programming, but they represent different kinds of relationships. Here's the difference:

1. Composition:

- Composition is a strong form of association where one class (the whole) is composed of one or more objects of another class (the parts).

- The lifetime of the composed objects is tightly coupled with the lifetime of the composite object. In other words, when the composite object is destroyed, all its composed objects are also destroyed.

- Composition implies ownership. The composed objects typically do not exist independently of the composite object and cannot be shared among multiple composite objects.

- In UML diagrams, composition is represented by a filled diamond shape on the side of the composite class.

Example: A car consists of an engine, wheels, and other components. If the car is destroyed, its engine and wheels are also destroyed.

2. Aggregation:

- Aggregation is a weaker form of association where one class (the whole) has a relationship with another class (the parts), but the parts can exist independently of the whole.

- The lifetime of the aggregated objects is not dependent on the lifetime of the aggregate object. Aggregated objects can exist before and after the aggregate object exists.

- Aggregation does not imply ownership. The aggregated objects may be shared among multiple aggregate objects or may exist independently of any aggregate object.

- In UML diagrams, aggregation is represented by an unfilled diamond shape on the side of the aggregate class.

Example: A university has departments. Departments can exist independently of the university and can be associated with multiple universities.

In summary, the main difference between composition and aggregation lies in the strength of the relationship and the lifetime dependency between the whole and its parts. Composition implies a strong ownership relationship with tight coupling, while aggregation represents a weaker relationship with looser coupling and independent lifetimes.

  • Explain String implementation and behavior in Java and what is difference between creation of String using Literals and 'new' keyword

Creating a String using the `new` keyword and creating a String using a literal have some important differences:

1. Memory Allocation:

- When you create a String using the `new` keyword, a new object is always created in the heap memory, even if a String with the same value already exists in the String pool. This means that memory is allocated for each `new` String object.

- When you create a String using a literal (e.g., `"hello"`), the JVM first checks the String pool. If a String with the same value already exists in the pool, a reference to that existing String object is returned. If not, a new String object is created in the pool. Therefore, String literals may reuse existing objects in the String pool, leading to potential memory savings.

2. String Pool:

- String literals are maintained in a special memory area called the "String pool" or "String constant pool." This pool is a part of the heap memory, and it stores unique String objects.

- When you create a String using the `new` keyword, it is not added to the String pool unless explicitly interned using the `intern()` method. Therefore, `new` Strings do not participate in String interning by default.

3. Immutability:

- Whether created using `new` or a literal, Strings are immutable in Java, meaning their values cannot be changed after creation. Any operation that appears to modify a String actually creates a new String object.

- However, String literals are inherently immutable, while `new` Strings may or may not be, depending on whether they are subsequently modified.

4. Performance:

- Due to the potential reuse of existing String objects in the String pool, using String literals can be more efficient in terms of memory usage and performance, especially when compared to creating multiple `new` String objects with the same value.

- Using `new` to create Strings may result in unnecessary memory consumption and slower performance if multiple identical String objects are created without interning.

In summary, creating a String using the `new` keyword always results in a new object in the heap memory, while creating a String using a literal may reuse existing objects from the String pool. The choice between `new` and literals should consider memory usage, performance, and whether you want the String to participate in String interning.

How HashMap works internally after Java 8 ?

In Java 8, the internal implementation of HashMap has undergone some improvements compared to earlier versions. Here’s a detailed look at how HashMap works internally in Java 8:

  1. Array of Nodes (Bucket Array):

    • HashMap internally maintains an array of Node objects, called the bucket array or table.

    • Each Node in this array represents a key-value pair stored in the HashMap.

  2. Hashing Function:

    • When you insert a key-value pair into a HashMap using put(key, value), Java computes the hash code of the key.

    • The hash code is then transformed to ensure better distribution using a technique called hash spreading, which helps reduce hash collisions.

  3. Index Calculation:

    • After computing the hash code and applying hash spreading, the index of the bucket array is determined using the formula index = (n - 1) & hash, where n is the current capacity of the HashMap.

  4. Handling Collisions:

    • If two keys hash to the same index (collision), HashMap uses a linked list to store multiple entries at the same bucket location.

    • Starting with Java 8, if a bucket contains more than a certain threshold of entries (currently 8), the linked list at that bucket is transformed into a balanced tree structure to improve worst-case performance from O(n) to O(log n) for operations like get and put.

  5. Load Factor and Rehashing:

    • HashMap has a load factor (loadFactor) that determines when to increase the capacity of the bucket array.

    • The default load factor is 0.75, which means when the ratio of the number of entries to the number of buckets exceeds 0.75, the capacity of the HashMap is automatically increased (rehashed).

  6. Iterating Over Entries:

    • When you iterate over a HashMap using an iterator (Iterator or enhanced for-loop), it traverses each bucket in the bucket array.

    • For each bucket, it iterates over either the linked list or the tree structure (depending on the number of entries) to return each key-value pair.

  7. Performance Characteristics:

    • HashMap in Java 8 generally provides O(1) time complexity for get and put operations under normal circumstances.

    • The worst-case time complexity is O(log n) due to the balanced tree structure introduced for buckets with many collisions.

Overall, HashMap in Java 8 is optimized for performance by using a combination of hashing, bucketing, and in certain cases, balanced trees to handle collisions efficiently. Understanding these internal workings helps in utilizing HashMap effectively and making informed decisions about its usage in Java applications.

Explain Java Collection Framework in Detail :
Click Here to check Java Collection Framework .

Related Stories