InterviewQuestions JavaFullStack
InterviewQuestions JavaFullStack
1. Java Basics...........................................................................................................................................3
Java Data types....................................................................................................................................4
Static....................................................................................................................................................9
Bit Manipulation................................................................................................................................12
Strings................................................................................................................................................14
Can we use a string in switch case in java?........................................................................................16
Stack , Heap and Metaspace..............................................................................................................20
How GC works in java........................................................................................................................23
Interface And Abstract.......................................................................................................................25
OOPS..................................................................................................................................................27
Overloading and Overriding...............................................................................................................30
What is Association?..............................................................................................................................35
Exception and try-catch.........................................................................................................................37
What does the keyword synchronize mean?.....................................................................................41
What is ReentrantLock? Can we call lock.lock() multiple times?.......................................................41
Deep vs. shallow copy........................................................................................................................41
Design Patterns..................................................................................................................................42
2. Collection Hierarchy..........................................................................................................................43
ArrayList.............................................................................................................................................43
List.....................................................................................................................................................46
Hashtable and HashMap....................................................................................................................48
3. Threads & Executor Service (Thread Pool Framework).....................................................................56
Questions...............................................................................................................................................56
Thread Basics.........................................................................................................................................58
ThreadPools...........................................................................................................................................61
Types of ThreadPool..............................................................................................................................62
Threads: producer and consumer problem?.....................................................................................65
Difference Between Process and Thread in Java...............................................................................65
What is the difference between concurrency and parallelism?.........................................................65
4.................................................................................................................................................................66
5. Java 8.................................................................................................................................................66
Functional Interfaces and Lambdas in Java 8.........................................................................................69
What Is Optional? How Can It Be Used?............................................................................................69
Stream API Java8...............................................................................................................................72
Tell me 5 features introduced in JDK 1.8?.........................................................................................74
Programs to check logics.......................................................................................................................76
6. Others................................................................................................................................................79
Java 19 Features....................................................................................................................................79
JDBC.......................................................................................................................................................81
7. Basic...................................................................................................................................................83
Which architectural designs are mostly used to design applications?...............................................83
Compare fail-fast and fail-safe iterators?..........................................................................................83
1. Java Basics
Whats the feature that make java write once and use anywhere? (Platform independent)
JRE is a piece of a software which is designed to run other software. It contains the class libraries, loader class, and JVM. In simple terms, if you
want to run Java program you need JRE. If you are not a programmer, you don't need to install JDK, but just JRE to run Java programs.
Though, all JDK versions comes bundled with Java Runtime Environment, so you do not need to download and install the JRE separately in your
PC. The full form of JRE is Java Runtime Environment.
JVM is an engine that provides a runtime environment to drive the Java Code or applications. It converts Java bytecode into machine language.
JVM is a part of Java Run Environment (JRE). It cannot be separately downloaded and installed. To install JVM, you need to install JRE. The full
form of JVM is Java Virtual Machine.
Java Data types
Suffix :By default, float numbers are double in java. In order to store them into float variable, you need to explicitly add the
suffix 'f' or 'F'.
Suppose we have a number 1.23456. Let's see what happens if we store it in the float variable num.
float num = 1.23456 // compiler error
Float is single precision floating point decimal number while Double is double precision decimal number.
In other words, a float can give you 6-7 digits decimal points precision.
double is a double precision floating point operation. In other words, double can give you 15-16 decimal points precision.
Can I store a double value in a long variable without casting?
How long do primitive variables exist in memory? Define the various scopes of primitive variables?
After a primitive variable is declared and initialized; how long it lives in memory is dependent on the scope of the variable.
Scope of a variable is determined based on where it is declared within a java class. Following are the various scopes of a
variable in a java program based on where they are declared.
Local variables
Local variables are variables declared within a method body. They live only as long as the method in which it is declared remains on
the stack.
Block variables
A class variable is a variable which has one copy per class. The class variables will not have a copy in the object.
How does Java programming language pass primitive variables to methods - by value or by
reference?
In Java, primitive variables are passed to methods by value. More specifically, a copy of the primitive value is passed to the method. If the
passed value changes in the method, it does not change the original value.
Access Modifires
Primitive Casting is used to convert primitive values from one data type to another. For example, an int value can be assigned to
a float data type, or a double value can be assigned to an int data type. Casting can be either implicit or explicit.
Implicit Casting: In implicit casting the conversion happens automatically, without writing specific code to do the conversion.
Implicit casting happens when you convert or assign a smaller value, like a byte, to a larger data type such as an int.
Explicit Casting: In explicit casting code has to be specifically written to perform the conversion from one primitive type to
another. Explicit casting is done by using the syntax (data_type) where data_type is the data type that the cast is being applied to.
Explicit casting happens when you convert or assign a larger value to a smaller data type.
In Java every data type requires some bytes of memory, How many bytes void data type requires?
Ans – 0
First of all, null is not a valid object instance, so there is no memory allocated for it. It is simply a value that indicates that the object reference is
not currently referring to an object.
Inner class can only be accessed using reference of outer class ( Class name , if inner class is static or object reference, if inner class is non
static ) whereas Sub class is accessed directly.
In terms of memory, inner class is stored just like another class having it's own body whereas sub class carries the body of parent class as well
as its own fields in memory.
What's the default access specifier for variables and methods of a class?
Default access specifier for variables and method is package protected i.e. variables and class is available to any other class but in
the same package, not outside the package.
What are wrapper classes in Java programaming language?
There are many cases where we cannot directly use primitive data types. For example, We cannot put primitives into Java collections since Java
collections (Lists, Sets etc.) can only store objects.
Static
What happen if we don’t write static method?
Static methods and static variables are stored in the meta space in Java. Meta space is a region of memory that is
used to store class metadata, such as the names of classes, fields, and methods, as well as the bytecode for static
methods. Meta space is also used to store interned strings.
Prior to Java 8, static methods and static variables were stored in the permanent generation (PermGen) space.
However, PermGen was known to be difficult to tune, and it could become a bottleneck in applications that used a
lot of static data. In Java 8, PermGen was replaced with meta space, which is a more flexible and scalable memory
region.
Meta space is located in the heap memory, which means that it can grow and shrink as needed. This makes meta
space less likely to become a bottleneck than PermGen was.
It is important to note that static methods and static variables are shared by all instances of a class. This means
that there is only one copy of each static method and static variable in memory, even if there are multiple
instances of the class.
Overriding is based on dynamic binding at runtime, static members are bound at compile time.
Can we have static methods in an Interface?
Yes, from Java 8, an interface can also be defined.
Static methods can't be overridden in any class while any methods in an interface are by default abstract and are supposed to
be implemented in the classes being implementing the interface. So it makes no sense to have static methods in an interface in
Java.
Bit Manipulation
Logical & Bitwise Operator
The Bitwise Algorithms are used to perform operations at bit-level or to manipulate bits in different ways. The bitwise operations are found to be
much faster and are some times used to improve the efficiency of a program.
For example: To check if a number is even or odd. This can be easily done by using Bitwise-AND(&) operator. If the last bit of the operator is
set than it is ODD otherwise it is EVEN. Therefore, if num & 1 not equals to zero than num is ODD otherwise it is EVEN.
Little and big endian are two ways of storing multibyte data-types ( int, float, etc). In little endian machines, last byte of binary representation of
the multibyte data-type is stored first. On the other hand, in big endian machines, first byte of binary representation of the multibyte data-type is
stored first.
Suppose integer is stored as 4 bytes (For those who are using DOS based compilers such as C++ 3.0 , integer is 2 bytes) then a variable x with
value 0x01234567 will be stored as following.
Memory representation of integer ox01234567 inside Big and little endian machines
What are the examples of little, big endian and bi-endian machines ?
Intel based processors are little endians. ARM processors were little endians. Current generation ARM processors are bi-endian.
Motorola 68K processors are big endians. PowerPC (by Motorola) and SPARK (by Sun) processors were big endian. Current version of these
processors are bi-endians.
What is a compile time constant in Java? What is the risk of using it?
Ans: public static final variables are also known as a compile time constant, the public is optional there. They are replaced with
actual values at compile time because compiler know their value up-front and also knows that it cannot be changed during run-
time. One of the problem with this is that if you happened to use a public static final variable from some in-house or third party
library and their value changed later than your client will still be using old value even after you deploy a new version of JARs. To
avoid that, make sure you compile your program when you upgrade dependency JAR files.
What is the difference between ++x and x++ under increment operators?
In ++x, the value of x will get incremented before it is used in the expression.
In x++, the previous value is used in the expression first, and after that x is modified.
Strings
Additionally, strings in Java are reserved in a special area in heap memory called the String Constant Pool. When a string is declared in your
program, a String object reference is created in stack memory, and additionally, a String object with the string value is created in the heap. The
intention of this is for string reusability, but a consequence is that there is a good chance that the string will remain in memory for a prolonged
period of time. This is an even bigger security threat.
Another aspect to consider is the risk of printing the password to a logging device. Storing a password as a string does create this possibility, as
strings are easily appended to log writers or even the standard system output stream. Conversely, with an array, accidentally printing this to a
log or output stream would print the location of the array in memory.
The answer is only 1 object is created. String strObj1 will create a new object in String constant pool whereas strObj2 will create
the reference to the String strObj1.
An immutable object is an object that will not change its internal state after creation. Immutable objects are very useful in multithreaded
applications because they can be shared between threads without synchronization. To create immutable class in java, you have to do
following steps.
String Pool: Designers of Java were aware of the fact that String data type is going to be majorly used by the programmers and
developers. Thus, they wanted optimization from the beginning. They came up with the notion of using the String pool (a storage area
in Java heap) to store the String literals. They intended to decrease the temporary String object with the help of sharing. An immutable
class is needed to facilitate sharing. The sharing of the mutable structures between two unknown parties is not possible. Thus,
immutable Java String helps in executing the concept of String Pool.
Multithreading: The safety of threads regarding the String objects is an important aspect in Java. No external synchronization is
required if the String objects are immutable. Thus, a cleaner code can be written for sharing the String objects across different threads.
The complex process of concurrency is facilitated by this method.
Collections: In the case of Hashtables and HashMaps, keys are String objects. If the String objects are not immutable, then it can get
modified during the period when it resides in the HashMaps. Consequently, the retrieval of the desired data is not possible. Such
changing states pose a lot of risks. Therefore, it is quite safe to make the string immutable
Java String class has a special method to check if the string is empty or not. isEmpty() method internally checks if
the length of the string is zero. If it is zero, that means the string is empty, and the isEmpty() method will return
true.
If the length of the string is not zero, then the isEmpty() method will return false.
String and StringBuffer both represent String objects. Can we compare String and StringBuffer in
Java?
Although String and StringBuffer both represent String objects, we can't compare them with each other and if we try to compare them, we get
an error.
When a lot of changes are required in data, which one should be a preference to be used? String or
StringBuffer?
What is the difference between StringBuffer and StringBuilder ?
StringBuffer is synchronized whereas StringBuilder is not synchronized.
Storage area: In string, the String pool serves as the storage area. For StringBuilder and StringBuffer, heap memory is the storage
area.
Mutability: A String is immutable, whereas both the StringBuilder and StringBuffer are mutable.
Efficiency: It is quite slow to work with a String. However, StringBuilder is the fastest in performing operations. The speed of a
StringBuffer is more than a String and less than a StringBuilder. (For example appending a character is fastest in StringBuilder and
very slow in String because a new memory is required for the new String with appended character.)
Thread-safe: In the case of a threaded environment, StringBuilder and StringBuffer are used whereas a String is not used. However,
StringBuilder is suitable for an environment with a single thread, and a StringBuffer is suitable for multiple threads.
Syntax:
// String
String first = "Interview";
String second = new String("Interview");
// StringBuffer
StringBuffer third = new StringBuffer("Interview");
// StringBuilder
StringBuilder fourth = new StringBuilder("Interview");
A. 42
B. 420
C. 462
D. 42042
E. Compilation fails.
Correct Answer: D
Write a java program to swap two string variables without using temp variable?
In Java, when we only declare a variable of a class type, only a reference is created (memory is not allocated for the object). To allocate memory
to an object, we must use new(). So the object is always allocated memory on heap
Basics
Heap
The heap is the largest and most widely used part of Java’s memory model. It is responsible for storing objects created during
the execution of a Java application. When you create an object using the “new” keyword, it gets allocated on the heap
In the example above, the “greeting” object is allocated on the heap. The heap can be further divided into two main areas: the
young generation and the old generation. The young generation is where new objects are initially created, while the old
generation contains objects that have survived multiple garbage collection cycles.
Stack
The stack is a memory area used to store local variables and method call information. Each thread in a Java application has its
own stack, which grows and shrinks as methods are called and returned. Stack memory is used to store primitive data types
(int, float, etc.) and references to objects.
In the example above, the main method calls the sum method, passing two integers as arguments. When the sum method is
called, a new stack frame is created, which stores the local variables (x, y, and total).
Metaspace
Metaspace, formerly known as PermGen (Permanent Generation), is a non-heap memory area that stores class metadata, constant
pool information, and method bytecode. It was introduced in Java 8 as a replacement for PermGen, which was removed due to
memory management issues.
Unlike the heap and stack, metaspace does not have a fixed size and can grow dynamically. However, it is still essential to
monitor its usage to avoid memory leaks and potential OutOfMemoryError exceptions.
Object space in Heap -- how much space each object consumes in the Java heap.
How objects are stored in Java?
In java, each object when created gets a memory space from a heap. When an object is destroyed by a garbage collector, the
space allocated to it from the heap is re-allocated to the heap and becomes available for any new objects.
When computing the shallow size of an object, we only consider the object itself. That is, if the object has references to other
objects, we only consider the reference size to the target objects, not their actual object size. For instance:
As shown above, the shallow size of the Triple instance is only a sum of three references. We exclude the actual size of the
referred objects, namely A1, B1, and C1, from this size.
On the contrary, the deep size of an object includes the size of all referred objects, in addition to the shallow size:
Here the deep size of the Triple instance contains three references plus the actual size of A1, B1, and C1. Therefore, deep sizes
are recursive in nature.
When the GC reclaims the memory occupied by an object, it frees a specific amount of memory. That amount is the retained
size of that object:
The retained size of the Triple instance only includes A1 and C1 in addition to the Triple instance itself. On the other hand, this
retained size doesn’t include the B1, since the Pair instance also has a reference to B1.
Sometimes these extra references are indirectly made by the JVM itself. Therefore, calculating the retained size can be a
complicated task.
To better understand the retained size, we should think in terms of the garbage collection. Collecting the Triple instance
makes the A1 and C1 unreachable, but the B1 is still reachable through another object. Depending on the situation, the retained
size can be anywhere between the shallow and deep size.
There are two classes named classA and classB. Both classes are in the same package. Can a private
member of classA can be accessed by an object of classB?
Private members of a class aren't accessible outside the scope of that class and any other class even in the same package can't
access them.
How GC works in java
1. Java Heap: It is used for dynamic memory allocation. It stores objects and other data structures created during program execution.
2. Stack: It is used to store local variables and method call frames. Each thread in Java has its own stack which is created when the
thread starts. All local variables inside that thread are stored in the stack. For objects created inside the stack, the actual object will be
in the heap and the local variable inside stack will store a reference for it.
There are other areas like Metaspace, registers etc which are not very relevant here.
When an object is created using new or any other object instantiation methods, memory for that object is allocated inside the heap. As the
application progresses, some of these objects become unreachable when they are not referenced anymore. If GC is not running, the entire
heap is quickly filled up and the application crashes as memory is not available.
There is a misconception that GC tracks all dead objects, which is not true. An easier and right way is to track all the live objects ( which are
needed for program execution) and clean up everything else. Now how do we identify all the live objects?
GC roots
Consider all the objects created inside the program as a tree. If we have access to all the roots of such trees, we can easily track all the live
objects( which are reachable). In Java , the following are considered as valid GC roots.
1. Local variables: This is available via thread stack and considered live as long as the method is active
2. Active Java threads.
3. Static variable: They belong to classes and are shared across all instances. They remain GC roots as long as the class is loaded.
4. JNI references: They are created as part of a JNI call. Objects thus created are managed specially as it is not possible to know
whether it is referred by the native code or not.
Marking: JVM runs the GC thread intermittently which traverses all the object trees starting from the GC roots. It marks all the objects reachable
as live.
Sweep: All the remaining heap space are marked(swept) as free for new allocations.
As you can see, to perform the marking phase, it is essential that we stop all the live application threads. Else, the object trees cannot be marked
safely. And the pause time depends on how much memory is live(not dead!!). The more live objects, the longer it takes for GC to traverse and
analyse them. And this brings us to the fundamental issue with GC — its impact on application performance.
Another issue associated with allocation/deallocation is memory fragmentation. It occurs when free memory is fragmented into smaller , non-
contiguous chunks making it impossible to allocate large objects even if memory is available. This quickly becomes a bottleneck if memory is not
compacted after each cleanup.
GC algorithms
Multiple GC algorithms and techniques are developed to reduce this performance issue and fragmentation. Let us discuss some of these.
Serial Collector
It is the simplest collector which uses a single thread to perform mark-sweep algorithm. This is a stop-the-world-approach where all the
application threads are paused while a single GC thread is running. This is suited for low concurrency applications with smaller memory
footprints.
Parallel Collector
The only difference from a serial collector is that it uses multiple GC threads. It is more suitable when multiple CPUs are available.
Concurrent Collector
The concurrent collector performs most of the activities concurrently while application threads are running. This helps with application
throughput and reduces the stop-the-world event duration, thus making the application more responsive.
Generational GC
As mentioned earlier, the GC performance depends on how many live objects are available in the heap. So in order to improve GC performance,
we need to make sure that live objects are as less as possible. This is the main reason behind dividing the heap into multiple generations. The
division allows different GC algorithms to be applied selectively based on the characteristics of objects residing there.
As you know, newly created objects are more likely to be short-lived, while objects that have been around for a while are more
likely to remain live for long. Objects are usually created in young area. As most of the objects are short-lived, the GC runs
quickly and cleans up most of them. If some objects survive a few GC cycles inside the young area, they are moved to the
old area. As long as the old area is not growing big, we can avoid running GC in old area altogether.
In order to optimise this further , some JVMs divide young gen into multiple regions: Eden space and Survivor spaces(usually
two). New objects are usually created in Eden space. During GC, surviving objects from Eden space and one of the Survivor
space are copied into another survivor space, thus keeping Eden and one survivor space always free. This helps with
fragmentation issues as we are always keeping Eden and one survivor space completely empty.
1. Collecting young gen is called minor GCs. Although they have a stop-the-world stage, it is very quick resulting in
shorter pause times.
2. The old gen contains long-lived objects and hence Major GCs are very less.
3. Different GC algorithms can be applied to each gen based on size and application requirements.
It is very important that GC should be fine-tuned based on the application requirement. For example, if the young gen is too
small, it will result in a lot of objects moving to the old generation. If the young gen is too large, minor GC cycles will take
longer time to complete. This will negatively impact application response time.
One of the recent algorithms available from Java 9 is G1 GC. It provided more predictable pause time and better scalability for
applications with large heaps.
How can you minimize the need of garbage collection and make the memory use more effective?
Ans: Use object pooling and weak object references.
Interface And Abstract
Can we declare a class as Abstract without having any abstract method?
What is an abstract class? How is it different from an interface? Why would you use it?
OOP concept is one of the oldest concepts in programming. Java and Python are object-oriented
languages. When we use oop there are many advantages. we can avoid code redundancy, manage
changes, manage complexity and code reuse support.
Changing the class internals does not affect any code outside of the class.
Managing change is easier. Changing implementation doesn’t reflect on the clients which use them.
In abstraction, implementation complexities are hidden using abstract classes and interfaces. While in encapsulation, the data is
hidden using methods of getters and setters.
Abstraction is the method of hiding unwanted implementation information. Whereas encapsulation is a method to hide the
data in a single entity or unit along with a method to protect information from outside.
What are the functional interface and marker interfaces?
An interface with only one abstract method is known as a functional interface. They can only
demonstrate one functionality at a time. A functional interface can have as many default methods as it
wants. Runnable and Comparable are examples of functional interfaces.
It’s a blank interface (no field or methods). Serializable and Cloneable are examples of marker
interfaces. All of these interfaces are completely empty. It is mainly used to say the type of an object to
the java compiler.
Overloading and Overriding
Polymorphism in Java can be performed by two different methods i.e Method Overloading and Overriding
Method Overloading is when a class has multiple methods with the same name, but the number, types and order of parameters
and the return type of the methods are different. Java allows the user freedom to use the same name for various functions as
long as it can distinguish between them by the type and number of parameters.
Runtime polymorphism in java is also known as Dynamic Binding or Dynamic Method Dispatch. In this process, the call to
an overridden method is resolved dynamically at runtime rather than at compile-time. Runtime polymorphism is achieved
through Method Overriding.
Method Overriding is done when a child or a subclass has a method with the same name, parameters and return type as the parent
or the superclass, then that function overrides the function in the superclass. In simpler terms, if the subclass provides its
definition to a method already present in the superclass, then that function in the base class is said to be overridden.
It should be noted that runtime polymorphism can only be achieved through functions and not data members.
Overriding is done by using a reference variable of the superclass. Which method to be called is determined based on the object
which is being referred to by the reference variable. This is also known as Upcasting.
Upcasting is done when the Parent class’s reference variable refers to the object of the child class. For example:
1class A{}
2class B extends A{}
3A a=new B(); //upcasting
Examples of Runtime Polymorphism in Java
1 class Money {
2. private String country = "India";
3. public String getC() { return country; }
4. }
5. class Yen extends Money {
6. public String getC() { return super.country; }
7. }
8. public class Euro extends Money {
9. public String getC(int x) { return super.getC(); }
10. public static void main(String[] args) {
11. System.out.print(new Yen().getC() + " " + new Euro().getC());
12. }
13. }
What is the result?
A. India
B. null India
C. India null
D. India India
E. Compilation fails due to an error on line 6.
F. Compilation fails due to an error on line 9.
Correct Answer: E
Section: All
Explanation
Explanation/Reference:
The field Money.country is not visible
Exception and try-catch
What’s the difference between error and exceptions?
“Throwable” act as the root for Java’s error and exception hierarchy. “Error” is a critical condition that cannot be handled by the code of the
program. “Exception” is the exceptional situation that can be handled by the code of the program. Error is caused due to lack of system
resources, and an exception is caused because of your code.
Unchecked exceptions are those exceptions which are not at all known to compiler. These exceptions occur only at run time. These
exceptions are also called as run time exceptions. All sub classes of java.lang.RunTimeException and java.lang.Error are unchecked
exceptions. For example NullPointerException, ArithmeticException etc.
Explain the user defined Exceptions?
Can we write only try block without catch and finally blocks?
Compile time error or runtime error?
Ans: No, it shows compilation error. The try block must be followed by either catch or finally block. You
can remove either catch block or finally block but not both.
What happens if I write return in try block? Will finally executes? What happens if write
system.exit(), will finally block executes?
Difference between final, finalize and finally?
Which is better Null Check or try-catch
Exceptions do take extra memory, as well as time, to catch. It is ALWAYS better to test for null if it’s a possible value. Another
thing to consider it that it’s simply less code and more readable to do the null test. Usually having try/catch blocks adds
essentially no overhead to your code for the normal case, but when the exception is triggered it’s quite expensive.
Exceptions are, as their names implies, to be used only for exceptional conditions, they should never be used for ordinary control
flow.
What does the keyword synchronize mean?
When you have two threads that are reading and writing to the same 'resource', say a variable named 'test', you need to ensure
that these threads access the variable in an atomic way. Without the synchronized keyword, your thread 1 may not see the change
thread 2 made to test.
synchronized blocks the next thread's call to method as long as the previous thread's execution is not finished. Threads can
access this method one at a time.
Unlike the shallow copy, a deep copy is a fully independent copy of an object. If we copied our Person object, we would copy
the entire object structure.
Design Patterns
Dependency Injection
Reusability of code
Ease of refactoring
Ease of testing
2. Collection Hierarchy
Java collection framework offers highly efficient and effective data structures that enhance the accuracy and speed of the program.
The program developed with the Java collection framework is easy to maintain.
A developer can mix classes with other types that result in increasing the reusability of code.
The Java collection framework enables programmers to modify the primitive collection types the way they like.
Suppose you have three objects in ArrayList i.e. [1,2,3] and you want to remove the second object, which is 2. You may call
remove(2), which is actually a call to remove(Object) if consider autoboxing, but will be interpreted as a call to remove
3rd element, by interpreting as remove(index).
You can ConcurrentModificationException, due to call to remove() method from ArrayList. This is easy in
simple examples like this, but in a real project, it can be really tough. Now, to fix this exception, just replace the call of
numbers.remove() to itr.remove(), this will remove the current object you are Iterating
List<Integer> numbers = new ArrayList<Integer>();
numbers.add(100);
numbers.add(200);
numbers.add(300);
numbers.add(400);
List
Hashmap Hashtable
It is not synchronized. It is synchronized.
HashMap allows one key as a null value. HashTable does not allow null values.
Either Iterator or Enumerator is used for traversing a
Iterator is used to traverse HashMap.
HashTable.
It can be used for both HashTable, HashMap and is fail-fast. It can be used with HashTable and is fail-safe.
HashMap perform faster than the HashTable. Hashtable is not much faster as compared to HashMap.
What difference between Hashmap vs concurrent hashmap and the follow-up question on how they
work internally etc?
HashMap uses its static inner class Node<K,V> for storing the entries in the map.
HashMap allows at most one null key and multiple null values.
The HashMap class does not preserve the order of insertion of entries into the map.
HashMap has multiple buckets or bins which contain a head reference to a singly linked list. That means there would be as many linked lists
as there are buckets. Initially, it has a bucket size of 16 which grows to 32 when the number of entries on the map crosses the 75%. (That means
after inserting in 12 buckets bucket size becomes 32)
HashMap is almost similar to Hashtable except that it’s unsynchronized and allows at max one null key and multiple null values.
HashMap uses hashCode() and equals() methods on keys for the get and put operations. So HashMap key objects should provide a good
implementation of these methods.
That’s why the Wrapper classes like Integer and String classes are a good choice for keys for HashMap as they are immutable and their object
state won’t change over the course of the execution of the program.
Note: Java HashMap is not thread-safe and hence it should not be used in multithreaded application. For the multi-threaded application, we
should use ConcurrentHashMap class.
What is Hashing?
It is the process of converting an object into an integer value. The integer value helps in indexing and faster searches. Same input have same
output value.
What is HashMap
HashMap is a part of the Java collection framework. It uses a technique called Hashing. It implements the map interface. It stores the data in the
pair of Key and Value. HashMap contains an array of the nodes, and the node is represented as a class. It uses an array and LinkedList data
structure internally for storing Key and Value. There are four fields in HashMap.
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.
We use put() method to insert the Key and Value pair in the HashMap. The default size of HashMap is 16 (0 to 15).
The developer cannot directly iterate map, but, this interface has two methods that gives view set of map. These methods are:
Set<Map.Entry<K, V>>entrySet(): It is a method that returns a set having the entries mention in the map. These
entries are generally objected, which has type Map. Entry.
Set<K>keySet(): This Java method returns a set that having the map key.
What is IdentityHashMap?
IdentityHashMap is a class that implements Serializable, Clonable interfaces, Map, and extends AbstractMap class. It is designed
for the case wherein there is a need of reference-equality semantics.
What is WeakHashMap?
WeakHashMap is an implementation of the Java Map. It is used to store weak references to its keys. Sorting using this Map
allows a key-value pair is collected as garbage. Its key is not referenced outside WeakHashMap.
What will happen if you try to store a key that is already present in HashMap? If you store an existing key
in the HashMap, then it will override the old value with the new value, and put() will return the old value. There will not be
any exception or error.
-----------------------------------------------------------------------------------------------------------------------------------------------------
Question: Given:
HashMap props = new HashMap();
props.put("key45", "some value");
props.put("key12", "some other value");
props.put("key39", "yet another value");
Set s = props.keySet();
//insert code here for sorting
What, inserted at line 39, will sort the keys in the props HashMap?
A. Arrays.sort(s);
B. s = new TreeSet(s);
C. Collections.sort(s);
D. s = new SortedSet(s);
Correct Answer: B
Since Java 8, we can use the Stream API and lambda expressions to sort the map. All we need is to call
the sorted method over the map’s stream pipeline.
map.entrySet()
.stream()
.sorted(Map.Entry.<String, Employee>comparingByKey())
.forEach(System.out::println);
-----------------------------------------------------------------------------------------------------------------------------------------------------
Sparse arrays can be used to replace hash maps when the key is an Integer or a Long (HashMap <Integer, V>).
is made to be memory efficient than using the regular HashMap
It is generally slower than a traditional HashMap
What is the difference between HashSet, HashMap and Hashtable? How do they behave in a multi-
threaded environment?
It does not allow null for both key and value. It will throw NullPointerException.
Hashtable does not maintain insertion order. The order is defined by the Hash function. So only use this if you do not
need data in order.
It is synchronized. It is slow. Only one thread can access in one time.
HashTable rea thread safe.
HashTable uses Enumerator to iterate through elements.
On the other hand fail-safe Iterators works on copy of collection instead of original collection.
Failfast Failsafe
It does not allow collection modification while iterating. It allows collection modification while iterating.
It can throw ConcurrentModificationException It can't throw any exception.
It uses the original collection to traverse the elements. It uses an original collection copy to traverse the elements.
There is no requirement of extra memory. There is a requirement of extra memory.
Collections.synchronizedList(list);
Collections.synchronizedMap(map);
Collections.synchronizedSet(set);
Ans Both poll() and remove() take out the object from the Queue but if poll() fails then it returns null but
if remove fails it throws Exception.
Questions
What’s the difference between class lock and object lock?
Class Lock: In java, each and every class has a unique lock usually referred to as a class level lock. These locks are achieved using the keyword
‘static synchronized’ and can be used to make static data thread-safe. It is generally used when one wants to prevent multiple threads from
entering a synchronized block.
Example:
Object Lock: In java, each and every object has a unique lock usually referred to as an object-level lock. These locks are achieved using the
keyword ‘synchronized’ and can be used to protect non-static data. It is generally used when one wants to synchronize a non-static method or
block so that only the thread will be able to execute the code block on a given instance of the class.
Example:
synchronized(monitor)
}
sleep(): As the name suggests, it is a static method that pauses or stops the execution of the current thread for
some specified period. It doesn’t release the lock while waiting and is mostly used to introduce pause on
execution. It is defined in thread class, and no need to call from a synchronized context.
Example:
synchronized(monitor)
//after 1000 milliseconds, the current thread will wake up, or after we call that is interrupt() method
What is Runnable and Callable Interface? Write the difference between them.
Both the interfaces are generally used to encapsulate tasks that are needed to be executed by another thread. But there are
some differences between them as given below:
Running Interface: This interface is basically available in Java right from the beginning. It is simply used to execute code on a
concurrent thread.
The Runnable interface is a functional interface and has a single run() method that doesn’t accept any parameters or return any
value
Callable Interface: This interface is basically a new one that was introduced as a part of the concurrency package. It addresses
the limitation of runnable interfaces along with some major changes like generics, enum, static imports, variable argument
method, etc. It uses generics to define the return type of object.
The Callable interface is a generic interface containing a single call() method that returns a generic value V:
Time Slicing: It is especially used to divide CPU time and allocate them to active threads. In this, each thread will get a
predefined slice of time to execute. When the time expires, a particular thread has to wait till other threads get their chances to
use their time in a round-robin fashion. Every running thread will get executed for a fixed time period.
Immutable objects are by default thread-safe because there state can not be modified once created. Since String is
immutable in Java, its inherently thread-safe.
Read only or final variables in Java are also thread-safe in Java.
Locking is one way of achieving thread-safety in Java.
Static variables if not synchronized properly becomes major cause of thread-safety issues.
Example of thread-safe class in Java: Vector, Hashtable, ConcurrentHashMap, String etc.
Atomic operations in Java are thread-safe e.g. reading a 32 bit int from memory because its an atomic operation it can't
interleave with other thread.
local variables are also thread-safe because each thread has there own copy and using local variables is good way to
writing thread-safe code in Java.
In order to avoid thread-safety issue minimize sharing of objects between multiple thread.
Volatile keyword in Java can also be used to instruct thread not to cache variables and read from main memory and can
also instruct JVM not to reorder or optimize code from threading perspective.
Thread Basics
Any class whose instances are meant to be run by a thread should implement the Runnable interface or thread class. There is
just one abstract method named to run in a runnable interface. It is used to act as a thread. We can’t extend any other class
when we extend the Thread class, even if we need to. We may save space for our class when we implement a Runnable
interface for threads. So that we can extend any other class in the future or right now.
2. Reusability : In "implements Runnable" , we are creating a different Runnable class for a specific behavior job (if the work
you want to be done is job). It gives us the freedom to reuse the specific behavior job whenever required. "extends Thread"
contains both thread and job specific behavior code. Hence once thread completes execution , it can not be restart again.
3. Object Oriented Design: Implementing Runnable should be preferred . It does not specializing or modifying the thread
behavior . You are giving thread something to run. We conclude that Composition is the better way. Composition means two
objects A and B satisfies has-a relationship.
"extends Thread" is not a good Object Oriented practice.
4. Loosely-coupled : "implements Runnable" makes the code loosely-coupled and easier to read .
Because the code is split into two classes . Thread class for the thread specific code and your Runnable implementation class for
your job that should be run by a thread code. "extends Thread" makes the code tightly coupled . Single class contains the
thread code as well as the job that needs to be done by the thread.
5. Functions overhead : "extends Thread" means inheriting all the functions of the Thread class which we may do not need .
job can be done easily by Runnable without the Thread class functions overhead.
In multi-threading how can we ensure that a resource isn't used by multiple threads
simultaneously?
In multi-threading, access to the resources which are shared among multiple threads can be controlled by using the concept of
synchronization. Using synchronized keyword, we can ensure that only one thread can use shared resource at a time and others
can get control of the resource only once it has become free from the other one using it.
Thread pool is a single FIFO task queue with a group of worker threads. The producers (E.g. the UI thread) sends tasks to the
task queue. Whenever any worker threads in the thread pool become available, they remove the tasks from the front of the
queue and start running them.
Comparing with starting a random number of individual worker threads, using a thread pool prevent the overhead of killing
and recreating threads every time a worker thread is needed. It also gives you fine control over the number of threads and
their lifecycle. E.g. ThreadPoolExecutor allows you to specify how many core threads, how many max threads the pool should
create and the keep alive time for the idle threads.
What is a ThreadPool? And is it more effective than using several separate Threads?
ThreadPool consists of a task queue and a group of worker threads, which allows it to run multiple parallel instances of a task.
Here, you’re assessing the app developer’s understanding of how multithreading has the potential to improve an app’s performance, but also how
it can negatively impact performance when used incorrectly.
Using ThreadPool is more efficient than having multiple operations waiting to run on a single thread, but it also helps you avoid the considerable
overhead of creating and destroying a thread every time you require a worker thread.
Java provides the Executor framework which is centered around the Executor interface, its sub-interface –ExecutorService and the class-
ThreadPoolExecutor, which implements both of these interfaces. By using the executor, one only has to implement the Runnable objects and
send them to the executor to execute.
Creating thread is expansive operation. Threadpool uses blocking queue (thread safe operation).
Types of ThreadPool
1.FixedThreadPool
2 CachedThreadPool: No control for no. threads created. It check for any thread free, if not create new
thread.
3. ScheduledThreadPool:
4. SingleThreadedPool: To ensure to run task in sequentially.
Threads: producer and consumer problem?
In computing, the producer–consumer problem (also known as the bounded-buffer problem) is a classic
example of a multi-process synchronization problem. The problem describes two processes, the
producer and the consumer, which share a common, fixed-size buffer used as a queue.
The producer’s job is to generate data, put it into the buffer, and start again.
At the same time, the consumer is consuming the data (i.e. removing it from the buffer), one
piece at a time.
Process and thread share a relationship where a process provides an environment for the execution of the thread. A process can contain
multiple threads.
Each process has its own address space whereas, the threads of the same process share the address space as that of the process.
In process based multitasking, more than two processes can run at the same time whereas, in thread-based multitasking, more than
two thread can run at the same time.
Inter-process communication between two processes is costlier than inter-thread communication.
Context switching between two processes is expensive and limited as compared to context switching between two threads.
A process is also called the heavyweight task whereas, the thread is called lightweight task.
Multitasking over a process is not under the control of Java whereas, the Multitasking over multithreading is under the control of
Java.
Components contained by a process its own address space, global variables, signal handlers, open files, child processes, accounting
information. On the other hand, a thread contains its own register, state, stack, program counter.
Check Android P
Parallelism is when tasks literally run at the same time, e.g., on a multicore processor.
Concurrency: A condition that exists when at least two threads are making progress. A
more generalized form of parallelism that can include time-slicing as a form of virtual
parallelism.
Parallelism: A condition that arises when at least two threads are executing
simultaneously.
4.
Ans:A final variable, not initalized at the time of declaration, is known as blank final variable
23.What’s wrong with using HashMaps in a multi-threaded environment? When does a get() method go
into an infinite loop?
5. Java 8
Ans:Transient keyword indicates that the value of this member variable does not have to be serialized
with the object.
34. Why would you use a synchronized block vs. synchronized method?
36.There are two classes: A and B. The class B need to inform a class A when some important event has
happened. What Java technique would you use to implement it?
Functional Interfaces and Lambdas in Java 8
A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit.
From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface
can have any number of default methods. Runnable, ActionListener, Comparable are some of the examples of functional
interfaces.
There are a lot of functional interfaces in the java.util.function package. The more common ones include, but are not limited to:
@FunctionalInterface Annotation
@FunctionalInterface annotation is used to ensure that the functional interface can’t have more than one abstract method. In
case more than one abstract methods are present, the compiler flags an ‘Unexpected @FunctionalInterface annotation’
message. However, it is not mandatory to use this annotation.
Interface
Optional has a special Optional.empty() value instead of wrapped null. Thus it can be used instead of a nullable value to get rid
of NullPointerException in many cases.
Optional introduces space overhead: an Optional is a separate object that consumes extra
memory.
Optional introduces time overhead: Its data must be accessed via an extra indirection, and
calling methods on it is more expensive than Java's efficient test for null.
Optional introduces coding overhead: You have to deal with its incompatibility with existing
interfaces that use null, with the fact that it is not serializable, etc.
There are many ways to create an object of the Optional class in Java, you can create an empty Optional by using the static
method Optional.empty() as shown below:
Optional<Person> p = Optional.empty();
This Optional is empty, if you want to create an Optional with a non-null value then you can write the following code:
n case the Person object is null, the resulting Optional object would be empty, but it won't throw the NullPointerException.
You can also create an instance of the Optional class by using the static factory method Optional.of() in Java 8 as shown
in the following example:
In very simple terms, a lambda expression is a function that we can reference and pass around as an object. Moreover, lambda
expressions introduce functional style processing in Java, and facilitate the writing of compact and easy-to-read code.
As a result, lambda expressions are a natural replacement for anonymous classes such as method arguments. One of their
main uses is to define inline implementations of functional interfaces.
Optional type declaration – when declaring the parameters on the left-hand side of the lambda, we don't need to declare
their types as the compiler can infer them from their values. So int param -> … and param ->… are all valid
Optional parentheses – when only a single parameter is declared, we don't need to place it in parentheses. This means
param -> … and (param) -> … are all valid, but when more than one parameter is declared, parentheses are required
Optional curly braces – when the expressions part only has a single statement, there is no need for curly braces. This means
that param – > statement and param – > {statement;} are all valid, but curly braces are required when there is more than one
statement
Optional return statement – when the expression returns a value and it is wrapped inside curly braces, then we don't need a
return statement. That means (a, b) – > {return a+b;} and (a, b) – > {a+b;} are both valid
Stream API Java8
forEach
map
Double the value of arrayList
filter
findFirst
toArray
flatMap
peek
Intermediate
terminal operations
Creation
1.Write a program in Java which Counts total number of Characters, Words and Lines
Java 19 Features
How will you implement interceptors and filters while using spring boot ?
What are the core classes to implement the Spring Security ? Is this any how different while using with
spring MVC or with spring boot ? Or
Is all Maven/Gradle dependency needs to add while using spring boot or is there any dedicate starter for
Spring Security?
Name two service discovery which you have implemented in your spring boot microservice application ?
Is there any configuration needs to be added to your application or in K8s cluster related to this ?
Name Load balancer which you are using in your application and what all steps need to follow while
configure it with Kubernetes or any of cloud ?
What is the difference b/w Joint Point and Point Cuts in Spring AOP.
What is cloud formation template ?
OR
What is use of Spring Batch , have you ever implemented the same , if yes kindly tell me the steps ?
What are the basic commands to create a docker image and where are you storing your docker images ?
What CICD tools your are using in your project for Continuous building and continuous deployment ?
What is the use of sleuth in spring boot microservice application ? As Spring boot 3.x no more
supporting sleuth ,please name the alternative for same.
JDBC
Steps to Connect Java Application with Database
Master-Slave Pattern
Layered Pattern
Monolithic Architecture
Operates It operates directly on the collection itself. It operates on a cloned copy of the collection.
Memory
It requires low memory during the process. It requires more memory during the process.
utilization
CopyOnWriteArrayList, ConcurrentHashMap,
Examples HashMap, ArrayList, Vector, HashSet, etc.
etc.
Bad way, as it costly, CopyOnWriteArrayList has no checkForComodification() and creates new array list, i.e. changing data soure.
What is double brace initialization in Java and where it is used?
In Java, double brace initialization is a combination of two separate processes. The two consecutive curly braces {{ involved in it.
The first curly brace represents the creation of an anonymous inner class. Remember that the second curly brace will not be considered in such
a case. It is just like creating an anonymous inner class.
The second curly brace represents an initialization block that we have seen in it as a class for initialization. When we use the initialization block
for an anonymous inner class it becomes Java double brace initialization. The inner class has a reference to the enclosing outer class. We can
use the reference by using this pointer.
It is used to initialize collections because it is easier to initialize a constant collection using double brace initialization. The example of double
brace initialization is as follows:
Why should you avoid to run non-UI code on the main thread?