Trivia style interview questions

Technical interviews have quite a bit of, for lack of a better term (or maybe not), trivia type knowledge.  Questsion that test your depth of understanding of common concepts.  Here's a quick overview of the major themes you'll be asked.

The final keyword in java

A final class cannot be subclassed, a final method cannot be overridden by subclasses, a final variable can only be initialized once.  Let's illustrate that..

If you were to uncomment any of the following code, there would be compile time issues, you can create multiple objects with final keywords in them (and initalize them in constructors), you can even update them, you just can't reassign them.

public class Test {

    public final List foo;

    public Test() {
        foo = new ArrayList();
        foo.add("foo"); // Modification-1
    }

    public void setFoo(List foo) {
        //this.foo = foo;  //compile time error.
    }

    public static void main(String args[]) {
        Test t1 = new Test();
        t1.foo.add("bruh");
        //t1.foo = new ArrayList();

        Test t2 = new Test();
        t1.foo.add("bruh");
    }

}

How does hashing work in Java

First off, start with this.  A hash function assigins an id and spot in an array allowing O(1) access if no collissions occur.

Hash Tables Explained

Hash collisions can be solved by...

  • linear probing: stick it in the next available space
  • separate chaining: arrange into buckets, then search that bucket

Now wrap your head around this Java example which demonstraits how a collission can cause issues

/**
 * 
 * @author largepixels
 *
 * This class provides a simple example for overloading the hashCode and equals methods.
 * Remember, hash tables use hashCode values to place objects into buckets, then the equals
 * method to determine if they are the same.  Two object can have the same hashCode but be
 * "unequal" to each other.  If two objects are equal they MUST have the same hashCode. 
 *
 */
public class OverloadHashCodeAndEquals {

	class Car {
		
		String name;
		int seats;
			
		@Override
		public int hashCode() {
			int hash = 5;
			hash = hash + (this.name != null ? this.name.hashCode() : 0);

			System.out.println("The hashcode for " + this.toString() + " is " + hash);

			return hash;
		}

		@Override
		public boolean equals(Object obj) {
			Car lhs = this;
			Car rhs = (Car) obj;

			boolean isEqual = lhs.name.equals(rhs.name) && lhs.seats == rhs.seats;

			System.out.println("Is " + lhs.toString() + " equal to " + rhs.toString() + ": " + isEqual);

			return isEqual;
		}
		
		@Override
		public String toString() {
			return name + "-" + seats + " seats";
		}
	}
	
	private void runMe() {
				
		Car a = new Car();
		a.name = "a";
		a.seats = 2;
		
		Car b = new Car();
		b.name = "b";
		b.seats = 4;
		
		Car c = new Car();
		c.name = "c";
		c.seats = 2;

		Car d = new Car();					//same name and seats as A
		d.name = "a";
		d.seats = 2;

		Car e = new Car();					//same name diff seats as A
		e.name = "a";
		e.seats = 4;

		a.hashCode();
		b.hashCode();
		c.hashCode();
		d.hashCode();
		e.hashCode();

		Set cars = new HashSet();

		System.out.print("\nLets insert into the HashSet \n\n");

		cars.add(a);
		cars.add(b);
		cars.add(c);
		cars.add(d);
		cars.add(e);	// same hashcode as car A, but equals method knows
						// they're different because it checks names and seats.
						// since they're unequal it inserts (into the same bucket)
						// car D had same seats and name as A same hashcode and equals result
						// means it won't insert into hash because it believes it already has it

		System.out.print("\nLets remove from the HashSet \n\n");

		cars.remove(b);
		cars.remove(d);
		cars.remove(e);
		
	}
	
	public static void main(String[] args) {
		OverloadHashCodeAndEquals overloadHashCodeAndEquals = new OverloadHashCodeAndEquals();
		overloadHashCodeAndEquals.runMe();
	}
	
}

And when you look at the output of this example, you can see that the hashing function has to check the equals if it runs into a hash collision.  If hash and equals are same, the object is not inserted into the hashset.

The hashcode for a-2 seats is 102
The hashcode for b-4 seats is 103
The hashcode for c-2 seats is 104
The hashcode for a-2 seats is 102
The hashcode for a-4 seats is 102

Lets insert into the HashSet 

The hashcode for a-2 seats is 102
The hashcode for b-4 seats is 103
The hashcode for c-2 seats is 104
The hashcode for a-2 seats is 102
Is a-2 seats equal to a-2 seats: true
The hashcode for a-4 seats is 102
Is a-4 seats equal to a-2 seats: false

Lets remove from the HashSet 

The hashcode for b-4 seats is 103
The hashcode for a-2 seats is 102
Is a-2 seats equal to a-2 seats: true
The hashcode for a-4 seats is 102

One last thing.  If you override the equals method, then you must override the hashcode method.  Otherwise you're hashset could have duplicates because the hashcode will different, but you specified they are the same with the equals method.  Comment out hashcode in the above example and everything will be inserted even though our equals method tells two of them are duplicates.

Multi threading overview

You're almost certain to get questions about threading and concurrency in an interview.  Checkout this summary of the Head First Java chapter on sockets and threading.

Head First Java - Sockets and Networking Chapter Summary

Don't forget about thread local.  When used each thread will have it's own copy of variables.  An easy way to avoid race conditions.

Thread Local Example - Jenkov.com

Java Futures allow you to continue on with program execution without having to write complicated multi threading applications.  See this working example here..

Simple Java Futures Example on GitHub

 

Spring and Hibernate

Don't forget that any company using Spring and Hibernate will usually have questions about Hibernate Caching levels, and low level questions how things like Scopes work in Spring.