Core Java Interview Questions

1. In which scenario, finally block will not get executed?

There are a few scenarios in which finally block may not get executed:

  1. System.exit() : If the System.exit() method is called before the finally block is reached, the Java Virtual Machine (JVM) will terminate, and the finally block won’t have a chance to execute.

2. Difference between ArrayList and LinkedList?

Aspect
ArrayListLinkedList
Underlying Data Structure
Dynamic array
Doubly-linked list

Access to Elements
Direct and fast using index
Slower, requires traversal

Insertions/Deletions
Slower in the middle
Faster, especially in the middle

Performance
Better for random access
Better for insertions/deletions
Memory Usage
Generally less per element
Generally more per element
3. What is the use of final keyword?

Final Variables:

  • When applied to a variable, the final keyword signifies that the variable’s value cannot be modified once it has been assigned. This is often used for constants.

Final Methods:

When applied to a method, the final keyword indicates that the method cannot be overridden by subclasses.

Final Class:

  • When applied to a class, the final keyword indicates that the class cannot be extended, and no subclasses can be created.
4. Why String is immutable? What benefits do we get by making it immutable in terms of memory?

the main benefits of keeping String Class as Immutable are caching, security, synchronization, and performance

String Pool: It is a storage area in heap memory, the String class keeps a pool of string, Every time a string literal is generated, the JVM checks its existence in the string pool first, if the string is already present in the string pool then the reference of string is returned otherwise new instance will be created inside the pool

5. Which data type is used to store passwords and why?

this question answer is very tricky while giving an answer you have to be careful because the interviewer wants to deep understand here

As a developer we prefer to use Char[] array over Strings, there are several reasons:

  1. Strings are Immutable: if you store the password as plain text it will be available in memory until the Garbage collector clears it and since String is used in the String pool for reusability
  2. Security Issue: anyone who has access to the memory dump can easily find the password in text format, and if we use plain text that anybody can see
  3. Log File Safety: With Plain String, there are much higher chances of accidentally printing the password in the logs
6. Difference between Synchronised and Concurrent HashMap?
  • Concurrent Hashmap: It is a class that was introduced in JDK 1.5, concurrent hashmap applies locks bucket level that is called a fragment, and it allows concurrent read and write operations, The Performance of concurrent hashmap is better than the synchronized map
Concurrent Map Example
  • Synchronized Hashmap: There is one Utill class called Collections, inside which we have the syncronizedHashMap() method this method applies a lock on the entire collection, which means if one thread is accessing the map then no other thread can access the same map
Synchronized HashMap Example
7. How is the thread lifecycle maintained using the ExecutorService Framework?

The ExecutorService framework is used to manage and control the lifecycle of the thread

Below are the 3 key concepts is important to maintain the life cycle of threads

  • ExecutorService: This is an Interface that manages a pool of threads for executing tasks
  • ThreadPoolExecutor: core implementation of Executor service
  • Task Queue: A queue where tasks are stored
Management of Thread Life Cycle:
  1. Creation of ExecutorService: we create an ExecutorService instance using one of the factory methods provided by the Executors class, such as newFixedThreadPool, newCachedThreadPool, or newSingleThreadExecutor.
  2. Submission of Tasks: we submit tasks to the ExecutorService for execution. and Tasks can be submitted either as Runnable instances or Callable instances. The ExecutorService manages the execution of these tasks asynchronously.
  3. Task Execution: The ExecutorService executes tasks using the threads from its managed thread pool. Depending on the type of ExecutorService (fixed thread pool, cached thread pool, etc.), it may reuse threads or create new ones as needed.
  4. Completion of Tasks: As tasks are executed, they can be completed successfully, throw exceptions, or be canceled. The ExecutorService handles the completion of tasks and manages their results or exceptions.
  5. Shutdown: When we are done using the ExecutorService, we should shut it down explicitly by calling its shutdown() method.
8. How to make class immutable?

There are 5 principles we have to follow to make any class immutable

  • Make the class final or sealed: This prevents subclasses from being created, ensuring the class definition and as we know final class can’t be inherit
  • Make field private and final: This restricts direct access and modification of internal data.
  • No setter methods: Instead, provide getter methods to access data, but return copies of mutable objects if applicable.
  • Perform deep copies in constructors and methods: When dealing with mutable objects within the class, create copies to avoid modifying the original data.
  • Consider immutability libraries: Some languages offer libraries or built-in mechanisms to simplify creating immutable classes.
9. What is try with Resource in Java and where should we use this?

Let’s understand first what is try-with-resource and then we will explain how you can use this feature

  • Try-with-Resource: this is one of the good features which ensure that each resource should be closed at the end of the statement, it was introduced in Java 7
  • Syntax:
Use Case of Try-with-Resource:

Let’s take a scenario where we need to read data from a file and process that, below is the code

  • In the above code, we are reading from a file named ‘jobinterviewquestion.txt
  • After that, we are creating a BufferedReader object to read the file, BufferedReader is a resource and that needs to be closed after use.
  • Inside the try block, we are reading each line from the file and processing
  • If any exception occurs we handle that in the catch block
  • the main advantage of this is we don’t need to write a finally block explicitly of if we are using try with resource
10. What is the significance of finally block?
  • As we know finally block is always executed even if we have a return statement in the code
  • Even if any exception occurs finally block is always executed
  • For critical tasks such as closing the DB connection, Network Connection, and rollback the transaction code, we can write code inside finally block
11.Can we override private method?

No, we can’t override private method because those methods are not accessible outside the class and hence private method of Base class will not be visible to Derived class.
If we try to override private method then we will get compile time error I.e. method_name() has private access in Base Class.
Lets understand with an example:

In this example, we are creating a reference object of Base class which is holding the object of Derived class. Here, the compiler should call method whose object gets created. However, if you execute above code then you will get compile time error.

We can understand by seeing an error that compiler tries to call run method of Base class because overrides didn’t happen.

12. Can we override protected method?

Yes, we can override protected method in Java only if those classes are on the same package. As you know, protected method will only be visible in the same package. 

If the base class method is protected, the Derived class can override it. Moreover, Derived class can change the access specifier.

If Base class method is protected then you can make it public or protected in derived class,. However, you can’t have weaker access specifier like private or default.

13. Can we override static method in Java?

No, we can’t override static method. It is because method overriding is determined at run-time but static methods are determined at compile time with static binding. Hence, if we try to override static method then Derived Class method will get hidden and Base class method will get called based on the object reference. This is also known as method hiding.
For example:

Will become

Since run() is a static method it didn’t get override due to which Base class run() is called.

14. What is compile time and run time polymorphism?

Compile time polymorphism: Compile time polymorphism is also known as early binding, static binding and it is obtained through method overloading. Method overloading allows us to have more than one method of same name with different behaviour by changing the number parameters or data type of parameters. Since this process gets executed or determined by compiler at compile time, that’s why it is known as compile time polymorphism.

Run time polymorphism: Run time polymorphism is also known as late binding, dynamic binding and it is obtained through method overriding. Method overriding allows us to have more than one method with same name and same signature with different behaviour. Since, this process gets executed or we should say method to be executed is determined at run time based on the type of object referenced.

15. Can we override final method?

We can’t override final method. If we try to override the final method in java, we will get an error.

Developers will keep methods as final when they know that the implementation/behaviour is fully completed.

16. What is method hiding?

Method hiding is a functionality in Java in which Derived class override the static method of Base class. In this case, method present in the Base class hides the one present in the Derived class.

17. What is Fail Fast and Fail Safe iterator?

Fail fast iterators are the iterators which can quickly detect any modifications made to the underlying collection while the iterator is iterating and immediately throws ‘’ConcurrentModificationException’. It ensures that the collection will not be modified by other threads during iteration. These iterators works on main memory area and mostly use in collections like ArrayList, HashMap, and other standard Java Collections.

Advantages: It detect concurrent modifications quickly which helps to avoid unpredictable behaviour and ensures that issues are identified early during development.

For Example:

Fail safe iterators make a copy of the collections at the time of creation. It does not throw any exception even if we do any modification while the iterator is iterating. These iterators are mostly use in ConcurrentHashMap and CopyOnWriteArrayList.

Advantages: Fail safe Iterators continues to work even if the underlying collection is modified which ensures the stability of the system. However, it might not reflect the most recent changes in the collection updated by other Threads.

For example:

The choice between fail-fast and fail-safe iterators depends on the specific requirements of your application. Fail-fast iterators are generally preferred when quick detection of concurrent modifications is crucial, whereas fail-safe iterators are suitable when you need to avoid exceptions during iteration and can tolerate working with a snapshot of the collection.

18. Can you explain internal working of HashMap?

The HashMap class is part of the Java Collections Framework and is used to store key-value pairs. It works on the principle of hashing and it provide constant time complexity when we perform put and get operations on it.

Lets understand the internal workings of HashMap:

  1. When you create a HashMap, array of 16 buckets is created in the memory to store key-value pairs.
  2. When you put a key-value pair into the HashMap, the hash of key is used to determine the bucket where the pair will be stored. There are several steps to be performed internally.

Lets understand with an example:

  1. Create a HashMap with an initial capacity of 16 (by default)
  1. Put key-value pairs into the HashMap
  1. Calculate the HashCode of key ”oneKey”. Here, the hash of the key is computed using the hashCode() method of the key object.
  2. The generated hash code is used to calculate the index of the bucket in which the key-value pair will be stored.
  3. Calculate index as hash & (capacity – 1), where hash is the generated hash code, and capacity is the current capacity of the HashMap(by default 16)., lets say index is 4
  4. Once the index is calculated, it then checks whether the specific bucket is empty or not.
  5. Go to index 4 of array, create a node and place this pair if there is no node exist
  6. If there is already a node exist at particular index then compare the content of existing key with given key using equals() method
  7. If both keys are equal then override the value
  8. If both are different then create another node and place given key-value pair.

To handle collisions, HashMap uses a linked list (a chain) at each bucket. If multiple key-value pairs map to the same bucket, they are stored as nodes in this linked list.

Process to retrieve values:

When you retrieve values using keys, the same process is repeated to calculate the bucket index, locate the correct node in the linked list and get the value.

19. When Resizing gets happen in HashMap?

If you keep on adding the key-value pair in HashMap, if the load factor (the ratio of the number of elements to the capacity) exceeds a threshold, the HashMap is resized, and the existing elements of array are rehashed into a larger array of buckets.

20. What is Load Factor in HashMap?

The load factor of a HashMap is the ratio of the number of stored elements to the total number of buckets.

It is denoted by size/capacity.

The default load factor in Java is 0.75.

21. What is Collision in HashMap?

Collision occur in HashMap when different keys generate the same hash code which end up placing the key-value pair to the same index/bucket.

HashMap uses a linked list (chain of nodes) at each bucket to handle collisions. In short, each bucket can store multiple key-value pairs in a linked list. When a new key-value pair gets stored to an existing bucket, it is added as a new node in the linked list.

22. What is equals() method in Java?

The equals() method  in Java is used to compare two variables and returns true if they are logically same. The default implementation of equals() method compares the reference or memory location of both the object. However, we can customise the default implementation by overriding this method in our custom Java classes.

The default implementation of equals() method defined in Object class is:

23. What is hashCode() method in Java?

The hashCode() method  in Java is used to distinguish buckets in Hash implementations like HashMap, HashSet and it returns an integer value which represents the value of object. The default implementation of hashCode() method returns the reference or memory location of object. However, similar to equals() method, we can also customise its default implementation by overriding this method in our custom Java classes.

24. What is equal and HashCode contract?

The contract between the equals() and hashCode() methods is important when working with Hash implementation like HashMap. We have to override hashCode(0 method if we are overriding equals() method. If we don’t override any one of them, it might give incorrect result while working with HashMap. 

This contract says that if two object are equal as per equals(0 method, then their hashcode() should return same integer value.

For example:

If x.equals(y) returns true, then x.hashCode() should be equal to y.hashCode().

Note: There might be the scenario where two unequal object will have the same hashCode and this problem known as Collision.

25. What if we don’t override equal and HashCode?

Consider, we have to store Student Objects as a key in HashMap and Student class does  not override equals() and HashCode().

In this case, all the student object (keys) will be considered duplicate even if they have same content and it end up getting stored in different buckets.

26. What if we override equal but not HashCode?

Consider, we have to store Student Objects as a key in HashMap and Student class does override equals() but not HashCode().

In this case, all the student object (keys) will be considered duplicate even if they have same content and it end up getting stored in different buckets.

27. What if we override hashCode but not equals()?

Consider, we have to store Student Objects as a key in HashMap and Student class does override hashCode() but not equals().

In this case, all the student object (keys) will be considered duplicate even if they have same content . Student object having same content will be stored in same bucket but in a separate Node(Collision).

28. What if we override hashCode and equals() both?

Consider, we have to store Student Objects as a key in HashMap and Student class does override both the methods().

In this case, student object having same content will generate same HashCode and it gives the same index number. While storing the key-value pair on bucket, if their is already a node present then equals return true and value gets update of that key.

29. What changes has been made in HashMap in java 8?

There are several enhancements and improvements were introduced to the HashMap class.

If a bucket contains large number of collision keys then all the entries will get stored in Balanced tree instead of linked list once the threshold is reached.

While converting list to binary tree, hashCode() method is used as a differentiator, If there are same hash code value present in same bucket then the bigger one will go to the right of the tree and smaller one will go on the left side. However, if the hash code is same then comparable interface comes into the picture that will compare the keys and find the key position to be placed in a tree to maintain the proper order.

Advantage: It helps us to achieve high performance.

30. Why we need lambda expression and what benefit we get in terms of memory management?

Lambda expression is the most important features of Java 8. It helps us to write concise, compact and readable code in a. Functional style.

Earlier, we used to provide implementation of Functional Interface in a separate class which is very difficult to maintain. We also used to provide implementation in anonymous class in which class it needed but it is not reusable, as we can’t access those implementation outside class. To overcome this problem, Lambda function or expression comes into the picture.

Lets understand with an example:

31. How to remove duplicate elements from a list using stream API?

You can use Stream.distinct() method to remove duplicate elements. This method is just like distinct clause in SQL which eliminate the duplicate entry.

32. How to remove duplicate elements from a list using standard Java Collections?

You can use HashSet to remove duplicate elements as it only contains unique elements.

Drawback of this approach is that it does not maintain the insertion order after removing duplicate elements. However, if you have to maintain the insertion order then go with LinkedHashSet.

33. Find the sum of all the elements present in a list using Stream API?

You can use Stream.reduce() to get the sum of all the elements.

There is one more way to achieve sum by using mapToInt() method provided by Stream Api which convert our stream to an IntStream Object.

Leave a comment