Top Core Java Interview Questions

    1

    What is the difference between JDK, JRE, and JVM?

    JDK (Java Development Kit) Complete development environment JRE (Java Runtime Environment) Runtime environment for Java applications JVM (Java Virtual Machine) Executes Java bytecode javac javadoc jar debugger

    JVM (Java Virtual Machine): An abstract machine that provides a runtime environment to execute Java bytecode. It's platform-specific and handles memory management, garbage collection, and bytecode interpretation.

    JRE (Java Runtime Environment): Contains JVM along with core libraries and other components needed to run Java applications. It's what end-users need to run Java programs.

    JDK (Java Development Kit): A complete development environment that includes JRE plus development tools like compiler (javac), debugger, documentation generator (javadoc), and other utilities needed to develop Java applications.

    2

    What is the entry point of a Java program? Which method is called when running a Java application?

    The main() method is the entry point of every Java application. When you run a Java program, the JVM looks for this specific method to start execution.

    Traditional Syntax:

    public static void main(String[] args)

    Breakdown:

    • public - JVM needs access from outside the class
    • static - Called without creating an object instance
    • void - Doesn't return anything
    • main - JVM specifically looks for this method name
    • String[] args - Command-line arguments

    Example:

    public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); if (args.length > 0) { System.out.println("First argument: " + args[0]); } } }

    Modern Java (21+) - Simplified for Learning:

    // No class declaration needed! void main() { System.out.println("Hello, World!"); } // With command line arguments void main(String[] args) { System.out.println("Hello " + (args.length > 0 ? args[0] : "World")); }

    Key Points:

    • JVM searches specifically for the main() method as entry point
    • Must be static because JVM calls it before any objects are created
    • Java 21+ introduced simplified syntax (void main()) for educational purposes
    • Traditional syntax still required for production applications
    3

    What are the main concepts of Object-Oriented Programming (OOP)?

    OOP Object-Oriented Programming Encapsulation Data hiding and bundling data with methods Private fields, Public methods Inheritance Acquiring properties from parent class (IS-A relationship) extends, super keywords Polymorphism One interface, multiple implementations Method overloading/overriding Abstraction Hiding implementation details Abstract classes, Interfaces

    Encapsulation Example:

    public class BankAccount { private double balance; // Encapsulated field public void deposit(double amount) { if (amount > 0) { balance += amount; } } public double getBalance() { return balance; // Controlled access } }

    Inheritance Example:

    // Parent class class Animal { protected String name; public void eat() { System.out.println(name + " is eating"); } } // Child class class Dog extends Animal { public void bark() { System.out.println(name + " is barking"); } }

    Polymorphism Example:

    interface Shape { double calculateArea(); } class Circle implements Shape { private double radius; public double calculateArea() { return Math.PI * radius * radius; } } class Rectangle implements Shape { private double length, width; public double calculateArea() { return length * width; } }
    4

    What is the difference between == and .equals() in Java?

    str1 str2 String Object 1 "Hello" String Object 2 "Hello" == Comparison Compares references str1 == str2 → false .equals() Comparison Compares content str1.equals(str2) → true
    public class StringComparison { public static void main(String[] args) { // Different objects with same content String str1 = new String("Hello"); String str2 = new String("Hello"); // Reference comparison System.out.println(str1 == str2); // false - different objects // Content comparison System.out.println(str1.equals(str2)); // true - same content // String literals (same object due to string pool) String str3 = "Hello"; String str4 = "Hello"; System.out.println(str3 == str4); // true - same object in pool System.out.println(str3.equals(str4)); // true - same content } }

    Key Points:

    • == compares memory addresses/references
    • .equals() compares actual content
    • String literals are stored in String Pool, so == might return true
    • Always use .equals() for content comparison
    5

    What is an Exception in Java? Explain the exception hierarchy.

    Throwable Exception Error IOException SQLException ClassNotFoundException ParseException RuntimeException NullPointerException ArrayIndexOutOfBounds IllegalArgumentException NumberFormatException OutOfMemoryError StackOverflowError

    Exception handling example:

    public class ExceptionHandlingExample { public static void main(String[] args) { try { // Checked exception - must be handled FileReader file = new FileReader("nonexistent.txt"); // Unchecked exception - optional to handle int result = 10 / 0; } catch (FileNotFoundException e) { System.out.println("File not found: " + e.getMessage()); } catch (ArithmeticException e) { System.out.println("Arithmetic error: " + e.getMessage()); } finally { System.out.println("Cleanup code here"); } } // Method that throws checked exception public void readFile() throws IOException { throw new IOException("File operation failed"); } }

    Key Differences:

    • Checked Exceptions: Must be handled at compile time (IOException, SQLException)
    • Unchecked Exceptions: Runtime exceptions, optional to handle (NullPointerException, ArrayIndexOutOfBoundsException)
    • Errors: Serious problems that applications shouldn't try to catch (OutOfMemoryError, StackOverflowError)
    6

    What is String Pool in Java?

    The String Pool (also called String Constant Pool) is a special memory area in the Java heap where string literals are stored. It's designed to save memory by reusing string objects.

    Key Points:

    • String literals are automatically interned (stored in pool)
    • new String() creates objects in heap, not in pool
    • intern() method adds strings to pool and returns reference
    • Pool is part of heap memory (since Java 7)
    String s1 = "abc" String s2 = "abc" String s3 = new String("abc") String s4 = "xyz" Heap Memory String Pool "abc" "xyz" "abc"
    7

    What is the difference between ArrayList and LinkedList?

    ArrayList (Dynamic Array) A [0] B [1] C [2] D [3] O(1) access LinkedList (Doubly Linked List) A prev next B prev next C prev next D prev next O(1) insert

    ArrayList vs LinkedList in Java

    Java provides two commonly used List implementations: ArrayList and LinkedList. Both implement the List interface but have different internal structures and performance characteristics.

    • ArrayList is backed by a dynamic array. It provides fast random access (O(1) for get(index)), but inserting or removing elements (except at the end) is slow because elements must be shifted.
    • LinkedList is a doubly linked list. It allows fast insertions and deletions at the beginning or end (O(1)), but random access is slow (O(n)) because you must traverse the list.

    Performance Comparison Table

    OperationArrayListLinkedList
    Get by indexO(1)O(n)
    Add at endO(1) amortizedO(1)
    Add at beginningO(n)O(1)
    Add at middleO(n)O(n)
    Remove by indexO(n)O(n)
    Remove at endsO(1) amortizedO(1)
    Memory overheadLowHigh (extra pointers)

    Example Code:

    8

    What is the difference between abstract classes and interfaces?

    šŸ…°ļø Abstract Class āœ” Can have abstract & concrete methods āœ” Can have instance variables āœ” Can have constructors āœ” Can have static & final methods āœ” Access modifiers: public/protected/private āœ– Multiple inheritance (only single) āœ” Use 'extends' keyword āœ” Can implement interfaces IS-A relationship 0–100% abstraction šŸ…ø Interface āœ” All methods abstract (Java 7-) āœ” Default & static methods (Java 8+) āœ– Constructors not allowed āœ” Only public static final variables āœ” Only public methods āœ” Multiple inheritance (via interfaces) āœ” Use 'implements' keyword āœ” Can extend multiple interfaces CAN-DO relationship 100% abstraction (pure) VS

    Abstract Class vs Interface in Java: Key Differences

    FeatureAbstract ClassInterface
    MethodsAbstract & concreteAbstract (Java 7-), default/static (8+)
    VariablesAny type, any modifierpublic static final only
    ConstructorsAllowedNot allowed
    Multiple InheritanceNot supportedSupported (via interfaces)
    Access ModifiersAny (public/protected/private)Only public
    InheritanceSingle (extends)Multiple (implements)
    Abstraction Level0–100%100% (pure)
    RelationshipIS-ACAN-DO
    Use CaseBase class with shared codeContract for capabilities

    When to use which?

    • Use an abstract class when you want to share code among closely related classes, or need constructors, fields, or non-static methods.
    • Use an interface to define a contract for unrelated classes, or when you need multiple inheritance of type.

    Abstract Class Example:

    // Abstract class - can have concrete and abstract methods abstract class Vehicle { // Concrete method public void startEngine() { System.out.println("Engine started"); } // Abstract method - must be implemented by subclasses public abstract void accelerate(); // Can have fields protected String brand; protected int year; // Can have constructor public Vehicle(String brand, int year) { this.brand = brand; this.year = year; } } // Concrete class extending abstract class class Car extends Vehicle { public Car(String brand, int year) { super(brand, year); } @Override public void accelerate() { System.out.println("Car accelerating..."); } } // Usage Vehicle car = new Car("Toyota", 2023); car.startEngine(); // Inherited concrete method car.accelerate(); // Overridden abstract method

    Interface Example:

    // Interface - only abstract methods (before Java 8) interface Flyable { void fly(); // Implicitly public abstract } interface Swimmable { void swim(); // Implicitly public abstract } // Class can implement multiple interfaces class Duck implements Flyable, Swimmable { @Override public void fly() { System.out.println("Duck flying..."); } @Override public void swim() { System.out.println("Duck swimming..."); } } // Java 8+ interfaces can have default and static methods interface ModernInterface { // Abstract method void doSomething(); // Default method - provides implementation default void doSomethingElse() { System.out.println("Default implementation"); } // Static method static void utilityMethod() { System.out.println("Static utility method"); } } // Usage Duck duck = new Duck(); duck.fly(); // Interface method duck.swim(); // Interface method ModernInterface.utilityMethod(); // Static method call

    Key Differences in Practice:

    // Abstract class - single inheritance, can have state abstract class Animal { protected String name; // Can have fields public Animal(String name) { this.name = name; // Can have constructor } public abstract void makeSound(); public void sleep() { // Can have concrete methods System.out.println(name + " is sleeping"); } } // Interface - multiple inheritance, no state (before Java 8) interface Pet { void play(); // Only abstract methods } interface Domestic { void feed(); } // Class can extend one abstract class and implement multiple interfaces class Dog extends Animal implements Pet, Domestic { public Dog(String name) { super(name); } @Override public void makeSound() { System.out.println(name + " barks"); } @Override public void play() { System.out.println(name + " plays fetch"); } @Override public void feed() { System.out.println(name + " eats dog food"); } }

    9

    What is method overloading and method overriding?

    Method Overloading (Compile-time / Static Polymorphism) Same method name, different parameters void print(int a) void print(String s) void print(int a, int b) double print(double d) Rules: • Same class, same method name • Different parameter list (number, type, or order) • Return type can be same or different • Resolved at compile time • Also called Static Polymorphism Method Overriding (Runtime / Dynamic Polymorphism) Same method signature, different implementation Parent Class void draw() { /* parent code */ } Child Class @Override void draw() { /* child code */ } Rules: • Parent-child relationship required • Same method signature (name + parameters) • Same or covariant return type • Cannot reduce visibility • Resolved at runtime • Also called Dynamic Polymorphism • @Override annotation recommended

    Visual Summary:

    AspectMethod OverloadingMethod Overriding
    Where?Same classSubclass (child)
    SignatureSame name, different parametersSame name & parameters
    Return typeCan be same or differentMust be same or covariant
    TimingCompile-time (static)Runtime (dynamic)
    PurposeIncrease method flexibilityChange/inherit behavior

    Method Overloading Example:

    public class Calculator { // Method overloading - same name, different parameters public int add(int a, int b) { return a + b; } public double add(double a, double b) { return a + b; } public int add(int a, int b, int c) { return a + b + c; } public String add(String a, String b) { return a + b; } } // Usage Calculator calc = new Calculator(); System.out.println(calc.add(5, 3)); // Output: 8 System.out.println(calc.add(5.5, 3.2)); // Output: 8.7 System.out.println(calc.add(1, 2, 3)); // Output: 6 System.out.println(calc.add("Hello ", "World")); // Output: Hello World

    Method Overriding Example:

    // Parent class class Animal { public void makeSound() { System.out.println("Some animal sound"); } public void eat() { System.out.println("Animal is eating"); } } // Child class overriding parent methods class Dog extends Animal { @Override public void makeSound() { System.out.println("Woof! Woof!"); } @Override public void eat() { System.out.println("Dog is eating bones"); } } class Cat extends Animal { @Override public void makeSound() { System.out.println("Meow! Meow!"); } @Override public void eat() { System.out.println("Cat is eating fish"); } } // Usage demonstrating runtime polymorphism Animal animal1 = new Dog(); Animal animal2 = new Cat(); animal1.makeSound(); // Output: Woof! Woof! animal2.makeSound(); // Output: Meow! Meow! animal1.eat(); // Output: Dog is eating bones animal2.eat(); // Output: Cat is eating fish
    10

    What is the difference between final, finally, and finalize?

    KeywordTypePurposeUsage
    finalModifierMakes entities unchangeableVariables, methods, classes
    finallyBlockGuaranteed executionException handling
    finalize()MethodObject cleanup before GCGarbage collection

    final keyword examples:

    public class FinalExample { // Final variable - constant public static final double PI = 3.14159; private final List<String> names = new ArrayList<>(); // Final method - cannot be overridden public final void displayInfo() { System.out.println("This method cannot be overridden"); } public void demonstrateFinal() { // Final local variable final int x = 10; // x = 20; // Compilation error - cannot reassign // Final reference - object can be modified, reference cannot change names.add("John"); // This is allowed // names = new ArrayList<>(); // Compilation error } } // Final class - cannot be inherited final class ImmutableClass { private final String value; public ImmutableClass(String value) { this.value = value; } public String getValue() { return value; } } // class ChildClass extends ImmutableClass {} // Compilation error

    finally block example:

    public class FinallyExample { public void demonstrateFinally() { FileInputStream fis = null; try { fis = new FileInputStream("file.txt"); // Some file operations int result = 10 / 0; // This will throw ArithmeticException } catch (FileNotFoundException e) { System.out.println("File not found: " + e.getMessage()); } catch (ArithmeticException e) { System.out.println("Arithmetic error: " + e.getMessage()); } finally { // This block always executes System.out.println("Finally block executed"); if (fis != null) { try { fis.close(); System.out.println("File closed"); } catch (IOException e) { System.out.println("Error closing file"); } } } } public int finallyWithReturn() { try { return 1; } finally { System.out.println("Finally executed even with return"); // return 2; // This would override the try block return } } }

    finalize() method example:

    public class FinalizeExample { private String resourceName; public FinalizeExample(String resourceName) { this.resourceName = resourceName; System.out.println("Resource " + resourceName + " created"); } // finalize() method - called by GC before object destruction @Override protected void finalize() throws Throwable { try { System.out.println("Finalizing resource: " + resourceName); // Cleanup code here (not recommended approach) } finally { super.finalize(); } } public static void main(String[] args) { // Create objects FinalizeExample obj1 = new FinalizeExample("Object1"); FinalizeExample obj2 = new FinalizeExample("Object2"); // Remove references obj1 = null; obj2 = null; // Suggest garbage collection (not guaranteed) System.gc(); try { Thread.sleep(1000); // Wait for GC } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Program ends"); } }

    Important Notes:

    • finalize() is deprecated since Java 9
    • finally block doesn't execute if JVM exits (System.exit()) or thread is killed

    For more details on garbage collection and memory management, you can read more about it here.

    • final keyword helps in creating immutable objects and preventing inheritance
    11

    What is a singleton design pattern? How do you implement it?

    Singleton Only one instance Single Instance Client Client

    Singleton ensures only one instance of a class exists and provides global access to it.

    Common Use Cases:

    • Database connections
    • Logging services
    • Configuration settings
    • Cache managers
    • Thread pools

    Examples

    public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } public void doSomething() { System.out.println("Doing something..."); } }
    12

    What is the Collections Framework in Java?

    The Java Collections Framework is a set of classes and interfaces that provides built-in data structures to store, manage, and manipulate groups of objects. It includes interfaces like List, Set, Queue, and Map, along with their standard implementations such as ArrayList, HashSet, LinkedList, and HashMap. The framework standardizes how collections are handled, making code more reusable, efficient, and easy to maintain.

    Collection<E> List<E> Set<E> Queue<E> Map<K,V> ArrayList LinkedList Vector HashSet TreeSet LinkedHashSet PriorityQueue ArrayDeque HashMap TreeMap LinkedHashMap Hashtable Collection Types List: Ordered, allows duplicates Set: No duplicates allowed Queue: FIFO data structure Map: Key-value pairs Deque: Double-ended queue

    Collection Framework Examples:

    1. List Examples:

    import java.util.*; public class ListExamples { public static void main(String[] args) { // ArrayList - Best for random access List<String> arrayList = new ArrayList<>(); arrayList.add("Apple"); arrayList.add("Banana"); arrayList.add("Cherry"); arrayList.add("Apple"); // Duplicates allowed System.out.println("ArrayList: " + arrayList); System.out.println("Element at index 1: " + arrayList.get(1)); // LinkedList - Best for insertions/deletions List<Integer> linkedList = new LinkedList<>(); linkedList.add(10); linkedList.add(20); linkedList.add(0, 5); // Insert at beginning System.out.println("LinkedList: " + linkedList); // Vector - Thread-safe, legacy Vector<String> vector = new Vector<>(); vector.add("Old"); vector.add("School"); System.out.println("Vector: " + vector); } }

    2. Set Examples:

    import java.util.*; public class SetExamples { public static void main(String[] args) { // HashSet - No order, fast operations Set<String> hashSet = new HashSet<>(); hashSet.add("Red"); hashSet.add("Green"); hashSet.add("Blue"); hashSet.add("Red"); // Duplicate ignored System.out.println("HashSet: " + hashSet); // TreeSet - Sorted order Set<Integer> treeSet = new TreeSet<>(); treeSet.add(30); treeSet.add(10); treeSet.add(20); treeSet.add(10); // Duplicate ignored System.out.println("TreeSet: " + treeSet); // [10, 20, 30] // LinkedHashSet - Insertion order maintained Set<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("First"); linkedHashSet.add("Second"); linkedHashSet.add("Third"); System.out.println("LinkedHashSet: " + linkedHashSet); } }

    3. Map Examples:

    import java.util.*; public class MapExamples { public static void main(String[] args) { // HashMap - No order, fast operations Map<String, Integer> hashMap = new HashMap<>(); hashMap.put("Alice", 25); hashMap.put("Bob", 30); hashMap.put("Charlie", 35); System.out.println("HashMap: " + hashMap); System.out.println("Alice's age: " + hashMap.get("Alice")); // TreeMap - Sorted by keys Map<String, String> treeMap = new TreeMap<>(); treeMap.put("Zebra", "Black and White"); treeMap.put("Apple", "Red"); treeMap.put("Banana", "Yellow"); System.out.println("TreeMap: " + treeMap); // Sorted by keys // LinkedHashMap - Insertion order Map<Integer, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put(3, "Three"); linkedHashMap.put(1, "One"); linkedHashMap.put(2, "Two"); System.out.println("LinkedHashMap: " + linkedHashMap); // Iterate through map for (Map.Entry<String, Integer> entry : hashMap.entrySet()) { System.out.println(entry.getKey() + " -> " + entry.getValue()); } } }

    4. Queue Examples:

    import java.util.*; public class QueueExamples { public static void main(String[] args) { // PriorityQueue - Natural ordering Queue<Integer> priorityQueue = new PriorityQueue<>(); priorityQueue.offer(30); priorityQueue.offer(10); priorityQueue.offer(20); System.out.println("PriorityQueue polling: "); while (!priorityQueue.isEmpty()) { System.out.println(priorityQueue.poll()); // 10, 20, 30 } // ArrayDeque - Double-ended queue Deque<String> deque = new ArrayDeque<>(); deque.addFirst("First"); deque.addLast("Last"); deque.addFirst("New First"); System.out.println("Deque: " + deque); System.out.println("Remove first: " + deque.removeFirst()); System.out.println("Remove last: " + deque.removeLast()); } }

    Performance Comparison:

    CollectionGetAddRemoveContains
    ArrayListO(1)O(1)*O(n)O(n)
    LinkedListO(n)O(1)O(1)**O(n)
    HashSetN/AO(1)O(1)O(1)
    TreeSetN/AO(log n)O(log n)O(log n)
    HashMapO(1)O(1)O(1)O(1)
    TreeMapO(log n)O(log n)O(log n)O(log n)
    13

    What is the difference between HashMap and ConcurrentHashMap?

    HashMap (Not Thread-Safe) Single Lock for Entire Map Bucket 0 Bucket 1 Bucket 2 Bucket 3 Bucket 4 Bucket 5 SYNCHRONIZED LOCK ✘ Not thread-safe ✘ Data corruption in multithreading ✘ Infinite loops possible āœ” Better performance (single thread) āœ” Lower memory overhead ✘ Requires external synchronization āœ” Allows null key and values ✘ Fail-fast iterators āœ” Since Java 1.2 āœ” extends AbstractMap Performance: O(1) average ConcurrentHashMap (Thread-Safe) Segment-Based Locking (J7) / CAS (J8+) Segment 0 Lock 0 Segment 1 Lock 1 Segment 2 Lock 2 Segment 3 Lock 3 āœ” Thread-safe āœ” High concurrency āœ” Segment-based locking (Java 7) āœ” CAS operations (Java 8+) āœ” Better scalability ✘ Higher memory overhead ✘ No null keys or values āœ” Weakly consistent iterators āœ” Since Java 1.5 āœ” implements ConcurrentMap Performance: O(1) average

    HashMap vs ConcurrentHashMap Examples:

    1. HashMap (Not Thread-Safe):

    import java.util.*; import java.util.concurrent.*; public class HashMapExample { public static void main(String[] args) throws InterruptedException { Map<Integer, String> hashMap = new HashMap<>(); // Single thread - works fine hashMap.put(1, "One"); hashMap.put(2, "Two"); hashMap.put(3, "Three"); System.out.println("HashMap: " + hashMap); // Multi-threaded scenario - dangerous! demonstrateThreadUnsafety(); } public static void demonstrateThreadUnsafety() throws InterruptedException { Map<Integer, Integer> map = new HashMap<>(); // Multiple threads modifying HashMap concurrently ExecutorService executor = Executors.newFixedThreadPool(10); for (int i = 0; i < 100; i++) { final int key = i; executor.submit(() -> { map.put(key, key * 2); // Potential data corruption }); } executor.shutdown(); executor.awaitTermination(1, TimeUnit.SECONDS); System.out.println("HashMap size (should be 100): " + map.size()); // Size might be less than 100 due to data corruption } }

    2. ConcurrentHashMap (Thread-Safe):

    import java.util.concurrent.*; import java.util.*; public class ConcurrentHashMapExample { public static void main(String[] args) throws InterruptedException { // Thread-safe map ConcurrentHashMap<Integer, String> concurrentMap = new ConcurrentHashMap<>(); concurrentMap.put(1, "One"); concurrentMap.put(2, "Two"); concurrentMap.put(3, "Three"); System.out.println("ConcurrentHashMap: " + concurrentMap); // Safe concurrent operations demonstrateThreadSafety(); // Atomic operations demonstrateAtomicOperations(); } public static void demonstrateThreadSafety() throws InterruptedException { ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<>(); ExecutorService executor = Executors.newFixedThreadPool(10); // Multiple threads safely modifying ConcurrentHashMap for (int i = 0; i < 1000; i++) { final int key = i; executor.submit(() -> { map.put(key, key * 2); // Thread-safe operation }); } executor.shutdown(); executor.awaitTermination(1, TimeUnit.SECONDS); System.out.println("ConcurrentHashMap size: " + map.size()); // Always 1000 } public static void demonstrateAtomicOperations() { ConcurrentHashMap<String, Integer> counter = new ConcurrentHashMap<>(); // Atomic increment operations counter.put("count", 0); // Using compute methods for atomic updates counter.compute("count", (key, val) -> val == null ? 1 : val + 1); counter.computeIfAbsent("newKey", key -> 100); counter.computeIfPresent("count", (key, val) -> val * 2); // Merge operation counter.merge("count", 10, Integer::sum); System.out.println("Counter: " + counter); // Bulk operations (Java 8+) counter.forEach((key, value) -> System.out.println(key + " -> " + value)); // Parallel operations long sum = counter.reduceValues(1, Integer::sum); System.out.println("Sum of all values: " + sum); } }

    Key Differences Summary:

    FeatureHashMapConcurrentHashMap
    Thread SafetyāŒ Not thread-safeāœ… Thread-safe
    Performance (Single)āœ… FasterāŒ Slightly slower
    Performance (Multi)āŒ Poor with syncāœ… Excellent
    Null Valuesāœ… AllowsāŒ Not allowed
    LockingāŒ External sync neededāœ… Internal segment locks
    IteratorsāŒ Fail-fastāœ… Weakly consistent
    Memoryāœ… Lower overheadāŒ Higher overhead
    Since VersionJava 1.2Java 1.5
    14

    What is the difference between Stack and Heap memory in Java?

    Answer:

    • Stack Memory: Used for static memory allocation and the execution of a thread. Stores primitive types and references to objects in the heap. Each thread has its own stack.
    • Heap Memory: Used for dynamic memory allocation for Java objects and JRE classes. Shared among all threads.

    Diagram:

    Stack int a = 10; MyObj ref Local variables & references Heap MyObj instance All Java objects reference

    Code Example:

    public class MemoryDemo { public static void main(String[] args) { int a = 10; // Stack MyObj obj = new MyObj(); // obj ref in Stack, object in Heap } } class MyObj {}

    For more details on JVM memory architecture and troubleshooting, you can read more about it here.

    15

    What is the difference between process and thread in Java?

    Answer:

    • Process: An independent program in execution with its own memory space.
    • Thread: A lightweight sub-process, shares memory with other threads in the same process.

    Diagram:

    Process 1 Thread 1 Thread 2 Shared Memory Process 2 Thread 1 Thread 2

    Code Example:

    public class ThreadDemo extends Thread { public void run() { System.out.println("Thread running"); } public static void main(String[] args) { ThreadDemo t1 = new ThreadDemo(); t1.start(); } }

    For more details refer this blog.


    16

    What is the use of the 'transient' keyword in Java?

    Answer: The transient keyword prevents fields from being serialized. When an object is serialized, transient fields are skipped.

    Code Example:

    class User implements Serializable { private String name; private transient String password; // Not serialized }

    17

    19. What is the 'volatile' keyword in Java?

    Answer: volatile ensures that changes to a variable are visible to all threads. It prevents caching of variables in threads.

    Code Example:

    class Shared { private volatile boolean flag = false; // ... }

    18

    What is the Java Memory Model (JMM)?

    Answer: The Java Memory Model (JMM) is a specification that describes how the Java virtual machine works with computer memory, especially in the context of multithreaded programs. It defines how and when changes made by one thread to shared variables become visible to other threads, and what kinds of low-level memory operations (such as reordering or caching) are allowed by the JVM and hardware.

    JMM ensures three key properties:

    • Visibility: When one thread modifies a shared variable, other threads will eventually see the updated value.
    • Ordering: The model specifies rules about the order in which reads and writes to variables can happen, both within a thread and between threads. This prevents certain types of unexpected behaviors due to instruction reordering.
    • Atomicity: Some operations (like reading and writing to variables of certain types) are guaranteed to be atomic, meaning they cannot be observed in a partially-completed state.

    The JMM is crucial for writing correct concurrent code in Java. It explains why you need to use synchronization, volatile, or other concurrency constructs to ensure that threads see consistent and up-to-date values of shared variables. Without proper synchronization, threads may see stale or inconsistent data due to caching or reordering by the JVM or CPU.

    For more details on JVM memory architecture and troubleshooting, you can read more about it here.


    19

    What is the difference between checked and unchecked exceptions?

    Answer:

    • Checked Exception: Checked at compile time (e.g., IOException). You need to handle them using try-catch or throw them.
    • Unchecked Exception: Checked at runtime (e.g., NullPointerException). You don't need to handle them.

    For more details on exception handling and testing, you can read more about it here.

    Code Example:

    private void methodThrowingUncheckedException() { throw new NullPointerException(); } private void methodThrowingCheckedException() throws IOException { throw new IOException(); } public static void main(String[] args) { try { methodThrowingCheckedException(); // Need to handle the exception and add throws IOException in the method signature } catch (IOException e) { // Handle the exception } methodThrowingUncheckedException(); // No need to handle the exception }

    20

    What is the use of the 'super' keyword in Java?

    Answer: super refers to the immediate parent class object. Used to access parent class methods, variables, and constructors.

    Code Example:

    class Parent { void show() { System.out.println("Parent"); } } class Child extends Parent { void show() { super.show(); // Calls Parent's show System.out.println("Child"); } }

    21

    What is method hiding in Java?

    Answer: If a subclass defines a static method with the same signature as a static method in the parent class, the method in the child hides the one in the parent.

    Code Example:

    class A { static void display() { System.out.println("A"); } } class B extends A { static void display() { System.out.println("B"); } }

    22

    What is the difference between shallow copy and deep copy?

    Answer:

    • Shallow Copy: Copies object references.
    • Deep Copy: Copies actual objects recursively.

    Code Example:

    // Shallow copy List<String> list1 = new ArrayList<>(); List<String> list2 = list1; // Deep copy List<String> list3 = new ArrayList<>(list1);

    23

    What is the use of the 'this' keyword in Java?

    Answer: this refers to the current object instance. Used to resolve ambiguity between instance variables and parameters.

    Code Example:

    class Demo { int x; Demo(int x) { this.x = x; } }

    24

    26. What is the difference between '==', 'equals()', and 'hashCode()'?

    Answer:

    • == compares references.
    • equals() compares values.
    • hashCode() returns an integer for hashing.

    Code Example:

    String a = new String("test"); String b = new String("test"); System.out.println(a == b); // false System.out.println(a.equals(b)); // true System.out.println(a.hashCode() == b.hashCode()); // true

    25

    What is the use of the 'instanceof' keyword?

    Answer: Checks if an object is an instance of a specific class or interface.

    Code Example:

    if (obj instanceof String) { // obj is a String }

    In modern Java you can use instanceof with pattern matching to simplify the code. You can read more about it Java 23 Pattern Matching.


    26

    What is autoboxing and unboxing in Java?

    Answer:

    • Autoboxing: Automatic conversion of primitive types to their wrapper classes.
    • Unboxing: Conversion of wrapper classes to primitive types.

    Code Example:

    Integer a = 5; // Autoboxing int b = a; // Unboxing

    27

    29. What is the Stream API in Java?

    Answer: Introduced in Java 8, it processes collections of objects in a functional style.

    Code Example:

    List<String> list = Arrays.asList("a", "b"); list.stream().forEach(System.out::println);

    For more details on Stream API and functional programming, you can read more about it here.


    28

    What is Optional in Java?

    Answer: A container object which may or may not contain a non-null value. Helps avoid NullPointerException.

    Code Example:

    Optional<String> opt = Optional.of("test"); opt.ifPresent(System.out::println);

    For more details on Optional and modern Java features, you can read more about it here.


    29

    31. What is the difference between Comparator and Comparable?

    Answer: Both Comparable and Comparator are used for sorting objects, but they serve different purposes:

    • Comparable: Defines the natural ordering of a class by implementing compareTo() method within the class itself.
    • Comparator: Defines custom ordering by implementing compare() method in a separate class or lambda expression.

    Key Differences:

    AspectComparableComparator
    Packagejava.lang.Comparablejava.util.Comparator
    MethodcompareTo(T o)compare(T o1, T o2)
    ImplementationInside the classSeparate class or lambda
    Natural OrderDefines natural orderingDefines custom ordering
    ModificationRequires class modificationNo class modification needed
    Multiple OrdersOnly one natural orderMultiple custom orders
    UsageCollections.sort(list)Collections.sort(list, comparator)

    1. Comparable Example - Natural Ordering:

    // Student class with natural ordering by ID public class Student implements Comparable<Student> { private int id; private String name; private double gpa; public Student(int id, String name, double gpa) { this.id = id; this.name = name; this.gpa = gpa; } // Natural ordering: by ID (ascending) @Override public int compareTo(Student other) { return Integer.compare(this.id, other.id); } // Getters public int getId() { return id; } public String getName() { return name; } public double getGpa() { return gpa; } @Override public String toString() { return "Student{id=" + id + ", name='" + name + "', gpa=" + gpa + "}"; } } // Usage public class ComparableExample { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student(3, "Alice", 3.8), new Student(1, "Bob", 3.5), new Student(2, "Charlie", 3.9) ); System.out.println("Before sorting: " + students); // Natural sorting (by ID) Collections.sort(students); System.out.println("After sorting by ID: " + students); // Also works with TreeSet TreeSet<Student> studentSet = new TreeSet<>(students); System.out.println("TreeSet (sorted by ID): " + studentSet); } }

    2. Comparator Examples - Custom Ordering:

    // Multiple comparators for different sorting criteria public class StudentComparators { // Comparator for sorting by name public static class NameComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { return s1.getName().compareTo(s2.getName()); } } // Comparator for sorting by GPA (descending) public static class GpaComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { return Double.compare(s2.getGpa(), s1.getGpa()); // Descending order } } // Comparator for sorting by GPA then by name public static class GpaThenNameComparator implements Comparator<Student> { @Override public int compare(Student s1, Student s2) { int gpaComparison = Double.compare(s2.getGpa(), s1.getGpa()); if (gpaComparison != 0) { return gpaComparison; } return s1.getName().compareTo(s2.getName()); } } } // Usage with different comparators public class ComparatorExample { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student(3, "Alice", 3.8), new Student(1, "Bob", 3.5), new Student(2, "Charlie", 3.9), new Student(4, "Alice", 3.8) // Same name and GPA as first Alice ); System.out.println("Original list: " + students); // Sort by name Collections.sort(students, new StudentComparators.NameComparator()); System.out.println("Sorted by name: " + students); // Sort by GPA (descending) Collections.sort(students, new StudentComparators.GpaComparator()); System.out.println("Sorted by GPA (descending): " + students); // Sort by GPA then by name Collections.sort(students, new StudentComparators.GpaThenNameComparator()); System.out.println("Sorted by GPA then name: " + students); } }

    3. Comparator Usage with Lambda Expressions:

    public class ModernComparatorExample { public static void main(String[] args) { List<Student> students = Arrays.asList( new Student(3, "Alice", 3.8), new Student(1, "Bob", 3.5), new Student(2, "Charlie", 3.9) ); // Lambda expressions for comparators Comparator<Student> byName = (s1, s2) -> s1.getName().compareTo(s2.getName()); Comparator<Student> byGpaDesc = (s1, s2) -> Double.compare(s2.getGpa(), s1.getGpa()); Comparator<Student> byId = (s1, s2) -> Integer.compare(s1.getId(), s2.getId()); // Method references Comparator<Student> byNameMethodRef = Comparator.comparing(Student::getName); Comparator<Student> byGpaMethodRef = Comparator.comparing(Student::getGpa); Comparator<Student> byGpaDescMethodRef = Comparator.comparing(Student::getGpa).reversed(); // Chaining comparators Comparator<Student> byGpaThenName = Comparator.comparing(Student::getGpa) .reversed() .thenComparing(Student::getName); // Null-safe comparators Comparator<Student> nullSafeByName = Comparator.comparing( Student::getName, Comparator.nullsLast(Comparator.naturalOrder()) ); // Usage examples System.out.println("Original: " + students); students.sort(byName); System.out.println("By name (lambda): " + students); students.sort(byGpaDesc); System.out.println("By GPA descending (lambda): " + students); students.sort(byGpaThenName); System.out.println("By GPA then name (chained): " + students); } }

    Key Points to Remember:

    1. Use Comparable when:

      • The class has a natural ordering
      • You want to define the default sorting behavior
      • The ordering is intrinsic to the class
    2. Use Comparator when:

      • You need multiple different sorting orders
      • You can't modify the class (third-party library)
      • You want to sort by criteria not intrinsic to the class
      • You need to sort collections of primitive types or existing classes
    3. Best Practices:

      • Make compareTo() consistent with equals() for Comparable
      • Use method references and lambda expressions for cleaner code
      • Consider null values in your comparators
      • Use Comparator.comparing() and thenComparing() for complex sorting
      • Remember that TreeSet and TreeMap use natural ordering by default

    For more details on sorting and collections, you can read more about it here.

    30

    What is the use of the 'default' keyword in interfaces?

    Answer: Allows interfaces to have default method implementations.

    Code Example:

    interface MyIntf { default void show() { System.out.println("default"); } }

    For more details on interface features and modern Java, you can read more about it here.


    31

    33. What is type erasure in Java generics?

    Answer: Type information is removed at compile time. Generics are implemented via type erasure.

    Code Example:

    List<String> list = new ArrayList<>(); // At runtime, it's just List

    For more details on generics and Java features, you can read more about it here.


    32

    What is the diamond operator <> in Java?

    Answer: Introduced in Java 7, it allows type inference for generic instance creation.

    Code Example:

    List<String> list = new ArrayList<>(); // No need to specify the type in new ArrayList<>()

    For more details on Java features and generics, you can read more about it here.


    33

    35. What is the difference between fail-fast and fail-safe iterators?

    Answer:

    • Fail-fast: Throws ConcurrentModificationException if collection is modified during iteration (e.g., ArrayList).
    • Fail-safe: Works on a clone, does not throw exception (e.g., CopyOnWriteArrayList).

    For more details on collections and concurrency, you can read more about it here.


    34

    What is reflection in Java?

    Answer: Allows inspection and modification of classes, methods, and fields at runtime.

    Code Example:

    Class<?> clazz = Class.forName("java.lang.String"); Method[] methods = clazz.getMethods();

    For more details on reflection and advanced Java features, you can read more about it here.


    35

    37. What is annotation in Java?

    Answer: A form of metadata that provides data about a program but is not part of the program itself.

    Code Example:

    @Override public String toString() { return "test"; }

    36

    What is the use of the 'transient' and 'volatile' keywords?

    Answer:

    • transient: Prevents serialization of a field.
    • volatile: Ensures visibility of changes to variables across threads.

    For more details on concurrency and thread safety, you can read more about it here.


    37

    39. What is the difference between composition and aggregation?

    Answer: Both composition and aggregation are types of associations between classes, but they differ in the strength and lifecycle of the relationship:

    • Composition: A strong "has-a" relationship where the child object cannot exist without the parent. The child's lifecycle is completely dependent on the parent.
    • Aggregation: A weak "has-a" relationship where the child object can exist independently of the parent. The child's lifecycle is independent of the parent.

    Key Differences:

    AspectCompositionAggregation
    Relationship TypeStrong associationWeak association
    LifecycleChild cannot exist without parentChild can exist independently
    OwnershipParent owns the childParent uses the child
    DestructionChild is destroyed when parent is destroyedChild survives parent destruction
    MultiplicityUsually 1-to-1 or 1-to-manyCan be many-to-many
    DependencyChild is tightly coupled to parentChild is loosely coupled to parent

    1. Composition Example - Strong Relationship:

    // Composition: Car and Engine - Engine cannot exist without Car public class Engine { private String type; private int horsepower; public Engine(String type, int horsepower) { this.type = type; this.horsepower = horsepower; } public void start() { System.out.println("Engine " + type + " starting with " + horsepower + " HP"); } public String getType() { return type; } public int getHorsepower() { return horsepower; } } public class Car { private String brand; private String model; private Engine engine; // Composition: Car owns the Engine public Car(String brand, String model, String engineType, int horsepower) { this.brand = brand; this.model = model; // Engine is created when Car is created this.engine = new Engine(engineType, horsepower); } public void startCar() { System.out.println("Starting " + brand + " " + model); engine.start(); } public Engine getEngine() { return engine; // Returns the owned engine } // Engine cannot be replaced or removed from Car // Engine is destroyed when Car is destroyed } // Usage public class CompositionExample { public static void main(String[] args) { Car car = new Car("Toyota", "Camry", "V6", 300); car.startCar(); // Engine is part of the Car, cannot exist independently Engine engine = car.getEngine(); System.out.println("Engine type: " + engine.getType()); // When car goes out of scope, engine is also destroyed } }

    2. Aggregation Example - Weak Relationship:

    // Aggregation: University and Student - Student can exist without University public class Student { private String name; private int studentId; private String major; public Student(String name, int studentId, String major) { this.name = name; this.studentId = studentId; this.major = major; } public void study() { System.out.println(name + " is studying " + major); } public String getName() { return name; } public int getStudentId() { return studentId; } public String getMajor() { return major; } @Override public String toString() { return "Student{name='" + name + "', id=" + studentId + ", major='" + major + "'}"; } } public class University { private String name; private List<Student> students; // Aggregation: University has students public University(String name) { this.name = name; this.students = new ArrayList<>(); } public void enrollStudent(Student student) { students.add(student); System.out.println(student.getName() + " enrolled in " + name); } public void removeStudent(Student student) { students.remove(student); System.out.println(student.getName() + " removed from " + name); } public void listStudents() { System.out.println("Students at " + name + ":"); for (Student student : students) { System.out.println(" - " + student); } } public List<Student> getStudents() { return new ArrayList<>(students); // Return copy to prevent external modification } } // Usage public class AggregationExample { public static void main(String[] args) { // Students can exist independently Student alice = new Student("Alice", 1001, "Computer Science"); Student bob = new Student("Bob", 1002, "Mathematics"); Student charlie = new Student("Charlie", 1003, "Physics"); // University aggregates students University university = new University("Tech University"); // Students can be added to university university.enrollStudent(alice); university.enrollStudent(bob); university.enrollStudent(charlie); university.listStudents(); // Students can be removed from university university.removeStudent(bob); university.listStudents(); // Students still exist independently bob.study(); // Bob can still study even after leaving university // Students can be transferred to another university University anotherUniversity = new University("Another University"); anotherUniversity.enrollStudent(bob); anotherUniversity.listStudents(); } }
    38

    What is JIT (Just-In-Time) Compilation in Java?

    Answer: JIT (Just-In-Time) compilation is a technique used by the JVM to improve the performance of Java applications by compiling frequently executed bytecode into native machine code at runtime.

    JVM Architecture Overview Class Loader JVM Memory Method Area Heap Stack Native Stack Execution Engine JIT Compiler Garbage Collector Native Interface (JNI) Native Libraries

    JIT Compilation Process:

    1. Interpretation: JVM starts by interpreting bytecode
    2. Profiling: Monitors method execution frequency
    3. Hot Spot Detection: Identifies frequently executed methods
    4. Compilation: Compiles hot methods to native code
    5. Optimization: Applies various optimizations
    6. Code Cache: Stores compiled native code
    7. Execution: Uses native code for better performance

    JIT Compiler Types:

    • C1 Compiler (Client): Fast compilation, basic optimizations
    • C2 Compiler (Server): Slower compilation, aggressive optimizations
    • Tiered Compilation: Combines both for optimal performance

    For more details on JVM memory management and garbage collection, you can read more about it here.


    39

    What is ClassLoader in Java?

    Answer: ClassLoader is a crucial component of the JVM that is responsible for loading Java classes into memory during runtime. It follows a hierarchical delegation model to ensure class loading security and consistency.

    Bootstrap Extension System Custom Delegation: Each loader asks its parent first

    Java ClassLoader Hierarchy:

    • Bootstrap ClassLoader: Loads core Java classes (e.g., java.lang.*)
    • Extension ClassLoader: Loads JDK extension classes
    • System ClassLoader: Loads classes from your application's classpath
    • Custom ClassLoader: User-defined, loads classes from custom sources

    Delegation Model: When loading a class, each ClassLoader first asks its parent. If the parent can't find the class, the current loader tries to load it. This prevents core Java classes from being overridden.

    For more details on JVM internals and memory management, you can read more about it here.

    40

    What is try-with-resources in Java?

    Answer: Try-with-resources is a feature introduced in Java 7 that automatically manages resources by ensuring they are properly closed after use, even if an exception occurs. It eliminates the need for explicit resource cleanup in finally blocks.

    Key Features:

    • Automatic Resource Management: Resources are automatically closed
    • Exception Handling: Suppressed exceptions are preserved
    • Clean Code: Eliminates boilerplate cleanup code
    • Multiple Resources: Can manage multiple resources simultaneously

    Code Examples:

    1. Basic Try-with-Resources:

    import java.io.*; public class TryWithResourcesExample { // Traditional approach (verbose) public void readFileTraditional(String filename) { FileInputStream fis = null; try { fis = new FileInputStream(filename); int data = fis.read(); while (data != -1) { System.out.print((char) data); data = fis.read(); } } catch (IOException e) { System.err.println("Error reading file: " + e.getMessage()); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { System.err.println("Error closing file: " + e.getMessage()); } } } } // Try-with-resources approach (clean) public void readFileModern(String filename) { try (FileInputStream fis = new FileInputStream(filename)) { int data = fis.read(); while (data != -1) { System.out.print((char) data); data = fis.read(); } } catch (IOException e) { System.err.println("Error reading file: " + e.getMessage()); } // fis is automatically closed here } }

    2. Multiple Resources:

    import java.io.*; import java.sql.*; public class MultipleResourcesExample { public void copyFile(String source, String destination) { // Multiple resources in single try-with-resources try (FileInputStream fis = new FileInputStream(source); FileOutputStream fos = new FileOutputStream(destination); BufferedInputStream bis = new BufferedInputStream(fis); BufferedOutputStream bos = new BufferedOutputStream(fos)) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = bis.read(buffer)) != -1) { bos.write(buffer, 0, bytesRead); } } catch (IOException e) { System.err.println("Error copying file: " + e.getMessage()); } // All resources automatically closed in reverse order } public void databaseOperation() { try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "user", "pass"); PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users"); ResultSet rs = stmt.executeQuery()) { while (rs.next()) { System.out.println("User: " + rs.getString("name")); } } catch (SQLException e) { System.err.println("Database error: " + e.getMessage()); } // Connection, Statement, and ResultSet all closed automatically } }

    3. Custom AutoCloseable Resources:

    public class CustomResourceExample { // Custom resource implementing AutoCloseable static class DatabaseConnection implements AutoCloseable { private String url; private boolean isOpen = true; public DatabaseConnection(String url) { this.url = url; System.out.println("Connected to: " + url); } public void executeQuery(String query) { if (!isOpen) { throw new IllegalStateException("Connection is closed"); } System.out.println("Executing: " + query); } @Override public void close() throws Exception { if (isOpen) { isOpen = false; System.out.println("Closing connection to: " + url); } } } // Custom resource implementing Closeable static class FileLogger implements Closeable { private PrintWriter writer; public FileLogger(String filename) throws IOException { this.writer = new PrintWriter(new FileWriter(filename, true)); } public void log(String message) { writer.println(message); writer.flush(); } @Override public void close() throws IOException { if (writer != null) { writer.close(); System.out.println("Logger closed"); } } } public void useCustomResources() { try (DatabaseConnection db = new DatabaseConnection("jdbc:mysql://localhost:3306/test"); FileLogger logger = new FileLogger("app.log")) { db.executeQuery("SELECT * FROM users"); logger.log("Query executed successfully"); } catch (Exception e) { System.err.println("Error: " + e.getMessage()); } // Both resources automatically closed } }
    41

    What are Records in Java?

    Answer: Records are a feature introduced in Java 14 (preview) and finalized in Java 16 that provide a concise way to create immutable data-carrying classes. They automatically generate constructors, getters, equals(), hashCode(), and toString() methods.

    Key Features:

    • Immutability: Records are inherently immutable
    • Concise Syntax: Reduces boilerplate code significantly
    • Data Classes: Perfect for DTOs, value objects, and data transfer
    • Pattern Matching: Works well with pattern matching (Java 17+)

    Code Example - Records vs Traditional Classes:

    Traditional Class (Lots of Boilerplate):

    public class Person { private final String name; private final int age; private final String email; public Person(String name, int age, String email) { this.name = name; this.age = age; this.email = email; } public String getName() { return name; } public int getAge() { return age; } public String getEmail() { return email; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null || getClass() != obj.getClass()) return false; Person person = (Person) obj; return age == person.age && Objects.equals(name, person.name) && Objects.equals(email, person.email); } @Override public int hashCode() { return Objects.hash(name, age, email); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", email='" + email + '\'' + '}'; } }

    Record (Minimal Boilerplate):

    public record Person(String name, int age, String email) { }

    For more details on records, you can read more about it here.

    42

    What is the use of the 'strictfp' keyword?

    Answer: Ensures consistent floating-point calculations across platforms.

    Code Example:

    strictfp class Calc { }
    43

    41. What is a functional interface?

    Answer: An interface with exactly one abstract method. Used in lambda expressions.

    Code Example:

    @FunctionalInterface interface MyFunc { void doWork(); }

    44

    What are lambda expressions in Java?

    Answer: A concise way to represent an anonymous function.

    Code Example:

    MyFunc f = () -> System.out.println("Work");

    For more details on lambda expressions and functional programming in Java, you can read more about it here.


    For more in-depth tutorials and resources, check out my blog and social media:

    šŸ”— Blog: https://codewiz.info

    šŸ”— YouTube: https://www.youtube.com/@Code.Wizzard

    šŸ”— LinkedIn: https://www.linkedin.com/in/code-wiz-740370302/

    šŸ”— Medium: https://medium.com/@code.wizzard01

    šŸ”— Github: https://github.com/CodeWizzard01

    Summarise

    Transform Your Learning

    Get instant AI-powered summaries of YouTube videos and websites. Save time while enhancing your learning experience.

    Instant video summaries
    Smart insights extraction
    Channel tracking