Java Concepts in Details
DS- Find Maximum element in Binary Tree(Not BST)
Finding Maximum in a binary tree can be done by below approach.
- data in current node.
- Find maximum in left subtree.
- Find maximum in right subtree.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | int findMax(Node node) { if(node == null) return Integer.MIN_VALUE; int max = node.data; int leftMax = findMax(node.left); int rightMax = findMax(node.right); if (leftMax > max) max = leftMax; if (rightMax > max) max = rightMax; return max; } |
Type Promotion
Type promotion happens in method calling.
A low type can be promoted to high type.
But type promotion not happens in case of Wrapper class like Integer, Long Double.
it always happens with primitive type like int, double, char, byte..etc
- Shot can be promoted to byte, int, long, float and double.
- byte can be promoted to int, long, float and double.
- char can be promoted to int, long, float and double.
- int can be promoted to long, float and double.
- long can be promoted to float and double.
- float can be promoted to double.
Below type promotion can place take when we call a method.
1 |
|
Garbage Collection
Garbage Collector is used to destroy the objects that are not in use or unreachable. So that heap memory can be object for application.
Its a daemon thread that runs periodically , and user don’t have to worry about running or executing it.
So if you have created any object without new, you can use finalize method to perform cleanup processing (destroying remaining objects).
This thread calls the finalize() method before object is garbage collected.
Mark & Sweep:-
It works in two steps:-
- Step 1: All currently running active objects are marked live.
- Step 2: Any object that is not marked live is removed
- In this approach first it defines some specific root objects (local variable and input parameters of the currently executing methods, active threads, static field of the loaded classes). Now GC travels whole object graph starting from root and marks all object live that are reachable or connected in that graph. And in second step it remove all object that are not marked as live. Disadvantage: While running this approach application thread need to be stopped, as GC can not traverse the graph if it keep changing.
- Concurrent Mark Sweep
- It is advanced version of Mark and Sweep. It uses multiple thread s for scanning the heap.
- Also it runs in parallel with application threads. So gives better performance than Mark & Sweep.
- Serial Garbage Collection
- This algorithm uses mark-copy for the Young Generation and mark-sweep-compact for the Old Generation. It works on a single thread.
- while executing it suspends all application threads until GC result has been concluded.
- Like Serial GC it also uses mark-copy for the Young Generation and mark-sweep-compact for the Old Generation.
- It works on multiple threads.
- We can configure the number of thread in JVM arguments.
- This basically divides the entire heap in small small segments.
- and each segment is marked as either Young generation or odd generation.
- This is parallel, concurrent, incrementally compacting low pause algorithm. This keeps tracking of the amount of live data in each region or segment. This information is used in knowing that which region keeps the most garbage. and that region is collection first. that is why the name is garbage first.
The Garbage collector of JVM collects only those objects that are created by new keyword.
Garbage collection is performed by a daemon thread called Garbage Collector(GC).
Below are the algorithm used for GC.
Thread Local
ThreadLocal can be used to provide a copy of variable for each thread.
That means each thread works on their own copy of variable and they can not see other threads variable value.
We use Thread Local to achieve thread safety apart from writing immutable classes.
InheritableThreadLocal
The InheritableThreadLocal class is a subclass of ThreadLocal.
Instead of each thread having its own value inside a ThreadLocal, the InheritableThreadLocal grants access to values to a thread and all child threads created by that thread.
1 |
|
Exception Class Hierarchy
Reentrant V/S Synchronization
There are four major differences between Reentrant Lock & Synchronization.
- Reentrant can be fairness. By passing fairness value true we can make sure the longest waited thread get the lock first.
- On the other hand, Synchronization wont guarantee that which thread will acquire the lock first once it is released.
- Reentrant provides tryLock method so that if the lock is not free the current thread will not be blocked, Or it will wait for provided period
- of time. While in synchronization,all threads trying to acquire the lock will be block if the lock is not released.
- In reentrant a lock can be acquire in one method and it can be unlocked in another method. While in Synchronization there is no such way, and lock is put on a
- block, method or scope.
- ReentrantLock also provides convenient method to get List of all threads waiting for lock.
Reentrant Lock, Cyclic Barrier, Count Down Latch
https://www.geeksforgeeks.org/reentrant-lock-java/
Cyclic Barrier: (Start & Wait) – Used to make threads wait for each other. It can be reset.
https://www.geeksforgeeks.org/java-util-concurrent-cyclicbarrier-java/
Count Down Latch: (Wait & Start) – Used to make sure that a task waits for other threads before it starts.
https://www.geeksforgeeks.org/countdownlatch-in-java/
FixedThreadPool v/s CachedThreadPool
Fixed Thread Pool:
In Fixed thread pool a pool is created of fixed size.And every time a new job comes, then a thread is pooled from the pool and assigned the job.
In some scenario when all thread are busy serving another request, the the new request/job has to wait in queue. As soon as a thread finishes its current request, it takes the new waiting request.
1 |
|
Cashed Thread Pool:
Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute
will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* * The below thread pool is cached thread pool. * Here when a new job comes, a new thread is created and after completing its task that thread is kept in pool till 60 seconds. * And if within 30 seconds a new job comes then the same thread is pooled out and assigned the job. */ ExecutorService cachedThredPool = Executors.newCachedThreadPool(); for(int i =0; i<100; i++) { cachedThredPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } }); } |
Returning Outcome:
We need to call submit method of ExecutorService when we want our thread to return some outcome. The submit method implements the Callable interface. The submit method is also capable of implementing the Runnable interface, but in that case it wont return any outcome.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | ExecutorService executor = Executors.newSingleThreadExecutor(); Future<Integer> outcome = executor.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { return 10; } }); System.out.println("outcome: "+ outcome.get()); //Submit method implementing Runnable interface executor.submit(new Runnable() { @Override public void run() { System.out.println("No outcome thread..."); } }); |
Threading- Print Even Odd Using two Threads
1 |
|
Sorting a HashMap
A hash map can be sorted by using below approaches.
- Using a TreeMap (default sorting based on key).
- Sorting using Comparator (Functional Interface).
- Sorting using Lambda Expression.
- Sorting Using Java Stream API.
Please See the below example
1 |
|
Sorting Algorithm Complexity
Exception Handling in Overriding
We can have following two cases in method overriding.
Case 1: Super class method does not declares/throws an exception.
In this case method in subclass can have below two choices.
- It may not declare/throw any exception.
- It can overridden method cannot declare the checked exception but it can declare unchecked exception (Runtime Exception).
In this case method in subclass can have below three choices.
- It may not declare/throw any exception.
- It can declare/throw the same exception that super class method has.
- It can declare/throw sub exception of the exception that super class method has.
Case 2: Super class declares/throws an exception
1 |
|
Serilizable vs Externalizable
We implement java.io.Externalizable interface if we want to serialize/desrialize only some specific attributes from a class.
The main disadvantage of using java.io.Serializable interface is that it serialize/desrialize the complete class. That means if a class is having even thousand attributes then it will serialize/desrialize all thousand attributes. With Serializable we can not skip any attribute.
So to get control over serialize/desrialize, we need to implement java.io.Externalizable.
In the target class we override public void writeExternal(ObjectOutput out) and public void readExternal(ObjectInput in) method from java.io.Externalizable interface.
1 |
|