FREE PREVIEW

You're viewing a free preview

This is a sample of 15 questions from our full collection of 150 interview questions.

Unlock all 150 questions with detailed explanations and code examples

Get Full Access

Java Basics

What are the main differences between the JDK, JRE, and JVM?

The three components form a hierarchy where each serves a specific purpose in Java development and execution:

Component Full Name Purpose Contains
JDK Java Development Kit Development environment JRE + development tools (javac, debugger)
JRE Java Runtime Environment Execution environment JVM + runtime libraries
JVM Java Virtual Machine Execution engine Bytecode interpreter/compiler
// This code requires different components:
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
// JDK needed to compile (javac HelloWorld.java)
// JRE needed to run (java HelloWorld)
// JVM executes the bytecode

The JDK is for developers who write Java code, JRE is for users who run Java applications, and JVM is the core execution engine that makes Java platform-independent.

References:

↑ Back to top

Why is Java considered platform-independent?

Java achieves platform independence through bytecode compilation and the Java Virtual Machine (JVM):

  1. Source Code → Bytecode: Java source code is compiled into platform-neutral bytecode (.class files)
  2. JVM per Platform: Each operating system has its own JVM implementation
  3. Bytecode Execution: The same bytecode runs on any JVM, regardless of the underlying OS
// This same .class file runs on Windows, Linux, macOS
public class PlatformIndependent {
    public static void main(String[] args) {
        System.out.println("Runs everywhere with JVM!");
    }
}

The principle "Write Once, Run Anywhere" (WORA) means developers write code once, and it executes on any platform with a JVM installed.

References:

↑ Back to top

How do you define the main method in a Java class, and what is its significance?

The main method serves as the entry point for Java applications and must follow this exact signature:

public static void main(String[] args) {
    // Application code starts here
    System.out.println("Hello World!");
}

Each keyword has specific significance:

  • public: Accessible from anywhere, allowing JVM to call it
  • static: Can be called without creating class instances
  • void: Returns no value to the operating system
  • String[] args: Command-line arguments passed to the program
// Example using command-line arguments
public class CommandLineExample {
    public static void main(String[] args) {
        if (args.length > 0) {
            System.out.println("First argument: " + args[0]);
        }
    }
}
// Run: java CommandLineExample hello
// Output: First argument: hello

The JVM looks specifically for this method signature to start program execution.

References:

↑ Back to top

What is the difference between byte, short, int, and long data types?

These are Java's integral primitive types, differing in size and range:

Type Size Range Use Case
byte 8 bits -128 to 127 Memory-efficient arrays, file I/O
short 16 bits -32,768 to 32,767 Unicode characters, small numbers
int 32 bits -2³¹ to 2³¹-1 (~±2 billion) Default integer type
long 64 bits -2⁶³ to 2⁶³-1 Large numbers, timestamps
public class IntegerTypes {
    public static void main(String[] args) {
        byte smallNumber = 100;
        short mediumNumber = 30000;
        int defaultNumber = 2000000000;
        long bigNumber = 9000000000000000000L; // Note the 'L' suffix
        
        System.out.println("Byte max: " + Byte.MAX_VALUE);
        System.out.println("Int max: " + Integer.MAX_VALUE);
        System.out.println("Long max: " + Long.MAX_VALUE);
    }
}

Choose the appropriate type based on the expected range of values and memory constraints.

References:

↑ Back to top

What are the default values of primitive data types in Java?

Default values apply only to instance variables and static variables, not local variables:

Type Default Value Note
byte 0
short 0
int 0
long 0L
float 0.0f
double 0.0d
char '\u0000' Null character
boolean false
public class DefaultValues {
    // Instance variables get default values
    private int number;          // 0
    private boolean flag;        // false
    private char character;      // '\u0000'
    
    public void demonstrateDefaults() {
        System.out.println("Default int: " + number);        // 0
        System.out.println("Default boolean: " + flag);      // false
        System.out.println("Default char code: " + (int)character); // 0
        
        // Local variables must be initialized
        int localVar; 
        // System.out.println(localVar); // Compilation error!
    }
}

Important: Local variables in methods must be explicitly initialized before use.

References:

↑ Back to top

What is the difference between "==" and equals() when comparing objects and primitives?

The == operator and equals() method serve different purposes depending on what you're comparing:

For Primitives:

  • ==: Compares actual values

For Objects:

  • ==: Compares memory references (identity)
  • equals(): Compares content (when properly overridden)
public class ComparisonExample {
    public static void main(String[] args) {
        // Primitive comparison
        int a = 5, b = 5;
        System.out.println(a == b); // true - same values
        
        // String comparison (objects)
        String str1 = new String("hello");
        String str2 = new String("hello");
        String str3 = "hello";
        String str4 = "hello";
        
        System.out.println(str1 == str2);        // false - different objects
        System.out.println(str1.equals(str2));   // true - same content
        System.out.println(str3 == str4);        // true - string pool
        
        // Custom object comparison
        Person person1 = new Person("John");
        Person person2 = new Person("John");
        System.out.println(person1 == person2);        // false - different objects
        System.out.println(person1.equals(person2));   // depends on equals() implementation
    }
}

Rule of thumb: Use == for primitives and reference comparison, use equals() for content comparison of objects.

References:

↑ Back to top

How do you convert a String to an int and vice versa?

Java provides several methods for converting between String and int:

String to int:

public class StringToInt {
    public static void main(String[] args) {
        // Method 1: Integer.parseInt() - preferred
        String numberStr = "123";
        int number1 = Integer.parseInt(numberStr);
        
        // Method 2: Integer.valueOf() - returns Integer object, auto-unboxed
        int number2 = Integer.valueOf(numberStr);
        
        // Handling exceptions
        try {
            int invalidNumber = Integer.parseInt("abc"); // NumberFormatException
        } catch (NumberFormatException e) {
            System.out.println("Invalid number format");
        }
        
        System.out.println("Converted: " + number1); // 123
    }
}

int to String:

public class IntToString {
    public static void main(String[] args) {
        int number = 456;
        
        // Method 1: String.valueOf() - preferred
        String str1 = String.valueOf(number);
        
        // Method 2: Integer.toString()
        String str2 = Integer.toString(number);
        
        // Method 3: String concatenation (less efficient)
        String str3 = number + "";
        
        System.out.println("Converted: " + str1); // "456"
    }
}

Best practices: Use Integer.parseInt() for String→int and String.valueOf() for int→String conversions.

References:

↑ Back to top

What is a package in Java, and how do you import classes from it?

A package is a namespace mechanism that groups related classes, interfaces, and sub-packages. It provides organization and prevents naming conflicts.

Package Declaration:

// File: com/example/utils/MathHelper.java
package com.example.utils;

public class MathHelper {
    public static int add(int a, int b) {
        return a + b;
    }
}

Importing Classes:

// Single class import (preferred)
import java.util.List;
import java.util.ArrayList;
import com.example.utils.MathHelper;

// Package wildcard import (use sparingly)
import java.util.*;

public class ImportExample {
    public static void main(String[] args) {
        List<String> names = new ArrayList<>();
        int result = MathHelper.add(5, 3);
        
        // Fully qualified name (no import needed)
        java.util.Date date = new java.util.Date();
    }
}

Package Benefits:

  • Organization: Groups related functionality
  • Access Control: Package-private visibility
  • Namespace: Prevents class name conflicts

Naming Convention: Reverse domain name (com.company.project.module)

References:

↑ Back to top

What is the use of the "final" keyword in Java?

The final keyword provides immutability and inheritance control at different levels:

1. Final Variables (Constants):

public class FinalVariable {
    // Compile-time constant
    public static final int MAX_SIZE = 100;
    
    // Runtime constant
    private final String name;
    private final List<String> items = new ArrayList<>();
    
    public FinalVariable(String name) {
        this.name = name; // Can be initialized once in constructor
        // this.name = "changed"; // Compilation error!
    }
    
    public void addItem(String item) {
        items.add(item); // Object is mutable, reference is final
        // items = new ArrayList<>(); // Compilation error!
    }
}

2. Final Methods (Cannot be overridden):

public class Parent {
    public final void criticalMethod() {
        System.out.println("This implementation cannot be changed");
    }
}

public class Child extends Parent {
    // public void criticalMethod() { } // Compilation error!
}

3. Final Classes (Cannot be extended):

public final class ImmutableClass {
    private final String value;
    
    public ImmutableClass(String value) {
        this.value = value;
    }
    
    public String getValue() {
        return value;
    }
}

// public class Extended extends ImmutableClass { } // Compilation error!

Use Cases:

  • Security: Prevent modification of critical values/methods
  • Design: Enforce immutability and prevent inheritance
  • Performance: Enable compiler optimizations

References:

↑ Back to top

How does Java handle memory allocation for primitive and reference types?

Java uses different memory areas for different types of data, managed by the JVM memory model:

Memory Areas:

public class MemoryAllocation {
    // Static variables - stored in Method Area/Metaspace
    private static int staticCounter = 0;
    
    // Instance variables - stored in Heap
    private int instanceVar = 42;
    private String name = "Example"; // Reference in heap, object in heap
    
    public void demonstrateMemory() {
        // Local primitives - stored in Stack
        int localInt = 10;
        char localChar = 'A';
        
        // Local object reference - reference in Stack, object in Heap
        StringBuilder sb = new StringBuilder("Hello");
        
        // Method call creates new stack frame
        helperMethod(localInt);
    }
    
    private void helperMethod(int parameter) {
        // New stack frame created
        // Parameter and local variables in this frame
        int localResult = parameter * 2;
    }
}

Memory Allocation Summary:

Type Location Managed By Lifetime
Primitive locals Stack Automatic Method scope
Object references Stack Automatic Method scope
Objects Heap Garbage Collector Until no references
Instance variables Heap Garbage Collector Object lifetime
Static variables Method Area/Metaspace Class loading Program lifetime

Key Points:

  • Stack: Fast allocation/deallocation, limited size, thread-specific
  • Heap: Shared memory, garbage collected, larger capacity
  • References: Always stored where the variable is declared
  • Objects: Always created in heap memory

References:

↑ Back to top

Object-Oriented Programming in Java

What are abstract classes and interfaces, and when do you use each?

Comparison Table:

Feature Abstract Class Interface
Methods Can have concrete and abstract methods Abstract methods (default/static allowed since Java 8)
Variables Instance variables allowed Only public static final constants
Inheritance Single inheritance (extends) Multiple inheritance (implements)
Constructor Can have constructors No constructors
Access Modifiers All modifiers allowed Public methods only (before Java 9)
// Abstract class - partial implementation
abstract class DatabaseConnection {
    protected String url;           // Instance variable
    
    public DatabaseConnection(String url) {  // Constructor
        this.url = url;
    }
    
    public void connect() {         // Concrete method
        System.out.println("Connecting to: " + url);
    }
    
    public abstract void executeQuery(String sql);  // Must implement
}

// Interface - contract definition
interface Drawable {
    int MAX_SIZE = 1000;           // public static final
    
    void draw();                   // abstract method
    
    default void setColor(String color) {  // default method (Java 8+)
        System.out.println("Setting color to: " + color);
    }
}

// Implementation
class MySQLConnection extends DatabaseConnection implements Drawable {
    public MySQLConnection(String url) {
        super(url);
    }
    
    @Override
    public void executeQuery(String sql) {
        System.out.println("Executing MySQL query: " + sql);
    }
    
    @Override
    public void draw() {
        System.out.println("Drawing database schema");
    }
}

When to Use:

  • Abstract Class: When you need shared implementation and state among related classes
  • Interface: When you need to define a contract that unrelated classes can implement
↑ Back to top

What does it mean that Java is an object-oriented programming language?

Java is object-oriented because it structures programs around objects rather than functions or procedures. Everything in Java (except primitives) is an object that contains:

  • Data (attributes/fields)
  • Behavior (methods)
  • Identity (unique reference)

Java enforces OOP principles by requiring all code to exist within classes, supporting inheritance, encapsulation, and polymorphism natively.

// Everything revolves around objects and classes
public class Car {
    private String model;  // Data
    
    public void start() {  // Behavior
        System.out.println("Car starting...");
    }
}

This design promotes code reusability, modularity, and maintainability by modeling real-world entities as software objects.

↑ Back to top

What are the four main principles of OOP, and how are they implemented in Java?

Principle Definition Java Implementation
Encapsulation Bundling data and methods, hiding internal details private fields, public getters/setters
Inheritance Creating new classes based on existing ones extends keyword, class hierarchies
Polymorphism Same interface, different implementations Method overriding, interfaces
Abstraction Hiding complex implementation details abstract classes, interface keyword
// All four principles in action
abstract class Animal {           // Abstraction
    private String name;          // Encapsulation
    
    public Animal(String name) {  // Constructor
        this.name = name;
    }
    
    public abstract void makeSound(); // Abstract method
}

class Dog extends Animal {        // Inheritance
    public Dog(String name) {
        super(name);
    }
    
    @Override
    public void makeSound() {     // Polymorphism
        System.out.println("Woof!");
    }
}

These principles work together to create flexible, maintainable, and scalable software systems.

↑ Back to top

How do you achieve encapsulation in Java?

Encapsulation is achieved by restricting direct access to class internals and providing controlled access through methods:

Key Techniques:

  • Private fields - Hide data from external access
  • Public methods - Provide controlled access (getters/setters)
  • Access modifiers - Control visibility levels
public class BankAccount {
    private double balance;        // Hidden from outside
    private String accountNumber;  // Protected data
    
    // Controlled access through methods
    public double getBalance() {
        return balance;
    }
    
    public void deposit(double amount) {
        if (amount > 0) {          // Validation logic
            balance += amount;
        }
    }
    
    public boolean withdraw(double amount) {
        if (amount > 0 && amount <= balance) {
            balance -= amount;
            return true;
        }
        return false;
    }
}

Benefits: Data integrity, validation, flexibility to change internal implementation without breaking client code.

Reference: Oracle Java Encapsulation Guide

↑ Back to top

What is inheritance, and how do you implement it?

Inheritance allows a class to acquire properties and methods from another class, promoting code reuse and establishing "is-a" relationships.

Implementation:

  • Use extends keyword
  • Child class inherits all non-private members
  • Can override parent methods
// Base class (parent)
public class Vehicle {
    protected String brand;
    protected int year;
    
    public void start() {
        System.out.println("Vehicle starting...");
    }
    
    public void displayInfo() {
        System.out.println(brand + " " + year);
    }
}

// Derived class (child)
public class Car extends Vehicle {
    private int doors;
    
    public Car(String brand, int year, int doors) {
        this.brand = brand;  // Inherited field
        this.year = year;    // Inherited field
        this.doors = doors;
    }
    
    @Override
    public void start() {    // Method overriding
        System.out.println("Car engine starting...");
    }
}

Key Points: Java supports single inheritance only (one parent class), but multiple interface implementation is allowed.

↑ Back to top

Want more questions?

You've seen 15 sample questions. Unlock all 150 En interview questions with detailed explanations, code examples, and expert insights.

150+ questions
Code examples
Expert explanations
Instant access
Unlock Full Access