Showing posts with label Java Interview Questions. Show all posts
Showing posts with label Java Interview Questions. Show all posts

Friday, 13 February 2015

Understanding how HashMap and HashSet work in Java

Background

Hashing is a very important concept in computer programming and a very popular concept for interview questions. Two important data structures related to hashing are HashMap and HashSet which is exactly what we are going to look at in this post.

Overview

If you are from a computer science background you would know HashMap is a data structure which stores key value pairs where as a HashSet stores unique data. In HashMap we have kind of buckets and each data added to a HashMap falls into one of the buckets depending on the hash value of it. Also you must have heard that adding and retrieving objects in HashMap happen in time complexity O(1).

But still there are open end question like -
  • What happens when two objects added to HashMap have same hash (code) value ? - a situation typically known as collision.
  • If above is handled how get and put work in hashmap?.... and so on.
We will address them now.

Understanding how HashMap works

 You can visualize HashMap as follows-




So you have an Array and each array position is essentially a Linked List. As you know you don't have to specify size of the HashMap. It increases dynamically like ArrayList.  The main data structure is essentially an array.

    /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */
    transient Entry[] table;


When you create a HashMap you either choose to provide initial capacity or when you don't a default value is used.

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 16;


 When table is created it is created with either this initial default capacity or the capacity you provide in the constructor.

Next important thing is when should out table we resized to meet the dynamically changing data size of HashMap. Answer depends on a threshold that is determined by load factor.

    /**

     * The load factor used when none specified in constructor.

     */

    static final float DEFAULT_LOAD_FACTOR = 0.75f;


HashMap provides a constructor to initialize load factor as well. So when your data size equals

  • threshold = table capacity * load factor

then the HashMap table is resized. Constructors are as follows -

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and load factor.
     *
     * @param  initialCapacity the initial capacity
     * @param  loadFactor      the load factor
     * @throws IllegalArgumentException if the initial capacity is negative
     *         or the load factor is nonpositive
     */
    public HashMap(int initialCapacity, float loadFactor) {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal initial capacity: " +
                                               initialCapacity);
        if (initialCapacity > MAXIMUM_CAPACITY)
            initialCapacity = MAXIMUM_CAPACITY;
        if (loadFactor <= 0 || Float.isNaN(loadFactor))
            throw new IllegalArgumentException("Illegal load factor: " +
                                               loadFactor);

        // Find a power of 2 >= initialCapacity
        int capacity = 1;
        while (capacity < initialCapacity)
            capacity <<= 1;

        this.loadFactor = loadFactor;
        threshold = (int)(capacity * loadFactor);
        table = new Entry[capacity];
        init();
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the specified initial
     * capacity and the default load factor (0.75).
     *
     * @param  initialCapacity the initial capacity.
     * @throws IllegalArgumentException if the initial capacity is negative.
     */
    public HashMap(int initialCapacity) {
        this(initialCapacity, DEFAULT_LOAD_FACTOR);
    }

    /**
     * Constructs an empty <tt>HashMap</tt> with the default initial capacity
     * (16) and the default load factor (0.75).
     */
    public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;
        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
        table = new Entry[DEFAULT_INITIAL_CAPACITY];
        init();
    }


How is data with keys generating same hash code stored in HashMap?

As mentioned earlier each index has reference to object of type Entry which is a Linked List. It has a next pointer. So if an entry is added to hash map it's hash code is computed which determines the index at which it should be put. If that index has an entry then new entry is added to the start of the linked list and existing linked list is appended to next of it.

    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

    void addEntry(int hash, K key, V value, int bucketIndex) {
    Entry<K,V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
        if (size++ >= threshold)
            resize(2 * table.length);
    }


Also note how null is handled. Yes null is an acceptable key in HashMap.

So how is data retrieved if two keys generate same has code?

Same hash code will make searched for both keys data land on same index in the table. From there the each Entry object is iterated over and it's key compared with the search key. On successful match corresponding value is returned.

    public V get(Object key) {
        if (key == null)
            return getForNullKey();
        int hash = hash(key.hashCode());
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                return e.value;
        }
        return null;
    }


Lastly lets see HashSet.

Understanding HashSet

Well if you are still guessing the data structure of HashSet then following would be a surprise -

    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();



Yup HashSet stores data as keys of HashMap with dummy value. Constructor is equivalent to that of HashMap -

    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * default initial capacity (16) and load factor (0.75).
     */
    public HashSet() {
    map = new HashMap<E,Object>();
    } 



    public HashSet(int initialCapacity, float loadFactor) {
    map = new HashMap<E,Object>(initialCapacity, loadFactor);
    }



    public HashSet(int initialCapacity) {
    map = new HashMap<E,Object>(initialCapacity);
    }


Add and Remove methods are as follows -

    public boolean add(E e) {
    return map.put(e, PRESENT)==null;
    }



    public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
    }


Related Links

Tuesday, 10 December 2013

Basic operations with Bitwise operators

Not a Java question as such but a more generic information that would be useful. Most of the interview questions consist of manipulations of bitwise operators. Some basic operations are listed below -

  • OR can be used to set a bit to one: 11101010 OR 00000100 = 11101110
  • AND can be used to set a bit to zero: 11101010 AND 11111101 = 11101000
  • AND together with zero-testing can be used to determine if a bit is set:
11101010 AND 00000001 = 00000000 = 0
11101010 AND 00000010 = 00000010 ≠ 0
  • XOR can be used to invert or toggle a bit:
11101010 XOR 00000100 = 11101110
11101110 XOR 00000100 = 11101010
  • NOT can be used to invert all bits.
NOT 10110010 = 01001101

Sunday, 9 June 2013

Interview Question #13 synchronization on static function/method.

Let me clarify the question with an example. You have the following class.

public class Counter{
private static int count = 0;

public static synchronized int getCount()
{
  return count;
}

public synchronized setCount(int count)
{
   this.count = count;
}

}


You have multi threaded environment. Can two threads simultaneously access
or process getCount() and setCount() methods? 
Even if we have following case.

Counter myCounter = new Counter();
myCounter.setCount(10);
myCounter.getCount();
 
 
 

Answer

First of all you should not access static functions/block using class instance. Though it is perfectly valid to do so. Why is it valid? Each of the class instances(objects) have class information and hence can hence access it. Lets get to our original question on synchronization.

Answer is yes! Two threads can simultaneously operate/process on the two functions getCount() and setCount(). This is because when synchronized method setCount() is called thread acquires an object level lock where as when getCount() method is called it being a static method(owned by class rather than it's instances) acquires a class level lock.

When you use synchronized method or a block lock is obtained on the monitor if the corresponding instance. So in above example for setCount() method lock obtained will be on the myCounter instance where as for method getCount() which is a static or class method lock is obtained on the Class object. You can get this object by using .class keyword or getClass() method. This Class object will be same for all the instances of that class.

Saturday, 18 May 2013

Interview Question #12 Differences between HashMap and Hashtable?

There are several differences between HashMap and Hashtable. Hashtable was introduced earlier whereas HashMap is a newly introduced as a part of Java Collection Framework.

  • Hashtable is synchronized whereas HashMap is not.This makes HashMap better for non-threaded applications, as unsynchronized Objects typically perform better than synchronized ones.
  • Hashtable does not allow null keys or values. HashMap allows one null key and any number of null values.
  • One of HashMap's subclasses is LinkedHashMap, so in the event that you'd want predictable iteration order (which is insertion order by default), you could easily swap out the HashMap for a LinkedHashMap. This wouldn't be as easy if you were using Hashtable.
If synchronization is not an issue for you HashMap is recommended. If synchronization becomes an issue, you may also look at ConcurrentHashMap.


Related Links

Interview Question #11 How to make an object/class immutable?

This is a very interesting question. To give some background let me give an example - String Object in Java. You must have used it a lot but did you know that Strings are immutable. This means once you create a String object you cannot modify it.
Next obvious question that may arise is How do I get different String when i use concat() or substring() functions ? The answer is you get a different String but not the modified Sting. Once desired operation is carried out and the result is computed a new String is created with this result and returned.

   Having the background information let us now get back to our original question - How can we make such an immutable object/class?

  • First thing that we can do is make the class itself final. This means this class cannot be sub classed any further. So you can start with - public final class Person{
    }
  •  Secondly make any data that you have in your class final. For example if you are creating a Person class  you can define name, age, DOB etc Final.
        final String name;
        final int age;
        final String DOB
    ;
    Once this is done you can be sure that the data will not be modified once it is initialized. But how do we initialize the data? We cannot use setter methods as final data cannot be modified.Hence we go for 3rd point.
  • Now create a constructor with these data as arguments and initialize the data.
    Now your class will look like -
    public final class Person {
        private final String name;
        private final int age;
        private final String DOB;
    
        public Test(String name, int age, String DOB) {
            this.name = name;
            this.age = age;
            this.DOB = DOB;
        }
    }
    


     
This will make your class/object immutable. You can simple create object by saying Person p = new Person("John",21,"12/7/1991");
If you do not wish anyone to instantiate your class. You can provide a method like get public static Person getInstance(String name, int age, String DOB). Inside this function you can create an object of type Person and return it. You can also make your class singleton by checking if any instance already exists. There are many things you can do as per your implementation but the points mentioned above are sufficient to make a class/object immutable.


Summary

  1. Don't provide "setter" methods — methods that modify fields or objects referred to by fields.
  2. Make all fields final and private.
  3. Don't allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
  4. If the instance fields include references to mutable objects, don't allow those objects to be changed:
    • Don't provide methods that modify the mutable objects.
    • Don't share references to the mutable objects. Never store references to external, mutable objects passed to the constructor; if necessary, create copies, and store references to the copies. Similarly, create copies of your internal mutable objects when necessary to avoid returning the originals in your methods.

Sunday, 5 May 2013

Interview Question #10 How ArrayList works internally in java?

Another favorite interview question. Honestly whole of Collections is an interesting topic and a lot of interview questions can be framed on it. Advantage of this being, Java knowledge of Candidate is tested along with his/her data structure knowledge.

So lets understand how ArrayList works. This is the most basic question you could frame. Many other questions to come are based on this.

Basic Data Structure used in an ArrayList is -

private transient Object[] elementData; 

So it's an array of Object(Just the declaration.)
When we actually create an arrayList following piece of code is executed -


this.elementData = new Object[initialCapacity];


You create an ArrayList as follows -
  • List<String> myList = new ArrayList<String>();  OR 
  • List<String> myList = new ArrayList<String>(6); 
 1st one invokes a default constructor while the second will invoke a constructor with an integer argument. When we create an ArrayList in the 2nd way it will internally create an array of Object with size specified in the constructor argument(6 in our case). Default value is 10 i.e if no size is supplied array with size 10 is created.

Code for it is as follows -

    public ArrayList(int initialCapacity) {
    super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
    this.elementData = new Object[initialCapacity];
    }



    public ArrayList() {
    this(10);
    } 



Once you tell this interviewer can be sure you know what data structure is internally used.Now we know ArrayList is better than normal arrays as it is size dynamically increases. But how does this take place internally? How much does the size increase?

Inside .add() method there is this check. Before adding element into the array it will check what is the current size of filled elements and what is the maximum size of the array. If size of filled elements is greater than maximum size of the array(or will be after adding current element) then size of the array must be increased. But if you know array basic you cannot dynamically increase the array size. So what happens internally is a new Array is created with size 1.5*currentSize and the data from old Array is copied into this new Array.

Code for it is as follows -

    public boolean add(E e) {
    ensureCapacity(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
    }



    public void ensureCapacity(int minCapacity) {
    modCount++;
    int oldCapacity = elementData.length;
    if (minCapacity > oldCapacity) {
        Object oldData[] = elementData;
        int newCapacity = (oldCapacity * 3)/2 + 1;
            if (newCapacity < minCapacity)
        newCapacity = minCapacity;
            // minCapacity is usually close to size, so this is a win:
            elementData = Arrays.copyOf(elementData, newCapacity);
    }
    }



If you wish to know more you can view the ArrayList Sourecode. In Eclipse press Ctrl+T(Open Type) and type in ArrayList. Open it to view the source code.To visualize the ArrayList class refer to following image -



Related Links


Saturday, 20 April 2013

Interview Question #9 Why multiple inheritance is not supported by Java?

Multiple inheritance has a problem known as The Deadly Diamond of Death.

Refer to the following diagram to understand The Deadly Diamond of Death-


Explanation -  

     Suppose you have class C which extends two classes A and B.Lets say A and B both have a function with same prototype eg. public int getData(). Now if we create an object of class C and call the function i.e ObjC.getData() which function will be called? Decision is ambiguous unless we have set some rules and priorities. To avoid such ambiguity Java does not allow multiple inheritance.


A language that allows Deadly Diamond of Death can lead to some ugly complexities, because you have to have special rules to deal with the potential ambiguities.

Java is designed to be simple. Java (unlike C++) protects you from having to think about Deadly Death of Diamond.

To provide similar functionality Java provides interfaces.
So Java can implement two or more interfaces but can extends only one super class.

Sunday, 14 April 2013

Interview Question #8 What happens when a class implements two interfaces with same method?

This is a very interesting question. If you still don't get it let me give an example to explain it further -
We have two interfaces  - InterfaceA and InterfaceB. Then we have a concrete class which implements these interfaces.

Code of InterfaceA

package testCodes;

public interface InterfaceA {
    public void color();
}


Code for InterfaceB

package testCodes;

public interface InterfaceB {
    public void color();
}


Code for class ConcreteClass

package testCodes;

public class ConcreteClass implements InterfaceA, InterfaceB {
    public void color() {
        System.out.println("Red");
    }
}


Note that though we have same method in both interface we need to implement it only once in our concrete subclass. So it does not matter if we have two interfaces with same method. It will be implemented only once.

Problem arises when.....

   Problem will arise when there are two interfaces having method with same name and parameter but different return type. When a class will implement these two interface it will have to implement these two methods with same name and parameters but different return type. But this is not allowed. JVM will not allow this code to be compiled. Functions can have same name(function overloading) but they must have different signatures(different parameters.)



Saturday, 6 April 2013

Interview Question #7 What is final in java?

A final class can't be extended ie., final class may not be subclassed. A final method can't be overridden when its class is inherited. You can't change value of a final variable (is a constant).

If you want a variable to be owned by the class and not by it's individual instances(objects) and also you want the value of the variable to be constant you can declare it as static and final both.

 For Example
       private final static String name = "JavaForGeeks";

The concept is interpreted a bit different way for Objects, Collections. You can change the data inside the object/Collection but cannot make the reference(which is final) point to different Object.

For example

public class HelloWorld {
   
    String greetings;
   
    public String getGreetings() {
        return greetings;
    }
    public void setGreetings(String greetings) {
        this.greetings = greetings;
    }

}


Even if the HellowWorld instance is defined final you can call setter method of it's data.

    public static void main(String args[]){
        final HelloWorld hw = new HelloWorld();
        hw.setGreetings("test");  //allowed
        //hw = new HelloWorld(); //not allowed
    }



Same goes for Collections

    public static void main(String args[]){
        final List<String> myList = new ArrayList<String>();
        myList.add("Test");    //allowed
        //myList = new ArrayList<String>();    //not allowed
    }

 

Interview Question #6 What is static in java?

Static means one per class, not one for each object no matter how many instance of a class might exist. This means that you can use them without creating an instance of a class.Static methods are implicitly final, because overriding is done based on the type of the object, and static methods are attached to a class, not an object. A static method in a superclass can be shadowed by another static method in a subclass, as long as the original method was not declared final. However, you can't override a static method with a nonstatic method. In other words, you can't change a static method into an instance method in a subclass.

For more details refer the tutorial on Static keyword in Java.

Sunday, 17 March 2013

Interview Question #5 What is the difference between creating string as new () and as a literal?

This is a very common and most basic interview question asked in Java and yet programmers are not able to explain it properly.

  • When we create a String using new operator it is created in heap and not added to String pool whereas String created as literals are created in String pool itself which exist in PermGen area of heap.
  • Let us take example to understand this better -

    1. Case1)   Lets create two string literals with different names.
      String firstLanguage = "Java";
      String secondLanguage = "Java";


      Now if we say

      if(firstLanguage == secondLanguage )
      {
           System.out.println("Both references point to same String \n");
      }
      else
      {
           System.out.println("Both references point to different Strings \n");
      }


      Output : Both references point to same String

      Explaination :
      When we create firstLanguage as literal it is created and stored in String pool. Now when we try to create secondLanguage JVM know that such a string already exists in the pool and hence returns reference of the same String and hence the output shown above.

      Note : '==' operator will return true only if both references or variables point to same object. In case of String if you really need to check if content of two strings are equal you must use .equals() method.
    2. Case2) Now lets create two String objects and repeat the same exercise we did above.

      String firstLanguage = new String("Java");
      String secondLanguage = new String("Java");


      Now if we say

      if(firstLanguage == secondLanguage )
      {
           System.out.println("Both references point to same String \n");
      }
      else
      {
           System.out.println("Both references point to different Strings \n");
      }



      Output :Both references point to different Strings

      Explaination :
      When we create firstLanguage as new() it is created and stored on the heap as a String object. Similarly when we create secondLanguage as new() it is again cretaed on heap as a different String object. Now since == operator returns true only when both variables point to same object which is not the case we get false.

      Note : As mentioned above if you want to check whether contents of firstLanguage object and secondLanguage object are the same that you can use .equals() method. It will return true if content of both String objects are same.

Saturday, 16 March 2013

Interview Question #4 What is immutable object? Can you write immutable object?

Immutable classes in java are classes whose object cannot be modified. Any modification in such objects returns a new object.Most instance variables and functions of immutable classes are also final in order from preventing subclasses to change the values by overriding methods which may compromise immutability. But there are other ways too, like declaring the members as private and changing it's value only in constructor.

      For example in Java String is an immutable class. Once a string is created it cannot be modified.What happens when we call functions like .substring() one might ask. What it does is it simply creates and returns a new String object by taking the sub-string from the source string.

    Other example includes the wrapper classes for the primitive types: java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float etc.

Yo know why String was decided to be made immutable go through the following article -

Why String is immutable or final in Java.

Saturday, 9 March 2013

Interview Question #3 What is the difference between a constructor and a method?

  • A constructor is a member function of a class that is used to create objects of that class. It has the same name as the class itself, has no return type, and is invoked using the new operator.
  •  A method is an ordinary member function of a class. It has its own name, a return type (which may be void), and is invoked using the dot operator.
  • A constructor is mandatory in a class.If you don't write any constructor compiler will write one for you.This constructor is called default constructor and has no parameters.Writing a method is completely based on user requirement.

Interview Question #2 What are principle concepts of OOP?

There are four principle concepts upon which object oriented design and programming rest. They are: 
  •  Data Abstraction(act of representing essential features without including the background details or explanations)
  • Data Encapsulation (Class structure + Access modifiers)
  • Polymorphism(super class reference for sub class object )
  • Inheritance(to avoid duplicate code)

Interview Question #1 What is the purpose of garbage collection in Java, and when is it used?

The purpose of garbage collection is to identify and discard objects that are no longer needed by a program so that their resources can be reclaimed and reused.Garbage collector is invoked automatically by JVM. A Java object is subject to garbage collection when it becomes unreachable to the program in which it is used and by  unreachable mean that there are no references of that object on the stack.You can also specify when to invoke garbage collector using System.gc() but it is not necessary that JVM will always invoke garbage collector on encountering this function.

Related Questions

t> UA-39527780-1 back to top