Top

Java Programming

31.

What is a Singleton class?

Ans:

The Singleton pattern is a creational design pattern that ensures a class has only one instance and provides a global point of access to it.

To implement the Singleton pattern, we need to:

  1. Make the constructor private to prevent direct instantiation of the class from outside.
  2. Create a private static instance of the class within the class itself.
  3. Provide a public static method (commonly named `getInstance()`) that returns the single instance of the class. This method creates the instance if it doesn't exist (lazy initialization) or simply returns the existing instance.

Example (Eager Initialization):

public class MySingleton {
    // Eagerly create the single instance
    private static final MySingleton instance = new MySingleton();

    // Make the constructor private
    private MySingleton() {}

    // Provide a global point of access
    public static MySingleton getInstance() {
        return instance;
    }
}

To make a Singleton thread-safe during lazy initialization, the `getInstance()` method needs to be synchronized or a technique like double-checked locking must be used.

32.

What are marker interfaces?

Ans:

A marker interface is an interface with no fields or methods. It is an empty interface.

Its purpose is to 'mark' a class as having a certain capability or property. The JVM or other frameworks can then check if a class implements this interface (using the `instanceof` operator) and perform special processing for it.

Classic examples from the JDK include:

  • java.io.Serializable: This interface marks a class as being serializable. The JVM's serialization mechanism checks for this interface before attempting to serialize an object.
  • java.lang.Cloneable: This interface indicates that the `Object.clone()` method can make a legal field-for-field copy of instances of that class. If a class doesn't implement `Cloneable`, calling `clone()` on it will throw a `CloneNotSupportedException`.
  • java.rmi.Remote: This interface marks an object as being accessible remotely.

33.

What is the difference between pass-by-value and pass-by-reference?

Ans:

This is a tricky question. The official answer is that Java is always strictly pass-by-value.

  • Pass-by-value: When a method is called, a copy of the argument's value is passed to the method. Changes made to the parameter inside the method do not affect the original argument.
  • Pass-by-reference: A reference to the actual argument (its memory address) is passed to the method. Changes made to the parameter inside the method will affect the original argument.

The confusion in Java arises when passing objects. When you pass an object to a method, you are passing a copy of the reference value, not a copy of the object itself. This reference value points to the same object in memory.

// Demo
class Dog {
    String name;
    Dog(String name) { this.name = name; }
}

// Main method
Dog myDog = new Dog("Max"); // myDog holds a reference value, say 'xyz123'
changeName(myDog);
System.out.println(myDog.name); // Prints "Fido"

void changeName(Dog dog) {
    // 'dog' receives a copy of the reference value 'xyz123'
    dog.name = "Fido"; // Modifies the 'name' field of the original object

    dog = new Dog("Buddy"); // 'dog' now points to a NEW object. This does NOT affect 'myDog'.
}

Because the method can change the *state* of the original object, it looks like pass-by-reference. However, because you cannot change the original reference itself (as shown by `dog = new Dog("Buddy")`), Java is technically pass-by-value.

34.

What is constructor chaining?

Ans:

Constructor chaining is the process of calling one constructor from another constructor within the same class or from a subclass.

1. Chaining within the same class (using `this()`):

The `this()` keyword is used to call another overloaded constructor in the same class. The `this()` call must be the very first statement in the constructor.

public class Employee {
    private String name;
    private int id;

    // Default constructor
    public Employee() {
        // Calls the parameterized constructor
        this("Default Name", 0);
    }

    // Parameterized constructor
    public Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }
}

2. Chaining to a superclass (using `super()`):

The `super()` keyword is used to call a constructor from the parent class. The `super()` call must also be the very first statement in the subclass's constructor. If you don't explicitly call `super()`, the compiler will automatically insert a call to the no-argument constructor of the superclass.

class Person {
    Person() {
        System.out.println("Person constructor called");
    }
}

class Student extends Person {
    Student() {
        super(); // Calls the Person constructor
        System.out.println("Student constructor called");
    }
}

35.

What is the difference between `Hashtable` and `HashMap`?

Ans:

Though both store data in key-value pairs, `Hashtable` is a legacy class that has been retrofitted into the Collections Framework, while `HashMap` is the standard choice.

FeatureHashtableHashMap
Thread SafetySynchronized. It is thread-safe. All its methods are synchronized.Not synchronized. It is not thread-safe. For a thread-safe alternative, you should use `ConcurrentHashMap` or `Collections.synchronizedMap()`.
PerformanceSlower due to the synchronization overhead on every operation.Faster because it is not synchronized.
Null ValuesDoes not allow null keys or null values. Will throw a `NullPointerException`.Allows one null key and multiple null values.
InheritanceIt inherits from the `Dictionary` class (an obsolete class).It inherits from the `AbstractMap` class.
IteratorUses `Enumerator` to iterate over values, which is considered legacy. It also supports `Iterator`.Uses `Iterator`, which is the modern standard and supports the `remove()` method.

Conclusion: You should almost always use `HashMap` in single-threaded applications and `ConcurrentHashMap` in multi-threaded applications. `Hashtable` should be avoided in new code.

36.

Explain the internal working of `ConcurrentHashMap`.

Ans:

ConcurrentHashMap is the preferred choice for thread-safe map operations in Java. It provides much better performance than a synchronized `HashMap` or a `Hashtable` by using a more granular locking mechanism.

  • Before Java 8 (Using Segments): The map was internally divided into a number of 'segments' (defaulting to 16). Each segment was essentially an independent `Hashtable`. When a thread needed to perform a write operation, it would only lock the specific segment the key belonged to, not the entire map. This allowed multiple threads to write to different segments concurrently, greatly improving performance.
  • Since Java 8 (Using Node-level Locking): The concept of segments was removed. Instead, `ConcurrentHashMap` uses a fine-grained locking mechanism on the first node of each bucket (hash index). When a thread wants to write to a bucket, it locks only that bucket's head node. If two different threads try to write to two different buckets, they can do so concurrently without any blocking. This provides even better concurrency than the segment-based approach. Size-related operations like `size()` are handled using atomic variables to avoid locking the whole map.

In short, `ConcurrentHashMap` avoids locking the entire map for write operations, which is why it offers high concurrency and scalability.

37.

What is the `CopyOnWriteArrayList`?

Ans:

CopyOnWriteArrayList is a thread-safe variant of `ArrayList` in which all mutative operations (like `add`, `set`, etc.) are implemented by creating a fresh copy of the underlying array.

How it works:

  • Read Operations: Read operations (like `get`, `iterator`) are very fast and do not require any locking. They operate on a snapshot of the array at a given point in time.
  • Write Operations: When a write operation is performed, the entire underlying array is copied, the modification is made to the new copy, and then the internal reference is switched to point to this new array. This is an expensive operation.

Key Properties:

  • Thread-Safe: It is inherently thread-safe due to its copy-on-write nature.
  • Iterator: Its iterator is fail-safe and will never throw a `ConcurrentModificationException`. The iterator works on a snapshot of the array from when the iterator was created.

When to use it: It is best suited for applications where reads are far more frequent than writes. For example, a list of listeners in an event-based system where listeners are rarely added or removed but are frequently iterated over to dispatch events.

38.

What are static and instance initializer blocks?

Ans:

Initializer blocks are used to initialize instance or static variables.

Instance Initializer Block:

  • This is a block of code inside a class, but outside any method or constructor.
  • It is executed every time an instance of the class is created.
  • The instance initializer block is invoked *after* the parent class constructor is called (via `super()`) but *before* the class's own constructor body is executed.
  • They are useful if you want to share some code between multiple constructors.
class MyClass {
    {
        // This is an instance initializer block
        System.out.println("Instance initializer block executed.");
    }

    MyClass() {
        System.out.println("Constructor executed.");
    }
}
// new MyClass() will print "Instance initializer block executed." then "Constructor executed."

Static Initializer Block:

  • This is a block of code prefixed with the static keyword.
  • It is executed only once, when the class is first loaded into memory by the JVM.
  • It is used to initialize static variables of the class.
class MyStaticClass {
    static {
        // This is a static initializer block
        System.out.println("Static initializer block executed.");
    }
}
// The message will be printed only the first time MyStaticClass is referenced.

39.

What is object cloning and what are its types?

Ans:

Object cloning is the process of creating an exact copy of an object. The clone() method of the `Object` class is used for this. A class must implement the `Cloneable` marker interface to indicate that its objects can be legally cloned.

There are two types of cloning:

1. Shallow Copy (Shallow Clone):

  • This is the default implementation of the `clone()` method.
  • It creates a new object and then copies the values of all fields from the original object to the new object.
  • If a field is a primitive type, its value is copied.
  • If a field is a reference to another object, only the reference value is copied, not the object itself. This means both the original object and the cloned object will point to the same referenced object.
  • A change in the referenced object will be reflected in both the original and the clone.

2. Deep Copy (Deep Clone):

  • A deep copy creates a new object and then recursively copies all objects referenced by the original object.
  • This means that the original object and the cloned object are completely independent of each other. A change in any referenced object within the clone will not affect the original object.
  • To achieve a deep copy, you must override the `clone()` method and manually handle the cloning of any mutable referenced objects.

40.

What is serialization and the `transient` keyword?

Ans:

Serialization is the process of converting a Java object's state into a byte stream. This byte stream can then be stored in a file, kept in memory, or transmitted across a network.

Deserialization is the reverse process: reconstructing the object from the byte stream.

To make a class serializable, it must implement the `java.io.Serializable` marker interface.

The transient keyword is a variable modifier used in serialization. If you define any data member as `transient`, it will not be serialized. When the object is deserialized, the value of the transient field will be its default value (e.g., 0 for `int`, `null` for objects).

This is useful for fields that you do not want to persist, such as:

  • Sensitive information like passwords.
  • Fields that can be derived or calculated.
  • Fields that represent resources that are not serializable themselves (like a database connection).
public class User implements Serializable {
    private String username;
    private transient String password; // Password will not be saved during serialization
    //...
}

Loading…
Tags: Java Programming Interview Questions and Answers || Java Programming Sort Questions and Answers || Java Programming Detailed Questions and Answers || Java Programming Tutorial