Monday, June 14, 2021

Core java interview questions

1.    CountDownLatch


java.util.concurrent.CountDownLatch, use in multithreaded environment, Suppose we want one of our threads wait for other threads to complete first and then finish its execution.

example:
we have main thread and 3 more threads span from main thread and we want other 3 threads always complete first its execution and then only main complete it execution

public class MainClass {
public static void main(String args[]) throws InterruptedException {
CountDownLatch latch = new CountDownLatch(3);
Thread t1 = new Thread(new RunnableClass(latch)) ;
t1.setName("thead-1");
Thread t2 = new Thread(new RunnableClass(latch)) ;
t1.setName("thead-2");
Thread t3 = new Thread(new RunnableClass(latch)) ;
t1.setName("thead-3");
t1.start();
t2.start();
t3.start();
latch.await();
System.out.println("Main thread ending now...");
}
}

public class RunnableClass implements Runnable{
CountDownLatch latch;
RunnableClass(CountDownLatch latch){
this.latch = latch;
}
@Override
public void run() {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread name "+ Thread.currentThread().getName());
latch.countDown();
}
}


2.    Cyclic barrier

Cyclic barrier used to make threads wait for each other after complete their subtask & reach at a barrier point. 
CyclicBarrier barier = new CyclicBarrier(parties); // parties are no. of threads

Here parties are no. of thread involved to break the barrier. 
There is await() method that will call by each thread after complete their subtask and then start waiting, atlast  when the final thread calls await barrier will break and rest of the execution of threads will continue.

public class CyclicbarrierDemo {
public static void main(String args[]) {
CyclicBarrier barier = new CyclicBarrier(3);
Thread t1 = new Thread(new RunnableClass2(barier)) ;
t1.setName("thead-1");
Thread t2 = new Thread(new RunnableClass2(barier)) ;
t1.setName("thead-2");
Thread t3 = new Thread(new RunnableClass2(barier)) ;
t1.setName("thead-3");
t1.start();
t2.start();
t3.start();
}
}

public class RunnableClass2 implements Runnable{
CyclicBarrier barrier;
RunnableClass2(CyclicBarrier barrier){
this.barrier = barrier;
}
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Thread :"+ Thread.currentThread().getName()+" reached barrier point");
try {
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("After barrier execution continue for thread"+Thread.currentThread().getName());
}
}


3.    Difference cyclic barrier and countdown latch

The major difference between these two is countdown latch can not be reinitialize after count reach to zero. But in case of cyclic barrier you can reinitialize the barrier.


4.    Wait(), notify() and notifyAll() method

All of these are Object class methods because they apply on object and not on any thread.
Object.wait() is to suspend the current thread. This will make the current thread to wait until another thread invoke notify or notifyAll.
Another version (overloaded method) of wait are wait( long timeout) and wait(long timeout, int nanoSecond) for more accurate at nano second level.


5.    Immutable class

If you can not change the content of any object and if you try to do so then it will create a new object then class said to be immutable.
String is immutable class, similarly all wrapper classes are immutable.

how to create immutable class ?

1.    Make class final  so that nobody can extends and create subclass
2.    Make variables private and final and provide only getter and no setter.
3.    Initialize variable inside the constructor and if instance variables are mutable please create deep           copy of that means return new object of that.


5.    Factory pattern

It is a creational pattern that uses factory method to solve the problem of creation of object and provide loose coupling means factory method eliminates the hard coding of class name.




6.    Abstract Factory Pattern

It creates factory of factory.



7.    How to restrict child class from being serialized if parent class implements Serializable interface

If parents implements serializable interface child class will automatically serialized, to restrict this we can override readObject() & writeObject() methods throw NotSerializabe exception from this overriden methods.

8. HashMap : Rehashing
 
In Java, the HashMap class employs rehashing as part of its strategy to maintain efficiency when dealing with hash collisions and changes in the number of elements stored in the map. Rehashing occurs automatically when the load factor of the HashMap exceeds a certain threshold.
Here's an explanation of how rehashing works in a HashMap:
Load Factor:
The load factor is a measure of how full the hash map is. It is the ratio of the number of elements in the map to the size of the underlying array. The default load factor for HashMap is 0.75.
Capacity and Threshold:
HashMap has two important parameters related to capacity and rehashing: capacity and threshold.
capacity is the size of the underlying array, and it is always a power of two.
threshold is the product of the load factor and the current capacity. When the number of elements in the map exceeds the threshold, rehashing is triggered.
Rehashing Process:
When the number of elements in the HashMap exceeds the threshold, the capacity is doubled, and the map is rehashed.
The rehashing process involves creating a new larger array (twice the size of the current one) and redistributing the existing elements into the new array based on their updated hash codes.
Here's a simplified example:
import java.util.HashMap;
public class HashMapRehashingExample {
    public static void main(String[] args) {
        // Create a HashMap with default initial capacity (16) and default load factor (0.75)
        HashMap<String, Integer> hashMap = new HashMap<>();
        // Add elements to the HashMap
        for (int i = 0; i < 12; i++) {
            hashMap.put("Key" + i, i);
        }
        // At this point, rehashing may occur if the load factor threshold is exceeded
    }
}
In this example, when the number of elements reaches a point where the load factor threshold is exceeded (in this case, 12 elements for the default capacity of 16), the HashMap may trigger rehashing to ensure that the load factor remains below the specified threshold.
Understanding rehashing is important for developers using HashMap to ensure efficient performance, especially in scenarios where a large number of elements are dynamically added or removed from the map. Keep in mind that while rehashing is automatic, it can impact the performance momentarily as the elements are redistributed.
 
 
 






 

Labels: , , , ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home