Most Popular Java Interview Questions
and Answers

A comprehensive list of the most important and commonly asked Java interview questions
and answers with detailed explanation.

Java Interview Questions

37 questions

Android Interview Questions

25 questions

Git Interview Questions

12 questions

Django Interview Questions

11 questions

Spring Boot Interview Questions

1 questions

What are synchronized methods and synchronized statements?

Synchronized methods are methods that are used to control access to an object. A thread only executes a synchronized method after it has acquired the lock for the method's object or class. Synchronized statements are similar to synchronized methods. A synchronized statement can only be executed after a thread has acquired the lock for the object or class referenced in the synchronized statement.

What are the different ways to create threads in Java?

We can define and implement a thread in java using two ways: Extending the Thread class

class ThreadExample extends Thread {  
   public void run(){  
       System.out.println("Thread runs...");  
   public static void main(String args[]){  
       ThreadExample ib = new ThreadExample();  

Implementing the Runnable interface

class ThreadExample implements Runnable {  
   public void run(){  
       System.out.println("Thread runs...");  
   public static void main(String args[]){  
       Thread ib = new Thread(new ThreadExample()); 

Implementing a thread using the method of Runnable interface is more preferred and advantageous as Java does not have support for multiple inheritances of classes. start() method is used for creating a separate call stack for the thread execution. Once the call stack is created, JVM calls the run() method for executing the thread in that call stack.

What is difference between thread and process?

A thread is a class in java that belongs to java.lang package. A thread is an lightweight process and has its own call stack. In Java, you can run multiple threads parallely. A thread is used to perform long running jobs dedicated without disturbing to the other part of program. Even if you don't create any new threads in your program, there is at least one thread i.e. main thread() which runs the application.

  1. Threads share the address space of the process that created it; processes have their own address.
  2. Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process.
  3. Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
  4. Threads have almost no overhead; processes have considerable overhead.
  5. New threads are easily created; new processes require duplication of the parent process.
  6. Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
  7. Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process do not affect child processes.

What are the different states of a thread's life cycle?

  1. New - When a thread is instantiated it is in New state until the start() method is called on the thread instance. In this state the thread is not considered to be alive.
  2. Runnable - The thread enters into this state after the start method is called in the thread instance. The thread may enter into the Runnable state from Running state. In this state the thread is considered to be alive.
  3. Running - When the thread scheduler picks up the thread from the Runnable thread's pool, the thread starts running and the thread is said to be in Running state.
  4. Waiting/Blocked/Sleeping - In these states the thread is said to be alive but not runnable. The thread switches to this state because of reasons like wait method called or sleep method has been called on the running thread or thread might be waiting for some i/o resource so blocked. Dead - When the thread finishes its execution i.e. the run() method execution completes, it is said to be in dead state. A dead state can not be started again. If a start() method is invoked on a dead thread a runtime exception will occur.

What are different ways in which a thread can enter the waiting state?

A thread can enter the waiting state by the following ways:

  1. Invoking its sleep() method,
  2. By blocking on I/O
  3. By unsuccessfully attempting to acquire an object's lock
  4. By invoking an object's wait() method.
  5. It can also enter the waiting state by invoking its (deprecated) suspend() method.

What is the difference between yield and sleep?

When a task invokes its yield() method, it returns to the ready state, either from waiting, running or after its creation. When a task invokes its sleep() method, it returns to the waiting state from a running state.

Extending Thread class or implementing Runnable Interface. Which is better?

You have two ways to create a thread in Java. First, making your class "extends" Thread class. The other way is making your class implement "Runnable" interface.

The latter is more advantageous, cause when you are going for multiple inheritance, then only interface can help. If you are already inheriting a different class, then you have to go for Runnable Interface. Also, if you are implementing interface, it means you have to implement all methods in the interface.

Both Thread class and Runnable interface are provided for convenience and use them as per the requirement. But if you are not extending any class, better extend Thread class as it will save few lines of coding. Otherwise performance wise, there is no distinguishable difference. A thread is in the ready state after it has been created and started.

What is Mutual Exclusion (Mutex)? How to Handle Mutex in Java?

Mutual exclusion in Java is a mechanism that allows only one thread to access a shared resource or critical section of code at a time, preventing race conditions where multiple threads can access and modify the same resource simultaneously.

For mutual exclusion, you can simply use the synchronized keyword, which can be applied to a method or a block of code to ensure that only one thread can access the synchronized code at a time.

Java offers different options to achieve mutual exclusion, such as the Semaphore class, the ReadWriteLock interface, the AtomicInteger class, and the StampedLock class. The choice of implementation depends on the specific requirements and constraints of the application.

  1. Semaphore: The Semaphore class can be used to implement mutual exclusion. It allows a limited number of threads to access a critical section at the same time.
  2. ReadWriteLock: The ReadWriteLock interface can be used to implement mutual exclusion for read and write operations. It allows multiple threads to read a shared resource simultaneously, but only one thread can write to the resource at a time.
  3. AtomicInteger: The AtomicInteger class can be used to implement mutual exclusion for integer values. It provides atomic operations such as incrementAndGet() and decrementAndGet(), which ensures that only one thread can modify the value at a time.
  4. StampedLock: The StampedLock class can be used to implement mutual exclusion for read and write operations. It provides optimistic read locks, which allow multiple threads to read a shared resource simultaneously, and a write lock, which allows only one thread to write to the resource at a time.

What is the difference between preemptive scheduling and time slicing?

Under preemptive scheduling, the highest priority task executes until it enters the waiting or dead states or a higher priority task comes into existence. Under time slicing, a task executes for a predefined slice of time and then re-enters the pool of ready tasks. The scheduler then determines which task should execute next, based on priority and other factors.

What is deadlock?

When two threads are waiting for each other and can't proceed until the first thread obtains a lock on the other thread or vice versa, the program is said to be in a deadlock.

What are the differences between HashMap and HashTable in Java?

HashMap is not synchronized thereby making it better for non-threaded applications.HashTable is synchronized and hence it is suitable for threaded applications.
Allows only one null key but any number of null in the values.This does not allow null in both keys or values.
Supports order of insertion by making use of its subclass LinkedHashMap.Order of insertion is not guaranteed in HashTable.

What is a volatile keyword?

In general, each thread has its own copy of the variable, such that one thread is not concerned with the value of the same variable in the other thread. But sometime this may not be the case. Consider a scenario in which the count variable is holding the number of times a method is called for a given class irrespective of any thread calling, in this case, irrespective of thread access the count has to be increased so the count variable is declared as volatile.

The copy of the volatile variable is stored in the main memory, so every time a thread access the variable even for reading purpose the local copy is updated each time from the main memory. The volatile variable also has performance issues.

What is Serializable?

Serializable is a marker interface. When an object has to be transferred over a network ( typically through RMI or EJB) or persists the state of an object to a file, the object Class needs to implement a Serializable interface. Implementing this interface will allow the object converted into a byte stream and transfer over a network.

What is use of serialVersionUID?

During object serialization, the default Java serialization mechanism writes the metadata about the object, which includes the class name, field names, types, and superclass. This class definition is stored as a part of the serialized object. This stored metadata enables the deserialization process to reconstitute the objects and map the stream data into the class attributes with the appropriate type every time an object is serialized the java serialization mechanism automatically computes a hash value.

ObjectStreamClass’s computeSerialVersionUID() method passes the class name, sorted member names, modifiers, and interfaces to the secure hash algorithm (SHA), which returns a hash value. The serialVersionUID is also called suid.

So when the serialized object is retrieved, the JVM first evaluates the suid of the serialized class and compares the suid value with the one of the objects. If the suid values match then the object is said to be compatible with the class and hence it is de-serialized. If not InvalidClassException exception is thrown.

Changes to a serializable class can be compatible or incompatible.

What is difference between ArrayList and Vector?

  • Synchronization – ArrayList is not thread-safe whereas Vector is thread-safe. In Vector class each method like add()get(int i) is surrounded with a synchronized block and thus making Vector class thread-safe.
  • Data growth – Internally, both the ArrayList and Vector hold onto their contents using an Array. When an element is inserted into an ArrayList or a Vector, the object will need to expand its internal array if it runs out of room. A Vector defaults to doubling the size of its array, while the ArrayList increases its array size by 50 percent.

What is difference between HashMap and HashTable?

Both collections implement Map. Both collections store value as key-value pairs. The key differences between the two are

  • Hashmap is not synchronized in nature but HashTable is.
  • Another difference is that the iterator in the HashMap is fail-safe while the enumerator for the HashTable isn’t. Fail-safe – if the HashTable is structurally modified at any time after the iterator is created, in any way except through the iterator’s own remove method, the iterator will throw a ConcurrentModificationException
  • HashMap permits null values and only one null key, while Hashtable doesn’t allow key or value as null.

    When to use ArrayList or LinkedList?

    • For the ArrayList, doing random lookup using get() is fast, but for LinkedList, it’s slow. It’s slow because there’s no efficient way to index into the middle of a linked list.
    • When removing elements, using ArrayList is slow. This is because all remaining elements in the underlying array of Object instances must be shifted down for each remove operation. But here LinkedList is fast because deletion can be done simply by changing a couple of links.
    • So an ArrayList works best for cases where you’re doing random access on the list, and a LinkedList works better if you’re doing a lot of editing in the middle of the list.

    What is final, finalize() and finally? What does it mean that a class or member is final?

    • final – Variables defined in an interface are implicitly final. A final class can’t be extended i.e., the final class may not be subclassed. This is done for security reasons with basic classes like String and Integer. It also allows the compiler to make some optimizations and makes thread safety a little easier to achieve. A final method can’t be overridden when its class is inherited. You can’t change the value of a final variable (which is a constant)
    • finally – a keyword used in exception handling will be executed whether or not an exception is thrown. For example, the closing of open connections is done in the final method.
    • finalize – helps in garbage collection. finalize() method is used just before an object is destroyed and garbage collected.

    What is Method Overriding? What restrictions are placed on method overriding?

    When a class defines a method using the same name, return type, and argument list as that of a method in its superclass, the method in the subclass is said to override the method present in the Superclass. When the method is invoked for an object of the class, it is the new definition of the method that is called and not the method definition from the superclass. Restrictions placed on method overriding

    • Overridden methods must have the same name, argument list, and return type.
    • The overriding method may not limit the access of the method it overrides. Methods may be overridden to be more public, not more private.
    • The overriding method may not throw any exceptions that may not be thrown by the overridden method.

    What makes a HashSet different from a TreeSet?

    Although both HashSet and TreeSet are not synchronized and ensure that duplicates are not present, there are certain properties that distinguish a HashSet from a TreeSet.

    Implementation: For a HashSet, the hash table is utilized for storing the elements in an unordered manner. However, TreeSet makes use of the red-black tree to store the elements in a sorted manner.

    Complexity/ Performance: For adding, retrieving, and deleting elements, the time amortized complexity is O(1) for a HashSet. The time complexity for performing the same operations is a bit higher for TreeSet and is equal to O(log n). Overall, the performance of HashSet is faster in comparison to TreeSet.

    Methods: hashCode() and equals() are the methods utilized by HashSet for making comparisons between the objects. Conversely, compareTo() and compare() methods are utilized by TreeSet to facilitate object comparisons.

    Objects type: Heterogeneous and null objects can be stored with the help of HashSet. In the case of a TreeSet, runtime exception occurs while inserting heterogeneous objects or null objects.

    Showing page 1 of 2