Grokking The Java Developer Interview More Than 200 Questions To Crack The Java, Spring, SpringBoot & Hibernate Interview-1-200

Download as pdf or txt
Download as pdf or txt
You are on page 1of 200

Grokking The Java Developer Interview

More Than 200 Questions To Crack The Java, Spring,


SpringBoot
& Hibernate Interview

JATIN ARORA
GROKKING THE JAVA DEVELOPER INTERVIEW
COPYRIGHT © 2020 BY JATIN ARORA.
All rights reserved. No part of this book may be reproduced,
distributed, or transmitted in any form or by any means, including
photocopying, recording or other electronic or mechanical
methods, without the prior written permission of the author,
except in the case of brief quotations embodied in critical reviews
and certain other non-commercial uses permitted by copyright
law.
For permission or any other information, contact me at:
[email protected]
Preface
Grokking The Java Developer Interview helps you to crack a Java, Spring &
Hibernate interview.
This book covers enough details of a Java/Spring topic that will surely help
the absolute beginners and if you are already familiar with Java & Spring,
then this book will help you to brush-up on the concepts.
The book has more than 200 questions that are frequently asked during an
interview for Java, Spring, SpringBoot & Hibernate profile. Some of the
important topics like Multi-threading, Collection framework, Singleton
Pattern, SpringBoot Annotations and many more are covered in detail. Most
of these topics are explained with code examples that will help you to
quickly grasp the concept.

Who is this book for?


This book is for you if you are either preparing for an interview, planning to
move into this field in future, brushing up your Java & Spring skills or just
want to get an in-depth overview of the field. This book provides the most
important and frequently asked questions along with their solutions.
Who is this book NOT for?
This book is not for you if you are looking for an in-depth study of Java or
Spring. The objective of this book is not to discuss the ongoing research or
challenges in this industry or serve as a substitute for a course book.
If you follow this book diligently, you would be better equipped to face any
Java interview. Whether you are a beginner or an intermediate level expert
in Java, this book has enough juice for you.

This book contains a lot of code examples, most of the code snippets are
displayed in image format that you can zoom-in and out of. However, if
some image is not clearly visible on your device, you can also refer to the
GitHub repository for this book. The GitHub repo contains all of the snippets
shown in this book and it can be found at:
https://github.com/reachjatin/Grokking-The-Java-Developer-
Interview

Contact Information
I would love to hear from you.
For feedback or queries, you can contact me at
[email protected]

Your valuable suggestions to improve the book are always welcomed.


I wish you all the best and I am confident that this book will help you in
making that job switch that you are looking for.
Happy Learning, Cheers :)
-Jatin Arora
Acknowledgements
I thank my brother, Sumit Kumar, for encouraging me to take up this project.
From reading early drafts to advising me on the structure of the book to
making sure that it was written in a manner that was coherent, organized
and engaging at the same time, his role has been pivotal in the making of
this book.
To elaborate a little on his background, Sumit is an UChicago Alum, and
presently working for Amazon, Seattle as a Research Scientist at Alexa AI. He
has also worked with Samsung, India as a Lead Engineer. He is an active
blogger and regularly post articles on Data structures and Algorithms,
System Design, NLP and many more interesting topics. You can find those at:
https://medium.com/@sumit.arora
https://blog.reachsumit.com

To Sumit, for his patience in reading through various preliminary versions of


this book, and his vital suggestions. Thank you brother for never saying no to
my numerous feedback requests and providing all the constructive criticism.
I dedicate this book to him.
I would like to express my sincere gratitude to my family, friends, and
everyone who motivated me throughout. Thanks for the support, the honest
feedback, and for everything else that has helped to make this book possible
in its current form.

-Jatin Arora
Table of Contents
Preface
Acknowledgements
Question 1: What are the 4 pillars of OOPS?
Question 2: What is an abstract class?
Question 3: Does Abstract class have constructor?
Question 4: What is an Interface?
Question 5: Difference between abstract class and interface
Question 6: What to choose – interface or abstract class
Question 7: Why Java 8 has introduced default methods?
Question 8: Why Java 8 has introduced static methods?
Question 9: Why Java does not allow multiple inheritance?
Question 10: What are the rules for Method Overloading and Method
Overriding?
Question 11: Can we override final methods?
Question 12: Can constructors and private methods be overridden?
Question 13: What is final keyword and where it can be used?
Question 14: What is exception and exception handling?
Question 15: Difference between error and exception
Question 16: What are the different types of exceptions?
Question 17: How exception handling is done in java?
Question 18: Can we write a try block without catch block?
Question 19: How to handle multiple exceptions together?
Question 20: When finally block will not get executed
Question 21: Difference between throw and throws keyword. And discuss
Exception Propagation
Question 22: Exception handling w.r.t. method overriding
Question 23: Programs related to Exception handling and return keyword
Question 24: How to make your own custom exception class?
Question 25: How to make custom checked / unchecked exception?
Question 26: What happens when you throw an exception from finally
block?
Question 27: What will be Output of below program related to try-catch-
finally?
Question 28: Explain try-with-resources
Question 29: Why String is Immutable?
Question 30: What does the equals() method of String class do?
Question 31: Explain StringBuffer and StringBuilder
Question 32: Explain the output of below program related to equals()
method of StringBuilder
Question 33: When to use String/StringBuffer/StringBuilder
Question 34: Explain equals and hashcode contract
Question 35: What is Marker Interface?
Question 36: Can you write your own custom Marker interface?
Question 37: What is Comparable and Comparator?
Question 38: How to compare a list of Employees based on name and age
such that if name of the employee is same then sorting should be based on
age
Question 39: Difference between Comparable and Comparator
Question 40: Different methods of Object class
Question 41: What type of arguments are allowed in System.out.println()
method?
Question 42: Explain System.out.println() statement
Question 43: Explain Auto-boxing and Un-boxing
Question 44: Find the output of below program
Question 45: Can you pass primitive long value in switch statement?
Question 46: Explain static keyword in Java
Question 47: What is an Inner Class in Java, how it can be instantiated and
what are the types of Inner Classes?
Question 48: What is Constructor Chaining in java?
Question 49: What is init block?
Question 50: What is called first, constructor or init block?
Question 51: What is Variable shadowing and Variable hiding in Java?
Question 52: What is a constant and how we create constants in Java?
Question 53: Explain enum
Question 54: What is Cloneable?
Question 55: What is Shallow Copy and Deep Copy?
Question 56: What is Serialization and De-serialization?
Question 57: What is SerialVersionUID?
Question 58: Serialization scenarios with Inheritance
Question 59: Stopping Serialization and De-serialization
Question 60: What is Externalizable Interface?
Question 61: Externalizable with Inheritance
Question 62: Difference between Serializable and Externalizable
Question 63: How to make a class Immutable?
Question 64: Explain Class loaders in Java
Question 65: What is Singleton Design Pattern and how it can be
implemented?
Question 66: What are the different ways in which a Singleton Design
pattern can break and how to prevent that from happening?
Question 67: What are the different design patterns you have used in your
projects?
Question 68: Explain Volatile keyword in java
Question 69: What is Garbage Collection in Java, how it works and what are
the different types of Garbage Collectors?
Question 70: Explain Generics in Java
Question 71: What is Multi-threading?
Question 72: How to create a thread in Java?
Question 73: Which way of creating threads is better: Thread class or
Runnable interface
Question 74: What will happen if I directly call the run() method and not the
start() method to execute a thread
Question 75: Once a thread has been started can it be started again
Question 76: Why wait, notify and notifyAll methods are defined in the
Object class instead of Thread class
Question 77: Why wait(), notify(), notifyAll() methods must be called from
synchronized block
Question 78: difference between wait() and sleep() method
Question 79: join() method
Question 80: yield() method
Question 81: Tell something about synchronized keyword
Question 82: What is static synchronization?
Question 83: What will be output of below program where one
synchronized method is calling another synchronized method?
Question 84: Programs related to synchronized and static synchronized
methods
Question 85: What is Callable Interface?
Question 86: How to convert a Runnable to Callable
Question 87: Difference between Runnable and Callable
Question 88: What is Executor Framework in Java, its different types and
how to create these executors?
Question 89: Tell something about awaitTermination() method in executor
Question 90: Difference between shutdown() and shutdownNow() methods
of executor
Question 91: What is Count down latch in Java?
Question 92: What is Cyclic Barrier?
Question 93: Atomic classes
Question 94: What is Collection Framework?
Question 95: What is Collections?
Question 96: What is ArrayList?
Question 97: What is default size of ArrayList?
Question 98: Which data structure is used internally in an ArrayList?
Question 99: How add() method works internally or How the ArrayList grows
at runtime
Question 100: How to make an ArrayList as Immutable
Question 101: What is LinkedList?
Question 102: When to use ArrayList / LinkedList
Question 103: What is HashMap?
Question 104: Explain the internal working of put() and get() methods of
HashMap class and discuss HashMap collisions
Question 105: equals and hashCode method scenarios in HashMap when the
key is a custom class
Question 106: How to make a HashMap synchronized?
Question 107: What is Concurrent HashMap?
Question 108: What is HashSet class and how it works internally?
Question 109: Explain Java’s TreeMap
Question 110: Explain Java’s TreeSet
Question 111: Difference between fail-safe and fail-fast iterators
Question 112: Difference between Iterator and ListIterator
Question 113: Difference between Iterator.remove and Collection.remove()
Question 114: What is the difference between a Monolith and Micro-service
architecture?
Question 115: What is Dependency Injection in Spring?
Question 116: What are the different types of Dependency Injection?
Question 117: Difference between Constructor and Setter injection
Question 118: What is @Autowired annotation?
Question 119: What is the difference between BeanFactory and
ApplicationContext?
Question 120: Explain the life-cycle of a Spring Bean
Question 121: What are the different scopes of a Bean?
Question 122: What is the Default scope of a bean?
Question 123: What happens when we inject a prototype scope bean in a
singleton scope bean?
Question 124: How to inject a prototype scope bean in a singleton scope
bean?
Question 125: Explain Spring MVC flow
Question 126: What is the difference between <context:annotation-config>
and <context:component-scan>?
Question 127: What is the difference between Spring and SpringBoot?
Question 128: What is auto-configuration in SpringBoot?
Question 129: What are SpringBoot starters?
Question 130: What is @SpringBootApplication Annotation?
Question 131: Where does a Spring Boot application start from?
Question 132: How to remove certain classes from getting auto-configured
in SpringBoot?
Question 133: How to autowire a class which is in a package other than
SpringBoot application class’s package or any of its sub-packages
Question 134: What is application.properties file in a SpringBoot
application?
Question 135: How to configure the port number of a SpringBoot
application?
Question 136: Which jar builds our springboot application automatically
whenever we change some code just like a node.js application?
Question 137: What default embedded server is given in spring boot web
starter and how we can change the default embedded server to the one of
our choice
Question 138: Where should we put our html and javascript files in a spring
boot application?
Question 139: What are the different stereotype annotations?
Question 140: Difference between @Component, @Controller, @Service,
@Repository annotations?
Question 141: Difference between @Controller and @RestController
annotation
Question 142: What is @RequestMapping and @RequestParam annotation?
Question 143: How to define a Get or Post endpoint?
Question 144: Which annotation is used for binding the incoming json
request to the defined pojo class?
Question 145: What is @Qualifier annotation?
Question 146: What is @Transactional annotation?
Question 147: What is @ControllerAdvice annotation?
Question 148: What is @Bean annotation?
Question 149: Difference between @Component and @Bean
Question 150: How to do profiling in a SpringBoot application
Question 151: What is RestTemplate?
Question 152: What is Spring Data JPA?
Question 153: What is the difference between JPARepository,
CRUDRepository, PagingAndSortingRepository and which one you have used
in your applications?
Question 154: What is Spring AOP?
Question 155: Have you used Spring Security in your application
Question 156: What do you know about Spring Batch framework?
Question 157: Difference between SOAP and REST
Question 158: What is Restful api?
Question 159: What is a stateless object?
Question 160: What is the difference between Web Server and Application
Server?
Question 161: What do you know about CommandLineRunner and
ApplicationRunner?
Question 162: What do you know about Eureka Naming Server?
Question 163: What do you know about Zuul?
Question 164: What do you know about Zipkin?
Question 165: What do you know about Hysterix?
Question 166: What is JPA?
Question 167: What is Hibernate?
Question 168: Difference between JPA and Hibernate
Question 169: What is @Entity?
Question 170: How to give a name to a table in JPA?
Question 171: What is @Id, @GeneratedValue?
Question 172: How to use a custom database sequence in Hibernate to
generate primary key values?
Question 173: How to give names to the columns of a JPA Entity
Question 174: How to define a @OneToMany relationship between entities
Question 175: Why annotations should be imported from JPA and not from
Hibernate?
Question 176: What is the difference between get() and load() method of
Hibernate Session?
Question 177: What is the difference between save(), saveOrUpdate() and
persist() method of Hibernate Session?
Question 178: What is Session and SessionFactory in Hibernate?
Question 179: What is First Level and Second Level Cache in Hibernate?
Question 180: What is session.flush() method in Hibernate?
Question 181: How can we see the SQL query that gets generated by
Hibernate?
Question 182: What is Hibernate Dialect and why we need to configure it?
Question 183: What do you know about hibernate.hbm2ddl.auto property in
Hibernate?
Question 184: What is Maven?
Question 185: What is pom.xml?
Question 186: What is local repo and central repo?
Question 187: Where we define our local repo path?
Question 188: Where do we define proxies so that maven can download jars
from the internet in a corporate environment?
Question 189: Explain Maven build life-cycle
Question 190: What do you know about SQL Joins?
Question 191: Difference between TRUNCATE & DELETE statements
Question 192: Difference between Function and Stored Procedure
Question 193: What is DDL, DML statements?
Question 194: How to find the nth highest salary from Employee table
Question 195: Difference between UNION and UNION ALL commands in SQL
Question 196: Difference between Unique Key and Primary Key in SQL
Question 197: What is the difference between Primary and Foreign key in
SQL?
Question 198: What is the difference between clustered and non-clustered
index?
Question 199: What is the difference between WHERE and HAVING clause in
SQL
Question 200: How to change the gender column value from Male to Female
and Female to Male using single Update statement
Question 201: Find first 3 largest numbers in an array
Question 202: Move all negative numbers at the beginning of an array and
all positive numbers at the end
About the Author
Question 1: What are the 4 pillars of OOPS?
Answer: 4 pillars of OOPS are:

1. Abstraction
2. Encapsulation
3. Inheritance
4. Polymorphism
Let’s take a look at them:

1. Abstraction: Abstraction is a process of hiding the


implementation details and showing only functionality to the
user.

Real world examples:


- TV remote: To start the TV, you have to press the power
button, you don’t have to know about the internal circuit
operations like how infrared waves are passing.
- Car gears: We know what happens when we change the gear.
But we don’t know how changing gear works under the hood,
that information is irrelevant to us, so it is abstracted.
In java, Abstraction can be achieved in two ways:
- Abstract
classes
- Interfaces
2. Encapsulation: Encapsulation is a process of Binding data and
methods within a class. Think of it like showing the essential
details of a class by using the access control modifiers (public,
private, protected). So, we can say that Encapsulation leads to
the desired level of Abstraction.

Example:
Java Bean, where all data members are made private and you
define certain public methods to the outside world to access
them.
3. Inheritance: Using inheritance means defining a parent-child
relationship between classes, by doing so, you can reuse the
code that is already defined in the parent class. Code reusability
is the biggest advantage of Inheritance.

Java does not allow multiple inheritance through classes but it allows
it through interfaces.
4. Polymorphism: Poly means many and Morph means forms.
Polymorphism is the process in which an object or function takes
different forms. There are 2 types of Polymorphism :

- Compile Time Polymorphism (Method


Overloading)
- Run Time Polymorphism (Method Overriding)

In Method overloading, two or more methods in one class have the


same method name but different arguments. It is called as Compile time
polymorphism because it is decided at compile time which overloaded
method will be called.
Overriding means when we have two methods with same name and same
parameters in parent and child class. Through overriding, child class can
provide specific implementation for the method which is already defined in
the parent class.

Question 2: What is an abstract class?


Answer: A class that is declared using “abstract” keyword is known as
abstract class. It can have abstract methods (methods without body) as well
as concrete methods (methods with body).
Some points to remember:
- An abstract class cannot be instantiated, which means you are
not allowed to create an object of the abstract class. This also
means, an abstract class has no use unless it is extended by
some other class
- If there is any abstract method in a class then that class must
be declared abstract
- The first non-abstract class which is extending from an abstract
class will have to give implementation of the abstract methods
defined in abstract class
Example:
Output:

Question 3: Does Abstract class have constructor?


Answer: This is a famous interview question and the answer is: Yes, abstract
classes have constructor. Either you can provide it or the default one will be
provided by Java. Now, you must be wondering if you cannot create an
object of abstract class then what is the need of a constructor.
One thing you must know is that the constructors are used when you are
creating an object of a class, to initialize the data members of that class and
your abstract class can have data members.
Now, when your class extends abstract class then the same abstract class
will become super class for your extending class and remember when you
have constructor of your class then first line of your constructor is always a
call to super class constructor and this is the time when your abstract class
constructor will get called.
Example 1:

Output:

Example 2:
Output:
Question 4: What is an Interface?
Answer:
- An interface in Java is a blueprint of a class. It has static
constants and abstract methods.
- Interface specify what a class must do but not how to do
- An interface is like defining a contract that is fulfilled by
implementing classes
- An interface is used to achieve full abstraction.
- All methods in an interface are public and abstract by default
and all variables declared in an interface are constants i.e.
public, static and final
- A class which implements an interface will have to provide
implementation of all the methods that are defined in the
interface
- A class can implement more than one interface, this is how
Java allows multiple inheritance.
- Since Java 8, we can have default and static methods in an
interface

Question 5: Difference between abstract class and


interface
Answer: The differences are:
- Abstract class can have both abstract and concrete methods
but interface can only have abstract methods (Java 8 onwards,
it can have default and static methods as well)
- Abstract class methods can have access modifiers other than
public but interface methods are implicitly public and abstract
- Abstract class can have final, non-final, static and non-static
variables but interface variables are only static and final
- A subclass can extend only one abstract class but it can
implement multiple interfaces
- An Abstract class can extend one other class and can
implement multiple interfaces but an interface can only extend
other interfaces
In this question, the interviewer may try to confuse you by saying that from
Java 8 onwards, you can have static and default methods in an Interface so
now what is the difference between abstract class and interface and the
answer you should tell is – We can still extend only one class but can
implement multiple interfaces.

Question 6: What to choose – interface or abstract class


Answer: Consider these points while choosing between the two:
- When you want to provide default implementation to some of
the common methods that can be used directly by the sub-
classes then you can use abstract class because it can have
concrete methods also, this is not the case with Interface
because the child classes that are implementing this interface
will have to provide implementation for all the methods that
are declared in the interface
- If your contract keeps on changing then Interface will create
problems because then you will have to provide
implementation of those new methods in all the implementing
classes, whereas with abstract class you can provide one
default implementation to the new methods and only change
those implementing classes that are actually going to use these
new methods
Most of the times, interfaces are a good choice. It is also one of the best
practices, when you code in terms of interfaces.

Question 7: Why Java 8 has introduced default methods?


Answer: To extend the capability of an already existing interface, default
methods are introduced in Java 8. Let’s understand this by one example:
Consider there are 100 classes that are implementing one interface.
Now you want to define one new method inside your interface. In this case
you will have to change all the implementation classes to fulfill the interface
contract. So, Java introduced default methods, here you can provide default
implementation of that new method inside your interface and as it is not
mandatory to provide implementation of default methods by the
implementing classes, all the 100 classes can use the default implementation
or if they want they can provide their own implementation by overriding the
default method.
Now consider one interesting scenario: You have two interfaces, Interface1
and Interface2 both having default method hello() and one class is
implementing these 2 interfaces without giving implementation to this
default method. You see the problem here? Yes, it is the famous Diamond
Problem (Refer to Question 9, if you’re not already familiar with this
problem).

So, to avoid this error, it is mandatory to provide implementation for


common default methods of interfaces

Output:
Question 8: Why Java 8 has introduced static methods?
Answer: Consider an example where you want to define a utility class, what
you usually do is you define a class which contains static methods and then
you call these methods using class name. Now, Java 8 onwards you can do
the same thing using an Interface by giving only static methods inside your
interface. This way of using Interface for defining utility classes is better as it
helps in performance also, because using a class is more expensive
operation than using an interface.

Question 9: Why Java does not allow multiple inheritance?


Answer: Multiple inheritance occurs when a class has more than one parent
classes.
Why Java does not allow this: let us consider there are 2 parent classes
having a method named hello() with same signature and one child class is
extending these 2 classes, if you call this hello() method which is same in
both parents, which parent class method will get executed – it results into
an ambiguous situation, this is also called Diamond Problem.
You will get a compile time error if you try to extend more than one class.
Question 10: What are the rules for Method Overloading
and Method Overriding?
Answer: Method Overloading Rules: Two methods can be called overloaded
if they follow below rules:
- Both have same method
name
- Both have different
arguments
If both methods follow above two rules, then they may or may not:
- Have different access modifiers
- Have different return types
- Throw different checked or unchecked exceptions
Method Overriding Rules: The overriding method of child class must follow
below rules:
- It must have same method name as that of parent class
method
- It must have same arguments as that of parent class method
- It must have either the same return type or covariant return
type (child classes are covariant types to their parents)
- It must not throw broader checked exceptions
- It must not have a more restrictive access modifier (if parent
method is public, then child method cannot be
private/protected)

Question 11: Can we override final methods?


Answer: No, final methods cannot be overridden.

Question 12: Can constructors and private methods be


overridden?
Answer: No

Question 13: What is final keyword and where it can be


used?
Answer: If you use final with a primitive type variable, then its value cannot
be changed once assigned.
If you use final with a method, then you cannot override it in the subclass.
If you use final with class, then that class cannot be extended.
If you use final with an object type, then that object cannot be referenced
again.

Question 14: What is exception and exception handling?


Answer: An exception is an event that disrupts the normal flow of the
program. It is an object which is thrown at runtime, so exception handling is
a mechanism by which normal flow of the program is maintained.
Program showing the exception is thrown:

Output:

Program showing that the exception is handled:

Output:
Question 15: Difference between error and exception
Answer: Error: Errors in a program are irrecoverable, they indicate that
something severe has gone wrong in the application and the program gets
terminated in case of error occurrence e.g. running out of memory:
OutOfMemoryError, making too many recursive calls: StackOverflowError
etc.
Exception: Exceptions on the other hand are something that we can recover
from by handling them properly e.g.: trying to access a property/method
from a null object: NullPointerException, dividing an integer by zero:
ArithmeticException etc.

Question 16: What are the different types of exceptions?


Answer: There are 2 types of exceptions:
- Checked Exceptions: All exceptions other than
RuntimeException and Error are known as Checked exception.
These exceptions are checked by the compiler at the compile
time itself. E.g. when you are trying to read from a file, then
compiler enforces us to handle the FileNotFoundException
because it is possible that the file may not be present. Some
other checked exceptions are SQLException, IOException etc.
- Unchecked Exceptions: Runtime Exceptions are known as
Unchecked exceptions. Compiler does not force us to handle
these exceptions but as a programmer, it is our responsibility
to handle runtime exceptions e.g. NullPointerException,
ArithmeticException, ArrayIndexOutOfBoundException etc.

Question 17: How exception handling is done in java?


Answer: try-catch block is used for exception handling. If you think that
certain statements may throw an exception, surround them with try block.
A try block is always followed by a catch block or finally or both.
You cannot use the try block alone:

Question 18: Can we write a try block without catch block?


Answer: Yes, we can write a try block with finally, but we cannot write a try
block alone.

Question 19: How to handle multiple exceptions together?


Answer: You can write multiple catch blocks one after another for each
exception or you can write a single catch block using a pipe symbol (|) to
separate the exceptions.
While writing multiple catch block, you have to follow the below rule:
-
Handle the most specific exception and then move down to the
most generic ones, means you cannot handle Exception (base
class of exception) before FileNotFoundException

Suppose, your method is throwing more than one exception and you want
to perform some specific action based on the exception thrown, you should
use multiple catch blocks in this case.
Example using multiple catch blocks:
When using pipe (|) symbol:

Question 20: When finally block will not get executed


Answer:
- when System.exit() is called
- when JVM crashes

Question 21: Difference between throw and throws


keyword. And discuss Exception Propagation
Answer:

- throw is a keyword which is used to explicitly throw an


exception in the program, inside a function or inside a block of
code, whereas throws is a keyword which is used with the
method signature to declare an exception which might get
thrown by the method while executing the code
- throw keyword is followed by an instance of an Exception class
whereas throws is followed by Exception class names
- You can throw one exception at a time but you can declare
multiple exceptions using throws keyword
- Using throw keyword, only unchecked exceptions are
propagated, whereas using throws keyword both checked and
unchecked exceptions can be propagated.
Exception propagation:
An exception is first thrown from the top of the stack and if it is not caught,
it drops down the call stack to the previous method, If not caught there, the
exception again drops down to the previous method, and so on until they
are caught or until they reach the very bottom of the call stack. This is called
exception propagation.

- When method m1() calls method m2() which calls method


m3(), a stack is formed which gets unfold from the top, so if
method m3() throws an exception and it is not handled there,
it will drop down the call stack to method m2(), if it is not
handled there, it will drop down the call stack to method m1(),
this happens until we reach the bottom of the stack or until
the exception is caught. This is called Exception Propagation in
java.

Example: unchecked exception is thrown and it can be seen from the call
stack that it is propagated
Output:

Example: Here the unchecked exception is handled

Output:

Example: checked exceptions are not propagated down the call chain by
default,

You have to use throws keyword if you want to propagate the checked
exception, like

Notice in the above example that the checked exception is propagated and
now it is the responsibility of the caller method to either handle the
exception or throw it further. Below example is showing that the checked
exception is handled,

Output:

throws can be used with unchecked exceptions also, though it is of no use


because unchecked exceptions are by default propagated. See this in the
below program:
Output:

Unchecked exceptions are by default propagated:

Output:

Question 22: Exception handling w.r.t. method overriding


Answer:

- If the parent class method does not declare an exception then


child class overridden method cannot declare checked
exceptions but it can declare unchecked exceptions
- If the parent class method declares an exception, then child
class overridden method
- can declare no exception
- can declare same exception
- can declare a narrower exception (more broader
exception declaration than parent one is not allowed)
Example when parent class method does not declare an exception and
child class declares checked exception:

Example when parent class method does not declare an exception and
child class declares unchecked exception:
Output:

Example when Child class overridden method throws a broader exception


than the parent one:

Example when child class overridden method throws same exception as the
parent one:
Output:

Example when child class overridden method declares a narrower


exception than the parent one:
Output:

Example when parent class method declares an exception and child class
overridden method does not declare any exception:
Output:

Question 23: Programs related to Exception handling and


return keyword
Answer: These questions are asked a lot of times to the new programmers.

One thing you should remember is, if you write anything after return
statement / throw exception statement, then that will give Compile time
error as ‘Unreachable code’.

Program 1:

Program 2: finally block is always executed


Output:

Program 3: program execution returns from the finally block


Program 4:
Output:

Program 5:
Output:

Question 24: How to make your own custom exception


class?
Answer: In java, you can create your own custom exception class which are
basically derived classes from the Exception class.
For Example:
Output:

Question 25: How to make custom checked / unchecked


exception?
Answer: If you want to make a custom unchecked exception class then
extend RuntimeException and for creating a custom checked exception class,
extend Exception class.

Question 26: What happens when you throw an exception


from finally block?
Answer: When exception is thrown from finally block, then it takes
precedence over the exceptions that are thrown from try/catch block

Question 27: What will be Output of below program


related to try-catch-finally?
With everything you have read so far, you should be able to answer this
easily. I will leave this one for you.

Question 28: Explain try-with-resources


Answer: try-with-resources concept was introduced in Java 7. It allows us to
declare resources which will be used inside the try block and it assures us
that the resources will be closed after execution of this block. A resource is
an object that must be closed after finishing the program. The resources
declared must implement AutoCloseable interface.
Syntax:

Question 29: Why String is Immutable?


Answer: String is immutable for below reasons:

1. String Pool: String Pool is possible only because String is


Immutable in Java. String pool is a special storage area in Java
heap. If the string is already present in the pool, then instead of
creating a new object, old object’s reference is returned. This
way different String variables can refer to the same reference in
the pool, thus saving a lot of heap space also. If String is not
immutable then changing the string with one reference will lead
to the wrong values to other string variables having the same
reference.
2. Security: String parameters are used in network connections,
database URL’s, username and passwords etc. Because String is
immutable, these values can’t be changed. Otherwise any hacker
could change the referenced values which will cause severe
security issues in the application.
3. Multi-threading: Since String is immutable, it is safe for
multithreading. A single String instance can be shared across
different threads. This avoids the use of synchronization for
thread safety. Strings are implicitly thread-safe.
4. Caching: The hashcode of string is frequently used in Java. Since
string is immutable, the hashcode will remain the same, so it can
be cached without worrying about the changes. This makes it a
great candidate for using it as a Key in Map.
5. Class Loaders: Strings are used in Java ClassLoaders and since
String is made immutable, it provides security that correct class
is being loaded.

Question 30: What does the equals() method of String class


do?
Answer: As we know, Object class is the parent of all classes, and Object
class has a equals() method that compares the reference of two objects, but
String class has overridden this method, and String class’s equals() method
compares the contents of two strings.
Program:

Output:

Question 31: Explain StringBuffer and StringBuilder


Answer: Both StringBuffer and StringBuilder classes are used for String
manipulation. These are mutable objects. But StringBuffer provides thread-
safety as all its methods are synchronized, this makes performance of
StringBuffer slower as compared to StringBuilder.
StringBuffer class is present from Java 1.0, but due to its slower
performance, StringBuilder class was introduced in Java 1.5
If you are in a single-threaded environment or don’t care about thread
safety, you should use StringBuilder. Otherwise, use StringBuffer for thread-
safe operations.

Question 32: Explain the output of below program related


to equals() method of StringBuilder

Output:

Answer: This is another very famous interview question. If you were


expecting ‘Equal’ as output, then you were wrong. The output is not ‘Equal’
because StringBuffer and StringBuilder does not override equals and
hashcode methods. In the above program, Object’s class equals() method is
getting used and as it compares the reference of two objects, the output of
above program is ‘Not Equal’.
Since hashcode is used in data structures that use hashing algorithm to store
the objects. Examples are HashMap, HashSet, HashTable,
ConcurrentHashMap etc. and all these data structures requires their keys
not to be changed so that stored values can be found by using hashcode
method but StringBuffer/StringBuilder are mutable objects. This makes
them a very poor choice for this role.
You must have heard about the equals and hashcode contract in Java, which
states that if two objects are equals according to equals() method then their
hashcode must be same, vice-versa is not true. Now, had the equals method
for StringBuilder/StringBuffer be overridden, their corresponding hashcode
method would also need to be overridden to follow that rule. But as
explained earlier, these classes don’t need to have their own hashcode
implementation and hence same is with their equals method.

Question 33: When to use


String/StringBuffer/StringBuilder
Answer: You should use String class if you require immutability, use
StringBuffer if you require mutability + Thread safety and use StringBuilder if
you require mutability and no thread safety.

Question 34: Explain equals and hashcode contract


Answer: The equals and hashcode contract says:
-
If two objects are equals according to equals() method, then their
hashcode must be same but reverse is not true i.e. if two objects
have same hashcode then they may/may not be equals.

Question 35: What is Marker Interface?


Answer: Marker interface is an interface which is empty. Some of the
Marker interfaces are Cloneable, Serializable, Remote etc. If you have read
that Marker interfaces indicate something to the compiler or JVM, then you
have read it wrong, it has nothing to do with JVM.
Consider the example of Cloneable:
It is said that you cannot call clone() method on a class object unless the
class implements Cloneable interface. Well this statement is true, because
when you call clone() method then the first statement in clone() is, obj
instanceOf Cloneable.
The class object on which clone() method is getting called is checked,
whether the class implements Cloneable interface or not, by using
instanceOf operator. If class does not implement Cloneable interface then
CloneNotSupportedException is thrown.
Same is true with writeObject(Object) method of ObjectOutputStream class.
Here, obj instanceOf Serializable is used to check whether the class
implements Serializable interface or not. If class does not implement
Serializable interface then NotSerializableException is thrown.

Question 36: Can you write your own custom Marker


interface?
Answer: Yes. As you already know that Marker interfaces have got nothing
to do with indicating some signal to JVM or compiler, instead it is just a mere
check of using instanceOf operator to know whether the class implements
Marker interface or not.
In your method, you can put a statement like: object instanceOf
MyMarkerInterface.
You can use Marker interface for classification of your code.

Question 37: What is Comparable and Comparator?


Answer: Both Comparable and Comparator interfaces are used to sort the
collection of objects. These interfaces should be implemented by your
custom classes, if you want to use Arrays/Collections class sorting methods.
Comparable interface has compareTo(Obj) method, you can override this
method in your class, and you can write your own logic to sort the
collection.
General rule to sort a collection of objects is:
If ‘this’ object is less than passed object, return negative integer.
If ‘this’ object is greater than passed object, return positive integer.
If ‘this’ object is equal to the passed object, return zero.
Comparable Example:
Employee.java

ComparableDemo.java:
Output:

Here, we have sorted the Employee list based on ‘id’ attribute.


Now, if we want to sort the employee list based on any other attribute, say
name, we will have to change our compareTo() method implementation for
this. So, Comparable allows only single sorting mechanism.
But Comparator allows sorting based on multiple parameters. We can define
another class which will implement Comparator interface and then we can
override it’s compare(Obj, Obj) method.
Suppose we want to sort the Employee list based on name and salary.
NameComparator.java:
String class already implements Comparable interface and provides a
lexicographic implementation for compareTo() method which compares 2
strings based on contents of characters or you can say in lexical order. Here,
Java will determine whether passed String object is less than, equal to or
greater than the current object.
ComparatorDemo.java:

Output:
The output list is sorted based on employee’s names.

SalaryComparator.java:

ComparatorDemo.java:

Output:

Question 38: How to compare a list of Employees based on


name and age such that if name of the employee is same
then sorting should be based on age
Answer: When comparing by name, if both names are same, then
comparison will give 0. If the compare result is 0, we will compare based on
age.
NameAgeComparator.java:

ComparatorDemo.java:

Output:
Question 39: Difference between Comparable and
Comparator
Answer:
- Comparable interface can be used to provide single way of
sorting whereas Comparator interface is used to provide
multiple ways of sorting
- Comparable interface is present in ‘java.lang’ package whereas
Comparator interface is present in ‘java.util’ package
- For using Comparable, the class needs to implement
Comparable interface whereas for using Comparator, there is
no need to make changes in the class
- Comparable provides compareTo() method to sort elements,
whereas Comparator provides compare() method to sort
elements
- We can sort the list elements of Comparable type by using
Collections.sort(listObj) method, whereas to sort the list
elements of Comparator type, we have to provide a
Comparator object like, Collections.sort(listObj, Comparator)
At times, when you are using any third-party classes or the classes where
you are not the author of the class, then in that case Comparator is the only
choice to sort those objects

Question 40: Different methods of Object class


Answer: Object class sits at the top of class hierarchy tree. Every class is a
child of Object class. Below methods are present inside Object class:
//Creates and returns a copy of this object
protected native Object clone() throws
CloneNotSupportedException
//Indicates whether some other object is "equal to" this
one
public boolean equals(Object obj)
//Returns a hash code value for the object
public native int hashCode()
//Returns the runtime class of an Object
public final native Class<?> getClass()
//Returns a string representation of the object
public String toString()
//Called by the garbage collector on an object when
garbage collection
//determines that there are no more references to the
object
protected void finalize() throws Throwable
//Wakes up a single thread that is waiting on this
object's monitor
public final native void notify()
//Wakes up all threads that are waiting on this object's
monitor
public final native void notifyAll()
public final native void wait(long timeout) throws
InterruptedException
public final void wait(long timeout, int nanos) throws
InterruptedException
public final void wait() throws InterruptedException

Question 41: What type of arguments are allowed in


System.out.println() method?
Answer: println() method of PrintStream class is overloaded, and it accepts
below arguments :

Question 42: Explain System.out.println() statement


Answer:

- System is a class in java.lang package


- out is a static member of System class and is an instance of
java.io.PrintStream
- println() is a method of PrintStream class

Question 43: Explain Auto-boxing and Un-boxing


Answer: In Java 1.5, the concepts of Auto-boxing and Un-boxing were
introduced to automatically convert primitive type to object and vice-versa.
When Java automatically converts a primitive type, like int into its
corresponding wrapper class object i.e. Integer, then this is called Auto-
boxing. While the opposite of this is called Un-boxing, where an Integer
object is converted into primitive type int.
Example:
Output:

Question 44: Find the output of below program


Answer: Here, the compiler is confused as to which method to be called, so
it throws Compile Time error.

Question 45: Can you pass primitive long value in switch


statement?
Answer: No, switch works only with 4 primitives and their wrappers, as well
as with the enum type and String class:

- byte and Byte


- short and Short
- char and Character
- int and Integer
- enum
- String

Question 46: Explain static keyword in Java


Answer: In Java, a static member is a member of a class that isn’t associated
with an instance of a class. Instead, the member belongs to the class itself.
In Java, Static is applicable for the following:

-Variable
-Method
-Block
-Nested
class
Static Variable: if any variable is declared as static, then it is known as ‘static
variable’. Only single copy of the variable gets created and all instances of
the class share same static variable. The static variable gets memory only
once in the class area at the time of class loading.
When to use static variable: static variables should be used to declare
common property of all objects as only single copy is created and shared
among all class objects, for example, the company name of employees etc.

Static Method: When a method is declared with static keyword then it is


known as static method. These methods belong to the class rather than the
object of the class. As a result, a static method can be directly accessed
using class name without the need of creating an object.
One of the basic rules of working with static methods is that you can’t access
a non-static method or field from a static method because the static method
doesn’t have an instance of the class to use to reference instance methods
or fields. Another restriction is, ‘this’ and ‘super’ cannot be used in static
context.
For example: main() method is static, Java Runtime uses this method to start
an application without creating an object.

Static Block: Static block gets executed exactly once when the class is first
loaded, use static block to initialize the static variables.

Static nested classes:


Static nested classes are a type of inner class in java where the inner class is
static. Static nested classes can access only the static members of the outer
class. The advantage of using static nested classes is that it makes the code
more readable and maintainable.
In the case of normal inner class, you cannot create inner class object
without first creating the outer class object, but in the case of static inner
class, there can be a static inner class object without the outer class object.
How to create object of static inner class:
OuterClass.StaticNestedClass nestedClassObject = new
OuterClass.StaticNestedClass();

Compile Time Error comes when we try to access non-static member inside
static nested class:

Using inner class object:


Output:

If you have static members in your Static Inner class then there is no need to
create the inner class object:
Output:

Question 47: What is an Inner Class in Java, how it can be


instantiated and what are the types of Inner Classes?
Answer: In Java, when you define one non-static class within another class, it
is called Inner Class/Nested Class. Inner class enables you to logically group
classes that are only used in one place, thus, this increases the use of
encapsulation and creates more readable and maintainable code.
Java inner class is associated with the object of the class and they can access
all the variables and methods of the outer class. Since inner classes are
associated with the instance, we can’t have any static variables in them.
The object of java inner class is part of the outer class object and to create
an instance of the inner class, we first need to create an instance of outer
class.
Java Inner classes can be instantiated like below:
OuterClass outerObject = new OuterClass();
OuterClass.InnerClass innerObject = outerObject.new InnerClass();

Example:
Output:

Compile time error when static variable and static method is present in
Inner class:
There are 2 special types of Inner Classes:

- local inner class


- anonymous inner class
local inner class: Local Inner Classes are the inner classes that are defined
inside a block. Generally, this block is a method body. Sometimes this block
can be a for loop, or an if clause. Local Inner classes are not a member of any
enclosing classes. They belong to the block in which they are defined in, due
to which local inner classes cannot have any access modifiers associated
with them. However, they can be marked as final or abstract. These classes
have access to the fields of the class enclosing it. Local inner class must be
instantiated in the block they are defined in.
Points to remember:
- local inner class cannot be instantiated from outside of the
block where they are defined
- local inner class has access to the members of the enclosing
class
- till Java 1.7, local inner class can access only final local variable
of the enclosing block where they are defined. But from Java
1.8 onwards, it is possible to access the non-final local variable
of the enclosing block
- the scope of local inner class is restricted to the block where
they are defined
- A local inner class can extend an abstract class or can
implement an interface
Example:
Output:

Remember, you can only access the block level variables, and cannot change
them. You will get compile time error if you try to change them:
A variable whose value is not changed once initialized is called as effectively
final variable.

Anonymous inner class:


An inner class that does not have any name is called Anonymous Inner class.
You should use them when you want to use local class only once. It does not
have a constructor since there is no class name and it cannot be declared as
static.
Generally, they are used when you need to override the method of a class or
an interface.

When to use:
Example 1 : Let’s understand this by an example, Suppose you are want to
return a list of employee class objects and they should be sorted based on
employee name, now for this you can write a comparator in a separate class
and pass its object inside the Collections.sort(list, comparatorObject)
Instead, you can use the anonymous inner class and you don’t have to
create a new class just for writing a comparator that you are not going to
use later on.

Program:
Employee.java:
AnonymousInnerDemo.java:
Output:

Example 2: Using anonymous inner class, you can implement a Runnable


also
Output:

Example 3: You can use anonymous inner class in situations where you want
to override the parent class method without creating a separate child class:
Output:

Some points to remember:


- anonymous class does not have a constructor as it does not
have any class name
- in anonymous class, we cannot have static members except
static constants
- an anonymous class has access to the members of its enclosing
class
- an anonymous class cannot access local variables in its
enclosing scope(block) that are not final or effectively final

Anonymous Inner Class Example:


Output:
Compile time error in case of using static variable which is not final:

Question 48: What is Constructor Chaining in java?


Answer: when one constructor calls another constructor, it is known as
constructor chaining. This can be done in two ways:
- this() : it is used to call the same class constructor
- super() : it is used to call the parent class
constructor
this() Example:

Output:
super() example:
Output:

Some points to remember:


- this() can call same class constructor only
- super() can call immediate super class constructor only
- this() and super() call must be the first statement, because of
this reason both cannot be used at the same time
- you must use super() to call the parent class constructor but if
you do not provide a super() call, JVM will put it automatically

Question 49: What is init block?


Answer: init block is called instance initializer block

- init block is used to initialize the instance data members


- init block runs each time when object of the class is created
- init block runs in the order they appear in the program
- compiler replaces the init block in each constructor after the
super() statement
- init block is different from static block which runs at the time
of class loading
Example 1:
Output:

Example 2:
Output:

Example 3:
Output:
Order of execution:
- static blocks of super classes
- static blocks of the class
- init blocks of super classes
- constructors of super classes
- init blocks of the class
- constructors of the class
1. The code in static initialization block will be executed at
class load time (and yes, that means only once per class
load), before any instances of the class are constructed
and before any static methods are called.
2. The instance initialization block is actually copied by the
Java compiler into every constructor the class has. So, the
code in instance initialization block is
executed exactly before the code in constructor.

Question 50: What is called first, constructor or init block?


Answer: Constructor is invoked first. Compiler copies all the code of instance
initializer block into the constructor after first statement super().

Question 51: What is Variable shadowing and Variable


hiding in Java?
Answer: Variable shadowing: When a local variable inside a method has the
same name as one of the instance variables, the local variable shadows the
instance variable inside the method block.
Example 1:
Output:

If you want to access instance variables then you can do so using ‘this’
keyword like below:
Example 2:
Output:

Variable Hiding: When the child and parent classes both have a variable
with the same name, the child class variable hides the parent class variable.
Example 1:
Output:

If you want to access parent’s class variable then you can do this using super
keyword:
Example 2:
Output:

Variable hiding is not same as Method Overriding:


While variable hiding looks like overriding a variable (similar to method
overriding), it is not. Overriding is applicable only to methods while hiding is
applicable to variables.
In the case of method overriding, overridden methods completely replace
the inherited methods, so when we try to access the method from a parent's
reference by holding a child's object, the method from the child class gets
called.
But in variable hiding, the child class hides the inherited variables instead of
replacing them, so when we try to access the variable from the parent's
reference by holding the child's object, it will be accessed from the parent
class.
When an instance variable in a subclass has the same name as an instance
variable in a super class, then the instance variable is chosen from the
reference type.
Output:

Question 52: What is a constant and how we create


constants in Java?
Answer: A constant is a variable whose value cannot change once it has
been assigned. To make any variable a constant, we can use ‘static’ and
‘final’ modifier like below:
public static final TYPE NAME_OF_CONSTANT_VARIABLE = VALUE;
We can also use “enum” to define constants.

Question 53: Explain enum


Answer: enum in java is a data type which contains a fixed set of constants.
In enum, we can also add variables, methods and constructors. Some
common examples of enums are: days of week, colors, excel report columns
etc.
Some points to remember:
- enum constants are static and final implicitly
- enum improves type safety
- enum can be declared inside or outside of a class
- enum can have fields, constructors (private) and methods
- enum cannot extend any class because it already extends
Enum class implicitly but it can implement many interfaces
- We can use enum in switch statement
- We can have main() method inside an enum
- enum has values(), ordinal() and valueOf() methods. values()
return an array containing all values present inside enum,
ordinal() method returns the index of given enum value and
valueOf() method returns the value of given constant enum
- enum can be traversed
- enum can have abstract methods
- enum cannot be instantiated because it contains private
constructor only
- The constructor is executed for each enum constant at the
time of enum class loading
- While defining enum, constants should be declared first, prior
to any fields or methods, or else compile time error will come
Example 1:
main() method in enum, iterating over enum:
Output:

Example 2:

Output:
Question 54: What is Cloneable?
Answer: Cloneable is an interface in Java which needs to be implemented by
a class to allow its objects to be cloned.
A class implements the Cloneable interface to indicate to the Object.clone()
method that it is legal for that method to make a field-for-field copy of
instances of that class.
If you try to Clone an object which doesn’t implement the Cloneable
interface, it will throw CloneNotSupportedException.

Example without implementing Cloneable interface:


Program 1:
Output:

Here, we have created Employee object e1 with new keyword but then we
created another object Employee e2 which has the same reference as of e1.
So, any change in e2 object will reflect in e1 object and vice-versa.
Now, let’s implement Cloneable interface in our Employee class and invoke
the clone() method on e1 object to make its clone:
Program 2:
Output:

In the above example, we have only primitive types in our Employee class,
what if we have an object type i.e. another class object reference, see the
example below:
Program 3:
Can you guess the output of the last 2 sysout? Here is the output:

If you are surprised with the above output, then let me make it clear by
saying that, by default Object’s clone() method provide Shallow copy. This
brings us to the next interview question: What is shallow copy and deep
copy
Question 55: What is Shallow Copy and Deep Copy?
Answer: Shallow Copy: When we use the default implementation of clone()
method, a shallow copy of object is returned, meaning if the object that we
are trying to clone contains both primitive variables and non-primitive or
reference type variable, then only the object’s reference is copied not the
entire object itself.
Consider this with the example:
Employee object is having Company object as a reference, now when we
perform cloning on Employee object, then for primitive type variables,
cloning will be done i.e. new instances will be created and copied to the
cloned object but for non-primitive i.e. Company object, only the object’s
reference will be copied to the cloned object. It simply means Company
object will be same in both original and cloned object, changing the value in
one will change the value in other and vice-versa.
Now, if you want to clone the Company object also, so that your original and
cloned Employee object will be independent of each other, then you have to
perform Deep Copy.

Deep Copy: in Deep copy, the non-primitive types are also cloned to make
the original and cloned object fully independent of each other.
Program 1:
Output:
In above example, we have overridden the clone method in our employee
class and we called the clone method on mutable company object.
We can also use Copy constructor to perform deep copy:
Program 2:
Output:

There are 2 other methods by which you can perform deep copy:

- By using Serialization, where you serialize the original object


and returns the deserialized object as a clone
- By using external library of Apache Commons Lang. Apache
Common Lang comes with SerializationUtils.clone() method for
performing deep copy on an object. It expects all classes in the
hierarchy to implement Serializable interfaces else
SerializableException is thrown by the system

Question 56: What is Serialization and De-serialization?


Answer: Serialization is a mechanism to convert the state of an object into a
byte stream while De-serialization is the reverse process where the byte
stream is used to recreate the actual object in memory. The byte stream
created is platform independent that means objects serialized on one
platform can be deserialized on another platform.
To make a Java Object serializable, the class must implement Serializable
interface. Serializable is a Marker interface. ObjectOutputStream and
ObjectInputStream classes are used for Serialization and Deserialization in
java.
We will serialize the below Employee class:

SerializationDemo.java:
Output:

Here, while de-serializing the employee object, salary is 0, that is because


we have made salary variable to be ‘transient’. ‘static’ and ‘transient’
variables do not take part in Serialization process. During de-serialization,
transient variables will be initialized with their default values i.e. if objects, it
will be null and if “int”, it will be 0 and static variables will be having the
current value.

And if you look at the file present in C:/temp/bytestream.txt, you can see
how the object is serialized into this file,
Question 57: What is SerialVersionUID?
Answer: SerialVersionUID: The serialization process at runtime associates an
id with each Serializable class which is known as SerialVersionUID. It is used
to verify the sender and receiver of the serialized object. The sender and
receiver must have the same SerialVersionUID, otherwise,
InvalidClassException will be thrown when you deserialize the object. A
Serializable class can declare its own UID explicitly by declaring a field. It
must be static, final and of type long. Remember, there is an exception for
SerialVersionUID that although it is static, it gets serialized too, so that at the
object deserialization the sender and receiver can be verified.
If a serializable class doesn’t explicitly declare a serialVersionUID, then the
serialization runtime will calculate a default one for that class based on
various aspects of class. This default serialVersionUID gets changed, when
you add a new field or remove the transient keyword from a variable or
convert the static variable to non-static variable. And if you are modifying
the class structure after Serialization has been done, you will not be able to
deserialize the object, see the example below:
Let’s change the Employee class in our previous example and remove the
transient keyword from salary variable:
Program 1:
We have already serialized the Employee object in our previous example,
now let’s try to de-serialize it back:

Output:
java.io.InvalidClassException: com.serialization.demo.Employee; local class
incompatible: stream classdesc serialVersionUID = -3697389390179909057,
local class serialVersionUID = -3759917827722067163
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at
com.serialization.demo.DeserializationTest.main(DeserializationTest.java:13)

Hence, it is strongly recommended that all serializable classes explicitly


declare serialVersionUID value, in case you are using an IDE and not giving
any serialVersionUID, compiler will give you a warning like below:

Example with SerialVersionUID:


Program 2:

SerializationDemo.java:
Output:

Now, let’s add one more field ‘company’ and remove the transient keyword
from our Employee class. Here, as we are changing the class structure, let’s
see if we get the error of InvalidClassException again:
Program 3:
DeserializationTest.java:

Output:

Some Points to remember:


- If a parent class has implemented Serializable interface then
child class doesn’t need to implement it but the reverse is not
true
- Static data members and transient data members are not
saved via Serialization process (serialVersionUID is an
exception). So, if you don’t want to save value of a non-static
data member then make it transient
- Constructor of serialized class is never called when the
serialized object is deserialized (in case of inheritance, no-arg
constructor of parent gets called during de-serialization)

Question 58: Serialization scenarios with Inheritance


Case 1: If super class is Serializable then by default, its sub-classes are also
Serializable
Output:
Case 2: When super class does not implement the Serializable Interface,
then also we can serialize the subclass provided that it implements
Serializable interface.
In this case, when we de-serialize the subclass object, then no-arg
constructor of its parent class gets called. So, the serializable sub-class must
have access to the default no-arg constructor of its parent class (general rule
is that the Serializable sub-class must have access to the no-arg constructor
of first non-Serializable super class).

(Note: serializeObject() and deserializeObject() remains same as the Case 1


program)
Output:

When no-arg constructor is present in Super class:


(Note: serializeObject() and deserializeObject() remains same as the Case 1
program)
Output:

Question 59: Stopping Serialization and De-serialization


Suppose, parent class implements Serializable interface but we don’t need
the child class to be serialized
Here, we can implement writeObject() and readObject() methods in sub-
class and throw NotSerializableException from these methods :
(Note: serializeObject() and deserializeObject() remains same as the
Question 58 - Case 1 program)
Output:
Serialization and De-serialization process can be customized also by
providing writeObject() and readObject() methods in the class that we want
to serialize.

Declaring both methods as private is necessary (public methods will not


work), so other than the JVM nothing else can see them. This also proves
that neither method is not inherited nor overridden or overloaded. The JVM
automatically checks these methods and calls them during the serialization-
deserialization process. The JVM can call these private methods, but other
objects cannot. Thus, the integrity of the class is maintained and the
serialization protocol can continue to work as normal.
For example, you can have encryption and decryption logic in these
methods.

Question 60: What is Externalizable Interface?


Answer: The default serialization process is very slow as it is fully recursive,
so whenever we try to serialize one object, the serialization process tries to
serialize all the fields of our class (except static and transient variables). So, if
we have a class with lots of variables present and we do not want to serialize
all of them, we have to make all of those variables as transient, all these
fields will always be assigned with default values. This makes the entire
process very slow.
Externalizable interface is used when we want to implement custom logic to
serialize/deserialize an object. Externalizable interface extends the
Serializable interface, and it has two methods, writeExternal() and
readExternal() which are used for serialization and de-serialization. This way,
we can change the JVM’s default serialization behavior because while using
Externalizable, we decide what to store in stream.
Program 1:
Employee.java:
TestExternalizable.java:

Output:
Now, one thing to remember here is that the public no-arg constructor gets
called before readExternal() method, so we have to provide this no-arg
constructor or else we will get an exception during run-time.
Comment the public no-arg constructor from Employee.java:
Program 2:

Now, run TestExternalizable.java, you will get below output:

So, if interviewer asks a question that you have a class which has 1000
variables and you want to serialize only 10 specific variables, your answer
should be using an Externalizable interface.
Some points to remember:
- Using Externalizable interface, we can implement custom logic
for serialization and deserialization of object
- When using Externalizable, we have to explicitly mention what
fields or variables we want to serialize
- When using Externalizable, a public no-arg constructor is
required
- Using Externalizable, we can also serialize transient and static
variables
- readExternal() method must read the values in the same
sequence and with the same types as were written by
writeExternal() method

Question 61: Externalizable with Inheritance


If a class is implementing Externalizable and also has a parent class, how we
can save the data of parent class and how we can recover it back. In case of
Externalizable, we have to implement the readExternal() and writeExternal()
methods in each and every class we want to serialize or deserialize.
Case 1: When both parent and child classes are implementing Externalizable
interfaces:
Department.java:
Student.java:
Here, in the overridden writeExternal() and readExternal() methods in child
class Student, we are also calling super.writeExternal() and
super.readExternal() methods to serialize and de-serialize fields of parent
class Department.

ExternalizableDemo.java:
Output:

The capacity and age variable values are 0 because we did not serialize these
two variables.

Case 2: When only child class is implementing the Externalizable interface


Department.java:
Student.java:
Here, we are using getters and setters of parent class, Department, to
serialize and de-serialize its fields.

ExternalizableDemo.java:
Output:

Question 62: Difference between Serializable and


Externalizable
Answer:
- Serializable is a marker interface which means it does not
contain any method whereas Externalizable is a child interface
of Serializable and it contains two methods writeExternal() and
readExternal()
- When using Serializable, JVM takes full responsibility for
serializing the class object but in case of Externalizable, the
programmer has full control over serialization logic
- Serializable interface is a better fit when we want to serialize
the entire object whereas Externalizable is better suited for
custom serialization
- Default serialization is easy to implement but it comes with
some issues and performance cost whereas in case of
Externalizable, the programmer has to provide the complete
serialization logic which is a little hard but results in better
performance
- Default serialization does not call any constructor whereas a
public no-arg constructor is needed when using Externalizable
interface
- When a class implements Serializable interface, it gets tied
with default serialization which can easily break if structure of
the class changes like adding/removing any variable whereas
using Externalizable, you can create your own binary format
for your object

Question 63: How to make a class Immutable?


Answer: As we know, String is an Immutable class in Java, i.e. once initialized
its value never change. We can also make our own custom Immutable class,
where the class object’s state will not change once it is initialized.
Benefits of Immutable class:
- Thread-safe: With immutable classes, we don’t have to worry
about the thread-safety in case of multi-threaded environment
as these classes are inherently thread-safe
- Cacheable: An immutable class is good for Caching because
while we don’t have to worry about the value changes
How to create an Immutable class in java:
- Declare the class as final so that it cannot be extended
- Make all fields as private so that direct access to them is not
allowed
- Make all fields as final so that its value can be assigned only
once
- Don’t provide ‘setter’ methods for variables
- When the class contains a mutable object reference,

1. While initializing the field in constructor, perform a


deep copy
2. While returning the object from its getter method,
make sure to return a copy rather than the actual
object reference
Example:
We will make Employee class as immutable, but Employee class contains a
reference of Address class
Address.java:
Employee.java:

TestImmutable.java:
Here, after creating Employee object, the first change is done in local
address object and then we used the employee’s getter method to access
the address object and tried to change the value in it.

Output:

As, you can see that the value remained the same.
If we don’t follow the rule about mutable object reference present in the
class, let’s see what will happen in that case.
Let’s change the Employee class constructor and getter method:
Employee.java:
Now, if we run our TestImmutable.java class, below is the output:

Why we perform deep copy in constructor:


- When you assign the actual address object in the constructor,
then remember it is storing the reference of address object, so
if you change the value in this address object, it will reflect in
the employee object
Why we don’t return original reference from the getter:
-
When you return the original address object from the getter
method then you can use the returned object reference to
change the values in employee object

Question 64: Explain Class loaders in Java


Answer: ClassLoader is a java class which is used to load .class files in
memory. When we compile a java class, JVM creates a bytecode which is
platform independent. The bytecode is present in .class file. When we try to
use a class, then classloader loads it into memory.
There are 3 types of built-in class loaders in java:
1. Bootstrap class loader: it loads JDK class files from jre/lib/rt.jar
and other core classes. It is the parent of all class loaders, it is
also called Primordial classloader.
2. Extensions class loader: it loads classes from JDK extensions
directory, it delegates class loading request to its parent,
Bootstrap and if the loading of class is unsuccessful, it loads
classes from jre/lib/ext directory or any other directory pointed
by java.ext.dirs system property.
3. System class loader: It loads application specific classes from the
CLASSPATH. We can set classpath while invoking the program
using -cp or classpath command line options. It is a child of
Extension ClassLoader.

Java class loader is based on three principles:

1. Delegation principle: It forwards the request for class loading to


its parent class loader. It only loads the class if the parent does
not find or load the class.
2. Visibility principle: According to Visibility principle, the child
ClassLoader can see all the classes loaded by parent ClassLoader.
But the parent class loader cannot see classes loaded by the
child class loader.
3. Uniqueness principle: According to this principle, a class loaded
by Parent should not be loaded by Child ClassLoader again. It is
achieved by delegation principle.

Suppose, you have created a class Employee.java and compiled this class
and Emloyee.class file is created. Now, you want to use this class, the first
request to load this class will come to System/Application ClassLoader,
which will delegate the request to its parent, Extension ClassLoader which
further delegates to Primordial or Bootstrap class loader
Now, Bootstrap ClassLoader will look for this class in rt.jar, since this class is
not there, the request will come to Extension ClassLoader which looks in
jre/lib/ext directory and tries to locate this class there, if this class is found
there then Extension ClassLoader will load this class and Application
ClassLoader will not load this class, this has been done to maintain the
Uniqueness principle. But if the class is not loaded by Extension ClassLoader,
then this Employee.class will be loaded by Application ClassLoader from the
CLASSPATH.
Employee.java:

Output:

If you are thinking why null is printed when we tried to know which
classloader is loading the java.lang.System class then take a look at the
Javadoc :
We can also create our own custom class loader by extending the
ClassLoader class.
Question 65: What is Singleton Design Pattern and how it
can be implemented?
Answer: This is a famous interview question, as it involves many follow-up
questions as well. I will cover all of them here:
What is Singleton Design Pattern?
Singleton design pattern comes under Creational Design Patterns category
and this pattern ensures that only one instance of class exists in the JVM.
Singleton pattern is used in:
- logging, caching, thread pool etc.
- other design patterns like Builder, Prototype, Abstract Factory
etc.
- core java classes like java.lang.Runtime etc.
How to implement Singleton Pattern
To implement a Singleton pattern, we have different approaches but all of
them have the below common concepts:

- private constructor to restrict instantiation of the class from


other classes.
- private static variable of the same class that is the only
instance of the class.
- public static method that returns the instance of the class, this
is the global access point for outer world to get the instance of
the singleton class.
The approaches to implement singleton pattern are:
Eager Initialization: In eager initialization, the instance of Singleton Class is
created at the time of class loading, this is the easiest method to create a
singleton class but it has a drawback that instance is created even though
client application might not even use it.
Example:
A.java:
Test.java:

Output:

We can also access the instance by using the classname like A.instance
because of static keyword but we will have to change its access modifier to
‘public’, so that it is visible outside the singleton class.
Let’s suppose you are creating a large object by using a lot of resources,
there may be a chance that object creation may throw an exception but the
above way of creating a singleton class does not provide any option for
exception handling as you can write try-catch only inside a block of code.
There is a solution to tackle this particular problem where you can create
the class instance inside a static block.

Static Block Eager Initialization:


Both the above approaches create the object even before it is used
(initialized at the time of class loading because of static variable and static
block), but there are other approaches where we can create a Singleton
class instance in a lazy initialization way i.e. only when someone asks for it.
These approaches are discussed below.

Lazy Initialization: using this way of creating Singleton class, the object will
not get created unless someone asks for it. Here we will create the class
instance inside the global access method.
This approach is suitable for only single-threaded application, suppose there
are 2 threads and both have checked that the instance is null and now they
are inside the “if(…)” condition, it will destroy our singleton pattern and both
threads will have different instances. So, we must overcome this problem so
that our singleton pattern doesn’t break in case of multi-threaded
environment.

Thread Safe Singleton implementation: here the easiest way to prevent


multiple threads from creating more than one instance is to make the global
access method ‘synchronized’, this way threads will acquire a lock first
before entering the getInstance() method.
Synchronizing the entire method comes with performance degradation, also
acquiring the lock and releasing the lock on every call to getInstance()
method seems un-necessary, because only first few calls to getInstance()
method needs to be synchronized, what I mean to say by this statement is:
let’s suppose there are 10 threads that are trying to call getInstance()
method, now you need to apply synchronization to only these 10 threads at
this time and the thread which first acquires the lock will create the object.
After that, every thread will get the same object because of null check in if
condition, so we can optimize the above code by using double-checked
locking principle, where we will use a synchronized block inside the if
condition, like shown below:
The reason of second if condition inside the synchronized block: suppose
there are 2 threads and both called the getInstance() method at the same
time, now they will both be inside the first if condition as instance is null at
this time, and the first thread which acquires the lock will create the object
and as soon as it exits the synchronized block, other thread which was
waiting, will acquire the lock and it will also create another object thus
breaking the singleton pattern. This is why it is called “double-checked
locking”.

Now, some people have faced issues with the above approach in java 1.4
and earlier versions, which was solved in later versions by using ‘volatile’
keyword with the above approach like below:
localRef variable is there for the cases where instance is already initialized
(discussed above), the volatile field is only accessed once because we have
written return localRef not return instance.
There is another approach where an inner static class is used to create the
Singleton class instance and it is returned from the global access method.
This approach is called Bill Pugh Singleton Implementation.
Bill Pugh Singleton Implementation Program:
The inner class does not get loaded at the time of class A loading, only when
someone calls getInstance() method, it gets loaded and creates the
Singleton instance.

Question 66: What are the different ways in which a


Singleton Design pattern can break and how to prevent
that from happening?
Answer: There are 3 ways which can break Singleton property of a class,
they are discussed below with examples:
Reflection: Reflection API in java is used to change the runtime behavior of a
class. Hibernate, Spring’s Dependency injection also uses Reflection. So,
even though in the above singleton implementations, we have defined the
constructor as private, but using Reflection, even private constructor can be
accessed, so Reflection can be used to break the singleton property of a
class.
A.java:
Notice, I am using public access modifier with the only instance of singleton
class so that it can be accessed outside this class using just the class name.
Now, let’s see how Reflection can break Singleton:

Test.java:
Output:

As we can see from the output, the 2 instances have different hashcode,
thus destroying Singleton.
Now to prevent Singleton from Reflection, one simple solution is to throw
an exception from the private constructor, so when Reflection tries to
invoke private constructor, there will be an error.

Now, if you run Test.java, you will get below output:


The other solution to prevent Singleton from Reflection is using Enums, as
its constructor cannot be accessed via Reflection, JVM internally handles the
creation and invocation of enum constructor
SingletonEnum.java:

TestSingletonEnum.java:
Output:

Another way which can break Singleton property of a class is:


Serialization and Deserialization: Our Singleton class may implement
Serializable interface so that the object’s state can be saved and at a later
point in time, it can be accessed back using Deserialization, now the problem
here is, when we deserialize the object, a new instance of the class will be
created, thus breaking the singleton pattern.
See, the example below:
A.java:
Test.java:

Output:
To prevent our Singleton class from Serialization, there is a method called
readResolve() which is called when ObjectInputStream has read an object
from the stream and is preparing to return it to the caller, so we can return
the only instance of this class from this method, and this way the only
instance of singleton will be assigned to instance2, see below:
A.java:

Test.java:
Output:

You can also throw an exception from the readResolve() method, but
returning the only instance approach is better as your program execution
will not stop.

One last way which can break Singleton property of a class is:
Cloning: As we know, Cloning is used to create duplicate objects (copy of the
original object). If we create a clone of the instance of our Singleton class
then a new instance will be created thus breaking our Singleton pattern.
See the program below:
TestSingleton.java:
Output:

As you can see, both instances have different hashcodes indicating our
Singleton pattern is broken, so to prevent this we can override clone method
in our Singleton class and either return the same instance or throw
CloneNotSupportedException from it.
See the program changes below:
Output:

clone() returning the same instance, see the program changes below:

Output:

Question 67: What are the different design patterns you


have used in your projects?
Answer: You will be asked this question almost in all interviews nowadays.
So, be prepared with some design patterns that are used in mostly all
projects, like:
- Factory Design Pattern
- Abstract Factory Design
Pattern
- Strategy Design Pattern
- Builder Design Pattern
- Singleton Design Pattern
- Observer Design Pattern
And any other if you have used in your projects.

Question 68: Explain Volatile keyword in java


Answer: Volatile is a keyword in java, that can be applied only to variables.
You cannot apply volatile keyword to classes and methods. Applying volatile
to a shared variable that is accessed in a multi-threaded environment
ensures that threads will read this variable from the main memory instead
of their own local cache.
Consider below code:

Now, let’s suppose 2 threads are working on this class and both threads are
running on different processors having their own local copy of variable x. if
any thread modifies its value, the change will not be reflected back in the
original variable x in the main memory leading to data inconsistency because
the other thread is not aware of the modification.
So, to prevent data inconsistency, we can make variable x as volatile:
Now, all the threads will read and write the variable x from/to the main
memory. Using volatile, also prevents compiler from doing any reordering or
any optimization to the code.

Question 69: What is Garbage Collection in Java, how it


works and what are the different types of Garbage
Collectors?
Answer: Garbage collection in java is the process of looking at heap memory,
identifying which objects are in use and which are not and deleting the
unused objects. An unused object or unreferenced object, is no longer
referenced by any part of your program.
Garbage collector is a daemon thread that keeps running in the background,
freeing up heap memory by destroying the unreachable objects.
There was an analysis done on several applications which showed that most
objects are short lived, so this behavior was used to improve the
performance of JVM. In this method, the heap space is divided into smaller
parts or generations. These are, Young Generation, Old or Tenured
Generation and Permanent Generation.
The Young Generation is where all new objects are allocated and aged. The
young generation is further divided into 3 parts: Eden Space, Survivor space
S0 and Survivor space S1. When the young generation fills up, this causes a
minor garbage collection. Some surviving objects are aged and eventually
move to the old generation. All minor garbage collections are "Stop the
World" events. This means that all application threads are stopped until the
operation completes. Minor garbage collections are always Stop the World
events.
The Old Generation is used to store long surviving objects. Typically, a
threshold is set for young generation object and when that age is met, the
object gets moved to the old generation. Eventually the old generation
needs to be collected. This event is called a major garbage collection. Major
garbage collection are also Stop the World events. Often a major collection
is much slower because it involves all live objects. So, for Responsive
applications, major garbage collections should be minimized. Also note that
the length of the Stop the World event for a major garbage collection is
affected by the kind of garbage collector that is used for the old generation
space.

The Permanent generation contains metadata required by the JVM to


describe the classes and methods used in the application. The permanent
generation is populated by the JVM at runtime based on classes in use by
the application. In addition, Java SE library classes and methods may be
stored here.

Classes may get collected (unloaded) if the JVM finds they are no longer
needed and space may be needed for other classes. The permanent
generation is included in a full garbage collection. And Perm Gen was
available till Java 7, it is removed from Java 8 onwards and JVM uses native
memory for the representation of class metadata which is called MetaSpace.
There is a flag MaxMetaspaceSize, to limit the amount of memory used for
class metadata. If we do not specify the value for this, the Metaspace re-
sizes at runtime as per the demand of the running application.

How Garbage collection works:


When new objects are first created, they are stored in the eden space of
Young Generation and at that time both Survivor spaces are empty. When
the eden space is filled, then a minor garbage collection is triggered. All the
unused or un-referenced objects are cleared from the eden space and the
used objects are moved to first Survivor space S0.
At the next minor garbage collection, same process happens, un-referenced
objects are cleared from the eden space but this time, the surviving objects
are moved to Survivor space S1. In addition, the objects that were in S0 will
also be matured and they also get moved to S1. Once all surviving objects
are moved to S1, both eden and S0 are cleared.
At the next minor GC, the same process repeats. When surviving objects
reached a certain threshold, they get promoted from Young generation to
Old generation. These minor GC will continue to occur and objects will
continue to be promoted to the Old generation.
Eventually, a major GC will be performed on the Old generation which
cleans up and compacts the space.

Types of Garbage collector in Java:


Serial GC:
Serial GC is designed for smaller applications that have small heap sizes of
up to a few hundred MBs. It only uses single virtual CPU for its garbage
collection and the collection is done serially. It takes around couple of
second for Full garbage collections.
It can be turned on by using -XX:+UseSerialGC
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -
XX:+UseSerialGC -jar C:\temp\test.jar

Parallel/Throughput GC:
Parallel garbage collector uses multiple threads to perform the garbage
collection. By default, on a host with N CPUs, this collector uses N garbage
collector threads for collection. The number of collector threads can be
controlled with the command line option: -XX:ParallelGCThreads=<N>
It is called Throughput collector as it uses multiple CPUs to speed up the
application throughput. A drawback of this collector is that it pauses the
application threads while performing minor or full GC, so it is best suited for
applications where long pauses are acceptable. It is the default collector in
JDK 8.
It can be turned on by using below 2 options:
-XX:+UseParallelGC
With this command line option, you get a multi-thread young generation
collector with a single-threaded old generation collector. The option also
does single-threaded compaction of old generation.
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -
XX:+UseParallelGC -jar C:\temp\test.jar
-XX:+UseParallelOldGC
With this option, the GC is both a multithreaded young generation collector
and multithreaded old generation collector. It is also a multithreaded
compacting collector.
Compacting describes the act of moving objects in a way that there are no
holes between objects. After a garbage collection sweep, there may be holes
left between live objects. Compacting moves objects so that there are no
remaining holes. This compacting of memory makes it faster to allocate new
chunks of memory to the heap.
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -
XX:+UseParallelOldGC -jar C:\temp\test.jar

Concurrent Mark Sweep (CMS) Collector:


The CMS collector, also called as the concurrent low pause collector, collects
the tenured generation. It attempts to minimize the pauses due to garbage
collection, by doing most of the garbage collection work concurrently with
the application threads.
It can be turned on by passing -XX:+UseConcMarkSweepGC in the command
line option.
If you want to set number of threads with this collector, pass -
XX:ParallelCMSThreads=<N>
java -Xmx12m -Xms3m -Xmn1m -XX:PermSize=20m -XX:MaxPermSize=20m -
XX:+UseConcMarkSweepGC -XX:ParallelCMSThreads=2 -jar C:\temp\test.jar

G1 Garbage Collector:
The Garbage First or G1 collector is a parallel, concurrent and incrementally
compacting low-pause garbage collector
G1 collector partitions the heap into a set of equal-sized heap regions. When
G1 performs garbage collection then a concurrent global marking phase is
performed to determine the liveliness of objects throughout the heap. After
this mark phase is complete, G1 knows which regions are mostly empty. It
collects unreachable objects from these regions first, which usually yields a
large amount of free space, also called Sweeping. So G1 collects these
regions (containing garbage) first, and hence the name Garbage-First.
It can be turned on by passing -XX:+UseG1GC in the command line options
java –Xmx25g –Xms5g -XX:+UseG1GC -jar C:\temp\test.jar

Java 8 has introduced one JVM parameter for reducing the unnecessary use
of memory by creating too many instances of the same String. This
optimizes the heap memory by removing duplicate String values to a global
single char[] array. We can use the -XX:+UseStringDeduplication JVM
argument to enable this optimization.
G1 is the default garbage collector in JDK 9.

Question 70: Explain Generics in Java


Answer: Java Generics provides a way to reuse the same code with different
inputs.
Advantages:
-
Generics provide compile-time type safety that allows
programmers to catch invalid types at compile time.
Before Generics:
After Generics:

-
When using Generics, there is no need of type-casting.
Before Generics:

After Generics:

-
By using generics, programmers can implement generic
algorithms that work on collections of different types, can be
customized and are type safe and easier to read.
Output:
Multi-threading: you will be asked many questions on multi-threading,
so, read as much as you can and whatever you can. Here, I am including
some of the important questions that are mostly asked in every interview.

Question 71: What is Multi-threading?


Answer: Multi-threading is a process of executing two or more threads
concurrently, utilizing available CPU resources. A single thread is a
lightweight sub-process and the smallest unit of processing. Threads are
independent, if any exception occurs in one thread, it does not affect other
threads.
When we execute a Java program without making any separate thread, then
also our program runs on a thread called ‘main thread’.
There are 2 types of threads in an application, user thread and daemon
thread. When the application is first started, main thread is the first user
thread created. We can create multiple user threads and daemon threads.
One thing to remember here is that, JVM does not have any control on a
thread’s execution. The thread execution is controlled by Thread scheduler
which is part of Operating System. A thread can be assigned a priority using
setPriority(int) method, where 1 is the minimum and 10 is the maximum
priority, however thread priority is not guaranteed as it is platform
dependent.
Multi-threading is used in a time-consuming task, one common example is
File Upload.

Question 72: How to create a thread in Java?


Answer: There are 2 ways to create a thread:
- By extending Thread class
- By implementing Runnable
interface
By extending Thread class:
ThreadTest.java:
Output:

Here a Task class extends Thread class and overrides the run() method which
contains the business logic, then we make an object of this Task and call the
start() method, which starts the thread execution. start() method internally
calls run() method.

By implementing Runnable interface:


ThreadTest.java:

Output:

If you see the outputs of this and previous program, you will see that they
are different, because any thread can get a chance to execute its run()
method, when the CPU resources are available.

Question 73: Which way of creating threads is better:


Thread class or Runnable interface
Answer: Implementing Runnable is always the preferred choice, see the
reasons below:
- As you know, Java does not allow multiple inheritance through
classes (because of Diamond problem discussed in Question 9),
so if you are creating threads by extending Thread class then
you will not be able to extend any other class.
- When we are working with multi-threading, we are not looking
to overwrite any existing functionality of Thread class, we just
want to execute the code with multiple threads, so in that way
also, Runnable is a good choice.
- One more reason to choose Runnable is that, most people
don’t work with just Raw Threads, they use the Executor
framework that is provided from Java 5, that separates the task
from its execution and we can execute Runnables using
execute(Runnable Task) method of Executor interface.

Question 74: What will happen if I directly call the run()


method and not the start() method to execute a thread
Answer: if run() method is called directly, then a new thread will not be
created instead the code will run on the current thread which is main
thread. Calling run() method directly will make it behave as any other
normal method call. Only a call to start() method creates separate thread.

Question 75: Once a thread has been started can it be


started again
Answer: No. A thread can be started only once in its lifetime. If you try to
start a thread which has already been started, an
IllegalThreadStateException is thrown, which is a runtime exception. A
thread in runnable state or a dead thread cannot be restarted.

Question 76: Why wait, notify and notifyAll methods are


defined in the Object class instead of Thread class
Answer: This is another very famous multi-threading interview question. The
methods wait, notify and notifyAll are present in the Object class, that
means they are available to all class objects, as Object class is the parent of
all classes.
wait() method – it tells the current thread to release the lock and go to sleep
until some other thread enters the same monitor and calls notify()
notify() method – wakes up the single thread that is waiting on the same
object’s monitor
notifyAll() method – wakes up all the threads that called wait() on the same
object

if these methods were in Thread class, then thread T1 must know that
another thread T2 is waiting for this particular resource, so T2 can be
notified by something like T2.notify()
But in java, the object itself is shared among all the threads, so one thread
acquires the lock on this object’s monitor, runs the code and while releasing
the lock, it calls the notify or notifyAll method on the object itself, so that
any other thread which was waiting on the same object’s monitor will be
notified that now the shared resource is available. That is why these
methods are defined in the Object class.
Threads have no specific knowledge of each other. They can run
asynchronously and are independent. They do not need to know about the
status of other threads. They just need to call notify method on an object, so
whichever thread is waiting on that resource will be notified.
Let’s consider this with a real-life example:
Suppose there is a petrol pump and it has a single washroom, the key of
which is kept at the service desk. This washroom is a shared resource for all.
To use this shared resource, the user must acquire the key to the washroom
lock. So, the user goes to service desk, acquires the key, opens the door,
locks it from the inside and use the facility.
Meanwhile if another user arrives at the petrol pump and wants to use the
washroom, he goes to the washroom and found that it is locked. He goes to
the service desk and the key is not there because it is with the current user.
When the current user finishes, he unlocks the door and returns the key to
the service desk. He does not bother about the waiting users. The service
desk gives the key to waiting user. If there are more than one user waiting to
use the facility, then they must form a queue.
Now, apply this analogy to Java, one user is one thread and the washroom is
the shared resource which the threads wish to execute. The key will be
synchronized keyword provided by Java, through which thread acquires a
lock for the code it wants to execute and making other threads wait until the
current thread finishes. Java will not be as fair as the service station,
because any of the waiting threads may get a chance to acquire the lock,
regardless of the order in which the threads came. The only guarantee is
that all the waiting threads will get to use the shared resource sooner or
later.
In this example, the lock can be acquired on the key object or the service
desk and none of them is a thread. These are the objects that decide
whether the washroom is locked or not.

Question 77: Why wait(), notify(), notifyAll() methods must


be called from synchronized block
Answer: these methods are used for inter-thread communication. So, a
wait() method only makes sense when there is a notify() method also.
If these methods are not called from a synchronized block then
- IllegalMonitorStateException will be thrown
- Race condition can occur
Let’s first look at the IllegalMonitorStateException:
WaitDemo.java:
Output:

Now, let’s understand how a race condition can occur:


Producer-Consumer problem: The problem describes two processes, the
producer and the consumer, who 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. The problem is to make
sure that the producer won't try to add data into the buffer, if it's full and
that the consumer won't try to remove data from an empty buffer.
The solution for the producer is to either go to sleep or discard data if the
buffer is full. The next time the consumer removes an item from the buffer,
it notifies the producer, who starts to fill the buffer again. In the same way,
the consumer can go to sleep if it finds the buffer empty. The next time the
producer puts data into the buffer, it wakes up the sleeping consumer.
Pseudo code:

How the race condition problem can occur:


Suppose, a thread has called the consume() method and it finds that the
buffer is Empty
Now, just before the wait() method is called, another thread calls produce()
and adds an item to the buffer and calls notify()
And The first thread calls the wait() method. In this case, notify() call by the
second thread will be missed
if by any chance, produce() method is not called then the consumer thread
will be stuck in waiting state indefinitely, even though there is data available
in the buffer.
The solution to above problem is using synchronized method/block to make
sure that notify() is never called between the condition isEmpty() and wait()
Question 78: difference between wait() and sleep() method
Answer: The differences are:

- wait() method can only be called from a synchronized context


while sleep() method can be called without synchronized
context
- wait() method releases the lock on the object while waiting but
sleep() method does not release the lock it holds while waiting,
it means if the thread is currently in a synchronized
block/method then no other thread can enter this
block/method
- wait() method is used for inter-thread communication while
sleep() method is used to introduce a pause on execution
- waiting thread can be waked by calling notify() or notifyAll(),
while sleeping thread will wake up when the specified sleep
time is over or the sleeping thread gets interrupted
- wait() method is non-static, it gets called on an object on which
synchronization block is locked while sleep() is a static method,
we call this method like Thread.sleep(), that means it always
affects the currently executing thread
- wait() is normally called when a condition is fulfilled like if the
buffer size of queue is full then producer thread will wait,
whereas sleep() method can be called without a condition

Question 79: join() method


Answer: join() method causes the current thread to pause execution until
the thread which has called join() method is dead.
join() method can be used to execute the threads sequentially or in some
specific order.
Let’s see an example below:
There are 3 threads and I want to execute them in the order 1, 3, 2:
JoinMethodDemo.java:

Output:
In the code, if you don’t write t2.join(), then current thread will not wait
from the t2 thread to die, see the output below when t2.join() statement is
commented from the code :

There are overloaded versions of join() method also,

- join(long milliseconds) : when this method is called, then the


current thread will wait at most for the specified milliseconds
- join(long milliseconds, long nanoseconds) : when this method
is called, then the current thread will wait at most for the
specified milliseconds plus nanoseconds.
These join methods are dependent on the underlying Operating system for
timing. So, you should not assume that join() will wait exactly as long as you
specify.
You can execute threads in a sequence using CountDownLatch also.

Question 80: yield() method


Answer: yield() method pauses the currently executing thread temporarily
for giving a chance to the remaining waiting threads of the same priority to
execute. If there is no waiting thread or all the waiting threads have a lower
priority then the same thread will continue its execution.
When the yielded thread will get the chance for execution is decided by the
thread scheduler whose behavior is vendor dependent. Yield method
doesn’t guarantee that the current thread will pause or stop but it
guarantees that CPU will be relinquished by current Thread as a result of a
call to Thread.yield() method in java.

Question 81: Tell something about synchronized keyword


Answer: synchronized keyword in java is used to control the access of
multiple threads to any shared resource, so that any consistency problem
can be avoided.
We can make the entire method as synchronized or just the part where the
shared resource is getting used, to do this synchronized blocks are used.
Synchronized method/block can only have one thread executing inside it, all
the other threads trying to enter into the synchronized method/block will
get blocked until the thread inside finishes its execution. When the thread
exits the synchronized method/block then Java guarantees that changes to
the state of the object is visible to all the threads. This eliminates the
memory inconsistency errors.

Question 82: What is static synchronization?


Answer: When synchronized keyword is used with a static method, then that
is called static synchronization. In this, lock will be on the class not the
object. This means only one thread can access the class at a time.
The purpose of static synchronization is to make the static data thread-safe.
Let’s look at some programs:
Here, we have a Hello class which has a synchronized method:

A Task class which implements Runnable and its run() method simply calls
the synchronized method of Hello class:
Our main class:
We have 2 objects of our Hello class, one object is shared among First and
Second thread, and one object is shared among Third and Fourth thread,
and we are starting these threads.
Output:
As you can see from the output, the First and Second thread are not having
any thread interference. Same way, Third and Fourth thread does not have
any thread interference but First and Third thread are entering the
synchronized method at the same time with their own object locks (Hello
obj1 and obj2).
Lock which is hold by First thread will only stop the Second thread from
entering the synchronized block, because they are working on the same
instance i.e. obj1, but it cannot stop Third or Fourth thread as they are
working on another instance i.e. obj2.

If we want our synchronized method to be accessed by only one thread at a


time then we have to use a static synchronized method/block to have the
synchronization on the class level rather than on the instance level.
Let’s see the output now:
Here, only one thread is accessing the static synchronized method.
Same can be done by synchronized block also:

Question 83: What will be output of below program where


one synchronized method is calling another synchronized
method?

Output:
One thing to remember here is that Java synchronized keyword is re-entrant
in nature, it means if a synchronized method calls another synchronized
method which requires same lock then current thread which is holding the
lock can enter into that method without acquiring lock.

Question 84: Programs related to synchronized and static


synchronized methods
There are some confusing programs that interviewer can ask where some
methods are static synchronized and some methods are non-static
synchronized, and sometimes they are calling each other, so let’s discuss
those.
Scenario 1: There are 2 threads that are calling 2 different static
synchronized methods.
Here, these 2 threads will block each other, as only one lock per class exists.
So, these 2 static synchronized methods will not be executed at the same
time.
Program:
Output:
Scenario 2: There are 2 threads, one is calling static synchronized method on
one object, and the other thread is calling non-static synchronized method
on another object.
Here, these 2 threads will not block each other and will be executed
concurrently as both locks are different, the thread executing the static
synchronized method holds a lock on the class and the thread executing the
non-static synchronized method holds the lock on the object on which the
method has been called.
In short, static synchronized method do not block a non-static synchronized
method.
Program:

(Main class is same as Scenario 1)


Output:
Question 85: What is Callable Interface?
Answer: Callable interface represents an asynchronous task which can be
executed by a separate thread, it has one call() method, which returns a
Future object.
A Runnable can be executed by passing it into the Thread class constructor
but Thread class does not have a constructor that accepts a Callable, so
Callable can be executed only by submit() method of ExecutorService
Interface.
Callable’s call() method can throw checked exceptions, the exceptions are
collected in Future object which can be checked by making a call to
Future.get() method, an ExecutionException is thrown which wraps the
original exception. We can get the original checked exception by making a
call to getCause() method on the exception object thrown. However, if we
don’t call Future.get() method then the exception will not be reported back
and the task will be marked as completed.
One thing you should remember is that the Future.get() method blocks the
execution, so timeouts should be used when using this method to avoid
unexpected waits.
Program showing how Callable is used and how the result is returned in
Future object:

Output:
Let’s pass a negative number, so that exception will be thrown:

Output:

You can call e.getCause() to get the original exception.

Question 86: How to convert a Runnable to Callable


Answer: We have a utility method in “Executors” class:
- callable(Runnable task) : Returns a Callable object that, when
called, runs the given task and returns null.
- callable(Runnable task, T result) : Returns a Callable object
that, when called, runs the given task and returns the given
result

Question 87: Difference between Runnable and Callable


Answer: The difference is:

- Runnable tasks can be executed by using Thread class or


ExecutorService interface whereas Callable tasks can be
executed by using ExecutorService interface only
- Return type of Runnable’s run() method is void whereas
Callable’s call() method returns Future object
- Runnable’s run() method does not throw checked exceptions
whereas Callable’s call() method can throw checked exceptions

Question 88: What is Executor Framework in Java, its


different types and how to create these executors?
Answer: Executor Framework is an abstraction to managing multiple threads
by yourself. So, it decouples the execution of a task and the actual task itself.
Now, we just have to focus on the task that means, only implement the
Runnables and submit them to executor. Then these runnables will be
managed by the executor framework. It is available from Java 1.5 onwards.
Also, we don’t have to create new threads every time. With executor
framework, we use Thread pools. Think of Thread Pool as a user-defined
number of threads which are called worker threads, these are kept alive and
reused. The tasks that are submitted to the executor will be executed by
these worker threads. If there are more tasks than the threads in the pool,
they can be added in a Queue and as soon as one of thread is finished with a
task, it can pick the next one from this Queue or else, it will be added back in
the pool waiting for a task to be assigned.
So, it saves the overhead of creating a new thread for each task. If you are
thinking about what is the problem with creating a new thread every time
we want to execute a task, then you should know that creating a thread is
an expensive operation. Thread objects use a significant amount of memory,
and in a large-scale application, allocating and deallocating many thread
objects creates a significant memory management overhead and new
threads without any throttling will lead to the creation of large number of
threads. These threads will cause wastage of resources.
There are 2 main interfaces that you must know, one is Executor and the
other is ExecutorService.
Executor interface contains execute(Runnable task) method through which
you can execute only Runnables. Also, the return type of execute() method
is void, since you are passing a Runnable to it and it does not return any
result back.
ExecutorService interface contains the submit() method which can take both
Runnable and Callable, and its return type is Future object. ExecutorService
extends the Executor Interface, so it also has the execute() method.

Now, we have an idea of what is an Executor Framework, let’s look at


different types of Executors:
SingleThreadExecutor:
This executor has only one thread and is used to execute tasks in a
sequential manner. If the thread dies due to an exception while executing
the task, a new thread is created to replace the old thread and the
subsequent tasks are executed in the new thread.
How to create a SingleThreadExecutor:
ExecutorService executor =
Executors.newSingleThreadExecutor();
Executors is a utility class which contains many factory methods to create
different types of ExecutorService, like the one called SingleThreadExecutor,
we just created.
FixedThreadPoolExecutor:
As its name suggests, this is an executor with a fixed number of threads. The
tasks submitted to this executor are executed by the specified number of
threads and if there are more tasks than the number of threads, then those
tasks will be added in a queue (e.g. LinkedBlockingQueue).
How to create a FixedThreadPoolExecutor:
ExecutorService executor =
Executors.newFixedThreadPool(5);
Here, we have created a thread pool executor of 5 threads, that means at
any given time, 5 tasks can be managed by this executor. If there are more
active tasks, they will be added to a queue until one of the 5 threads
becomes free.
An important advantage of the fixed thread pool is that applications using it
degrade gracefully. To understand this, consider a web server application
where each HTTP request is handled by a separate thread. If the application
simply creates a new thread for every new HTTP request, and the system
receives more requests than it can handle immediately, the application will
suddenly stop responding to all requests when the overhead of all those
threads exceed the capacity of the system. With a limit on the number of
the threads that can be created, the application will not be servicing HTTP
requests as quickly as they come in, but it will be servicing them as quickly as
the system can sustain.

CachedThreadPoolExecutor:
This executor is mainly used when there are many short-lived tasks to be
executed. If you compare this with the fixed thread pool, here the number
of threads of this executor pool is not bounded. If all the threads are busy
executing the assigned tasks and if there is a new task, then a new thread
will be created and added to the pool. If a thread remains idle for close to
sixty seconds, it is terminated and removed from the cache.
Use this one, if you are sure that the tasks will be short-lived, otherwise
there will be a lot of threads in the pool which will lead to performance
issues.
How to create a CachedThreadPoolExecutor:
ExecutorService executor =
Executors.newCachedThreadPool();

ScheduledExecutor:
Use this executor, when you want to schedule your tasks, like run them at
regular intervals or run them after a given delay. There are 2 methods which
are used for scheduling tasks: scheduleAtFixedRate and
scheduleWithFixedDelay.
How to create ScheduledExecutor:
ExecutorService executor =
Executors.newScheduledThreadPool(4);
ScheduledExecutorService interface extends the ExecutorService interface.

Now, apart from using Executors class to create executors, you can use
ThreadPoolExecutor and ScheduledThreadPoolExecutor class also. Using
these classes, you can manually configure and fine-tune various parameters
of the executor according to your need. Let’s see at some of those
parameters:

Core and Max Pool sizes:


A ThreadPoolExecutor will automatically adjust the pool size according to
the bounds set by corePoolSize and maximumPoolSize
When a new task is submitted to the executor then:
- If the number of threads running are less than the
corePoolSize, a new thread is created to handle the request
- If the number of threads running are more than corePoolSize
but less than maximumPoolSize then a new thread will be
created only if the queue is full
Let’s understand this with an example:
You have defined the core pool size as 5, maximum pool size as 10 and the
queue capacity as 100. Now as tasks are coming in, new threads will be
created up to 5, then other new tasks will be added to queue until it reaches
100. Now when the queue is full and if new tasks are coming in, threads will
be created up to the maximumPoolSize i.e. 10. Once all the threads are in
use and the queue is also full, the new tasks will be rejected. As the queue
reduces, so does the number of active threads.

Keep Alive Time and TimeUnit:


When the number of threads are greater than the core size, this is the
maximum time that excess idle threads will wait for new tasks before
terminating. It is used to avoid the overhead of creating a new thread.
Let’s understand this with an example:
You have defined the core pool size as 5 and maximum pool size as 15 and
all the 15 threads are getting used at the moment. Now when the threads
are getting finished with their work, the excess 10 threads (15-5) become
idle and eventually die. To avoid these 10 threads being killed too quickly,
we can specify the keep alive time for these by using the keepAliveTime
parameter in the ThreadPoolExecutor constructor. If you have given its value
as 1 and time unit as TimeUnit.MINUTE, each thread will wait for 1 min after
it had finished executing a task. Basically, it is waiting for a new task to be
assigned. If it is not given any task, it would let itself complete. And in the
end, the executor will be left with the core threads (5).

BlockingQueue:
The queue to use for holding tasks before they are executed. This queue will
hold only the Runnable tasks submitted by the execute method, you can use
a ArrayBlockingQueue or LinkedBlockingQueue like:
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<>
(100);

ThreadFactory:
The factory to use when the executor creates a new thread. Using thread
factories removes hardwiring of calls to new Thread, enabling applications to
use special thread subclasses, priorities, etc.

RejectedExecutionHandler:
This handler is used when a task is rejected by the executor because all the
threads are busy and the queue is full.
When this handler is not provided and the task submitted to execute()
method is rejected, then an unchecked RejectedExecutionException is
thrown.
But adding a handler is a good practice to follow, there is a method:
void rejectedExecution(Runnable r, ThreadPoolExecutor
executor);
This method will be invoked by ThreadPoolExecutor when execute() cannot
accept a task.

Putting it all together:

Question 89: Tell something about awaitTermination()


method in executor
Answer: This method blocks until all tasks have completed execution after a
shutdown request, or the timeout occurs, or the current thread is
interrupted, whichever happens first.

It returns true if this executor is terminated and false if the timeout is


elapsed before termination.

Question 90: Difference between shutdown() and


shutdownNow() methods of executor
Answer: An executor will not shut down automatically even when there is no
task to process. It will stay alive and wait for new work. It will keep the JVM
running.
When shutdown() method is called on an executor, then the executor will
not accept new tasks and it will wait for the currently executing tasks to
finish.
When shutdownNow() is called, it tries to interrupt the running threads and
shutdown the executor immediately. However, there is no guarantee that all
the running threads will be stopped at the same time.
One good way to shutdown an executor is to use both of these methods
along with awaitTermination(). With this approach, the executor will stop
accepting new tasks and waits up to the specified duration for all running
tasks to be completed. If the time expires, it will shutdown immediately.
Question 91: What is Count down latch in Java?
Answer: CountDownLatch is used in requirements where you want one or
more tasks to wait for some other tasks to finish before it starts its own
execution. One example can be a server which is dependent on some
services to be up and running before it can start processing requests.
How to use: When we create an object of CountDownLatch, then we specify
the number of threads that it should wait for, then waiting thread calls the
countDownlatch.await() method and until all the specified thread calls
countDownLatch.countDown() method, the waiting thread will not start its
execution.
For example, there are 3 services which a server is dependent on, before the
server accepts any request, these services should be up and running. We will
create a CountDownLatch by specifying 3 threads that the main thread
should wait for, then main thread will call await() method means it will wait
for all 3 threads. Once the threads are complete they will call countdown()
method, decreasing the count by 1. The main thread will start its execution
only when count reaches to zero.

You might also like