Core Java Interview Qs

Author:Vivek Prasad


Core Java Interview Qs

Q1) What’s the difference between String, StringBuffer, and StringBuilder?

String:


A String is like a fixed, unchangeable sequence of characters. Once you create a String, you can't change its content. If you want to modify it, you actually create a new String. It's good for situations where you don't need to change the text often.

StringBuffer:


A StringBuffer is like a String that you can edit or change. It's more efficient for making lots of changes to a piece of text because it doesn't create new objects every time you modify it. It's useful when you need to work with text that changes frequently, like when building a long piece of text step by step.

StringBuilder:


A StringBuilder is very similar to a StringBuffer. The main difference is that StringBuilder is not synchronized, which makes it faster in most situations. You should use StringBuilder when you're working with text that doesn't need to be shared among multiple threads (like in multithreading).

In simple terms, use String when you have text that doesn't change much, use StringBuffer when you have text that changes a lot, and use StringBuilder when you have text that changes a lot but don't need to worry about multiple threads working on it simultaneously.

Q2) What is the difference between final, finalize and finally?

final:


final is a keyword used in programming languages like Java and C++. When you declare a variable as final, it means that the variable's value cannot be changed once it's been assigned. When you declare a method as final, it means that the method cannot be overridden by subclasses. It's all about making things immutable or unchangeable.

finalize:


finalize is a method in Java (not present in languages like C++). This method is called by the garbage collector before an object is reclaimed (destroyed) to give the object a chance to clean up any resources it holds. It's used for performing cleanup operations like closing files or releasing memory associated with an object before it's deleted.

finally:


finally is a keyword used in exception handling, particularly in languages like Java. It's used in a try-catch-finally block to ensure that a block of code (the "finally block") is executed regardless of whether an exception is thrown or not. It's often used for tasks like closing files or releasing resources, ensuring they are done even if an exception occurs. In summary:

final is about making variables or methods unchangeable or non-overridable. finalize is a method used for object cleanup before they are destroyed, mainly in Java. finally is used in exception handling to ensure a block of code always executes, whether an exception occurs or not.

Q3) Describe polymorphism?

Polymorphism is a concept in programming that allows objects of different classes to be treated as objects of a common superclass. It's a fundamental principle in object-oriented programming and is often associated with two types: compile-time (static) and runtime (dynamic) polymorphism. Let me explain it in simple terms:

a) Compile-Time (Static) Polymorphism:


This is also known as method overloading. It occurs when you have multiple methods in the same class with the same name but different parameters. The appropriate method to call is determined at compile time based on the number or types of arguments provided.

Example: You might have a method called calculateArea that can accept different shapes as arguments (e.g., circles, rectangles) and calculates their areas based on the input provided.

b) Runtime (Dynamic) Polymorphism:


This is also known as method overriding. It occurs when a subclass provides a specific implementation for a method that is already defined in its superclass. When you call the method on an object, the actual implementation that gets executed is determined at runtime based on the type of object.

Example: You have a superclass called Animal with a method makeSound(). Subclasses like Dog and Cat can override this method to produce their unique sounds.

Polymorphism is powerful because it allows you to write code that can work with objects of different classes in a more general way. This makes your code more flexible and easier to maintain because you can add new classes that inherit from a common superclass without having to modify existing code that uses those objects. In essence, polymorphism allows you to treat different objects in a unified way based on their shared characteristics (like method names) while still preserving their individual behaviors.

Q4) What all elements are included in a method signature

A method signature in programming typically includes the following components:

Method Name:


This is the name of the method that uniquely identifies it within a class or namespace.

Return Type:


It specifies the data type of the value that the method will return when it is executed. Some methods may not return any value, in which case the return type is often specified as "void."

Parameter List:


This includes the list of input parameters (also known as arguments) that the method accepts. Each parameter has a data type and a name. These parameters are used to pass information into the method when it is called.

The combination of the method name, return type, and parameter list is what constitutes the method signature. It's used to uniquely identify and distinguish one method from another within a class or namespace. Here's a simple example:


public int add(int num1, int num2) {
    return num1 + num2;
}


So, the method signature is int add(int num1, int num2). This signature tells us that the method is named "add," it returns an integer (int), and it accepts two integer parameters named num1 and num2.

Q5) What are interfaces in java?

In Java, an interface is a fundamental concept that defines a contract of methods that a class must implement. An interface specifies a set of method signatures (method names, return types, and parameter lists) that must be defined by any class that claims to implement that interface. Interfaces play a crucial role in achieving abstraction, multiple inheritance of type, and ensuring a consistent API for classes that implement them.

Here are some key points about interfaces in Java:

a) Declaration:


To declare an interface, you use the interface keyword. For example:


interface MyInterface {
    void someMethod(); // This is a method signature without a body
}


b) Implementing Interfaces:


Classes that want to adhere to the contract defined by an interface must use the implements keyword to declare that they implement the interface. For example:


class MyClass implements MyInterface {
    @Override
    public void someMethod() {
        // Provide an implementation for the method
    }
}


c) Multiple Interfaces:


A Java class can implement multiple interfaces. This allows a class to inherit the method signatures from multiple sources. For example:


class MyClass implements Interface1, Interface2 {
    // Class must provide implementations for methods in Interface1 and Interface2
}


d) Default Methods (Java 8 and later):


Java introduced the concept of default methods in interfaces. These are methods with a default implementation in the interface itself. Classes that implement the interface can choose to override these default methods or use the provided implementation.


interface MyInterface {
    void someMethod();

    default void anotherMethod() {
        // Default implementation
    }
}



e) Static Methods (Java 8 and later):


Interfaces can also contain static methods, which are associated with the interface itself, not with instances of implementing classes.


interface MyInterface {
    void someMethod();

    static void staticMethod() {
        // Static method implementation
    }
}


Interfaces are commonly used for achieving abstraction and defining a common contract for classes with varying implementations, allowing for more flexible and organized code in Java applications.

Q6) what are abstract classes in java

An abstract class in Java is a class that cannot be instantiated (you cannot create objects from it) and is typically used as a blueprint or template for other classes. Abstract classes are designed to be extended by subclasses, which must provide concrete implementations for the abstract methods defined in the abstract class.

Here are some key characteristics and uses of abstract classes:

a) Abstract Methods:


Abstract classes can declare abstract methods, which are methods without a body. Subclasses that extend an abstract class must provide concrete (implemented) versions of these abstract methods.


abstract class AbstractShape {
    abstract void draw(); // Abstract method without a body
}


b) Inheritance:


Subclasses of an abstract class inherit the abstract methods and fields (including any non-abstract methods) defined in the abstract class.


class Circle extends AbstractShape {
    @Override
    void draw() {
        // Provide a concrete implementation for the abstract method
        System.out.println("Drawing a circle");
    }
}


c) Cannot Be Instantiated:


You cannot create instances of an abstract class directly. It's meant to serve as a base for other classes.


// This is not allowed: AbstractShape shape = new AbstractShape();


d) May Contain Concrete Methods:


An abstract class can also contain fully implemented (concrete) methods. Subclasses inherit these methods as well.


abstract class AbstractShape {
    abstract void draw(); // Abstract method

    void move() {
        System.out.println("Moving the shape");
    }
}


e) Purpose:


Abstract classes are used when you want to define a common interface and some shared behavior for a group of related classes, but you don't want instances of the abstract class itself. Subclasses provide specific implementations of the shared behavior.

Abstract classes are a way to achieve abstraction and enforce a structure in your code, ensuring that subclasses conform to a specific contract (by implementing abstract methods) while allowing for some flexibility in their individual implementations.

Q7) What is difference between HashMap and HashTable

HashMap and Hashtable are both data structures in Java that store key-value pairs. They are used to associate values (the "values") with unique keys. However, there are some important differences between the two:

a) Synchronization:


Hashtable is synchronized, which means it is thread-safe. Multiple threads can access and modify a Hashtable concurrently without causing data corruption.

HashMap is not synchronized by default, which means it is not thread-safe. If you want to use a HashMap in a multi-threaded environment, you would need to add your own synchronization mechanisms (e.g., using Collections.synchronizedMap) to make it thread-safe.

b) Performance:


Because Hashtable is synchronized, it can be slower in a single-threaded environment compared to HashMap. This is due to the overhead of synchronization.

HashMap tends to be faster in single-threaded scenarios because it doesn't have the synchronization overhead.

c) Null Values:


Hashtable does not allow null keys or null values. If you attempt to insert a null key or value, it will throw a NullPointerException.

HashMap allows one null key and multiple null values. This can be useful in some cases.

d) Legacy:


Hashtable is a legacy class that has been around since the early versions of Java. It's part of the original Java Collections Framework.

HashMap is part of the newer Java Collections Framework introduced in Java 1.2 and is preferred for most use cases due to its better performance and flexibility.

In general, if you need thread safety, you might choose Hashtable. However, in modern Java programming, it's more common to use HashMap and handle synchronization explicitly if needed. Most of the time, HashMap is the preferred choice due to its better performance and flexibility unless you specifically require the thread safety provided by Hashtable.

Q8) What are collections in java

The term "collections" refers to a framework or set of classes and interfaces in the Java Collections Framework (JCF) that provide data structures to store, manage, and manipulate groups of objects. The term "collections" refers to a framework or set of classes and interfaces in the Java Collections Framework (JCF) that provide data structures to store, manage, and manipulate groups of objects.

a) Hierarchy:


The Java Collections Framework has a hierarchical structure with a set of core interfaces at the top, which are implemented by various classes. The core interfaces include:

Collection: The root interface that represents a group of objects.

List: An ordered collection that allows duplicates and provides indexed access to elements (e.g., ArrayList, LinkedList).

Set: A collection that does not allow duplicates and does not provide indexed access (e.g., HashSet, LinkedHashSet).

Map: A collection that associates keys with values (e.g., HashMap, TreeMap).

b) Common Collection Classes:


Some commonly used collection classes in Java include:

ArrayList: A dynamic array-based list.

LinkedList: A doubly-linked list.

HashSet: An unordered set that doesn't allow duplicates.

HashMap: A key-value map.

TreeSet: A set with elements sorted in natural order.

TreeMap: A map with keys sorted in natural order.

c) Generics


Java collections use generics to ensure type safety. You can specify the type of elements a collection can hold when you declare it, helping to prevent type-related errors.

d) Iterators:


Collections provide iterators that allow you to traverse the elements in a collection in a uniform manner, regardless of the specific type of collection.

e) Sorting:


Many collection classes can be sorted using the Collections.sort() method, and some, like TreeSet and TreeMap, are naturally sorted.

f) Concurrency:


Java provides concurrent collection classes (e.g., ConcurrentHashMap, CopyOnWriteArrayList) for multithreaded programming.

Performance Trade-offs:


Different collection classes have different performance characteristics. The choice of which a collection to use depends on your specific requirements in terms of access patterns, performance, and memory usage.

Different collection classes have different performance characteristics. The choice of which collection to use depends on your specific requirements in terms of access patterns, performance, and memory usage.

Q9) What is the difference between a list and a set?

List and Set are both interfaces in the Java Collections Framework, but they have distinct characteristics and use cases:

List:


Ordered Collection: A List is an ordered collection, which means it maintains the order of elements based on their insertion sequence. Each element has an index (starting from 0), and you can access elements by their index.

Allows Duplicates: List allows duplicate elements. You can have the same element repeated multiple times within a List.

Common Implementations: Common implementations of the List interface include ArrayList, LinkedList, and Vector. ArrayList is often the preferred choice due to its efficiency in most scenarios.

Use Cases: Use List when you need to maintain the order of elements, and duplicates are allowed. It's suitable for scenarios where you need to access elements by their position in the list.


List<String> myList = new ArrayList<>();
myList.add("apple");
myList.add("banana");
myList.add("apple"); // Duplicates allowed
System.out.println(myList.get(0)); // Access by index



Set:


Unordered Collection: A Set is an unordered collection, which means it does not guarantee any specific order for its elements. Elements are stored in a way that optimizes search and retrieval.

Does Not Allow Duplicates: Set does not allow duplicate elements. If you attempt to add an element that is already present, it won't be added again.

Common Implementations: Common implementations of the Set interface include HashSet, LinkedHashSet, and TreeSet. HashSet is often used for its fast access times, while TreeSet keeps elements in a sorted order.

Use Cases: Use Set when you want to store a collection of unique elements, and you don't require any specific order. It's suitable for scenarios where you need to check for the existence of an element or ensure that each element occurs only once.


Set<String> mySet = new HashSet<>();
mySet.add("apple");
mySet.add("banana");
mySet.add("apple"); // Duplicate not allowed, won't be added again
System.out.println(mySet.contains("banana")); // Check for existence



In summary, the main differences between List and Set are their ordering guarantees (ordered vs. unordered) and whether duplicates are allowed (allowed in List, not allowed in Set). The choice between them depends on your specific requirements for maintaining order and handling duplicate elements.