# Java for Interviews (Core Java - I)

# Basics:

## JVM, JRE, and JDK:

### JVM:

* JVM (Java Virtual Machine) is an abstract machine that enables your computer to run a Java program.
    
* When you run the Java program, the Java compiler first compiles your Java code to bytecode. Then, the JVM translates bytecode into native machine code (a set of instructions that a computer's CPU executes directly).
    
* Java is a platform-independent language. It's because when you write Java code, it's ultimately written for JVM but not your physical machine (computer). And JVM can be run on different platforms.
    
* JVM is platform-dependent. Because JVM translates the Java bytecode which is platform-independent into machine code on different platforms.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674402804831/6fe24d6c-f08f-4516-bbcc-e9a55d6e1e09.png align="center")
    

### JRE:

* JRE (Java Runtime Environment) is a software package that provides **Java class libraries, Java Virtual Machine (JVM), and other components that are required to run Java applications**.
    
* JRE is the superset of JVM.
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674407193046/ac4173fc-f2ab-4c6d-9841-8f9b0c30a8ad.png align="center")
    

### JDK:

* JDK (Java Development Kit) is a software development kit required to develop applications in Java. When you download JDK, JRE is also downloaded with it.
    
* In addition to JRE, JDK also contains several development tools (compilers, JavaDoc, Java Debugger, etc).
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674402943053/4eccd703-0422-4bd9-a0a4-1106beb30742.png align="center")
    

---

## JVM Memory Model:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403006682/ff297564-edcf-4d02-9f07-0476d612aaf9.png align="center")

1. **Young Generation:**
    
    * The Y**oung Generation** is the place where all the new objects are created.
        
    * When the young generation is filled, garbage collection is performed. This garbage collection is called **Minor GC.**
        
    * Young Generation is divided into three parts - **Eden Memory** and two **Survivor Memory** spaces.
        
    * Important points regarding **Young Generation** →
        
        * Most of the newly created objects are located in the Eden memory space.
            
        * When Eden space is filled with objects, Minor GC is performed and all the survivor objects are moved to one of the survivor spaces.
            
        * Minor GC also checks the survivor objects and moves them to a single survivor space. So at a time, one of the survivor spaces is always empty.
            
        * Objects that have survived after many cycles of GC are moved to the **Old Generation** memory space. Usually, it’s done by setting a threshold for the age of the young generation objects before they become eligible to be promoted to **Old Generation**.
            
2. **Old Generation:**
    
    * **Old Generation** memory contains the objects that are long-lived and survived after many rounds of Minor GC.
        
    * Usually, garbage collection is performed in Old Generation memory when it’s full.
        
    * Old Generation Garbage Collection is called **Major GC** and usually takes a longer time.
        
3. **Permanent Generation:**
    
    * **Permanent Generation or “Perm Gen”** contains the application metadata required by the JVM to describe the classes and methods used in the application.
        
    * Note that Perm Gen is not part of Java Heap memory.
        
    * Perm Gen is populated by JVM at runtime based on the classes used by the application.
        
    * Perm Gen also contains Java SE library classes and methods.
        
    * Perm Gen objects are garbage collected in a full garbage collection.
        
    * Method Area is part of space in the Perm Gen and is used to store class structure (runtime constants and static variables) and code for methods and constructors.
        

---

## String, StringBuffer, and StringBuilder:

* The string is immutable whereas StringBuffer and StringBuilder are mutable classes.
    
* StringBuffer is thread-safe and synchronized whereas StringBuilder is not.
    
* The string concatenation operator (+) internally uses StringBuffer or StringBuilder class.
    
* For String manipulations in a multi-threaded environment, we should use the StringBuffer class because it is thread-safe and synchronized.
    
* For String manipulations in a single-threaded environment, we should use the StringBuilder class because we don’t have to care about thread safety and synchronization.
    
* As StringBuilder is not thread-safe and not synchronized, the performance is greater and the memory it uses is also low when compared to StringBuffer.
    
* **Example StringBuffer vs StringBuilder performance:**
    
    ```java
    import java.util.GregorianCalendar;
    
    public class TestString {
    
    	public static void main(String[] args) {
    		System.gc();
    		long start=new GregorianCalendar().getTimeInMillis();
    		long startMemory=Runtime.getRuntime().freeMemory();
    		StringBuffer sb = new StringBuffer();
    		//StringBuilder sb = new StringBuilder();
    		for(int i = 0; i<10000000; i++){
    			sb.append(":").append(i);
    		}
    		long end=new GregorianCalendar().getTimeInMillis();
    		long endMemory=Runtime.getRuntime().freeMemory();
    		System.out.println("Time Taken:"+(end-start));
    		System.out.println("Memory used:"+(startMemory-endMemory));
    	}
    }
    ```
    

---

# Core Java - I (OOPs):

## Objects:

* The instances that can be instantiated from a particular class are called objects.
    
* An object is any entity that has a **state** and **behavior**.
    
* These properties and behaviors are implemented by methods inside the class from which the objects are instantiated.
    
* Objects are stored in **Heap Space** and their reference is stored in **Stack Memory**.
    

---

## Class:

* Class is a user-defined blueprint or prototype from which objects can be instantiated.
    
* Class is a logical entity of a physical object.
    

### Inner Class:

* An inner class or nested class is a class that is declared inside another class or interface.
    
* Inner classes are used to logically group classes and interfaces in one place to be more readable and maintainable.
    
* Inner classes can access all the members of the outer class, including the private data members and methods.
    
* There are two types of inner classes:
    
    1. Static nested class → A static class created within a class.
        
        * **Example:**
            
            ```java
            class Animal {
            
            // inner class
               class Reptile {
                  public void displayInfo() {
                    System.out.println("I am a reptile.");
                  }
               }
            
            // static class
               static class Mammal {
                  public void displayInfo() {
                    System.out.println("I am a mammal.");
                  }
               }
            }
            
            class Main {
               public static void main(String[] args) {
                  // object creation of the outer class
                  Animal animal = new Animal();
            
                  // object creation of the non-static class
                  Animal.Reptile reptile = animal.new Reptile();
                  reptile.displayInfo();
            
                  // object creation of the static nested class
                  Animal.Mammal mammal = new Animal.Mammal();
                  mammal.displayInfo();
            
               }
            }
            ```
            
    2. Non-static nested class → This is called an Inner class. Instances of the inner class have access to all the methods and attributes of the outer class.
        
        * Local inner class → Inner class defined inside a method.
            
        * Anonymous inner class → A class created for implementing an interface or extending a class. Java compiler decides its name.
            
        * Member inner class → A class created within class and outside method.
            

### Abstract Class and Method:

* The abstract class in Java cannot be instantiated (we cannot create objects of abstract classes).
    
* An abstract class can have both regular methods and abstract methods.
    
* A method that doesn't have its body is known as an abstract method. We use the same `abstract` keyword to create abstract methods.
    
* If a class contains an abstract method, then the class should be declared abstract. Otherwise, it will generate an error.
    
* Though abstract classes cannot be instantiated, we can create subclasses from them. We can then access members of the abstract class using the object of the subclass.
    
* **Example:**
    
    ```java
    abstract class Language {
    
      // method of abstract class
      public void display() {
        System.out.println("This is Java Programming");
      }
    }
    
    class Main extends Language {
    
      public static void main(String[] args) {
        
        // create an object of Main
        Main obj = new Main();
    
        // access method of abstract class
        // using object of Main class
        obj.display();
      }
    }
    ```
    

---

## Interface:

* An interface is a fully abstract class.
    
* Interfaces are classes that contain method signatures without a body which can be implemented in other classes.
    
* By using interfaces, we can share common methods by overriding them.
    
* Interfaces are used to implement abstraction.
    
* **Example:**
    
    ```java
    interface Polygon {
      void getArea(int length, int breadth);
    }
    
    // implement the Polygon interface
    class Rectangle implements Polygon {
    
      // implementation of abstract method
      public void getArea(int length, int breadth) {
        System.out.println("The area of the rectangle is " + (length * breadth));
      }
    }
    
    class Main {
      public static void main(String[] args) {
        Rectangle r1 = new Rectangle();
        r1.getArea(5, 6);
      }
    }
    ```
    

---

## Abstraction:

* In Java, **Data Abstraction** is defined as the process of reducing the object to its essence so that only the necessary characteristics are exposed to the users.
    
* Abstraction defines an object in terms of its properties (attributes), behavior (methods), and interfaces (means of communicating with other objects).
    

---

## Encapsulation:

* Wrapping the data (variables) and code acting on those data (methods) together as a single unit.
    
* The variables of a class will be hidden from other classes and can be accessed only through the methods of their current class.
    
* This is also called **Data Hiding**.
    
* **Example:**
    
    ```java
    class Area {
    
      // fields to calculate area
      int length;
      int breadth;
    
      // constructor to initialize values
      Area(int length, int breadth) {
        this.length = length;
        this.breadth = breadth;
      }
    
      // method to calculate area
      public void getArea() {
        int area = length * breadth;
        System.out.println("Area: " + area);
      }
    }
    
    class Main {
      public static void main(String[] args) {
    
        // create object of Area
        // pass value of length and breadth
        Area rectangle = new Area(5, 6);
        rectangle.getArea();
      }
    }
    ```
    

---

## Inheritance:

* Creating new classes, by building upon existing classes are called inheritance.
    
* This way the new classes can access the attributes and methods of the existing class.
    
* The existing class is called the parent class, and the new class will be called the child class.
    
* In Java, inheritance is an **is-a** relationship. That is, we use inheritance only if there exists an is-a relationship between two classes. \[e.g\] **Car** is a **Vehicle**.
    
* In Java, if a class includes `protected` fields and methods, then these fields and methods are accessible from the subclass of the class.
    
* Example:
    
    ```java
    class Animal {
    
      // field and method of the parent class
      String name;
      public void eat() {
        System.out.println("I can eat");
      }
    }
    
    // inherit from Animal
    class Dog extends Animal {
    
      // new method in subclass
      public void display() {
        System.out.println("My name is " + name);
      }
    }
    
    class Main {
      public static void main(String[] args) {
    
        // create an object of the subclass
        Dog labrador = new Dog();
    
        // access field of superclass
        labrador.name = "Rohu";
        labrador.display();
    
        // call method of superclass
        // using object of subclass
        labrador.eat();
    
      }
    }
    ```
    

### Types of Inheritance:

1. Single Inheritance:
    
    * In single inheritance, a single subclass extends from a single superclass.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403190249/6ca9de23-0932-47f7-b01d-f293f6ad6db2.png align="center")
        
2. Multi-level Inheritance:
    
    * In multilevel inheritance, a subclass extends from a superclass and then the same subclass acts as a superclass for another class.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403218670/184f4875-3fb7-4473-a5df-43fdb55f94d1.png align="center")
        
3. Hierarchical Inheritance:
    
    * In hierarchical inheritance, multiple subclasses extend from a single superclass.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403229665/20b17b83-4d72-4fc3-ac12-2af9c90cc768.png align="center")
        
4. Multiple Inheritance:
    
    * In multiple inheritances, a single subclass extends from multiple superclasses.
        
    * Java doesn't support multiple inheritances. However, we can achieve multiple inheritances using interfaces.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403259999/6d609cd0-b07a-4fa2-beb8-009f73f987a7.png align="center")
        
5. Hybrid Inheritance:
    
    * Hybrid inheritance is a combination of two or more types of inheritance.
        
        ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1674403267654/b604674a-c83b-43d5-b44b-5837697d5a61.png align="center")
        

---

## Polymorphism:

* The word polymorphism means many forms. The ability of a message to be displayed in more than one form is called polymorphism. There are two types of polymorphism.
    
    * Compile Time polymorphism:
        
        * It is also known as static polymorphism.
            
        * This type of polymorphism is achieved by method overloading.
            
    * Run Time polymorphism:
        
        * It is also known as Dynamic Method Dispatch.
            
        * It is a process in which a function call to the overridden method is resolved at runtime.
            
        * This type of polymorphism is achieved by Method Overriding.
            

---
