Top 15 Core Java Interview Questions

Here is a list of core java interview questions.  These are questions that touch the basics of Java language. And it is good to know them even if you are not attending an interview.

Q) Describe the contract of equals() and hashCode(). Why is it important that if you implement one, then you must implement both?

The general contract for the hashCode() and equals() method of the same object is that the hashCode() method should consistently return same value if an object is unchanged. If an object is changed then the hashCode() should return a different value and the changed object should not be equals() to the old object. And for two different objects the contract is that if an object equals() another object then the hashCode() of both the objects should also be same. So it is very important that if one of the methods is overridden then the other one should also be overridden. One important thing to consider.

 It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

Example Class that overrides both equals() and hashCode()

package com.programtalk.learn.interview.questions;
/**
 * 
 * @author programtalk.com
 *
 */
public class Person {
	private String firstName;

	private String lastName;

	@Override
	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof Person)) {
			return false;
		}
		Person otherPerson = (Person) obj;
		return areEqual(firstName, otherPerson.getFirstName()) && areEqual(lastName, otherPerson.getLastName());
	}
	
	private boolean areEqual(String firstString, String secondString) {
		if (firstString == secondString) {
			return true;
		}
		return firstString != null ? firstString.equals(secondString) : false;
	}

	@Override
	public int hashCode() {
		int hashCode = 17; // start with a prime number
		hashCode = firstName != null ? firstName.hashCode(): 0;
		hashCode = lastName != null ? lastName.hashCode(): 0;
		return hashCode;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

}

 

Effective Java by Joshua Bloch is great book to read for core java related issues.

Read the java docs of hashCode() here. You will find some interesting things as to how Object returns distinct integers for distinct objects

Read the java docs of equals() here. Also look at the Note that refers to the contract defined above.

Q) What is the contract between equals() and hashCode() and how it’s used in Java collections?

We already defined the contract above. Now let’s discuss the importance of this contract in java Collections.

equals()

  • equals is used in java collections to find an element in a collections.
  • remove() methods iterates the list to check if an element in a collection equals the object to be removed
    • Arrays.asList(“111”, “222”).remove(“111”)
  • contains() method checks if a method is in collections. It also iterates the list and checks using equals whether an element in the list is equal to the object to be checked against.
    • Arrays.asList("111", "222").contains("1111")

hashCode()

When an object is inserted into HashMap, HashTable or HashSet, a hashcode is generated and used to store the objects. To insert an entry to HashMap,  a key and a value is needed. When a key is inserted to a HashMap, the hashCode() and equals() method of the key are used to store the key-value in a bucket( Bucket means each element of the HashMap). If a hashCode() generates the same hashcode for two keys that have equals as false, then both key-value pairs are stored in one bucket as a linked list.  And when a search is done on such a key, the linkedlist has to be iterated to find the key that equals the searched one .

Let’s take the worst case possible;  if all the unequal keys have same hashcode, then they would be stored in one bucket as a linkedlist in the HashMap. And hence the HashMap would practically become a LinkedList and search would be very very slow. So it is very important that the keys of the HashMap should have different hashcode so that they are stored in different buckets in HashMap. HashMap performance is the best when there is approximately one key in one bucket.  So it is very important to implement the hashCode() method properly and even effort should be made that unequal objects have not the same hashcode

HashMap

HashMap

Q) List three Collections interfaces and the basic contract of each. List concrete implementations of each, how they differ, and performance characteristics in space and time.

List<E> Set<E> Map<K,V>
Implementations LinkedList
ArrayList
HashSet
LinkedHashSet
TreeSet
IdentityHashMap
HashMap
TreeMap
Duplicates Allowed Not Allowed Duplicate keys not allowed
Order of Elements List is ordered collection. The List interface by itself enforces the order on the implementation A Set can be an ordered Collection. But the Set interface doesn’t enforce it. Only a key-value pair can be inserted.

 

You can find the complete answer to this question at differences of List, Set and Map.

Q) Describe Java collections, interfaces, implementations. What’s the difference between LinkedList and ArrayList?

The difference between LinkedList and ArrayList is best explained here on stackoverflow.

Q) What’s the difference between primitives and wrappers, where do they live, what’s autoboxing?

Primitives types are the basic data types in java. And the wrapper classes are classes that encapsulates these primitive types. Here is the list of primitive types and the corresponding wrapper classes in Java.

Primitive Type Wrapper Class
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

Differences between primitive and Wrapper classes

  1. Declaration
    • for primitive types, variables are declared e.g. int i = 0;
    • for wrapper types, a wrapper class has to be instantiated e.g; Integer i = new Integer(1);
  2. Assignment of null value
    • primitives don’t have a null value. (e,g. when declaring a variable, that usually cannot have a negative value is initialized with -1 as to know that the value comes from a declaration rather than computation)
    • wrapper classes can be initialized will null e.g. Integer i = null;. But this makes the program vulnerable to NullPointerException(a billion dollar mistake)
  3. Collections
    • primitives cannot be inserted into collections
    • only wrapper types can be inserted into collections.
  4. Memory
    • primitives takes less memory
    • Wrapper classes have the primitive values and in addition have the other overheads that lead to more memory consumption

Some other things that need to be considered here are  autoboxing . We will discuss it in next question.

Next thing that you should know is that BigDecimal and BigInteger are wrapper classes  but are not primitive wrapper classes. These are immutable wrapper classes

Q) What is autoboxing?

In java a an int type can be assigned directly to the Integer wrapper class.

int i = 1;
Integer iWrapper = i;

Behind this assignment Java creates an Integer object from the int type. That is called autoboxing.  I have written and article about autoboxing and it also gives the various things that should be known to a developer, please read Autoboxing.

Q) Where can you put keywords final and static and what do they do?

 final keyword is used to define a primitive variable as immutable. Once a variable has been declared final, it is not allowed to assign anything to that variable. The variable can no longer be changed. Why i did not say that it makes the variable immutable? Because the objects can be changed by the methods exposed by an object so the objects are still mutable. But the primitive variables cannot be changed except by assigning them to some value. So by defining them as final they become immutable. A final variable can be initialized on declaration or within a constructor. A final variable that is not initialized on declaration is called blank final. Anonymous inner classes declared within a method can only access the final variables available in the method scope.

final keyword can be used with a method and a class. A final method can not be overriding by a subclass. A final class can’t be inherited by any class. java.lang.String is a final class.

static keyword on a variable declares that variable belongs to a class rather than instance of that class. So only one instance of static field exists.  static keyword on a method means that the methods belongs to a class. A static method is available without creating an instance of class and can be invoked by ClassName.staticMethod(). Static methods cannot access the fields of the class unless the fields are marked as static. Fields can be accessed via an instance of the class. static keyword can also be used with an import to import a static method or a static field of another class.

Q) Access modifiers in Java.

Access modifiers are used to determine who can access a class, method or a member of a class. There are two levels of access control.

  1. Top Level class :  A top level class can have  either
    1. public : accessible to anyone.
    2. package private(no modifier): accessible only to the package level classes
  2. Members of class : At member level there are four types of access modifiers. A class has access to all its members independent of the modifier.
    1. public: accessible to everyone
    2. protected : accessible to the package and the subclasses
    3. package private(no modifier): only accessible within the same package as the class
    4. private : only accessible within the class and noone else.

Q) Difference between String and StringBuilder / StringBuffer.

To represent a string literals like “Hello” in java a String class is used. The String class is a sequence of characters. The String class is immutable. I have disussed  why string is immutable? The String class provides various method to concatenate, substring or creating a copy of the String. All these methods do not modify the String but they all return a new String. A String represents a string in UTF-16 format.

StringBuilder is a mutable object and can be used for creating strings. A StringBuilder has append method to create a string and append any String to the existing String. To change a String object, you need to create a new one. StringBuilder can append to strings without creating new objects and hence has a better performance. See my post for String vs StringBuilder vs stringBuffer performance.

StringBuffer has exactly the same properties as Stringbuilder but the only differnce between the two is that StringBuffer is safe to use in mutithreaded environment as StringBuffer is synchronized. So it is advised to use StringBuilder in a single threaded environment so to have a performance benefit over StringBuffer.

Q) Difference between interface and abstract class.

interface is a contract. Till java 8 no implementation was allowed in interfaces but with java 8 default methods interfaces can also have implementation in methods.In Interface all the methods take the same access modifier as declared for the interface. Any class implementing a interface has to implement all the methods from the interface except the default methods. A class can implement more than one interface.

Abstract class is a class that can have abstract methods that have no implementation and can also have methods that have implementation.  Only the method declared have to be implemented by the extending class. Since java doesn’t allow multiple inheritance of classes, a class can only extend one abstract class.

Q) Difference between overriding and overloading.

You can see a detailed answer here in java oops concept polymorphism

Q) Types of exceptions and “handle or declare” rule.

Java has three kinds of exception:

1. Checked Exceptions: Checked exceptions are the excpetions that need to be either handled with catch or throw. Checked Exceptions are checked at compile time. Even a checked Exception is not handled, the code will not compile. In the below example we will read a file and if the file is not found the readFile() method will throw IOException and in the main method we simply print the stacktrace.


package com.programtalk.learn.java.beginner;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadFile {
	public static void main(String[] args) {

		try {
			System.out.println(readFile());
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private static String readFile() throws IOException {
		String content = null;
		File file2Read = new File("myfile.txt");
		FileReader reader = null;
		try {
			reader = new FileReader(file2Read);
			char[] chars = new char[(int) file2Read.length()];
			reader.read(chars);
			content = new String(chars);
			reader.close();
		} finally {
			if (reader != null) {
				reader.close();
			}
		}
		return content;
	}
}

2. Error: Errors are exceptional conditions that are external to an application. Java does not enforce the handling of Errors. So if a method throws an Error, the calling method doesn’t need to handle it. The code will compile fine. An application cannot predict an error condition on compile time. Suppose if an application opens a file and cannot read a file due to some issue with the hardware, throwing java.io.IOError.

 

3. Runtime Exceptions: These exceptions are internal to an application. Usually these exceptions are because of some bugs with the application code. NullPointerException is a famous example of runtime exception. The below code has a bug that make the code throw a NullPointerException.

	public static void main(String[] args) {
		printIfHarry(null);
	}
	
	public static void printIfHarry(String firstName){
		if(firstName.equals("Harri")){
			System.out.println("I am Harray");
		}
	}

So there is a bug in the program and we need to fix it by either having a null check before invoking equals as below. So we don’t need to handle the exception but fix the bug.

	public static void printIfHarry(String firstName){
		if(firstName != null && firstName.equals("Harri")){
			System.out.println("I am Harray");
		}
	}

Handle or Declare:  If you are calling a method that is throwing an exception, a decision needs to be made whether exception has to be caught or thrown to the caller and make the caller handle the exception. The rule is to bubble up the exception to the place where it can handled best. Like a

Q) How does garbage collector work?

Object data is stored in heap. Heap is managed by garbage collector. A garbage collector can be configured at startup. Automatic garbage collection is a process of managing the heap memory. The garbage collector looks for the objects that any not used anymore. It does so by looking at the references of the object. If an object is not referenced from anywhere in the application, the objects are garbage collected and the memory used by these objects are reclaimed.

Here is a article that explains how garbage collector works for Oracle implementation of Java. One the nice book for performance you can read here.

Q) How to make a class immutable and what’s the point?

A class can be made immutable by declaring all the variables in the class as final. So that the state of the class cannot be changed. The immutability of any object makes that object safe for use as the user would be sure that the state of the object can’t change while the object is being used. The best example of immutability is the String class. An immutable object doesn’t need synchronized access on fields as the same value would be avaliable to all the threads and none of the threads can change the value of the object. Let’s make a Person class immutable.

package com.programtalk.learn.java.beginner;
/**
 * 
 * @author programtalk.com
 *
 */
public class Person {

	private final String firstName;
	private final String lastName;

	public Person(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}

	public String getFirstName() {
		return firstName;
	}

	public String getLastName() {
		return lastName;
	}

}

The state of a Person Object cannot be updated. It can only accept the firstName and lastName on creation and then nothing can be changed.

Q) What’s JIT compilation?

You can find the complete answer to this question at JIT compiler.

Q) What’s new in Java 8 / Java 7? What’s coming in Java 9?

In new features of Java 8  with examples I have discussed various new features. Here is the list of features:

  1. Lambda expressions
  2. Functional interfaces
  3. Default and static methods in interfaces
  4. forEach() in Iterable interface
  5. Stream API
  6. Java Date/Time API
  7. Concurrency improvements

In New Features in Java 9, I have discussed all the major features that are coming in Java 9. Here is the list of major changes:

  1. Module System (Jigsaw Project)
  2. JShell
  3. Collection Factory methods
  4. Private Methods in Interfaces
  5. Reactive Streams
  6. Multi Resolution Images API
  7. Process API
  8. Try-With Resources
  9. Diamond Operator Extension
  10. Deprated annotation Enhanced
  11. Unified JVM Logging
  12. SafeVarargs Scope Extension
  13. HTTP 2 Client
  14. HTML5 Javadoc

 

Q) What is a  default method?

In Java 8, a major change was introduced in interfaces. The interfaces can now have implementation of methods if they are defined with keyword as default. I have written a detailed article about it at Default methods in Java 8.

You may also be interested in:

Like this post? Don’t forget to share it!

Leave a Reply

Your email address will not be published. Required fields are marked *