Java Interview Question
Java Interview Question
Java is a high-level programming language that was developed by James Gosling in the year
1982. It is based on the principles of object-oriented programming and can be used to develop
large-scale applications.
The following article will cover all the popular Core Java interview questions, String Handling
interview questions, Java 8 interview questions, Java multithreading interview questions, Java
OOPs interview questions, Java exception handling interview questions, collections interview
questions, and some frequently asked Java coding interview questions.
Go through all the important questions to enhance your chances of performing well in the Java
Interviews. The questions will revolve around the basic, core & advanced fundamentals of Java.
So, let’s dive deep into the plethora of useful Java Technical Interview Questions and
Answers categorised into the following sections:
Play
Join our community and share your recent Java interview experiences.
Java language was developed so that it does not depend on any hardware or software
because the compiler compiles the code and then converts it to platform-independent
byte code which can be run on multiple systems.
The only condition to run that byte code is for the machine to have a runtime
environment (JRE) installed in it.
Learn More
Real-Life Problems
Prep for Target Roles
Create My Plan
Java supports primitive data types - byte, boolean, char, short, int, float, long, and
double and hence it is not a pure object oriented language.
3. Difference between Heap and Stack Memory in java. And how java
utilizes this.
Stack memory is the portion of memory that was assigned to every individual program.
And it was fixed. On the other hand, Heap memory is the portion that was not
allocated to the java program but it will be available for use by the java program when
it is required, mostly during the runtime of the program.
When we write a java program then all the variables, methods, etc are stored in the
stack memory.
And when we create any object in the java program then that object was created in the
heap memory. And it was referenced from the stack memory.
class Main {
public void printArray(int[] array){
for(int i : array)
[Link](i);
}
public static void main(String args[]) {
int[] array = new int[10];
printArray(array);
}
}
For this java program. The stack and heap memory occupied by java is -
Main and PrintArray is the method that will be available in the stack area and as well
as the variables declared that will also be in the stack area.
And the Object (Integer Array of size 10) we have created, will be available in the
Heap area because that space will be allocated to the program during runtime.
SRIKANTH VARMA
Computer Networking Course: Master Computer Networking
Enrolled: 36685
Free
SUMEET MALIK
NSET Course: Mathematics
4.7
Enrolled: 10354
Free
SUMEET MALIK
NSET Course: Logical reasoning
4.7
Enrolled: 10431
Free
SRIKANTH VARMA
Operating System Course: Learn Fundamentals of Operating System
Enrolled: 34951
Free
SRIKANTH VARMA
Microsoft Malware Detection using Machine Learning
Enrolled: 1454
Free
SRIKANTH VARMA
Netflix Movie Recommendation System using Machine Learning
5
Enrolled: 2728
Free
SRIKANTH VARMA
Amazon Fashion Discovery Engine using Machine Learning
Enrolled: 906
Free
SRIKANTH VARMA
Personalized Cancer Diagnosis using Machine Learning
Enrolled: 858
Free
SRIKANTH VARMA
Facebook Friend Recommendation using Graph Mining
Enrolled: 643
Free
SRIKANTH VARMA
Predicting tags for Stackoverflow using Machine Learning
Enrolled: 519
Free
SRIKANTH VARMA
Quora Question Pair Similarity Problem using Machine Learning
5
Enrolled: 580
Free
SRIKANTH VARMA
Taxi demand prediction in New York City using Machine Learning
Enrolled: 630
Free
MRINAL BHATTACHARYA
React JS Free Course
4.8
Enrolled: 25941
Free
YASH RAJ
AWS Free Course
4.7
Enrolled: 15458
Free
SUBHESH KUMAR
Object Oriented Programming in Java Course Online
4.95
Enrolled: 13823
Free
SRIKANTH VARMA
Deep Learning Course: Deep Dive into Deep Learning
Enrolled: 9688
Free
SRIKANTH VARMA
Free Maths for Machine Learning Course
Enrolled: 10566
Free
SRIKANTH VARMA
Supervised Machine Learning Course
Enrolled: 15348
Free
JAMSHAID SOHAIL
PyTorch for Deep Learning Course
4.8
Enrolled: 3995
Free
SRIKANTH VARMA
Unsupervised Machine Learning Course
Enrolled: 4717
Free
YASH SINHA
Data Science Course - Mastering the Fundamentals
4.7
Enrolled: 37240
Free
PRATEEK NARANG
Maths for Programmers
Enrolled: 7637
Free
ARNAV GUPTA
Spring Boot Course: Certified Course for Essential Skills
Enrolled: 22459
Free
GAURAV SISODIA
Keras & TensorFlow for Deep Learning
4.8
Enrolled: 3824
Free
PRATEEK NARANG
Coding Essentials: Learn Logic Building for Beginners Free Course
5
Enrolled: 17369
Free
ARNAV GUPTA
Machine Coding Tic Tac Toe - LLD Case Study
Enrolled: 3136
Free
MRINAL BHATTACHARYA
Node JS Certification Course - Master the Fundamentals
4.8
Enrolled: 25953
Free
PRATEEK NARANG
SQL for Beginners: Learn SQL using MySQL and Database Design Course
Enrolled: 55533
Free
ADITYA JAIN
Data Structures in C++ Course
4.5
Enrolled: 41886
Free
SUBHESH KUMAR
Java DSA Course - Master the Fundamentals and Beyond
4.95
Enrolled: 51345
Free
6. Pointers are used in C/ C++. Why does Java not make use of
pointers?
Pointers are quite complicated and unsafe to use by beginner programmers. Java
focuses on code simplicity, and the usage of pointers can make it challenging. Pointer
utilization can also cause potential errors. Moreover, security is also compromised if
pointers are used because the users can directly access memory with the help of
pointers.
Instance variables are those variables that are accessible by all the methods in the
class. They are declared outside the methods and inside the class. These variables
describe the properties of an object and remain bound to it at any cost.
All the objects of the class will have their copy of the variables for utilization. If any
modification is done on these variables, then only that instance will be impacted by it,
and all other class instances continue to remain unaffected.
Example:
class Athlete {
public String athleteName;
public double athleteSpeed;
public int athleteAge;
}
Local variables are those variables present within a block, function, or constructor
and can be accessed only inside them. The utilization of the variable is restricted to
the block scope. Whenever a local variable is declared inside a method, the other
class methods don’t have any knowledge about the local variable.
Example:
public void athlete() {
String athleteName;
double athleteSpeed;
int athleteAge;
}
Real-Life Problems
Detailed reports
Attempt Now
There are no default values assigned to the variables in java. We need to initialize the
value before using it. Otherwise, it will throw a compilation error of (Variable might
not be initialized).
But for instance, if we create the object, then the default value will be initialized by the
default constructor depending on the data type.
JIT stands for Just-In-Time and it is used for improving the performance during run
time. It does the task of compiling parts of byte code having similar functionality at the
same time thereby reducing the amount of compilation time for the code to run.
The compiler is nothing but a translator of source code to machine-executable code.
But what is special about the JIT compiler? Let us see how it works:
o First, the Java source code (.java) conversion to byte code (.class) occurs with the
help of the javac compiler.
o Then, the .class files are loaded at run time by JVM and with the help of an interpreter,
these are converted to machine understandable code.
o JIT compiler is a part of JVM. When the JIT compiler is enabled, the JVM analyzes the
method calls in the .class files and compiles them to get more efficient and native
code. It also ensures that the prioritized method calls are optimized.
o Once the above step is done, the JVM executes the optimized code directly instead of
interpreting the code again. This increases the performance and speed of the
execution.
11. Can you tell the difference between equals() method and equality
operator (==) in Java?
We are already aware of the (==) equals operator. That we have used this to compare
the equality of the values. But when we talk about the terms of object-oriented
programming, we deal with the values in the form of objects. And this object may
contain multiple types of data. So using the (==) operator does not work in this case.
So we need to go with the .equals() method.
Both [(==) and .equals()] primary functionalities are to compare the values, but the
secondary functionality is different.
So in order to understand this better, let’s consider this with the example -
[Link](str1 == str2);
This code will print true. We know that both strings are equals so it will print true. But
here (==) Operators don’t compare each character in this case. It compares the
memory location. And because the string uses the constant pool for storing the values
in the memory, both str1 and str2 are stored at the same memory location. See the
detailed Explanation in Question no 73: Link.
[Link](str1 == str2);
Then in this case, it will print false. Because here no longer the constant pool concepts
are used. Here, new memory is allocated. So here the memory address is different,
therefore ( == ) Operator returns false. But the twist is that the values are the same in
both strings. So how to compare the values? Here the .equals() method is used.
.equals() method compares the values and returns the result accordingly. If we
modify the above code with -
[Link]([Link](str2));
equals() ==
This is a method defined in the Object class. It is a binary operator in Java.
The .equals() Method is present in the Object
class, so we can override our custom .equals() It cannot be modified. They always compare
method in the custom class, for objects the HashCode.
comparison.
This method is used for checking the equality of This operator is used for comparing addresses
contents between two objects as per the specified (or references), i.e checks if both the objects
business logic. are pointing to the same memory location.
Note:
In the cases where the equals method is not overridden in a class, then the class uses
the default implementation of the equals method that is closest to the parent class.
Object class is considered as the parent class of all the java classes. The
implementation of the equals method in the Object class uses the == operator to
compare two objects. This default implementation can be overridden as per the
business logic.
Infinite loops are those loops that run infinitely without any breaking conditions. Some
examples of consciously declaring infinite loop is:
for (;;)
{
// Business logic
// Any break logic
}
while(true){
// Business logic
// Any break logic
}
do{
// Business logic
// Any break logic
}while(true);
4.5
100K+
Play Store
class Hospital {
int variable1, variable2;
double variable3;
public Hospital(int doctors, int nurses) {
variable1 = doctors;
variable2 = nurses;
}
public Hospital(int doctors) {
variable1 = doctors;
}
public Hospital(double salaries) {
variable3 = salaries
}
}
Three constructors are defined here but they differ on the basis of parameter type and
their numbers.
Copy Constructor is the constructor used when we want to initialize the value to the
new object from the old object of the same class.
class InterviewBit{
String department;
String service;
InterviewBit(InterviewBit ib){
[Link] = [Link];
[Link] = [Link];
}
}
Here we are initializing the new object value from the old object value in the
constructor. Although, this can also be achieved with the help of object cloning.
class Main {
public static void main(String args[]) {
[Link](" Main Method");
}
public static void main(int[] args){
[Link]("Overloaded Integer array Main Method");
}
public static void main(char[] args){
[Link]("Overloaded Character array Main Method");
}
public static void main(double[] args){
[Link]("Overloaded Double array Main Method");
}
public static void main(float args){
[Link]("Overloaded float Main Method");
}
}
The only difference in the return type of the method does not promote method
overloading. The following example will furnish you with a clear picture of it.
class OverloadingHelp {
public int findarea (int l, int b) {
int var1;
var1 = l * b;
return var1;
}
public int findarea (int l, int b, int h) {
int var2;
var2 = l * b * h;
return var2;
}
}
Both the functions have the same name but differ in the number of arguments. The
first method calculates the area of the rectangle, whereas the second method
calculates the area of a cuboid.
Method overriding is the concept in which two methods having the same method
signature are present in two different classes in which an inheritance relationship is
present. A particular method implementation (already present in the base class) is
possible for the derived class by using method overriding.
Let’s give a look at this example:
class HumanBeing {
public int walk (int distance, int time) {
int speed = distance / time;
return speed;
}
}
class Athlete extends HumanBeing {
public int walk(int distance, int time) {
int speed = distance / time;
speed = speed * 2;
return speed;
}
}
Both class methods have the name walk and the same parameters, distance, and
time. If the derived class method is called, then the base class method walk gets
overridden by that of the derived class.
17. A single try block and multiple catch blocks can co-exist in a Java
Program. Explain.
Yes, multiple catch blocks can exist but specific approaches should come prior to the
general approach because only the first catch block satisfying the catch condition is
executed. The given code illustrates the same:
Here, the second catch block will be executed because of division by 0 (i / x). In case
x was greater than 0 then the first catch block will execute because for loop runs till i =
n and array index are till n-1.
18. Explain the use of final keyword in variable, method and class.
In Java, the final keyword is used as defining something as constant /final and
represents the non-access modifier.
final variable:
o When a variable is declared as final in Java, the value can’t be modified once it has
been assigned.
o If any value has not been assigned to that variable, then it can be assigned only by the
constructor of the class.
final method:
o A method declared as final cannot be overridden by its children's classes.
o A constructor cannot be marked as final because whenever a class is inherited, the
constructors are not inherited. Hence, marking it final doesn't make sense. Java
throws compilation error saying - modifier final not allowed here
final class:
o No classes can be inherited from the class declared as final. But that final class can
extend other classes for its usage.
19. Do final, finally and finalize keywords have the same function?
Final: If any restriction is required for classes, variables, or methods, the final keyword
comes in handy. Inheritance of a final class and overriding of a final method is
restricted by the use of the final keyword. The variable value becomes fixed after
incorporating the final keyword. Example:
Finally: It is the block present in a program where all the codes written inside it get
executed irrespective of handling of exceptions. Example:
try {
int variable = 5;
}
catch (Exception exception) {
[Link]("Exception occurred");
}
finally {
[Link]("Execution of finally block");
}
Finalize: Prior to the garbage collection of an object, the finalize method is called so
that the clean-up activity is implemented. Example:
20. Is it possible that the ‘finally’ block will not be executed? If yes then
list the case.
Yes. It is possible that the ‘finally’ block will not be executed. The cases are-
21. Identify the output of the java program and state the reason.
1. public class InterviewBit
2. {
3. public static void main(String[] args) {
4. final int i;
5. i = 20;
6. int j = i+20;
7. i = j+30;
8. [Link](i + " " + j);
9. }
10. }
The above code will generate a compile-time error at Line 7 saying - [error: variable i
might already have been initialized]. It is because variable ‘i’ is the final variable.
And final variables are allowed to be initialized only once, and that was already done
on line no 5.
class Parent{
protected int num = 1;
Parent(){
[Link]("Parent class default constructor.");
}
Parent(String x){
[Link]("Parent class parameterised constructor.");
}
Child(){
//super constructor call should always be in the first line
// super(); // Either call default super() to call
default parent constructor OR
super("Call Parent"); // call parameterised super to call
parameterised parent constructor.
[Link]("Child class default Constructor");
}
void printNum(){
[Link](num);
[Link]([Link]); //prints the value of num of
parent class
}
@Override
public void foo(){
[Link]("Child class foo!");
[Link](); //Calls foo method of Parent class inside the
Overriden foo method of Child class.
}
}
Yes! There can be two or more static methods in a class with the same name but
differing input parameters.
The main method is always static because static members are those methods that
belong to the classes, not to an individual object. So if the main method will not be
static then for every object, It is available. And that is not acceptable by JVM. JVM
calls the main method based on the class name itself. Not by creating the object.
Because there must be only 1 main method in the java program as the execution
starts from the main method. So for this reason the main method is static.
No! Declaration of static methods having the same signature can be done in the
subclass but run time polymorphism can not take place in such cases.
Overriding or dynamic polymorphism occurs during the runtime, but the static methods
are loaded and looked up at the compile time statically. Hence, these methods cant be
overridden.
Static Methods and Static variables are those methods and variables that belong to
the class of the java program, not to the object of the class. This gets memory where
the class is loaded. And these can directly be called with the help of class names.
o For example - We have used mathematical functions in the java program like - max(),
min(), sqrt(), pow(), etc. And if we notice that, then we will find that we call it directly
with the class name. Like - [Link](), [Link](), etc. So that is a static method.
And Similarly static variables we have used like (length) for the array to get the length.
So that is the static method.
Static classes - A class in the java program cannot be static except if it is the inner
class. If it is an inner static class, then it exactly works like other static members of the
class.
The main objective of this process is to free up the memory space occupied by the
unnecessary and unreachable objects during the Java program execution by deleting
those unreachable objects.
This ensures that the memory resource is used efficiently, but it provides no guarantee
that there would be sufficient memory for the program execution.
Java Classloader is the program that belongs to JRE (Java Runtime Environment).
The task of ClassLoader is to load the required classes and interfaces to the JVM
when required.
Example- To get input from the console, we require the scanner class. And the
Scanner class is loaded by the ClassLoader.
Heap.
To copy the object's data, we have several methods like deep copy and shallow copy.
Example -
class Rectangle{
int length = 5;
int breadth = 3;
}
Shallow copy - The shallow copy only creates a new reference and points to the
same object. Example - For Shallow copy, we can do this by -
Now by doing this what will happen is the new reference is created with the name obj2
and that will point to the same memory location.
Deep Copy - In a deep copy, we create a new object and copy the old object value to
the new object. Example -
Both these objects will point to the memory location as stated below -
Now, if we change the values in shallow copy then they affect the other reference as
well. Let's see with the help of an example -
class Rectangle
{
int length = 5;
int breadth = 3;
}
public class Main
{
public static void main(String[] args) {
Rectangle obj1 = new Rectangle();
//Shallow Copy
Rectangle obj2 = obj1;
}
}
Output -
We can see that in the above code, if we change the values of object1, then the
object2 values also get changed. It is because of the reference.
Now, if we change the code to deep copy, then there will be no effect on object2 if it is
of type deep copy. Consider some snippets to be added in the above code.
class Rectangle
{
int length = 5;
int breadth = 3;
}
public class Main
{
public static void main(String[] args) {
Rectangle obj1 = new Rectangle();
//Shallow Copy
Rectangle obj2 = new Rectangle();
[Link] = [Link];
[Link] = [Link];
The above snippet will not affect the object2 values. It has its separate values. The
output will be
Now we see that we need to write the number of codes for this deep copy. So to
reduce this, In java, there is a method called clone().
The clone() will do this deep copy internally and return a new object. And to do this
we need to write only 1 line of code. That is - Rectangle obj2 = [Link]();
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.
Singleton classes are those classes, whose objects are created only once. And with
only that object the class members can be accessed.
Consider the water jug in the office and if every employee wants that water then they
will not create a new water jug for drinking water. They will use the existing one with
their own reference as a glass. So programmatically it should be implemented as -
class WaterJug{
private int waterQuantity = 500;
private WaterJug(){}
private WaterJug object = null;
In the above class, the Constructor is private so we cannot create the object of the
class. But we can get the object by calling the method getInstance(). And the
getInstance is static so it can be called without creating the object. And it returns the
object. Now with that object, we can call getWater() to get the water.
We can get the single object using this getInstance(). And it is static, so it is a thread-
safe singleton class. Although there are many ways to create a thread-safe singleton
class. So thread-safe classes can also be:
When singletons are written with double-checked locking, they can be thread-safe.
We can use static singletons that are initialized during class loading. Like we did in the
above example.
But the most straightforward way to create a thread-safe singleton is to use Java
enums.
We get a compile-time error in line 3. The error we will get in Line 3 is - integer
number too large. It is because the array requires size as an integer. And Integer
takes 4 Bytes in the memory. And the number (2241423798) is beyond the capacity of
the integer. The maximum array size we can declare is - (2147483647).
Because the array requires the size in integer, none of the lines (1, 2, and 4) will give
a compile-time error. The program will compile fine. But we get the runtime exception
in line 2. The exception is - NegativeArraySizeException.
Here what will happen is - At the time when JVM will allocate the required memory
during runtime then it will find that the size is negative. And the array size can’t be
negative. So the JVM will throw the exception.
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 = "InterviewBit";
String second = new String("InterviewBit");
// StringBuffer
StringBuffer third = new StringBuffer("InterviewBit");
// StringBuilder
StringBuilder fourth = new StringBuilder("InterviewBit");
Interface example:
The above program will give a compile-time error. The compiler will throw 2 errors in
this.
It is because abstract classes are incomplete classes that need to be inherited for
making their concrete classes. And on the other hand, the final keywords in class are
used for avoiding inheritance. So these combinations are not allowed in java.
Comparator is the interface in java that contains the compare method. And by
overloading the compare method, we can define that on what basis we need to
compare the values.
The statement in the context is completely False. The static methods have no
relevance with the objects, and these methods are of the class level. In the case of a
child class, a static method with a method signature exactly like that of the parent
class can exist without even throwing any compilation error.
Although both HashSet and TreeSet are not synchronized and ensure that duplicates
are not present, there are certain properties that distinguish a HashSet from a
TreeSet.
Implementation: For a HashSet, the hash table is utilized for storing the elements in
an unordered manner. However, TreeSet makes use of the red-black tree to store the
elements in a sorted manner.
Complexity/ Performance: For adding, retrieving, and deleting elements, the time
amortized complexity is O(1) for a HashSet. The time complexity for performing the
same operations is a bit higher for TreeSet and is equal to O(log n). Overall, the
performance of HashSet is faster in comparison to TreeSet.
Methods: hashCode() and equals() are the methods utilized by HashSet for making
comparisons between the objects. Conversely, compareTo() and compare() methods
are utilized by TreeSet to facilitate object comparisons.
Objects type: Heterogeneous and null objects can be stored with the help of
HashSet. In the case of a TreeSet, runtime exception occurs while inserting
heterogeneous objects or null objects.
10. Why is the character array preferred over string for storing
confidential information?
In Java, a string is basically immutable i.e. it cannot be modified. After its declaration,
it continues to stay in the string pool as long as it is not removed in the form of
garbage. In other words, a string resides in the heap section of the memory for an
unregulated and unspecified time interval after string value processing is executed.
As a result, vital information can be stolen for pursuing harmful activities by hackers if
a memory dump is illegally accessed by them. Such risks can be eliminated by using
mutable objects or structures like character arrays for storing any variable. After the
work of the character array variable is done, the variable can be configured to blank at
the same instant. Consequently, it helps in saving heap memory and also gives no
chance to the hackers to extract vital data.
JDK- For making java programs, we need some tools that are provided by JDK (Java
Development Kit). JDK is the package that contains various tools, Compiler, Java
Runtime Environment, etc.
JRE - To execute the java program we need an environment. (Java Runtime
Environment) JRE contains a library of Java classes + JVM. What are JAVA
Classes? It contains some predefined methods that help Java programs to use that
feature, build and execute. For example - there is a system class in java that contains
the print-stream method, and with the help of this, we can print something on the
console.
JVM - (Java Virtual Machine) JVM is a part of JRE that executes the Java program at
the end. Actually, it is part of JRE, but it is software that converts bytecode into
machine-executable code to execute on hardware.
12. What are the differences between JVM, JRE and JDK in Java?
Criteria JDK JRE JVM
Abbreviation Java Runtime
Java Development Kit Java Virtual Machine
Environment
Definition JVM is a platform-dependent,
JDK is a complete JRE is a software abstract machine comprising of 3
software development package providing specifications - document describing
kit for developing Java class libraries, the JVM implementation
Java applications. It JVM and all the requirements, computer program
comprises JRE, required components meeting the JVM requirements and
JavaDoc, compiler, to run the Java instance object for executing the Java
debuggers, etc. applications. byte code and provide the runtime
environment for execution.
Main JRE is mainly used
JDK is mainly used
Purpose for environment JVM provides specifications for all
for code development
creation to execute the implementations to JRE.
and execution.
the code.
Tools JDK provides tools JRE provides
JVM does not include any tools, but
provided like compiler, libraries and classes
instead, it provides the specification
debuggers, etc for required by JVM to
for implementation.
code development run the program.
Summary JRE = (JVM) +
JDK = (JRE) + JVM = Runtime environment to
Libraries to execute
Development tools execute Java byte code.
the application
13. What are the differences between HashMap and HashTable in Java?
HashMap HashTable
HashMap is not synchronized thereby making it HashTable is synchronized and hence it is
better for non-threaded applications. suitable for threaded applications.
Allows only one null key but any number of null in This does not allow null in both keys or
the values. values.
Supports order of insertion by making use of its Order of insertion is not guaranteed in
subclass LinkedHashMap. HashTable.
The term reflection is used for describing the inspection capability of a code on other
code either of itself or of its system and modify it during runtime.
Consider an example where we have an object of unknown type and we have a
method ‘fooBar()’ which we need to call on the object. The static typing system of Java
doesn't allow this method invocation unless the type of the object is known
beforehand. This can be achieved using reflection which allows the code to scan the
object and identify if it has any method called “fooBar()” and only then call the method
if needed.
Method methodOfFoo = [Link]().getMethod("fooBar", null);
[Link](fooObject, null);
Implementing a thread using the method of Runnable interface is more preferred and
advantageous as Java does not have support for multiple inheritances of classes.
start() method is used for creating a separate call stack for the thread execution.
Once the call stack is created, JVM calls the run() method for executing the thread in
that call stack.
16. What are the different types of Thread Priorities in Java? And what
is the default priority of a thread assigned by JVM?
There are a total of 3 different types of priority available in Java.
In Java, Thread with MAX_PRIORITY gets the first chance to execute. But the default
priority for any thread is NORM_PRIORITY assigned by JVM.
17. What is the difference between the program and the process?
18. What is the difference between the ‘throw’ and ‘throws’ keyword in
java?
The ‘throw’ keyword is used to manually throw the exception to the calling method.
And the ‘throws’ keyword is used in the function definition to inform the calling method
that this method throws the exception. So if you are calling, then you have to handle
the exception.
Example -
class Main {
public static int testExceptionDivide(int a, int b) throws
ArithmeticException{
if(a == 0 || b == 0)
throw new ArithmeticException();
return a/b;
}
public static void main(String args[]) {
try{
testExceptionDivide(10, 0);
}
catch(ArithmeticException e){
//Handle the exception
}
}
}
Constructor Method
Method is used for exposing the
Constructor is used for initializing the object state.
object's behavior.
Method should have a return type.
Constructor has no return type. Even if it does not return anything,
return type is void.
Method has to be invoked on the
Constructor gets invoked implicitly.
object explicitly.
If the constructor is not defined, then a default constructor is If a method is not defined, then the
provided by the java compiler. compiler does not provide it.
The name of the method can have
The constructor name should be equal to the class name.
any name or have a class name too.
A constructor cannot be marked as final because whenever a
A method can be defined as final
class is inherited, the constructors are not inherited. Hence,
but it cannot be overridden in its
marking it final doesn't make sense. Java throws compilation
subclasses.
error saying - modifier final not allowed here
A final variable if initialised inside
Final variable instantiations are possible inside a constructor
a method ensures that the variable
and the scope of this applies to the whole class and its
cant be changed only within the
objects.
scope of that method.
20. Identify the output of the below java program and Justify your
answer.
class Main {
public static void main(String args[]) {
Scaler s = new Scaler(5);
}
}
class InterviewBit{
InterviewBit(){
[Link](" Welcome to InterviewBit ");
}
}
class Scaler extends InterviewBit{
Scaler(){
[Link](" Welcome to Scaler Academy ");
}
Scaler(int x){
this();
super();
[Link](" Welcome to Scaler Academy 2");
}
}
The above code will throw the compilation error. It is because the super() is used to
call the parent class constructor. But there is the condition that super() must be the
first statement in the block. Now in this case, if we replace this() with super() then
also it will throw the compilation error. Because this() also has to be the first statement
in the block. So in conclusion, we can say that we cannot
use this() and super() keywords in the same block.
Java always works as a “pass by value”. There is nothing called a “pass by reference”
in Java. However, when the object is passed in any method, the address of the value
is passed due to the nature of object handling in Java. When an object is passed, a
copy of the reference is created by Java and that is passed to the method. The objects
point to the same memory location. 2 cases might happen inside the method:
Case 1: When the object is pointed to another location: In this case, the changes
made to that object do not get reflected the original object before it was passed to the
method as the reference points to another location.
For example:
class InterviewBitTest{
int num;
InterviewBitTest(int x){
num = x;
}
InterviewBitTest(){
num = 0;
}
}
class Driver {
public static void main(String[] args)
{
//create a reference
InterviewBitTest ibTestObj = new InterviewBitTest(20);
//Pass the reference to updateObject Method
updateObject(ibTestObj);
//After the updateObject is executed, check for the value of num in
the object.
[Link]([Link]);
}
public static void updateObject(InterviewBitTest ibObj)
{
// Point the object to new reference
ibObj = new InterviewBitTest();
// Update the value
[Link] = 50;
}
}
Output:
20
Case 2: When object references are not modified: In this case, since we have the
copy of reference the main object pointing to the same memory location, any changes
in the content of the object get reflected in the original object.
For example:
class InterviewBitTest{
int num;
InterviewBitTest(int x){
num = x;
}
InterviewBitTest(){
num = 0;
}
}
class Driver{
public static void main(String[] args)
{
//create a reference
InterviewBitTest ibTestObj = new InterviewBitTest(20);
//Pass the reference to updateObject Method
updateObject(ibTestObj);
//After the updateObject is executed, check for the value of num in
the object.
[Link]([Link]);
}
public static void updateObject(InterviewBitTest ibObj)
{
// no changes are made to point the ibObj to new location
// Update the value of num
[Link] = 50;
}
}
Output:
50
‘IS-A’ relationship is another name for inheritance. When we inherit the base class
from the derived class, then it forms a relationship between the classes. So that
relationship is termed an ‘IS-A’ Relationship.
Example - Consider a Television (Typical CRT TV). Now another Smart TV that is
inherited from television class. So we can say that the Smart iv is also a TV. Because
CRT TV things can also be done in the Smart TV.
So here ‘IS-A’ Relationship formed. [ SmartTV ‘IS-A’ TV ].
In order to achieve this, the attribute can be declared along with the usage
of transient keyword as shown below:
In the above example, all the fields except someInfo can be serialized.
25. What happens if the static modifier is not included in the main
method signature in Java?
There wouldn't be any compilation error. But then the program is run, since the JVM
cant map the main method signature, the code throws “NoSuchMethodError” error at
the runtime.
26. Consider the below program, identify the output, and also state the
reason for that.
public class Main{
public static void main(String[] args) {
[Link](" Hello. Main Method. ");
}
public static void main(int[] args) {
[Link](" Hello. Main Method2. ");
}
}
The output of the above program will be Hello. Main Method. This is because JVM
will always call the main method based on the definition it already has. Doesn't matter
how many main methods we overload it will only execute one main method based on
its declaration in JVM.
In java multithreading, the main() threads are always non-daemon threads. And there
is no way we can change the nature of the non-daemon thread to the daemon thread.
28. What happens if there are multiple main methods inside one class
in Java?
The program can't compile as the compiler says that the method has been already
defined inside the class.
29. What do you understand by Object Cloning and how do you achieve
it in Java?
It is the process of creating an exact copy of any object. In order to support this, a java
class has to implement the Cloneable interface of [Link] package and override the
clone() method provided by the Object class the syntax of which is:
In case the Cloneable interface is not implemented and just the method is overridden,
it results in CloneNotSupportedException in Java.
Exceptions are runtime errors. Suppose we are making an android application with
java. And it all works fine but there is an exceptional case when the application tries to
get the file from storage and the file doesn’t exist (This is the case of exception in
java). And if this case is not handled properly then the application will crash. This will
be a bad experience for users. This is the type of error that cannot be controlled by
the programmer. But programmers can take some steps to avoid this so that the
application won’t crash. The proper action can be taken at this step.
No, it is not necessary for a catch block to be present after a try block. - A try block
should be followed either by a catch block or by a finally block. If the exceptions
likelihood is more, then they should be declared using the throws clause of the
method.
33. Will the finally block get executed when the return statement is
written at the end of try block and catch block as shown below?
public int someMethod(int i){
try{
//some statement
return 1;
}catch(Exception e){
//some statement
return 999;
}finally{
//finally block statements
}
}
finally block will be executed irrespective of the exception or not. The only case where
finally block is not executed is when it encounters ‘[Link]()’ method anywhere in
try/catch block.
Yes, the concept can be termed as constructor chaining and can be achieved
using this().
35. Contiguous memory locations are usually used for storing actual
values in an array but not in ArrayList. Explain.
In the case of ArrayList, data storing in the form of primitive data types (like int, float,
etc.) is not possible. The data members/objects present in the ArrayList have
references to the objects which are located at various sites in the memory. Thus,
storing of actual objects or non-primitive data types (like Integer, Double, etc.) takes
place in various memory locations.
However, the same does not apply to the arrays. Object or primitive type values can
be stored in arrays in contiguous memory locations, hence every element does not
require any reference to the next element.
36. Why does the java array index start with 0?
It is because the 0 index array avoids the extra arithmetic operation to calculate the
memory address.
Example - Consider the array and assume each element takes 4-byte memory space.
Then the address will be like this -
Now if we want to access index 4. Then internally java calculates the address using
the formula-
Now if we apply the same formula here. Then we get - 116 as the starting address of
the 4th index. Which is wrong. Then we need to apply formula - [Base Address +
((index-1) * no_of_bytes)].
And for calculating this, an extra arithmetic operation has to be performed. And
consider the case where millions of addresses need to be calculated, this causes
complexity. So to avoid this, ) the index array is supported by java.
37. Why is the remove method faster in the linked list than in an array?
In the linked list, we only need to adjust the references when we want to delete the
element from either end or the front of the linked list. But in the array, indexes are
used. So to manage proper indexing, we need to adjust the values from the array So
this adjustment of value is costlier than the adjustment of references.
Example - To Delete from the front of the linked list, internally the references
adjustments happened like this.
The only thing that will change is that the head pointer will point to the head’s next
node. And delete the previous node. That is the constant time operation.
38. How many overloaded add() and addAll() methods are available in
the List interface? Describe the need and uses.
There are a total of 4 overloaded methods for add() and addAll() methods available in
List Interface. The below table states the description of all.
39. How does the size of ArrayList grow dynamically? And also state
how it is implemented internally.
ArrayList is implemented in such a way that it can grow dynamically. We don't need to
specify the size of ArrayList. For adding the values in it, the methodology it uses is -
1. Consider initially that there are 2 elements in the ArrayList. [2, 3].
2. If we need to add the element into this. Then internally what will happen is-
ArrayList will allocate the new ArrayList of Size (current size + half of the current size).
And add the old elements into the new. Old - [2, 3], New - [2, 3, null].
Then the new value will be inserted into it. [2, 3, 4, null]. And for the next time, the
extra space will be available for the value to be inserted.
3. This process continues and the time taken to perform all of these is considered as
the amortized constant time.
This is how the ArrayList grows dynamically. And when we delete any entry from the
ArrayList then the following steps are performed -
1. It searches for the element index in the array. Searching takes some time. Typically
it’s O(n) because it needs to search for the element in the entire array.
2. After searching the element, it needs to shift the element from the right side to fill
the index.
So this is how the elements are deleted from the ArrayList internally. Similarly, the
search operations are also implemented internally as defined in removing elements
from the list (searching for elements to delete).
Multiple-inheritance is not possible in Java. Classes can only extend from one
superclass. In cases where multiple functionalities are required, for example - to read
and write information into the file, the pattern of composition is preferred. The writer,
as well as reader functionalities, can be made use of by considering them as the
private members.
Composition assists in attaining high flexibility and prevents breaking of encapsulation.
Unit testing is possible with composition and not inheritance. When a developer wants
to test a class composing a different class, then Mock Object can be created for
signifying the composed class to facilitate testing. This technique is not possible with
the help of inheritance as the derived class cannot be tested without the help of the
superclass in inheritance.
The loosely coupled nature of composition is preferable over the tightly coupled nature
of inheritance.
package comparison;
public class Top {
public int start() {
return 0;
}
}
class Bottom extends Top {
public int stop() {
return 0;
}
}
In the above example, inheritance is followed. Now, some modifications are done to
the Top class like this:
If the new implementation of the Top class is followed, a compile-time error is bound
to occur in the Bottom class. Incompatible return type is there for the [Link]()
function. Changes have to be made to either the Top or the Bottom class to ensure
compatibility. However, the composition technique can be utilized to solve the given
problem:
class Bottom {
Top par = new Top();
public int stop() {
[Link]();
[Link]();
return 0;
}
}
‘>>’ Bitwise Right Shift Operator- This operator shifts each bit to its right position.
And this maintains the signed bit.
‘>>>’ Bitwise Right Shift Operator with trailing zero- This operator also shifts each
bit to its right. But this doesn’t maintain the signed bit. This operator makes the Most
significant bit to 0.
Consider the University as a class that has some departments in it. So the university
will be the container object. And departments in it will contain objects. Now in this
case, if the container object destroys then the contained objects will also get
destroyed automatically. So here we can say that there is a strong association
between the objects. So this Strong Association is called Composition.
Now consider one more example. Suppose we have a class department and there are
several professors' objects there in the department. Now if the department class is
destroyed then the professor's object will become free to bind with other objects.
Because container objects (Department) only hold the references of contained objects
(Professor’s). So here is the weak association between the objects. And this weak
association is called Aggregation.
The checking() function will return true as the same content is referenced by both the
variables.
Conversely, when a String formation takes place with the help of a new() operator,
interning does not take place. The object gets created in the heap memory even if the
same content object is present.
The checking() function will return false as the same content is not referenced by both
the variables.
Both ‘new’ and ‘newInstance()’ operators are used to creating objects. The difference
is- that when we already know the class name for which we have to create the object
then we use a new operator. But suppose we don’t know the class name for which we
need to create the object, Or we get the class name from the command line argument,
or the database, or the file. Then in that case we use the ‘newInstance()’ operator.
Yes, it is possible for the program to go out of memory in spite of the presence of a
garbage collector. Garbage collection assists in recognizing and eliminating those
objects which are not required in the program anymore, in order to free up the
resources used by them.
In a program, if an object is unreachable, then the execution of garbage collection
takes place with respect to that object. If the amount of memory required for creating a
new object is not sufficient, then memory is released for those objects which are no
longer in the scope with the help of a garbage collector. The memory limit is exceeded
for the program when the memory released is not enough for creating new objects.
Moreover, exhaustion of the heap memory takes place if objects are created in such a
manner that they remain in the scope and consume memory. The developer should
make sure to dereference the object after its work is accomplished. Although the
garbage collector endeavors its level best to reclaim memory as much as possible,
memory limits can still be exceeded.
Synchronization assists in resolving the issue and the resource is shared by a single
thread at a time. Let’s take an example to understand it more clearly. For example,
you have a URL and you have to find out the number of requests made to it. Two
simultaneous requests can make the count erratic.
No synchronization:
package anonymous;
public class Counting {
private int increase_counter;
public int increase() {
increase_counter = increase_counter + 1;
return increase_counter;
}
}
If a thread Thread1 views the count as 10, it will be increased by 1 to 11.
Simultaneously, if another thread Thread2 views the count as 10, it will be increased
by 1 to 11. Thus, inconsistency in count values takes place because the expected final
value is 12 but the actual final value we get will be 11.
With synchronization:
package anonymous;
public class Counting {
private int increase_counter;
public synchronized int increase() {
increase_counter = increase_counter + 1;
return increase_counter;
}
}
If a thread Thread1 views the count as 10, it will be increased by 1 to 11, then the
thread Thread2 will view the count as 11, it will be increased by 1 to 12. Thus,
consistency in count values takes place.
Ability to provide ... is a feature called varargs (variable arguments) which was
introduced as part of Java 5.
The function having ... in the above example indicates that it can receive multiple
arguments of the datatype String.
For example, the fooBarMethod can be called in multiple ways and we can still have
one method to process the data as shown below:
fooBarMethod("foo", "bar");
fooBarMethod("foo", "bar", "boo");
fooBarMethod(new String[]{"foo", "var", "boo"});
public void myMethod(String... variables){
for(String variable : variables){
// business logic
}
}
9. What will be the output of the below java program and define the
steps of Execution of the java program with the help of the below
code?
class InterviewBit{
int i;
static int j;
{
[Link](" Instance Block 1. Value of i = "+i);
}
static{
[Link](" Static Block 1. Value of j = "+j);
method_2();
}
{
i = 5;
}
static{
j = 10;
}
InterviewBit(){
[Link](" Welcome to InterviewBit ");
}
public static void main(String[] args){
InterviewBit ib = new InterviewBit();
}
public void method_1(){
[Link](" Instance method. ");
}
static{
[Link](" Static Block 2. Value of j = "+j);
}
{
[Link](" Instance Block 2. Value of i = "+i);
method_1();
}
public static void method_2(){
[Link](" Static method. ");
}
}
In above steps from 4 to 6, will be executed for every object creation. If we create
multiple objects then for every object these steps will be performed.
Now from the above code, the execution will happen like this -
static int j.
static block.
main method.
static method_2.
During identification, the JVM will assign the default value in the static int j variable.
Then it is currently in the state of reading and indirectly writing. Because the original
value is not assigned.
2. In the next step, it will execute the static block and assign the value in static
variables.
First static block it will print and because execution from top to bottom and original
value in j is not assigned. So it will print the default value of 0.
After executing static block 1. It will execute the static method_1 because it is called
from the static block 1.
Then it will assign the original value of 5 in the j variable. And executes the remaining
static block.
3. Now it will execute the main method. In which it will create an object for the class
InterviewBit. And then the execution of instances will happen.
int i.
Instance block 1.
Instance method_1.
Like a static variable, the instance variable also has been initialized with the default
value 0 and will be in the state of reading and writing indirectly.
5. It will execute the instance methods and assign the original value to the instance
variable.
Prints the Instance block 1. And the current value of i is not assigned till now, so it will
print 0.
Assign the original value to i. Then print instance block 2. And after that instance
method will be called and printed because it is being called in the instance block.
6. And at the last step, the constructor will be invoked and the lines will be executed in
the constructor.
So if we justify the statement, then we can say that if we want to print anything on the
console then we need to call the println() method that was present in PrintStream
class. And we can call this using the output object that is present in the System class.
New – When the instance of the thread is created and the start() method has not been
invoked, the thread is considered to be alive and hence in the NEW state.
Runnable – Once the start() method is invoked, before the run() method is called by
JVM, the thread is said to be in RUNNABLE (ready to run) state. This state can also
be entered from the Waiting or Sleeping state of the thread.
Running – When the run() method has been invoked and the thread starts its
execution, the thread is said to be in a RUNNING state.
Non-Runnable (Blocked/Waiting) – When the thread is not able to run despite the
fact of its aliveness, the thread is said to be in a NON-RUNNABLE state. Ideally, after
some time of its aliveness, the thread should go to a runnable state.
o A thread is said to be in a Blocked state if it wants to enter synchronized code but it is
unable to as another thread is operating in that synchronized block on the same
object. The first thread has to wait until the other thread exits the synchronized block.
o A thread is said to be in a Waiting state if it is waiting for the signal to execute from
another thread, i.e it waits for work until the signal is received.
Terminated – Once the run() method execution is completed, the thread is said to
enter the TERMINATED step and is considered to not be alive.
The following flowchart clearly explains the lifecycle of the thread in Java.
12. What could be the tradeoff between the usage of an unordered array
versus the usage of an ordered array?
The main advantage of having an ordered array is the reduced search time complexity
of O(log n) whereas the time complexity in an unordered array is O(n).
The main drawback of the ordered array is its increased insertion time which is O(n)
due to the fact that its element has to reordered to maintain the order of array during
every insertion whereas the time complexity in the unordered array is only O(1).
Considering the above 2 key points and depending on what kind of scenario a
developer requires, the appropriate data structure can be used for implementation.
13. Is it possible to import the same class or package twice in Java and
what happens to it during runtime?
This is a big NO. We need to understand that the importing of the sub-packages of a
package needs to be done explicitly. Importing the parent package only results in the
import of the classes within it and not the contents of its child/sub-packages.
NO. The control of the program post [Link](0) is immediately gone and the
program gets terminated which is why the finally block never gets executed.
Marker interfaces, also known as tagging interfaces are those interfaces that have no
methods and constants defined in them. They are there for helping the compiler and
JVM to get run time-related information regarding the objects.
This is a convenient means of initializing any collections in Java. Consider the below
example.
import [Link];
import [Link];
doSomething(stringSets);
}
In the above example, we see that the stringSets were initialized by using double
braces.
The first brace does the task of creating an anonymous inner class that has the
capability of accessing the parent class’s behavior. In our example, we are creating
the subclass of HashSet so that it can use the add() method of HashSet.
The second braces do the task of initializing the instances.
Care should be taken while initializing through this method as the method involves the
creation of anonymous inner classes which can cause problems during the garbage
collection or serialization processes and may also result in memory leaks.
18. Why is it said that the length() method of String class doesn't return
accurate results?
The length method returns the number of Unicode units of the String. Let's understand
what Unicode units are and what is the confusion below.
We know that Java uses UTF-16 for String representation. With this Unicode, we need
to understand the below two Unicode related terms:
o Code Point: This represents an integer denoting a character in the code space.
o Code Unit: This is a bit sequence used for encoding the code points. In order to do
this, one or more units might be required for representing a code point.
Under the UTF-16 scheme, the code points were divided logically into 17 planes and
the first plane was called the Basic Multilingual Plane (BMP). The BMP has classic
characters - U+0000 to U+FFFF. The rest of the characters- U+10000 to U+10FFFF
were termed as the supplementary characters as they were contained in the remaining
planes.
o The code points from the first plane are encoded using one 16-bit code unit
o The code points from the remaining planes are encoded using two code units.
Now if a string contained supplementary characters, the length function would count
that as 2 units and the result of the length() function would not be as per what is
expected.
“bit” would have been the result printed if the letters were used in double-quotes (or
the string literals). But the question has the character literals (single quotes) being
used which is why concatenation wouldn't occur. The corresponding ASCII values of
each character would be added and the result of that sum would be printed.
The ASCII values of ‘b’, ‘i’, ‘t’ are:
‘b’ = 98
‘i’ = 105
‘t’ = 116
20. What are the possible ways of making object eligible for garbage
collection (GC) in Java?
First Approach: Set the object references to null once the object creation purpose is
served.
Second Approach: Point the reference variable to another object. Doing this, the
object which the reference variable was referencing before becomes eligible for GC.
21. In the below Java Program, how many objects are eligible for
garbage collection?
class Main{
public static void main(String[] args){
int[][] num = new int[3][];
num[0] = new int[5];
num[1] = new int[2];
num[2] = new int[3];
In the above program, a total of 7 objects will be eligible for garbage collection. Let’s
visually understand what's happening in the code.
In the above figure on line 3, we can see that on each array index we are declaring a
new array so the reference will be of that new array on all the 3 indexes. So the old
array will be pointed to by none. So these three are eligible for garbage collection. And
on line 4, we are creating a new array object on the older reference. So that will point
to a new array and older multidimensional objects will become eligible for garbage
collection.
22. What is the best way to inject dependency? Also, state the reason.
Setters are mostly recommended for optional dependencies injection, and constructor
arguments are recommended for mandatory ones. This is because constructor
injection enables the injection of values into immutable fields and enables reading
them more easily.
23. How we can set the spring bean scope. And what supported scopes
does it have?
A scope can be set by an annotation such as the @Scope annotation or the "scope"
attribute in an XML configuration file. Spring Bean supports the following five scopes:
Singleton
Prototype
Request
Session
Global-session
Java Design patterns are categorized into the following different types. And those are
also further categorized as
Structural patterns:
Adapter
Bridge
Filter
Composite
Decorator
Facade
Flyweight
Proxy
Behavioral patterns:
Interpreter
Template method/ pattern
Chain of responsibility
Command pattern
Iterator pattern
Strategy pattern
Visitor pattern
J2EE patterns:
MVC Pattern
Data Access Object pattern
Front controller pattern
Intercepting filter pattern
Transfer object pattern
Creational patterns:
Factory method/Template
Abstract Factory
Builder
Prototype
Singleton
The Java Garbage Collector (GC) typically removes unused objects when they are no
longer required, but when they are still referenced, the unused objects cannot be
removed. So this causes the memory leak problem. Example - Consider a linked list
like the structure below -
In the above image, there are unused objects that are not referenced. But then also
Garbage collection will not free it. Because it is referencing some existing referenced
object. So this can be the situation of memory leak.
26. Assume a thread has a lock on it, calling the sleep() method on that
thread will release the lock?
A thread that has a lock won't be released even after it calls sleep(). Despite the
thread sleeping for a specified period of time, the lock will not be released.
return [Link]([Link]()- 1) +
getReverseWord([Link](0, [Link]() - 1));
}
}
In the above code, we are printing the base 2 Fibonacci values 0 and 1. And then
based on the length of Fibonacci to be printed, we are using the helper function to
print that.
3. Write a Java program to check if the two strings are anagrams.
The main idea is to validate the length of strings and then if found equal, convert the
string to char array and then sort the arrays and check if both are equal.
import [Link];
import [Link];
public class InterviewBit {
public static void main(String[] args) {
Scanner s = new Scanner([Link]);
//Input from two strings
[Link]("First String: ");
String string1 = [Link]();
[Link]("Second String: ");
String string2 = [Link]();
// check for the length
if([Link]() == [Link]()) {
// convert strings to char array
char[] characterArray1 = [Link]();
char[] characterArray2 = [Link]();
// sort the arrays
[Link](characterArray1);
[Link](characterArray2);
// check for equality, if found equal then anagram, else not an anagram
boolean isAnagram = [Link](characterArray1, characterArray2);
[Link]("Anagram: "+ isAnagram);
}
}
Idea is to find the sum of n natural numbers using the formula and then finding the
sum of numbers in the given array. Subtracting these two sums results in the number
that is the actual missing number. This results in O(n) time complexity and O(1) space
complexity.
public class IBMissingNumberProblem {
int[] array={4,3,8,7,5,2,6};
int missingNumber = findMissingNum(array);
[Link]("Missing Number is "+ missingNumber);
}
We have created the exception class named with CustomException and called the
base exception constructor with the error message that we want to print. And to avoid
handling exceptions in the main method, we have used the throws keyword in the
method declaration.
//Pointers.
int i = 0, j = [Link]()-1;
In the above code, we are storing the last character from the string to the first and the
first value to the last in the output character array. And doing the same thing in the
loop for the remaining 2nd to n-1 characters. This is how the string will be reversed.
9. Write a Java program to rotate arrays 90 degree clockwise by taking
matrices from user input.
mport [Link];
public class InterviewBit
{
public static void main(String[] args) {
Scanner sc = new Scanner([Link]);
int no;
[Link]("Enter size of Array : ");
no = [Link]();
int[][] a = new int[no][no];
[Link]("Enter "+ no*no+" Element Array : ");
[Link]("\n");
//Rotation
//Transpose
for(int i = 0; i < no; i++){
for(int j = i; j < no; j++){
int temp = a[i][j];
a[i][j] = a[j][i];
a[j][i] = temp;
}
}
In the above code, for rotating the matrix to 90 degrees we are first transposing the
matrix so the row becomes the column. And after that, we are reversing each row in
the matrix. So this is how the matrix got rotated.
10. Write a java program to check if any number given as input is the
sum of 2 prime numbers.
Example :
Input - 18
Output -
18 = 13 + 5
18 = 11 + 7
11. Write a Java program for solving the Tower of Hanoi Problem.
public class InterviewBit
{
//Recursive Method for Solving the Tower of hanoi.
private static void TOH(char source, char auxiliary, char destination,
int numOfDisk){
if (numOfDisk > 0){
TOH(source, destination, auxiliary, numOfDisk-1);
[Link]("Move 1 disk from "+source+" to
"+destination+" using "+auxiliary+".");
TOH(auxiliary, source, destination, numOfDisk-1);
}
}
public static void main(String[] args) {
TOH('A','B','C', 3);
}
}
In the above code we are first moving the n-1 disk from Tower A to Tower B, then
moving that nth disk from Tower A to Tower C, and finally, the remaining n-1 disk
from Tower B to Tower C. And we are doing this recursively for the n-1 disk.
//Calculating Mid.
int mid = (low + high)/2;
//Base Case.
if(low > high)
return false;
In the above code, we are finding the middle element each time and checking if the
element is in the middle or not. If it is not, then we check on which side from the
middle it exists. And Recursively searching on the particular subarray. So this way we
are reducing the search space by 2 every time. So the search time is very low.
String in Java is immutable, so its value can never change. When you do s += "b",
Java creates a new String object with "ab" and leaves the old "a" object as it is. That’s
why repeated joining of strings creates many extra objects. For many joins,
StringBuilder is faster and memory-friendly.
2. Why can == be true for some strings and false for others?
== checks memory reference, not value. Java sometimes reuses strings from a
special pool, so two same literals may point to the same object and == becomes true.
But if strings are created using new String(), they are different objects, so == becomes
false.
3. What happens if you call return in try and finally also return?
If both try and finally have returned, the one in the end always wins. Java executes
finally at the end no matter what happens in try or catch. So the return value from try is
ignored and replaced by the return from finally.
If two overloaded methods are equally good matches for a call, Java cannot decide
which one to use. This usually happens with null, type casting, or similar parameter
types. So the compiler throws an “ambiguous method call” error.
You can overload the main() method with different parameter types or counts.
However, the JVM only looks for the standard signature public static void main(String[]
args) to start execution. All other overloaded versions will not run automatically and
must be called from the main one.
When you remove the first element from an ArrayList, all remaining elements shift
one position to the left. This shifting takes time because it copies each element. That’s
why removing from the beginning is slow for large lists.
final is used to stop change, inheritance, or overriding. finally is a block that always
runs after try-catch. finalize is a method called before garbage collection, but its
execution is not guaranteed.
9. What’s the difference between throw and throws?
throw is used inside code to actually send an exception. throws is written in method
signature to say an exception might happen. One is action, the other is a warning.
10. Why does HashMap allow one null key, but Hashtable doesn’t?
HashMap is newer and designed to allow one null key and many null values.
Hashtable is older and does not allow any null keys or values. This was done to avoid
confusion in old thread-safe designs.
The first thing to check is memory usage to see if it keeps growing over time, which
may indicate a memory leak. Then object creation is reviewed to see if too many
objects are being created and not released. Application logs are checked because
excessive logging can slow down performance. Database calls are also reviewed to
find slow queries or stuck connections. Finally, CPU usage is monitored to identify any
background tasks consuming too many resources.
One common cause is too much caching where data keeps growing without limits.
Another reason is large collections like lists or maps holding data longer than needed.
Not closing resources such as database connections, streams, or files can also cause
memory issues. Sometimes infinite loops keep adding objects to memory. Poor
garbage collection tuning can also lead to this error.
4. Multiple users update the same record - how do you avoid wrong
data?
One way is using database locks so only one user can update the record at a time.
Another approach is versioning, where updates fail if the data has changed since it
was last read. Atomic updates help ensure data changes happen safely in one step.
Transactions are also used to keep updates consistent. These methods prevent users
from overwriting each other’s changes.
The job is designed to be idempotent so running it multiple times does not create
duplicate results. A marker such as a processed ID or status is stored in the database.
Before doing any work, the job checks whether the task has already been completed.
If it is already processed, the job safely skips it. This ensures correct results even if
the job runs twice.
6. You must handle 1 lakh requests per minute what changes in code or
design?
Connection pooling is used so new connections are not created for every request.
Caching is added to reduce repeated database or external API calls. Heavy
processing is moved out of the request flow whenever possible. Asynchronous
processing is used for non-critical tasks. These changes help the system remain fast
and stable under high load.
Resources are always closed in a finally block to ensure they are released. In modern
Java, try-with-resources is preferred for cleaner and safer code. This guarantees that
files, streams, and database connections are closed automatically. Even if an
exception occurs, resources are still freed. This prevents memory and connection
leaks.
Stack memory is used for method calls and local variables, and it works in a very fast
way. Each thread has its own stack, so data is not shared. Heap memory is used for
objects and is shared across the application. Objects live longer in heap compared to
stack variables. Stack is small and fast, heap is bigger but slower. Stack memory is
cleared automatically when a method ends.
A memory leak happens when objects are not needed but still kept in memory. For
example, a static list keeps adding objects and is never cleared. Even though GC
exists, it cannot remove these objects because they are still referenced. Over time,
memory usage keeps growing. This can crash the app. Long-running apps suffer the
most from leaks.
Memory usage is reduced by clearing caches that are no longer needed. Object
references are removed once the work is completed so they can be garbage collected.
Files, database connections, and streams are always closed properly. Storing large
objects for a long time is avoided unless necessary. Regular memory monitoring helps
identify and fix issues early.
Strong references keep objects in memory as long as they exist. Weak references
allow GC to remove the object when memory is needed. Weak references are often
used in caches.
OutOfMemoryError means the JVM cannot allocate more memory and the app may
crash. App slowness usually means high CPU, heavy GC, or slow DB calls. Slow apps
still run, but poorly. OOM is a serious failure. They are related but not the same
problem. A slow app can eventually lead to OOM if ignored.
8. When does GC run?
GC runs when the JVM decides memory needs to be freed. Developers cannot control
the exact timing. It usually runs when memory is low. You can request GC, but it may
not run immediately. The JVM manages this automatically. Different GC algorithms
behave differently.
LTS stands for Long Term Support. It means the Java version will be supported for a
long time. Updates and fixes are provided regularly. Teams choose LTS to reduce
risk. It helps keep applications stable over time.
var allows Java to automatically figure out the variable type. It is used only for local
variables inside methods. This reduces boilerplate code. It improves readability when
the type is obvious.
Example: var total = 100;
Java 11 introduced new String methods like isBlank, lines, and strip. These help
handle common string tasks easily. They reduce the need for extra checks and
trimming logic. Code becomes cleaner and shorter. Developers use them often in real
projects.
Java 11 added a modern built-in HTTP client. It supports HTTP/2 and asynchronous
requests. Earlier, developers relied on third-party libraries. Now basic HTTP calls are
simpler to write. This improves performance and readability.
Some older dependencies may not work properly with Java 11. Build tools like Maven
or Gradle might need updates. A few APIs were deprecated or removed. Testing is
very important after migration. Most issues are dependency-related.
The design starts by defining clear resources and meaningful URLs based on the
business domain. Correct HTTP methods like GET, POST, PUT, and DELETE are
chosen for each operation. Proper HTTP status codes are returned for both success
and error cases. Input validation is added at the request level to prevent invalid data.
Controllers are kept thin, while business logic is handled in service classes. Error
responses are kept consistent across all APIs.
Authentication is about verifying who the user is. Authorization decides what the user
is allowed to access. A user must be authenticated before authorization is checked. In
Java applications, this is commonly handled using Spring Security. Filters handle
authentication, while roles or permissions control access. Both are important for
secure systems.
3. How do you handle database transactions safely in a Java backend?
4. What causes N+1 queries in ORM like Hibernate and how do you fix
it?
N+1 queries happen when a parent list is loaded first and child data is fetched one by
one. This creates many unnecessary database calls. It usually occurs with lazy
loading. To fix it, I use fetch joins or entity graphs. Batch fetching can also reduce
queries. This improves performance significantly.
API latency is improved by caching frequently accessed data. Payload sizes are
reduced by returning only required fields. Pagination is added to avoid sending large
responses at once. Database queries and indexes are optimized for faster access.
Connections are reused through pooling. Heavy processing is moved to asynchronous
or background tasks.
API versioning is done using URL paths or request headers. Backward compatibility is
maintained wherever possible. Breaking changes are introduced only in new versions.
Older versions are deprecated gradually instead of being removed suddenly. Clear
timelines are shared with consumers to ensure smooth migration.
7. How do you approach debugging a production issue end to end?
The process starts by checking logs, metrics, and monitoring dashboards. Distributed
traces are used to identify slow or failing services. The issue is reproduced with
minimal data when possible. The problematic layer, such as UI, API, or database, is
isolated. Fixes are validated with tests. Monitoring confirms stability after release.
8. What testing mix do you typically aim for in full stack work?
Unit tests are used to validate core business logic. Integration tests cover API
endpoints and database interactions. End-to-end tests are added for critical user
flows. The goal is to balance coverage without slowing down builds. Fast feedback is
prioritized. This testing mix provides confidence before deployment.
9. How do you handle CORS and security headers in a full stack setup?
Allowed origins and HTTP methods are configured carefully. Wildcards are avoided for
authenticated APIs. CORS rules are applied at the gateway or backend level. Security
headers are added to protect against common web attacks. All settings are reviewed
carefully for production safety. This ensures secure communication.
10. How do you package and deploy a Java full stack app?