- Explain Java OOPS concepts
- Difference between method overloading and method overriding
- Internal working of Hashmap
- How to iterate Hashmap in Java?
- Difference between Hashmap and Treemap?
- Difference between Hashmap and Hashtable?
- Difference between Hashmap and Concurrent Hashmap?
- Difference between == and Equals()
- Why String is immutable?
- Type of Interfaces in Java
- What is Marker interface?
- What is the use of the keyword transient?
- Static method vs default method in Interface
- What is Serialization and Deserialization in Java?
- Explain Deadlock in Java?
- Explain String joiner
- How many ways can we create object of a class?
- How to prevent instantiation of a class
- Comparable vs Comparator in Java
- Life cycle of a thread?
- Difference between Vector and ArrayList
- Which is the form of threadsafe arraylist? Or you can say what is failfast, failsafe collection and can you name few of them?
- Explain Class loaders in Java
- Difference between Path and Classpath?
- What is Enum?
--------------------------------------------------------------------------------------------------------
Explain Java OOPS concepts
Object
Class
Inheritance
Polymorphism
Abstraction
Encapsulation
=> An Object can be defined as an instance of a class.
=> An Object contains an address and takes up some space in memory.
=> Constructor is used to allocate memory for the object
Class
=> Collection of objects is called class. It is a logical entity.
=> A class can also be defined as a blueprint from which you can create an individual object.
=> Class doesn't consume any space.
Inheritance
=> When one object acquires all the properties and behaviors of a parent object, it is known as inheritance.
=> It provides code reusability. It is used to achieve runtime polymorphism.
Polymorphism
=> If one task is performed in different ways, it is known as polymorphism.
=> In Java, we use method overloading and method overriding to achieve polymorphism.
Abstraction
=> Hiding internal details and showing functionality is known as abstraction. For example phone call, we don't know the internal processing.
=> In Java, we use abstract class and interface to achieve abstraction.
Encapsulation
=> Binding (or wrapping) code and data together into a single unit are known as encapsulation.
=> A java class is the example of encapsulation.
Difference between Method overloading and Method overriding
Method
overloading
|
Method
overriding
|
Method
overloading may or may not require inheritance.
|
Method
overriding always needs inheritance.
|
In
method overloading, methods must have the same name and different
signatures
|
In
method overriding, methods must have the same name and same
signature.
|
Internal working of Hashmap?
What is HashMap
=> HashMap is a part of the Java collection framework. It uses a technique called Hashing.
=> HashMap is used whenever data is stored as key-value pairs where values can be added, retrieved and deleted using keys
What is Hashing
=> It is the process of converting an object into an integer value. The integer value helps in indexing and faster searches.
=> Before understanding the internal working of HashMap, you must be aware of hashCode() and equals() method.
equals():
It checks the equality of two objects.
It compares the Key, whether they are equal or not.
It is a method of the Object class. It can be overridden. If you override the equals() method, then it is mandatory to override the hashCode() method.
hashCode():
This is the method of the object class.
It returns the memory reference of the object in integer form.
The value received from the method is used as the bucket number.
The bucket number is the address of the element inside the map.
Hash code of null Key is 0.
Buckets:
=> Array of the node is called buckets.
=> Each node has a data structure like a LinkedList.
=> More than one node can share the same bucket. It may be different in capacity.
To insert Key-Value pair in Hashmap :
=> We use method put() to insert Key-Value pair in Hashmap
=> Default size of Hashmap is 16 (0
to 15)
What is Hashing?
It is the process of converting an object into an integer value. The integer value helps in indexing and faster searches.
Before understanding the internal working of HashMap, you must be aware of hashCode() and equals() method.
hashCode():
This is the method of the object class.
It returns the memory reference of the object in integer form.
equals():
It checks the equality of two objects.
It compares the Key, whether they are equal or not.
It is a method of the Object class. It can be overridden. If you override the equals() method, then it is mandatory to override the hashCode() method.
How to iterate Hashmap in Java?
There is a numerous number of ways to iterate over HashMap of which 5 are listed as below:
-
Iterate through a HashMap Map.Entry EntrySet using Iterators.
-
Iterate through HashMap KeySet using Iterator.
-
Iterate HashMap using for-each loop.
-
Iterating through a HashMap using Lambda Expressions.
-
Loop through a HashMap using Stream API
Difference between HashMap and TreeMap?
HashMap |
TreeMap |
HashMap can contain one null key |
TreeMap cannot contain any null key |
HashMap maintains no order |
TreeMap maintains ascending order |
Difference between HashMap and HashTable?
HashMap
|
HashTable
|
Multiple
threads can operate concurrently So, HashMap is not-thread safe
|
At
a time, only one thread is allowed to operate So, HashTable is
thread-safe
|
HashMap
allows only one null key and multiple null values
|
HashTable
does not allow any null key or value
|
HashMap
is fast
|
HashTable
is slow
|
Difference between HashMap and ConcurrentHashMap?
(Youtube video Credits to the creator)
Difference Between == and Equals()
== Vs .equals()
Both are used to compare two objects in the java.
.equals() for content comparison
== checks if both objects point to same memory location
Why String is immutable?
When we assign value to a String reference variable, the String object will be created inside the String Pool.
If we assign another value to the same String reference variable, new String object will be created inside the String Pool, ie Existing String object will not be changed.
If we declare another one String reference variable with same string value, new String object will not be created and String reference variable in Stack memory will point to the existing String object value in the pool.
In short, String reference variables with same String value points to the same String object in the String pool instead of creating separate String object in the pool. Thats why we say String is immutable. This design pattern is called as Fly weight pattern.
If we create a String using the keyword new with the same String value, then it will create an object inside the heap memory but still points to the same String object in the String pool.
For more understanding :
(Credits to Navin Reddy (www.telusko.com))
How to make String mutable :
We can make String mutable by using
StringBuffer and StringBuilder.
Types of Interface in Java :
01. Normal Interface
02. Marker Interface
03. Functional or SAM(Single Abstract Method) Interface
01. Normal Interface
=> Interface which contains one or more abstract methods
02. Marker Interface
An Interface with no method is called as Marker Interface
Example for Predefined Marker Interfaces are Interface Serializable, Interface Cloneable
03. Functional or SAM(Single Abstract Method) Interface
SAM - Single Abstract Method Interface
An Interface that contains exactly one abstract method is known as Functional Interface.
=> Introduced in Java 8
=> Functional Interface can have any number of default and static methods but can contain only one abstract method
=> It can also declare methods of Object class
Example for Predefined Functional Interface : Java.Lang.Runnable
Functional Interface vs Normal Interface
=> Functional Interface can have only one abstract method whereas normal Interface can have multiple number of abstract methods.
What is Marker Interface :
An Interface with no method is called as Marker Interface
Example for Predefined Marker Interfaces are Interface Serializable, Interface CloneableWhat is Serialization and Deserialization in Java ?
Serialization
=> If we do not want any field to be part of object, then we declare it as either static or transient
=>The keyword transient can be used with the data members of the class in order to exclude it from serialization
=>If the class or its hierarchy does not extend the Interface Serializable, then transient does not make any sense.
static method vs default method in Interface :
static method in Java Interface |
default method in Java Interface |
Cannot override the static method of Interface |
Can override the default method of Interface |
static methods can be invoked using the name of the Interface |
default methods can be invoked using the object of implementation class |
Explain Deadlock in Java
=> Deadlock in Java occurs when two or more threads
are blocked forever, each waiting for a resource that
another thread holds, creating a circular dependency.
=> This results in a situation where none of the
threads can proceed, causing the program to hang.
Example of Deadlock in Java
public class DeadlockExample {
public static void main(String[] args) {
String resource1 = "Resource1";
String resource2 = "Resource2";
// Thread 1
Thread t1 = new Thread(() -> {
synchronized (resource1) {
System.out.println("Thread 1: Locked resource1");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (resource2) {
System.out.println("Thread 1: Locked resource2");
}
}
});
// Thread 2
Thread t2 = new Thread(() -> {
synchronized (resource2) {
System.out.println("Thread 2: Locked resource2");
try { Thread.sleep(100); } catch (Exception e) {}
synchronized (resource1) {
System.out.println("Thread 2: Locked resource1");
}
}
});
t1.start();
t2.start();
}
}
Explanation of the Example
Thread 1 locks resource1 and waits to lock resource2.
Thread 2 locks resource2 and waits to lock resource1.
Both threads are now waiting for each other to release
their respective resources, causing a deadlock.
The program will hang because neither thread can proceed.
How to avoid Deadlocks ?
=> Avoid nested locks as much as possible
=> Lock Ordering : Enforce a global ordering for acquiring
the locks.
For example, always acquire locks in alphabetical order
=> Timeouts : Use tryLock() which allows the thread to
backoff if the lock is not acquired.
=> Avoid Hold and Wait : Ensure the thread either acquires
all the resources at once or releases the resources before
waiting for others
=> Use java.util.concurrent classes like ExecutorService
How to detect Deadlocks ?
=> Use tools like jstack, VisualVM or JConsole
=> Use ThreadMXBean class to find deadlocked threads
import java.lang.management.*;
public class DeadlockDetector {
public static void main(String[] args) {
ThreadMXBean bean =
ManagementFactory.getThreadMXBean();
long[] deadlockedThreads =
bean.findDeadlockedThreads();
if (deadlockedThreads != null) {
System.out.println("Deadlock detected!");
}
}
}
Explain String Joiner
=> String Joiner Class introduced in Java 8
=> String Joiner Class provides efficient way to concatenate
multiple Strings with a defined delimiter (character),
optional prefix and suffix
Example :
import java.util.StringJoiner;
public class StringJoinerExample {
public static void main(String[] args) {
// Create a StringJoiner with comma and space as delimiter
StringJoiner sj1 = new StringJoiner(", ");
sj1.add("Apple");
sj1.add("Banana");
sj1.add("Cherry");
System.out.println("Joined String 1: " + sj1.toString());
// Output: Apple, Banana, Cherry
// Create a StringJoiner with a prefix, suffix, and delimiter
StringJoiner sj2 = new StringJoiner(" - ", "[", "]");
sj2.add("Red");
sj2.add("Green");
sj2.add("Blue");
System.out.println("Joined String 2: " + sj2.toString());
// Output: [Red - Green - Blue]
// Demonstrate merging
StringJoiner sj3 = new StringJoiner(" | ");
sj3.add("One");
sj3.add("Two");
sj1.merge(sj3); // Merges sj3 into sj1
System.out.println("Merged String: " + sj1.toString());
// Output: Apple, Banana, Cherry, One | Two
}
}
How many ways can we create an Object of a class ?
=> Using the new keyword
ClassName obj = new ClassName();
=> Using newInstance() and Class.forName();
Class<?> cls = Class.forName("ClassName");
Object obj = cls.newInstance(); // Calls default constructor
=> Using newInstance() and class.getConsructor()
Constructor<ClassName> constructor = ClassName.class.getConstructor();
ClassName obj = constructor.newInstance();
=> Using createInstance() factory method
ClassName obj = ClassName.createInstance(); // Example factory method
=> Using Object cloning - obj1.clone()
If class implements Cloneable interface, we can create copy of an
existing object using clone() method
ClassName obj1 = new ClassName();
ClassName obj2 = (ClassName) obj1.clone();
=> Using Deserialization - If an Object is serialized (Save in a file or stream),
we can recreate it by deserializing it - inputStream.readObject()
ObjectInputStream in = new ObjectInputStream(new FileInputStream("file.ser"));
ClassName obj = (ClassName) in.readObject();
How to prevent instantiation of a class ?
=> Abstract Class : Make a class Abstract. Abstract class cannot be instantiated directly
=> Private Constructor
=> Throw an exception in the constructor to explicitly prevent
=> Singleton Pattern : Combine private constructor with a static method to
access the instance. Only one instance is allowed
Comparable vs Comparator in Java ?
Java provides two interfaces to sort objects using data members of the class:
1. Comparable
2. Comparator
Life cycle of Thread
c2c : https://www.javatpoint.com/life-cycle-of-a-thread
In Java, a thread always exists in any one of the following states. These states are:
1. New
2. Active
3. Blocked / Waiting
4. Timed Waiting
5. Terminated
New: Whenever a new thread is created, it is always in the new state. For a thread in the new state, the code has not been run yet and thus has not begun its execution.
Active: When a thread invokes the start() method, it moves from the new state to the active state. The active state contains two states within it: one is runnable, and the other is running.
Runnable: A thread, that is ready to run is then moved to the runnable state. In the runnable state, the thread may be running or may be ready to run at any given instant of time. It is the duty of the thread scheduler to provide the thread time to run, i.e., moving the thread the running state.
A program implementing multithreading acquires a fixed slice of time to each individual thread. Each and every thread runs for a short span of time and when that allocated time slice is over, the thread voluntarily gives up the CPU to the other thread, so that the other threads can also run for their slice of time. Whenever such a scenario occurs, all those threads that are willing to run, waiting for their turn to run, lie in the runnable state. In the runnable state, there is a queue where the threads lie.
Running: When the thread gets the CPU, it moves from the runnable to the running state. Generally, the most common change in the state of a thread is from runnable to running and again back to runnable.
Blocked or Waiting: Whenever a thread is inactive for a span of time (not permanently) then, either the thread is in the blocked state or is in the waiting state.
For example, a thread (let's say its name is A) may want to print some data from the printer. However, at the same time, the other thread (let's say its name is B) is using the printer to print some data. Therefore, thread A has to wait for thread B to use the printer. Thus, thread A is in the blocked state. A thread in the blocked state is unable to perform any execution and thus never consume any cycle of the Central Processing Unit (CPU). Hence, we can say that thread A remains idle until the thread scheduler reactivates thread A, which is in the waiting or blocked state.
When the main thread invokes the join() method then, it is said that the main thread is in the waiting state. The main thread then waits for the child threads to complete their tasks. When the child threads complete their job, a notification is sent to the main thread, which again moves the thread from waiting to the active state.
If there are a lot of threads in the waiting or blocked state, then it is the duty of the thread scheduler to determine which thread to choose and which one to reject, and the chosen thread is then given the opportunity to run.
Timed Waiting: Sometimes, waiting for leads to starvation. For example, a thread (its name is A) has entered the critical section of a code and is not willing to leave that critical section. In such a scenario, another thread (its name is B) has to wait forever, which leads to starvation. To avoid such scenario, a timed waiting state is given to thread B. Thus, thread lies in the waiting state for a specific span of time, and not forever. A real example of timed waiting is when we invoke the sleep() method on a specific thread. The sleep() method puts the thread in the timed wait state. After the time runs out, the thread wakes up and start its execution from when it has left earlier.
Terminated: A thread reaches the termination state because of the following reasons:
• When a thread has finished its job, then it exists or terminates normally.
• Abnormal termination: It occurs when some unusual events such as an unhandled exception or segmentation fault.
A terminated thread means the thread is no more in the system. In other words, the thread is dead, and there is no way one can respawn (active after kill) the dead thread.
Difference between Vector and ArrayList
Which is the form of thread-safe arraylist? Or you can say what is failfast, failsafe collection and can you name a few of them?
Which is the form of thread-safe arraylist ?
=> An ArrayList is not thread safe by default but we can make it thread-safe and synchronized by using
1. Collections.synchronizedList() - method returns synchronized list
2. CopyOnWriteArrayList class - Thread safe variant of ArrayList
Explain Class Loaders in Java
Three types of class loader :
1. Bootstrap class loader
2. Extensions class loader
3. System class loader
Difference between Path and ClassPath ?
What is Enum ?
=> It is defined by using the keyword enum. It can include fields, constructors, methods.
Example : enum Day { MONDAY, TUESDAY, WEDNESDAY }