Java Fundamentals: Concepts and Structures
Java Fundamentals: Concepts and Structures
P - Static block
C - Static block
P - Initialisation block
P - Constructor
C - Initialisation block
C - Constructor
===============
==================
Compiler -
Interceptor -
JVM -
JRE -
JDK -
=====================
======
=============
JVm VS JDK
JVM -
Load Code.
Memomey allocation -
Class. - store class-level data, including class structures, method information, and static
variables.
Heap - Used to store objects created , All objects and their associated instance variables. ,
he actual data for class elds that belong to objects. — GC -
Native -
What It Is: Native memory is memory that is allocated outside the JVM's managed heap. It is
typically used by native code (e.g., JNI – Java Native Interface) and certain libraries like
DirectByteBuffer.
fi
fi
fl
Some operations require interaction with the operating system or native libraries, such as le I/O,
graphics processing, scanner , or networking. These operations often use native memory,
bypassing the garbage-collected heap.
JDK -
JIT compiler - Compilation: When a piece of code is executed multiple times, the JIT compiler
compiles that bytecode into native machine code for the speci c CPU architecture. Native code
is much faster to execute than interpreted bytecode.
JVM Architecture -
==
=====
Access speci ers de ne the visibility or scope of classes, methods, and variables in Java.
They determine whether other classes can access the elements of a class or not. The four main
access
Private -
Default -
Protected - Inheritance
Public.
=======
Access modi ers are a broader category that not only includes access speci ers but also
includes other modi ers that a ect how a member behaves in Java. The main access
modi ers
Public
Proceed
Default
Private
Final
Abstract
Static
Synchronised
Native
fi
fi
fi
fi
fi
fi
ff
fi
fi
fi
Transient - If you don’t want to write elds using serizlizable
Volatile
=======
Data Type
Non Private -
================
What is Unicode ?
Max -\UFFFF
Min - \U0000
Internationalization: With the rise of global communication and the internet, there was a
growing need for a character encoding system that could accommodate multiple languages and
scripts. Prior to Unicode, many encoding systems were limited to speci c languages (like ASCII
for English), making it dif cult to represent text in other languages.
===================
Naming convention -
=====================
===================
fl
fl
fi
fi
fi
Why we need mothods -
Code rreaulbality
=======================================
// New keyword
Executore objExe = new Executore();
// New instance
Class objClass = [Link]("[Link]");
Executore objclassin = (Executore) [Link]();
// Clone in java
Two types
Deep cloning -
// factory method
// Decerilizarion
========
Rules -
fi
- Same name as class
- We can’t add return type
==================
Static
===============================
Java principle
SOLID -
S - Single Responsibility
O - Open for extension and close for modi cation (Base calss should not be modi ed )
L - Liskov Substitution Principle (LSP) - The Liskov Substitution Principle says a subclass
should be substitutable for its superclass without altering the correctness of the
program.
This means that when you design a subclass, it should behave in a way that
doesn’t violate the expectations set by the superclass. If a class B is a subclass
of A, you should be able to replace instances of A with instances of B without
breaking the program.
I - Interface Segregation Principle - No client should be forced to depend on methods
it does not use.
D - Dependency Inversion Principle (DIP).
High-level modules should not depend on low-level modules. Both should depend on
abstractions. Abstractions should not depend on details. Details should depend on abstractions.
===
Inheritance -
====
Abstraction
===
Encapsulation
=====
Interface
Marker Interface: An interface with no methods. It is used to mark a class with some metadata.
For example, Serializable, Cloneable and remoting in Java.
- Serialisation - ObjectOutputStream - writeObject() , ush() , close()
- Deserilization - ObjectInputStream - readObject()
Its different topic - Externalisation - Write Object in to byte stream in compressed format .
Externalization is a more advanced way of customizing the serialization process. It allows you
to control the serialization and deserialization of an object's state more explicitly than the default
serialization mechanism. You do this by implementing the Externalizable interface,
which requires you to de ne the writeExternal and readExternal methods
Functional Interface: An interface with only one abstract method, introduced with Java 8 for
lambda expressions. For example, Runnable, Callable, and Comparator.
Normal Interface: These are standard interfaces that can have multiple abstract methods. For
example, List, Map, etc.
============
Polymorphism in java -
fi
fi
fl
Runtime - Overrding - Dynamic binding
Complitime - Overloading - Static binding
Overloading -
Same class ,
Same method name
Diffret parameter ,
No - But there operator which act like operator overloading that is + only
Overrding -
Inheritance
Same name
Same param
Visibility of the method
Return type ? It should be the same .
Can we change the return type no but there concept called Co -varient return type -
Covariant return type is a concept in Java that allows a subclass to override a method of its
superclass with a return type that is a subclass of the original return type. This means that when
you override a method, you can change the return type to a more speci c type (subclass) while
still maintaining the same method name and parameter list.
Key Points:
1. Same Method Signature: The method name and parameter list must be identical to the
method in the superclass.
2. Subclass Return Type: The return type of the overriding method can be a subclass of the
return type de ned in the superclass.
fi
fi
fi
fi
Parent Object class return. - then your subclass method can return Object , String , and
StringBuffer bus Object class is super class of String and StringBuffer
Parent Class method return Number then child class method can return - Integer , oat ,
double
Ex if the super class method is default you can not change the visibility in sub class
method to Private or Protected .
======================================================
====================
Static VS Final
Class leave. - Metod level
Static block - Decalarion time , Instance initlization block , Constructor
fi
fi
fl
What is static nal black variable ? - Should be initiate at a stick block or delcarion time
Instance of Operator
==============================
Java Array
=================
Wrapeer classes -
Class 8
Primitive to object ?
int i = 10;
Integer intVal = i;
// unboxing
1. State Consistency
• Immutability ensures that once an object is created, its state cannot change. This
predictability is crucial in programming, as it allows developers to reason about the
behavior of their code without worrying about unintended side effects.
2. Avoiding Bugs
• When an object is immutable, it cannot be modi ed after creation, reducing the risk of
bugs that stem from modifying shared or referenced objects. This is particularly important
in multi-threaded applications where multiple threads might access the same object.
3. Thread Safety
• Immutable objects are inherently thread-safe because their state cannot change. This
means that multiple threads can operate on the same instance of a wrapper class without
the need for synchronization, simplifying concurrent programming.
4. Performance Optimization
• Java takes advantage of the immutability of wrapper classes to cache frequently used
values. For example, Integer caches instances for values between -128 and 127. If
you create an Integer with a value within this range, it will reuse the existing instance
instead of creating a new one, which saves memory and improves performance.
5. Simpler Design
• Immutability simpli es the design of classes and APIs. Users can safely share immutable
objects without worrying about changes affecting other parts of the code. This leads to
cleaner, more maintainable code.
6. Functional Programming Paradigms
fi
fi
• The immutability of wrapper classes aligns with functional programming principles,
which promote the use of immutable data structures to avoid side effects. This is
increasingly important as more Java developers adopt functional programming styles
introduced in Java 8 (like Streams and Lambdas).
After you reassign ii to 24, the original Integer object holding the value 10 still exists in
memory (due to caching) but is no longer referenced by ii.
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference<V>
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray<E>
Recursion in java -
===============
Call by Value:
• In Java, when you pass a variable (either a primitive type or a reference) to a method, you
are passing a copy of its value.
• This means that any changes made to the parameter inside the method do not affect the
original variable outside the method.
Passing References:
• When you pass an object to a method, you are passing a copy of the reference (the address
in memory) to that object.
• This allows the method to modify the contents of the object (like its attributes), but if you
try to change what the reference points to (assign a new object), it won’t affect the
original reference outside the method.
======================
The strictfp keyword in Java is used to ensure that oating-point calculations yield
the same results on all platforms.
strictfp stands for strict oating-point. When you declare a class, method, or interface with
the strictfp modi er, you are enforcing the use of strict oating-point calculations, adhering
to the IEEE 754 standard.
class Example { strictfp oat calculate( oat a, oat b) { return a * b; // Strict oating-point
operation } oat anotherCalculation( oat a, oat b) { return a + b; // Not strict, could yield
different results on different platforms } }
—
This we can not apply on - Variables , Abstract methods ,and Constructor
======================================
Non Static
- Member inner class
Class A {
Class b{
}
}
Yes, an inner class (non-static member class) in Java can access all members of the outer class,
including private members. This is one of the key features of inner classes in Java.
you cannot have a static method in a non-static inner class (also known as a member inner
class) in Java.
In Java, the name of an inner class (both non-static inner classes and static nested classes)
depends on how it is nested within the outer class. The inner class's name is composed of the
outer class's name followed by the inner class's name, with a $ symbol used internally by the
Java compiler to separate them.
fl
fl
fl
fi
fl
fl
fl
fl
fl
fl
fl
fl
fl
fl
Ex = OuterClass$StaticNestedClass
An anonymous inner class in Java is a type of inner class that doesn't have a name. It is often
used when you need to create a one-time, quick implementation of an interface, abstract class, or
concrete class, usually in a concise manner. Anonymous inner classes are typically used to handle
events or provide speci c behavior for a single-use scenario.
An anonymous inner class in Java is a type of inner class that doesn't have a name. It is often
used when you need to create a one-time, quick implementation of an interface, abstract class, or
concrete class, usually in a concise manner. Anonymous inner classes are typically used to handle
events or provide speci c behavior for a single-use scenario.
A local inner class in Java is a class de ned within a block of code, such as a method,
constructor, or even within a loop or conditional block. It is local to the scope in which it is
de ned, meaning it can only be used within that block.
Static
- Static netset class
In Java, a static inner class (also known as a static nested class) is a class that is de ned inside
another class but is declared as static.
=================================
Packages in java -
Default packages imported in java is Lang - [Link] , String Class - We dot need to
import anything
fi
fi
fi
fi
fi
fi
Can we import package twice same package ? Yes but no use .
Do you need to import subpackage ? Yes
Static import in Java allows you to access static members ( elds and methods) of a class directly
without having to qualify them with the class name.
====================================
Design Patterns :
Structural - Structural design patterns deal with object composition, ensuring that if
one part of a system changes, the entire system doesn't need to do the same.
Creational : -
Singleton: Ensures a class has only one instance and provides a global point of access to it.
Rules :
- Private static data member / Object only one memory is created
- private constructor - No instance created
- public satic method so that we can access from anywhere without object creation ,.\
// Public method to provide access to the instance. - You are allowing to access the created
instance
fi
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton(); // Create the instance if it doesn't exist
}
return instance;
}
}
Types SingleTone
Eagger loading - As soon as you load the calls that time it will create the
instance of the class
Lazy Loading - When you call the method that it will check if the instance ic
created if not then only create .
Question -
if (objSingtoneEagger == null) {
synchronized ([Link]) {
if (objSingtoneEagger == null) {
objSingtoneEagger = new SingtoneEagger(); // Create the
instance if it doesn't exist
}
}
}
return objSingtoneEagger;
fi
}
Thread safe - Only one can access at a time - Concurrent modi cation
Exception
Non Thread Safe - This can not Does not throw
It is better to make only the require dblock synchronised. So that other thread
can nish the work and wait for block and it will save the time for other and
execution will be after
Yes we can
Can we deserialise it ? Yes we can but it will not return the singletons
instance .
a Singleton class can be serialized in Java, but care must be taken when deserializing the object.
By default, deserialization creates a new instance of the class
If you want to Decerlizes the singletons class but you want to get only one instance we need to
use readResolve() ;
Unit Testing
Tightly coupled
If the singleton class is corrupt entire system will fail .
- Serialisation
- Clone - Using closable inter implement the clone method in Singleton class then create then
use close method. -
Singleton singleton2 = (Singleton) [Link]();
- Re ection - Accessing the constructor of the ringtone class and set the constructor as
accessible true then create new Instance .
Constructor<Singleton> constructor = [Link]();
[Link](true);
// Make the constructor accessible
fl
fi
fi
Singleton singleton2 = [Link](); // Create a new instance
Exa :
package [Link];
}
return objSingtoneEagger;
============================
Factory Method:
The Factory Design Pattern is a way to create objects without the client knowing the exact class
being created. Instead of the client directly making an object, it asks a factory to do it. The
factory decides which object to make and returns it.
The Factory Method Design Pattern is a creational design pattern in Java that
allows for the creation of objects without specifying their exact classes
- Client only know the factory method not how the Instace are created . He just know to use iit .
- The Factory pattern abstracts the creation logic, allowing easy extension and modi cation.
It decouples the client from speci c implementations, making the system exible and
maintainable.
- You can easily add new object types (e.g., new payment methods or noti cation channels)
without touching existing code, following the Open/Closed Principle.
• The Factory pattern encapsulates the logic of creating objects in one place. If the object
creation process changes, you only need to modify the factory rather than touching
multiple parts of your codebase. This makes your code easier to maintain and scale.
2. Promotes Loose Coupling
• It decouples the client code from the concrete implementations. The client interacts with
the factory to get objects instead of creating them directly, allowing you to change object
implementations without affecting the client code.
3. Improved Code Reusability
• Since the factory handles object creation, it can be reused across different parts of your
application. You can centralize complex object creation logic, making it easier to update
or extend the system in the future.
4. Enhanced Scalability
• The Factory pattern simpli es adding new classes or subclasses. If new types of objects
need to be created, you can easily extend the factory without modifying existing client
code, which is ideal for scalable systems.
5. Supports Dependency Injection
• In unit tests, you can use the factory to inject mock objects or dependencies, which
improves testability. It isolates the creation process, making it easier to create controlled
test cases without dealing with complex setup code.
7. Encourages Adherence to SOLID Principles
• The Factory pattern aligns well with the Single Responsibility Principle (SRP) and the
Open/Closed Principle (OCP). The factory class handles the responsibility of object
creation, and new object types can be added without modifying existing code, which
follows OCP.
8. Improved Readability and Maintenance
• A well-structured Factory method makes the code more readable by clearly separating the
object creation process. This is useful in live projects with a large team, as it makes the
code easier to understand and maintain.
fi
fi
fi
fi
fl
fi
fi
============================================
-
Abstract Factory: Provides an interface for creating families of related or dependent objects
without specifying their concrete classes.
The Abstract Factory Design Pattern is a creational pattern that provides an interface to create
families of related or dependent objects without specifying their concrete classes. Unlike the
Factory pattern, which deals with creating a single product, the Abstract Factory pattern is used to
create families of related products. Each "factory" created by the Abstract Factory produces
related objects that follow a consistent theme or set of rules.
====================================
Prototype: Creates new objects by copying an existing object, known as the prototype.
The Prototype Design Pattern is a creational design pattern that allows you to create new
objects by copying an existing object, known as a prototype. This pattern is particularly useful
when the cost of creating a new instance of an object is more expensive than copying an existing
one.
Key Concepts
1. Prototype: The original object that serves as the template for creating new objects.
2. Cloning: The process of creating a copy of the prototype.
3. Deep Copy vs. Shallow Copy: A deep copy creates a new instance of the object and also
copies all objects referenced by the original object, while a shallow copy copies only the
references.
• Performance Improvement: Reduces the overhead of creating new objects when the
existing object is complex or expensive to create.
• Flexibility: You can create variations of an object without modifying the original
prototype.
• Decoupling: Clients can create objects without knowing the speci c class of the objects
they create.
• Ex -
// Clone the original car Car clonedCar = (Car) [Link]();
========================================
Builder: Separates the construction of a complex object from its representation, allowing the
same construction process to create different representations.
The Builder Design Pattern is a creational design pattern that provides a way to construct
complex objects step by step. It allows you to create different representations of an object using
the same construction process. This pattern is particularly useful when an object requires a large
number of parameters or when the construction process involves several steps that may vary.
Key Concepts
fi
fi
1. Builder: An interface or abstract class that de nes methods for creating parts of a
product.
2. Concrete Builder: A class that implements the builder interface and provides speci c
implementations for constructing the product.
3. Product: The complex object that is being built.
4. Director: A class that constructs the object using the builder interface. It de nes the order
in which to call the building methods.
Bene ts of the Builder Pattern
=================================
====================================================
fi
fi
fi
fi
fi
Structural design pattern -
The Bridge Design Pattern is a structural design pattern that separates an abstraction from
its implementation so that the two can vary independently. It is often used when we need to
decouple complex hierarchies into separate hierarchies, allowing more exibility and reusability.
◦ Shape and Color are independent, allowing you to extend them separately.
◦ Adding new shapes or colors does not require creating new subclasses for each
combination.
2. Avoids Class Explosion:
◦ Without the Bridge pattern, adding one more shape (e.g., Triangle) and one
more color (e.g., Green) would require 3×3 = 9 combinations.
◦ With the Bridge pattern, you can simply add one class for the new shape and one
for the new color.
3. Open/Closed Principle:
The Composite Design Pattern is used to compose objects into tree structures to represent part-
whole hierarchies. It allows individual objects and compositions of objects to be treated
uniformly. Below are multiple examples in Java to illustrate the concept.
The Proxy pattern suggests that you create a new proxy class with
the same interface as an original service object. Then you update
your app so that it passes the proxy object to all of the original
object’s clients. Upon receiving a request from a client, the proxy
creates a real service object and delegates all the work to it.
fi
fl
The Proxy Design Pattern is a structural design pattern that provides an object representing
another object. The proxy acts as an intermediary, controlling access to the real object. The proxy
object can perform additional operations such as lazy initialization, access control, logging,
monitoring, or caching before delegating the call to the real object.
In simple terms, a decorator is an object that allows you to add new behavior to an existing
object. Decorators are often used when you need to extend the functionality of classes in a
exible and reusable way.
The Facade Design Pattern is a structural design pattern that provides a simpli ed interface to a
complex subsystem. It hides the complexity of the system and exposes only the necessary
operations. This is useful when you want to make a subsystem easier to use, while still
maintaining the system’s internal complexity.
The Flyweight Design Pattern is a structural pattern that aims to reduce memory usage by
sharing common parts of objects instead of creating multiple instances of the same object. It is
particularly useful when many objects are created that share some common data but differ in
other aspects
=======
String
What is string -
String immutability in Java provides several bene ts, including security, thread safety, memory
ef ciency, and consistent behavior in collections.
==
Equals
compareTo
Two ways
+
Contact();
// Internal implementation of + operator
public class StringInternExample { public static void main(String[] args) { // String literal stored
in String Pool String str1 = "Hello"; // New String object created in heap String str2 = new
String("Hello"); // Before interning [Link](str1 == str2); // Output: false (different
references) // Interning the string str2 = [Link](); // After interning [Link](str1 ==
str2); // Output: true (same reference from String Pool) } }
/////////////
Immutable no. no
Override Equals No No
And compareTo
Methods
Sysnchronised. Yes. No
================
op = [Link]@3abfe836
[Link]().getName()+”@"+[Link](hashCode())
-What is SCP or what Stringpool ? When you create string using Laiteral it stops the values in
String pool
-String is primitive or non primitive ?
-Which one is the nal calls in all other String , StringBu er and StringBuildr - All of them .
- can we cal String class methods using string literal ? Yes
- When you create a string using the new String("hello") syntax without using a
string literal anywhere, Java will create two objects in memory:
1. String in the Heap: The new String("hello") creates a new String object in
the Heap. This object contains the string "hello".
2. String in the String Pool: When you create a String using new
String("hello"), the string literal "hello" is implicitly added to the String
Pool (if it isn't already there) when it is used inside the new statement. So, even though
you didn't explicitly use the string literal "hello", the string value will be added to the
String Pool.
================================================
Clone()
equals()
toString()
getClass()
Notify()
notifyall()
wait()
hasHcode()
nalised() - it is always called by GC (Garbage Collection)
- Which class does override equal and hashcode method - StringBu er and StrinBuilder
- Why wait notify and notify al in object class - Because these methods only called on Object
and These methods are used for Object commutation .
- Any nal method in Object calss ? Wait , Notify and Notifall .
- What is hashCode ? What is HasshCode Contract ?
1 - If the two objects are equal using equal method . Then has code should return the same
integers .
2 - If the two objects are equal using equal methods does not guaranty it will return the same
has code .
3 - Whenever it is invoked on the same object more than once during an execution of java
application it should return the same has code .
fi
ff
fi
fi
ff
ff
What is hashCode ? -
No, the hashCode() method in Java does not return the memory location of the object. While
the default implementation of the hashCode() method in the Object class might return an
integer derived from the memory address in some JVM implementations, this is not guaranteed
and is generally considered an implementation detail.
What Does hashCode() Return?
• Return Type: It returns an integer (int) that is used to identify the object in hash-based
collections.
• Contents of the Hash Code: The integer returned by hashCode() is typically derived
from the object's state, but it does not directly re ect the memory location. Instead, it is a
computed value based on the object's elds or other factors that are used for comparison.
* When we overdid the Hascode and Equal methods ? To compare the object and thee values ?
Code -
@Override
public int hashCode() {
return [Link](dep, empId, name);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != [Link]())
return false;
Employee other = (Employee) obj;
return [Link](dep, [Link]) && empId == [Link] &&
[Link](name, [Link]);
}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
[Link]([Link](emp1));
[Link]([Link](emp3));
[Link](emp);
[Link](emp1);
[Link](emp3);
[Link](eeList);
[Link](emp1);
[Link]([Link](eeList2));
[Link](setEE);
///////
}
}
true
false
[[Link]@89d52224,
[Link]@89d52224,
[Link]@eab7310]
false
[[Link]@89d52224,
[Link]@eab7310]
true
false
[[Link]@0,
[Link]@0,
[Link]@0]
false
[[Link]@0,
[Link]@0]
====
In your Employee class, the hashCode() method uses the [Link]() function
to combine the hash values of the dep, empId, and name elds. This ensures that two
Employee objects with the same empId and name will have the same hash code, which is
crucial for proper operation in hash-based collections.
Explanation:
• HashMap: Similarly, the HashMap uses the hash code to determine the "bucket" where
the object should be stored and retrieves it ef ciently based on the key.
• Objects that should be considered equal (based on business logic, such as empId and
name) could be treated as different if their hash codes differ.
• Since HashSet and HashMap rely on both methods for equality checks and
placement, failing to override equals() could lead to incorrect behavior, such as
duplicate objects being stored in a HashSet.
For example, without equals(), the HashSet might allow two objects with the same
empId and name but different reference addresses, because the default equals() method
from Object compares object references (memory locations), not content.
• If two objects are equal according to equals(), but they have different hash codes, the
collections like HashSet or HashMap may behave incorrectly.
• For instance, when you add an object to a HashSet, the hashCode() is used to
determine which "bucket" the object belongs to. If two equal objects have different hash
codes, the HashSet will fail to nd the matching object and might store duplicates.
5. Scenario: You have two Employee objects with identical empId and
name, but they belong to different departments. What will happen when you
add them to a HashSet?
Explanation:
In this case, two Employee objects have the same empId and name, but different dep.
• The equals() method compares all three elds: dep, empId, and name.
fi
fi
fi
fi
fi
fi
fi
• Since the dep eld differs between the two objects, the equals() method will return
false (they are not equal).
• Consequently, the hashCode() method will return different hash codes for the two
objects because dep is a part of the hash calculation.
• As a result, when you add both Employee objects to a HashSet, they will be treated
as distinct objects and both will be added to the HashSet.
Example Code for this Scenario:
java
Copy code
Employee emp1 = new Employee("IT", 101, "Alice");
Employee emp2 = new Employee("HR", 101, "Alice");
Explanation:
If both Employee objects have the same empId, name, and dep, they are logically equal
according to the equals() method.
• The hashCode() method will also return the same hash code for both objects.
• When you add the second object to the HashSet, it will not be added, because the
HashSet already contains an object that is considered equal to the new one based on
equals(), and both objects share the same hash code.
Example Code for this Scenario:
java
Copy code
Employee emp1 = new Employee("IT", 101, "Alice");
Employee emp2 = new Employee("IT", 101, "Alice");
• Two Employee objects with the same empId but different name or dep would be
considered equal based on the equals() method (since empId is not involved in the
comparison).
• However, this would be logically incorrect because empId is a key identi er for
employees, and two employees with different name or dep but the same empId should
not be considered equal.
• Also, since empId is not included in hashCode(), it could result in collisions in
hash-based collections, causing inef cient lookups and possible errors.
8. Can you add objects with different empId but the same name and dep to
the same HashSet?
Explanation:
Yes, you can add objects with different empId values but the same name and dep to the same
HashSet, as long as the equals() and hashCode() methods are correctly implemented
to re ect the equality logic. If empId is included in both equals() and hashCode(), they
will be treated as different objects because empId is a part of their equality check.
=====================================
Exception handling
Throwable - Class
Di erence Betweee
Can we delayer only try without catch or nally ? - You can not
Can we have multiple catch block ? Yes at time only one catch block will be executed .
Will the nally block always executed ? Yes
Discussed why nally is IMP - close db connection , close les …..
Catch block should follow the most speci c to most generic sequence .
What is nested try block ?
Finally - use for IMP code . There few scenarios where nally block to be executed \
- [Link]();
- Hardwere failure
}
catch(Exception e) {
[Link](e);
}
Throws keyword -
The throws keyword used to propagate / forward the exception from one method to another -
Throw Throws
Throw exclipctly exception Declare exception
Throw followed by instance - new Method and class
You can not throw the mutliple You can Throw multiple exception
Exception methodE() throws IOException , Exception {
What is try-with-resources?
The try-with-resources statement in Java is used to ensure that resources (like les,
streams, or database connections) are closed automatically after the operations on them are done.
It was introduced in Java 7.
Explanation
Custom Exception : -
How to create custom exception - Declare the calls , Extend the exception class .
- Create a class
- Extends Exception class .
-
Earlier
Exception in thread "main" [Link]:
Come back later
at
[Link]([Link])
Ex -
package [Link];
Call -
Interview question -
What is exception ?
How exception can be handled ?
What is the di erence between Exception and Error
Can we keep other statements between tray and catch block ? No
Can we write try block without catch and nally ? No
What is unreachable catch block exception ? Most speci c to most generic ow missed it .
Ex - catch (Exception e) {
[Link]("Caught exception in main: " + [Link]());
}
catch (IOException e) {
[Link]("Caught exception in main: " + [Link]());
}
What is printTrackTrace() ?
Can we write return statement in try catch block ? Yes but we need to add in try and catch both .
try {
return 0;
}
catch (Exception e) {
return 0;
}
Return statement in Try only or catch only will throw the error .
We can not write anything after return statement - Will get Unreachable code exception .
Ex -
try {
return 0;
[Link](); - Error line
}
catch (Exception e) {
return 0;
}
==============
But still you can request JVM to run GC - how ? Two ways
[Link]();
[Link]().gc();
[Link]().runFinalization();
Heap
Objects in Eden are not promoted directly to the Old Generation unless special circumstances
arise (e.g., large objects with size exceeding a threshold).
Objects must rst be moved to a Survivor space and then survive the required number of Minor
GCs.
Once promoted, the object resides in the Old Generation, where Major GC is responsible for
reclaiming memory.
Stack
A obj = new A();
- To store the object reference ex - obj; methods calls , local variables , Addresss
Native
Register
Class
========
fi
fi
fi
Thread ?
Thread lifecycle ?
Runnable -
public class ThreadRblImpl implements Runnable {
@Override
public void run() {
[Link]("Thread is running");
Thread class
package [Link];
@Override
public void run() {
[Link]("Thread is running");
}
Runable -
Thread class -
When you want to create a custom thread.
When you need to override the thread's behavior (e.g., adding extra functionality like
setting priorities, etc.).
When you need to control the thread more directly by extending the Thread class.
◦ If you're only looking to execute a task in a separate thread, and you don't need to
extend the Thread class, use Runnable.
◦ Example: Running a simple background task in a multi-threaded environment.
2. Scenario 2: Need for Custom Thread Behavior
◦ If you need more control over the thread itself (such as adjusting its priority,
handling interruptions, etc.), extend the Thread class.
◦ Example: Creating a thread that does something speci c, like interacting with
system resources or changing thread priorities.
3. Scenario 3: Task Reusability and Thread Pooling
◦ If you need to create a thread pool, where tasks are executed by different threads,
use Runnable with a ThreadPoolExecutor.
◦ Example: Implementing a task executor that processes a large number of tasks
concurrently.
start()
This method is used to begin the execution of the thread. It invokes the run() method
internally and starts the thread in a new, separate path of execution.
run()
This method contains the code that constitutes the thread’s task. The run() method is invoked
automatically when the thread starts, typically after start() is called.
sleep(long millis)
This method makes the current thread sleep (pause execution) for the speci ed number of
milliseconds.
Ex - [Link](2000);
fi
fi
join()
This method allows one thread to wait for the completion of another thread. It blocks the calling
thread until the thread it's called on nishes execution.
interrupt()
This method interrupts a thread, causing it to throw an InterruptedException if it’s
blocked in an operation like sleep() or wait(). It doesn’t stop the thread immediately but
signals it to stop.
Ex -
InterruptExample t = new InterruptExample(); [Link](); [Link](2000); // Main thread sleeps
for 2 seconds [Link](); // Interrupt the sleeping thread
isAlive()
This method checks whether the thread is alive or not. It returns true if the thread has been
started and has not yet nished.
getId()
This method returns the unique identi er assigned to the thread when it is created.
setPriority(int priority)
This method sets the priority of the thread. Valid priorities are integers between
Thread.MIN_PRIORITY (1) and Thread.MAX_PRIORITY (10), with
Thread.NORM_PRIORITY (5) as the default.
Three type -
MIN -1
NORM. -5
MAX - 10
Ex -
PriorityExample t = new PriorityExample();
[Link](Thread.MAX_PRIORITY);
// Set thread to maximum priority [Link]();
getName()
This method returns the name of the thread. Every thread has a name, which can be set explicitly
or defaults to a system-generated name.
setName(String name)
This method allows you to set the name of the thread.
SetNameExample t = new SetNameExample();
[Link]("MyCustomThread");
[Link]();
yield()
This method causes the currently executing thread to pause and allow other threads of the same
priority to execute. It doesn't guarantee that the thread will immediately yield; it merely hints to
the thread scheduler.
fi
fi
fi
Ex - [Link]();
currentThread()
This static method returns a reference to the currently executing thread.
Thread t = [Link](); // Get the current thread [Link]("Current Thread:
" + [Link]());
activeCount()
This static method returns the approximate number of active threads in the current thread's thread
group.
setDaemon(boolean on)
This method marks a thread as a daemon thread. A daemon thread is a low-priority thread that
runs in the background. The JVM terminates when all non-daemon threads are nished, and
daemon threads are killed automatically.
Ex -
DaemonExample t = new DaemonExample();
[Link](true);
// Set thread as daemon [Link]();
Suspend , Stop and Resume methods are removed from java 9 as those were causing rescue loss
and deadlock
The Thread Scheduler in Java is a part of the JVM responsible for determining which thread
should run at any given time when there are multiple threads in the Runnable state. The
scheduler uses the operating system's thread scheduling mechanism to allocate CPU time to
threads.
Threads do not run simultaneously on a single-core CPU; they share CPU time. The thread
scheduler decides the order and amount of time threads get for execution.
1. Preemptive Scheduling
In preemptive scheduling, the thread scheduler gives higher priority threads precedence over
lower-priority threads. If a higher-priority thread becomes runnable, it preempts (interrupts) the
execution of a lower-priority thread, even if the lower-priority thread is currently running.
fl
fi
Types of Preemptive Scheduling
ThreadPool -
A Thread Pool in Java is a collection of reusable threads that can be used to execute tasks.
Instead of creating a new thread for every task, the thread pool manages a set of worker threads
that are reused for multiple tasks. This improves application performance by:
The Executors class provides factory methods to create thread pools. Below are the common
types of thread pools:
Executors - Class
ExecutorService - Interface which has Execute method
Ex - ExecutorService executor = [Link](3); // Pool with 3
for (int i = 1; i <= 5; i++) { int taskId = i; [Link](() -> { [Link]("Task " +
taskId + " is executed by " + [Link]().getName()); }); }
A ThreadGroup in Java is a mechanism for grouping multiple threads into a single unit. It
allows threads to be organized hierarchically and provides a way to perform operations on a
group of threads collectively, such as setting their priority, interrupting all threads in the group, or
monitoring their status.
Thread groups were introduced in Java to simplify thread management, especially when working
with multiple threads. However, they are now considered somewhat outdated and are rarely used
in modern Java applications due to the introduction of the [Link]
package, which provides more robust thread management tools.
}, "Thread-1");
}, "Thread-2");
[Link]();
[Link]();
[Link]();
Metho Descriptio
d n
String Returns the name of the thread
getName() group.
ThreadGroup Returns the parent of the thread
getParent() group.
int Returns the number of active threads in the thread
activeCount() group.
int Returns the number of active thread groups in the thread
activeGroupCount() group.
void Prints information about the thread group to the standard
list() output.
boolean Checks if the thread group is a daemon
isDaemon() group.
void setDaemon(boolean Marks the thread group as a daemon
daemon) group.
void Interrupts all threads in the thread
interrupt() group.
void Destroys the thread group and removes it from its parent
destroy() group.
void Called by the JVM when a thread in the group
uncaughtException(Thread terminates due to an uncaught exception.
t, Throwable e)
What is shutdown hook in thread ?
A Shutdown Hook is a special construct in Java that allows you to de ne actions that should be
executed when the Java Virtual Machine (JVM) shuts down. This can happen due to:
Interview Question -
What is thread ?
How to create thread ?
Difference between runnable and Thread class - Runnable has only one method run ..
How can you make sure threads starts from main and end with the same order ? Using join
method
What is be t of using volatile keyword ?
The volatile keyword in Java is used to indicate that a variable's value will be modi ed by
multiple threads. Declaring a variable as volatile ensures:
What is the race condition in tow thread ? When two threads are trying to access the same
process / object
fi
fi
fi
How thread can communicate - using Wait , Notify and notify all methods .
A deadlock in Java occurs when two or more threads are waiting for each other to release a
resource, resulting in a situation where none of the threads can proceed.
1. Multiple threads hold some shared resources (e.g., locks) and wait for resources held by
other threads.
2. A circular dependency of locks occurs, causing the threads to be stuck inde nitely.
Difference between wait and sleep method ? Wait - Release the lock and sleep don’t release the
lock .
Difference between yield and sleep - Yield - Running to runable to state and sleep - Running to
wait state .
1. Object Lock:
• Used for instance synchronized methods/blocks.
• Lock is tied to the speci c instance of the class.
• Allows concurrent execution of instance methods for different objects.
• Synchronized instance methods or blocks use the object lock.
public synchronized void instanceMethod()
{ [Link]([Link]().getName() + " acquired object lock on instance
method"); try { [Link](2000); // Simulate some work } catch (InterruptedException e)
{ [Link](); } [Link]([Link]().getName() + " released object
lock"); }
2. Class Lock:
Used for static synchronized methods/blocks.
Lock is tied to the Class object of the class.
Only one thread can execute any static synchronized method in the class at a time.
Synchronized static methods or blocks use the class lock.
1. CountDownLatch
A CountDownLatch is used to block one or more threads until a certain condition is met. It
allows one or more threads to wait until the latch reaches a count of zero. Once the count reaches
zero, all waiting threads are released.
• When you want one or more threads to wait until a certain number of events (like tasks or
threads) are completed.
Ex -
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount); // Count of threads to wait
for
[Link](); // Main thread waits until all threads nish their work
[Link]("All threads have nished. Main thread proceeding...");
2. CyclicBarrier
◦ parties speci es the number of threads that must reach the barrier before they
can proceed.
• Methods:
◦ await(): Causes the current thread to wait until all threads reach the barrier.
◦ reset(): Resets the barrier for reuse.
int threadCount = 3;
fi
fi
fi
fi
CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> [Link]("All threads
reached the barrier. Proceeding..."));
// Let the threads perform their work and reach the barrier
[Link](3000);
==========================================================
ENUM
- Type Safety . - Enums are type-safe, meaning you cannot assign any other value except the
prede ned constants to an enum variable.
- We can use this switch statement .
- Can be traversed . - You can traverse all enum constants using the values() method.
- Enum is a class .
- Enum can implements many interface but can not extends any class because it internally
extends Enum class .
- The java Enum elds are static nal by default .
- It is available from JDK - 1.5
- There is value method in enum class which return Enum class array .
- Java internally create Enum as nal class which extends the enum class .
- Enum class has private construture .
-The values() method is a compiler-generated method in Java enums, and it is not
explicitly declared in the [Link] class. Instead, the Java compiler adds it to every
enum during compilation.
==============================================================
fi
fi
fi
fi
fi
fi
Generic in java -
- Generic class -
// Generic class de nition
class Box<T> {
private T value;
// Getter method
public T getValue() {
return value;
}
- Generic method -
class GenericMethodExample {
[Link]("Integer Array:");
printArray(intArray); // Works for Integer array
[Link]("String Array:");
printArray(strArray); // Works for String array
}
}
fi
3. Generic Collection
TEKVN
// Generic class with placeholder 'T' class Box<T> { private T value; public Box(T value)
{ [Link] = value; } public T getValue() { return value; } public void setValue(T value)
{ [Link] = value; } }
K is the placeholder for key in a map, such as HashMap, TreeMap, etc. Maps store key-value
pairs.
// Map with Integer as Key (K) and String as Value (V) Map<Integer, String> map = new
HashMap<>(); [Link](1, "One"); [Link](2, "Two"); [Link](3, “Three");
N stands for Number (can be used when the type should extend a numeric type).
N is typically used as a placeholder when you want the generic to represent numeric types (like
Integer, Double, etc.). You can constrain N to types that extend Number (e.g.,
Integer, Float, Double).
// Creating a Map with Integer as Key and String as Value Map<Integer, String> map = new
HashMap<>(); // Adding key-value pairs to the Map [Link](1, "One"); [Link](2, "Two");
[Link](3, "Three");
• The unbounded wildcard (?) represents any type. This means you can use it in situations
where the type could be anything.
import [Link].*;
• The upper-bounded wildcard (? extends T) allows you to specify that the unknown
type must be a subtype of T, including T itself.
• This is useful when you want to read from a structure and ensure that the objects are at
least of type T or a subtype of T.
import [Link].*;
• The lower-bounded wildcard (? super T) allows you to specify that the unknown
type must be a supertype of T, including T itself.
• This is useful when you want to write to a structure and ensure that you can safely add
elements of type T or its subtypes.
import [Link].*;
[Link](numberList);
[Link](objectList);
}
}
Interview Question -
=======================================================
Collection
What is collection - Its framework which provide the mechanimisum to manupulate the group of
Objects .
List -
The List interface provides methods for list-speci c operations such as maintaining the order
of elements. These methods include:
Basic Operations
ArrayList -
Methods in ArrayList
The ArrayList class provides implementations of all the above methods from the List
interface and adds a few speci c methods, mostly related to capacity management:
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
fi
1. void ensureCapacity(int minCapacity): Increases the capacity of the
ArrayList instance to ensure it can hold at least the speci ed number of elements.
2. void trimToSize(): Trims the capacity of the ArrayList to match its current
size, minimizing memory usage.
Ex -
1 Shifting of Elements
• An ArrayList grows dynamically when it runs out of capacity. The default growth
strategy increases its size by 1.5 times the current capacity.
• During resizing, the entire array needs to be copied to a new memory location, which
takes O(n) time.
• Frequent resizing can slow down performance, especially when the initial capacity is
small, and a large number of elements are added.
3. Random Access is Fast, But Not Index-Based Manipulation
Single Linked ?
Doubled linked ?
Node-based storage: A LinkedList is made up of nodes, where each node contains data and
a reference to the next node. The LinkedList does not use an internal array to store its
elements, so it does not have a xed or initial size.
Dynamic growth: Each time you add an element to the LinkedList, a new node is created
and linked to the existing nodes. Since LinkedList uses nodes and pointers, it grows
dynamically as new nodes are added. There is no pre-allocated capacity, and it doesn't need
resizing like an ArrayList does.
• If you need fast access by index and you're adding/removing elements mostly at the end
of the list, ArrayList is generally the better choice.
• If you need fast insertions and deletions at the beginning or middle of the list, and don't
require frequent random access, LinkedList is the better choice.
Iterator -
Iterator: Interface
• The Iterator interface provides basic methods to traverse a collection in one
direction, typically forward. The main methods are:
◦ hasNext(): Checks if there is a next element.
◦ next(): Returns the next element.
◦ remove(): Removes the current element (optional operation).
ListIterator: Interface
• The ListIterator interface extends Iterator and adds additional methods that
allow traversal in both directions (forward and backward) and more advanced operations
speci c to lists. These include:
◦ hasPrevious(): Checks if there is a previous element.
◦ previous(): Returns the previous element.
◦ add(E e): Adds an element to the list at the current position.
◦ set(E e): Replaces the last element returned by next() or previous()
with the speci ed element.
fi
fi
◦ nextIndex(): Returns the index of the element that would be returned by a
subsequent call to next().
◦ previousIndex(): Returns the index of the element that would be returned
by a subsequent call to previous().
For Each -
Vector -
Synchronised .
Legacy Class .
Increase size y 100% .
Default size is 10 .
Allow null .
Allow Duplicate .
Mention insertion order .
Vector internally uses an array
Enumeration is an Interface .
What is ConcurrentModi cationException - Multiple threads are modifying the same element .
Synchronised collection -
[Link](). Support add and remove opiste operation
[Link]()
[Link]()
STACK. -
Follows LIFO order
Thread-safe (synchronized)
Allows duplicate elements
Allows null values
Inherits from Vector, so it has dynamic resizing and a default size of 10
Provides methods like push(), pop(), peek(), empty(), and search()
Grow by 100 %
Yes, the Stack class in Java internally uses an array to store the elements.
Set -
◦ boolean add(E e)
Adds the speci ed element to the set if it is not already present.
◦ boolean remove(Object o)
Removes the speci ed element from the set, if it is present.
◦ boolean contains(Object o)
Returns true if the set contains the speci ed element.
◦ int size()
Returns the number of elements in the set.
◦ boolean isEmpty()
Returns true if the set contains no elements.
◦ void clear()
Removes all elements from the set.
◦ Iterator<E> iterator()
Returns an iterator over the elements in the set.
2. Bulk Operations:
◦ Stream<E> stream()
Returns a sequential Stream with the set as its source.
◦ Stream<E> parallelStream()
Returns a parallel Stream with the set as its source.
HashSet -
No duplicate
Unique values
No insertion order
Non Synchronised .
fi
fi
fi
fi
fi
fi
fi
One null value .
Default Size - 16 .
Internal using hashing mechanisms to store the value .
Only hash table-based storage
Hashing is the process of converting data (keys) into a xed-size hash code that determines
where the data should be stored in a hash-based data structure like a HashMap or HashSet.
Here's how it works under the hood:
a. Key
The value that is used to identify an entry in the hash table (e.g., a string or number).
b. Hash Function
A function that computes an integer value (hash code) from the key. This hash code is then used
to calculate the storage index.
c. Hash Table
A xed-size array where elements are stored. The hash code determines the index in this array.
d. Collision Handling
When two keys generate the same hash code and index, a collision occurs. Techniques like
chaining or open addressing handle this.
// Adding elements
[Link](“Apple”);
Chaining is a method where each bucket in the hash table holds a collection of elements that have
the same hash code. This collection can be a linked list, a tree, or any other data structure.
How it works:
• If two or more keys hash to the same index, they are stored in a linked list at that index.
• When inserting a new element, it is added to the list at the calculated index.
• When searching, the list is traversed to nd the matching key.
In open addressing, if a collision occurs (i.e., a bucket is already occupied), the hash table
searches for the next available slot using a probing strategy. There are different types of probing
techniques:
• Linear Probing
• Quadratic Probing
• Double Hashing
Let's explore Linear Probing as an example.
Linear Probing
In linear probing, when a collision occurs, the next index is checked sequentially until an empty
slot is found.
Quadratic Probing: Instead of checking the next consecutive slot, quadratic probing checks
indexes with a quadratic formula (index + i^2), where i is the number of collisions. This
can help reduce clustering.
Double Hashing: A second hash function is used to calculate the next index if a collision occurs,
which reduces clustering even further.
• Chaining is generally better when there are lots of collisions because it doesn’t suffer
from clustering. However, it requires additional memory to store linked lists or other data
structures.
fi
• Open Addressing is more memory ef cient because it uses the space of the hash table
itself, but it can suffer from clustering, especially with poor hash functions or when the
table is too full.
LinkedHashset -
No Duplicate
Default size 16
Non synchronised .
TreeSet -
No Duplicate
Non synchronised .
TreeSet does not have a load factor like HashSet or LinkedHashSet because it does
not use a hash table for storing its elements
If tree is not empty then create leaf node with colour Red .
If parent of new node is Red Then check the cooler of parent sibling .
Sibling colour is read then recolour and also check if present of new node is not root node then
recolour and recheck .
====================================================
Queue -
MAP
Map - Is interface
HashMap -
- Default capapctity 16
- Non Synchronised
- No duplicate key but duplicates values allowed but no use as it overrides latest Value .
In the linked list each node will contain - Key , Value , Hash and Next which is below =
How does it nd the index - Inside Out method it has below logic
hash = [Link]();
HashMapOwn methods -
=========================================
LinkedHashMap
- Key value pair
- Default capapctity 16
- Non Synchronised
- No duplicate key but duplicates values allowed but no use as it overrides latest Value .
▪ int hash
▪ K key
▪ V value
▪ Node next
▪ Node previous
Own Methods -
Metho Descriptio
d n
removeEldestEntry( Allows customization of eviction logic to remove the eldest
[Link]<K, V> entry when a certain condition is met (e.g., when the map
eldest) exceeds a certain size).
getAccess Refers to the constructor parameter that controls whether the
Order() LinkedHashMap should maintain the order of insertion or the order of
access (for LRU cache-like behavior).
==================
TreeMap
• comparator() – Returns the comparator used to order the keys in the map, or null
if the map uses the natural ordering of the keys.
• firstEntry() – Returns the rst (lowest) entry in the map.
• lastEntry() – Returns the last (highest) entry in the map.
TreeMap method -
=====================================================
HastTable =
fi
fi
Does no allow Duplicate key allow Duplicate values .
Synchronised
Default size 11
No Insertion order .
No null key and values not even single key and value .
What does internally us - Uses a hash table (array of buckets) for storing key-valu
pairs
Load factory 0.75
HasHap VS HashTable -
Ex -
ConcurrentHashMap -
HashTable -
// Create a Hashtable
Hashtable<String, String> hashtable = new Hashtable<>();
• If a thread wanted to access a segment, it would acquire the lock for that segment, not for
the whole map.
Java 8+: Replaced with bucket-level locking and atomic operations for better performance and
simplicity. The map no longer uses segments internally.