Pages

Saturday, July 9, 2016

Core Java Interview Questions

How to create a immutable object in Java? Count all benefits?

An immutable class is one whose state can not be changed once created. Here, state of object essentially means the values stored in instance variable in class whether they are primitive types or reference types.
To make a class immutable, below steps needs to be followed:
  1. Don’t provide “setter” methods or methods that modify fields or objects referred to by fields. Setter methods are meant to change the state of object and this is what we want to prevent here.
  2. Make all fields final and private. Fields declared private will not be accessible outside the class and making them final will ensure the even accidentally you can not change them.
  3. Don’t allow subclasses to override methods. The simplest way to do this is to declare the class as final. Final classes in java can not be overridden.
  4. Always remember that your instance variables will be either mutable or immutable. Identify them and return new objects with copied content for all mutable objects (object references). Immutable variables (primitive types) can be returned safely without extra effort.

Explain marker interfaces?

The marker interface pattern is a design pattern in computer science, used with languages that provide run-time type information about objects. It provides a means to associate metadata with a class where the language does not have explicit support for such metadata. In java, it is used as interfaces with no method specified.
A good example of use of marker interface in java is Serializable interface. A class implements this interface to indicate that its non-transient data members can be written to a byte steam or file system.

Why main() in java is declared as public static void?

Why public? main method is public so that it can be accessible everywhere and to every object which may desire to use it for launching the application. Here, i am not saying that JDK/JRE had similar reasons because java.exe or javaw.exe (for windows) use Java Native Interface (JNI) calls to invoke method, so they can have invoked it either way irrespective of any access modifier.
Why static? Lets suppose we do not have main method as static. Now, to invoke any method you need an instance of it. Right? Java can have overloaded constructors, we all know. Now, which one should be used and from where the parameters for overloaded constructors will come.
Why void? Then there is no use of returning any value to JVM, who actually invokes this method. The only thing application would like to communicate to invoking process is: normal or abnormal termination. This is already possible using System.exit(int). A non-zero value means abnormal termination otherwise everything was fine.

String pool concept

String pool is a special memory area separate from regular heap memory where these string constants are stored. These objects are referred string variables during the life cycle of application.
In java, String can be created by many ways. Lets understand them:

1) String assignment

String str = "abc";
Above code causes JVM to verify if there is already a string “abc” (same char sequence). If such string exist, JVM simply assign the reference of existing object to variable str, otherwise a new object “abc” will be created and its reference will be assigned to variable str.

2) Using new keyword

String str = new String("abc");
This version end up creating two objects in memory. One object in string pool having char sequence “abc” and second in heap memory referred by variable str and having same char sequence as “abc”.
As java docs says : Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

Keyword ‘intern’ usage

This is best described by java docs:
When the intern() method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this Stringobject is added to the pool and a reference to this String object is returned.
String str = new String("abc");
str.intern();
It follows that for any two strings s and ts.intern() == t.intern() is true if and only if s.equals(t) is true. Means if s and t both are different string objects and have same character sequence, then calling intern() on both will result in single string pool literal referred by both variables.

String comparison

Another favorite area in interviews. There are generally two ways to compare objects
  • Using == operator
  • Using equals() method
== operator compare for object references i.e. memory address equality. So if two string objects are referring to same literal in string pool or same string object in heap then s ==t will return true, else false.
equals() method is overridden in String class and it verify the char sequences hold by string objects. If they store the same char sequence, the s.equals(t) will return true, else false.



We all know the basic statement that finalize() method is called by garbage collector thread before reclaiming the memory allocated to the object. See this program which prove that finalize() invocation is not guaranteed at all. Other reasons can be:
  1. finalize() methods do not work in chaining like constructors. It means like when you call a constructor then constructors of all super classes will be invokes implicitly. But, in case of finalize methods, this is not followed. Super class’s finalize() should be called explicitly.
  2. Any Exception thrown by finalize method is ignored by GC thread and it will not be propagated further, in fact it will not be logged in your log files. So bad, isn’t it?
  3. Also, There is some performance penalty when finalize() in included in your class. In Effective java (2nd edition ) Joshua bloch says,
    “Oh, and one more thing: there is a severe performance penalty for using finalizers. On my machine, the time to create and destroy a simple object is about 5.6 ns. Adding a finalizer increases the time to 2,400 ns. In other words, it is about 430 times slower to create and destroy objects with finalizers.”

Why HashMap should not be used in multithreaded environment? Can it cause infinite loop as well?

We know that HashMap is non-synchronized collection where as its synchronized counter-part is HashTable. So, when you are accessing the collection in multithreaded environment and all threads are accessing a single instance of collection, then its safer to use HashTable for various obvious reasons e.g. to avoid dirty reads and to maintain data consistency. In worst case, this mutithreaded environment can result in infinite loop as well.
Yes, it is true. HashMap.get() can cause an infinite loop. Lets see how??
If you look at the source code HashMap.get(Object key) method, it looks like this:
public Object get(Object key) {
    Object k = maskNull(key);
    int hash = hash(k);
    int i = indexFor(hash, table.length);
    Entry e = table[i];
    while (true) {
        if (e == null)
            return e;
        if (e.hash == hash && eq(k, e.key))
            return e.value;
        e = e.next;
    }
}
while(true){...} can always be a victim of infinite loop at runtime in multithreaded environment, IF, somehowe.next can point to itself. This will result in infinite loop. But, how e.next will point to itself (i.e.).
This can happen in void transfer(Entry[] newTable) method, which is invoked at time the HashMap resizing is done.
do {
    Entry next = e.next;
    int i = indexFor(e.hash, newCapacity);
    e.next = newTable[i];
    newTable[i] = e;
    e = next;
} while (e != null);
This piece of code is prone to produce above condition, if resizing happen and at the same time other threads tried to modify the map instance.
Only way to avoid this scenario is to use synchronization in code, or better, use synchronized collection.

Explain abstraction and encapsulation? How are they related?

Abstraction

Abstraction captures only those details about an object that are relevant to the current perspective.
In object-oriented programming theory, abstraction involves the facility to define objects that represent abstract “actors” that can perform work, report on and change their state, and “communicate” with other objects in the system.
Abstraction in any programming language works in many ways. It can be seen from creating subroutines to defining interfaces for making low level language calls. Some abstractions try to limit the breadth of concepts a programmer needs, by completely hiding the abstractions they in turn are built on, e.g. design patterns.
Typically abstraction can be seen in two ways:
Data abstraction is the way to create complex data types and exposing only meaningful operations to interact with data type, where as hiding all the implementation details from outside works.
Control abstraction is the process of identifying all such statements and expose them as a unit of work. We normally use this feature when we create a function to perform any work.

Encapsulation

Wrapping data and methods within classes in combination with implementation hiding (through access control) is often called encapsulation. The result is a data type with characteristics and behaviors. Encapsulation essentially has both i.e. information hiding and implementation hiding.
Whatever changes, encapsulate it“. It has been quoted as a famous design principle. For that matter in any class, changes can happen in data in runtime and changes in implementation can happen in future releases. So, encapsulation applies to both i.e. data as well as implementation.
SO, they can relate like following :
– Abstraction is more about ‘What‘ a class can do. [Idea]
– Encapsulation is more about ‘How‘ to achieve that functionality. [Implementation]

How StringBuffer save the memory?

String is implemented as an immutable object; that is, when you initially decide to put something into aString object, the JVM allocates a fixed-width array of exactly the size of your initial value. This is then treated as a constant inside the JVM, which allows for very significant performance savings in the case where the String’s value is not changed. However, if you decide to change the String’s contents in any way, what the JVM then essentially does is copy the contents of the original String into a temporary space, make your changes, then save those changes into a whole new memory array. Thus, making changes to a String’s value after initialization is a fairly expensive operation.
StringBuffer, on the other hand, is implemented as a dynamically – growable array inside the JVM, which means that any change operation can occur on the existing memory location, with new memory allocated only as-needed. However, there is no opportunity for the JVM to make optimizations around the StringBuffer, since its contents are assumed to be changeable at any instance.

Deep copy and shallow copy?

A clone is an exact copy of the original. In java, it essentially means the ability to create an object with similar state as the original object. The clone() method provides this functionality.
Shallow copies duplicate as little as possible.  By default, java cloning is shallow copy or ‘field by field copy’ i.e. as the Object class does not have idea about the structure of class on which clone() method will be invoked. So, JVM when called for cloning, do following things:
1) If the class has only primitive data type members then a completely new copy of the object will be created and the reference to the new object copy will be returned.
2) If the class contains members of any class type then only the object references to those members are copied and hence the member references in both the original object as well as the cloned object refer to the same object.
Deep copies duplicate everything. A deep copy of a collection is two collections with all of the elements in the original collection duplicated. Here, we want a clone which is independent of original and making changes in clone should not affect original.
Deep cloning requires satisfaction of following rules.
  1. No need to separately copy primitives.
  2. All the member classes in original class should support cloning and in clone method of original class in context should call super.clone() on all member classes.
  3. If any member class does not support cloning then in clone method, one must create a new instance of that member class and copy all its attributes one by one to new member class object. This new member class object will be set in cloned object.

How to override equals and hashCode() methods?

hashCode() and equals() methods have been defined in Object class which is parent class for java objects. For this reason, all java objects inherit a default implementation of these methods.
hashCode() method is used to get a unique integer for given object. This integer is used for determining the bucket location, when this object needs to be stored in some HashTable like data structure. By default, Object’s hashCode() method returns and integer representation of memory address where object is stored.
equals() method, as name suggest, is used to simply verify the equality of two objects.  Default implementation simply check the object references of two objects to verify their equality.
Below are the important points to keep remember while overriding these functions.
  1. Always use same attributes of an object to generate hashCode() and equals() both. As in our case, we have used employee id.
  2. equals() must be consistent (if the objects are not modified, then it must keep returning the same value).
  3. Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
  4. If you override one, then you should override the other.

What happens if your Serializable class contains a member which is not serializable? How do you fix it?

In this case, NotSerializableException will be thrown at runtime. To fix this issue, a very simple solution is to mark such fields transient. It means these fields will not be serialized. If you want to save the state of these fields as well then you should consider reference variables which already implements Serializable interface.
You also might need to use readResolve() and writeResolve() methods. Lets summarize this:
  • First, make your non-serialisable field transient.
  • In writeObject(), first call defaultWriteObject() on the stream to store all the non-transient fields, then call other methods to serialize the individual properties of your non-serializable object.
  • In readObject(), first call defaultReadObject() on the stream to read back all the non-transient fields, then call other methods (corresponding to the ones you added to writeObject) to deserialise your non-serializable object

Explain transient and volatile keywords in java?

Transient

The transient keyword in Java is used to indicate that a field should not be serialized.” According to language specification: Variables may be marked transient to indicate that they are not part of the persistent state of an object. For example, you may have fields that are derived from other fields, and should only be done so programmatically, rather than having the state be persisted via serialization.
For example, in class BankPayment.java fields like principal and rate can be serialized while interest can be calculated any time even after de-serialization.
If we recall, each thread in java has its own local memory space as well and it does all read/write operations in its local memory. Once all operations are done, it write back the modified state of variable in main memory from where all threads access this variable. Normally, this is the default flow inside JVM. But, the volatilemodifier tells the JVM that a thread accessing the variable must always reconcile its own private copy of the variable with the master copy in memory. It means every time thread want to read the state of variable, it must flush its local memory state and update the variable from main memory.

Volatile

volatile is most useful in lock-free algorithms. You mark the variable holding shared data as volatile when you are not using locking to access that variable and you want changes made by one thread to be visible in another, or you want to create a “happens-after” relation to ensure that computation is not re-ordered, again, to ensure changes become visible at the appropriate time.
The volatile should be used to safely publish immutable objects in a multi-threaded Environment. Declaring a field like public volatile ImmutableObject foo secures that all threads always see the currently available instance reference.

What is synchronization? Object level locking and class level locking?

Synchronization refers to multi-threading. A synchronized block of code can only be executed by one thread at a time. Java supports multiple threads to be executed. This may cause two or more threads to access the same fields or objects. Synchronization is a process which keeps all concurrent threads in execution to be in synch. Synchronization avoids memory consistence errors caused due to inconsistent view of shared memory. When a method is declared as synchronized; the thread holds the monitor for that method’s object If another thread is executing the synchronized method, your thread is blocked until that thread releases the monitor.
Synchronization in java is achieved using synchronized keyword. You can use synchronized keyword in your class on defined methods or blocks. Keyword can not be used with variables or attributes in class definition.
Object level locking is mechanism when you want to synchronize a non-static method or non-static code block such that only one thread will be able to execute the code block on given instance of the class. This should always be done to make instance level data thread safe.
Class level locking prevents multiple threads to enter in synchronized block in any of all available instances on runtime. This means if in runtime there are 100 instances of  DemoClass, then only one thread will be able to execute demoMethod() in any one of instance at a time, and all other instances will be locked for other threads. This should always be done to make static data thread safe.

Difference between sleep() and wait()?

sleep() is a method which is used to hold the process for few seconds or the time you wanted but in case of wait() method thread goes in waiting state and it won’t come back automatically until we call the notify() or notifyAll().
The major difference is that wait() releases the lock or monitor while sleep() doesn’t releases any lock or monitor while waiting. Wait is used for inter-thread communication while sleep is used to introduce pause on execution, generally.
Thread.sleep() sends the current thread into the “Not Runnable” state for some amount of time. The thread keeps the monitors it has aquired — i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread. Note that sleep is a static method, which means that it always affects the current thread (the one that is executing the sleep method). A common mistake is to call t.sleep() where t is a different thread; even then, it is the current thread that will sleep, not the t thread.
object.wait() sends the current thread into the “Not Runnable” state, like sleep(), but with a twist. Wait is called on a object, not a thread; we call this object the “lock object.” Before lock.wait() is called, the current thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the “wait list” associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.

Why wait and notify is declared in Object class instead of Thread?

Wait, notify, notifyAll methods are only required when you want your threads to access a shared resource and a shared resource could be any java object which is on the heap. So, these methods are defined on the core Object class so that each object has control of allowing threads to wait on it’s monitor. Java doesn’t have any special object which is used for sharing a common resource. No such data structure is defined.So, onus is given on the Object class to be able to become shared resource providing it will helper methods likewait(),notify() and notifyAll().
Java is based on Hoare‘s monitors idea. In Java all object has a monitor. Threads waits on monitors so, to perform a wait, we need 2 parameters:
– a Thread
– a monitor (any object)
In the Java design, the thread can not be specified, it is always the current thread running the code. However, we can specify the monitor (which is the object we call wait on). This is a good design, because if we could make any other thread to wait on a desired monitor, this would lead to an “intrusion”, posing difficulties on designing /programming concurrent programs. Remember that in Java all operations that are intrusive in another thread’s execution are deprecated (e.g. stop()).

Explain the working of HashMap. How duplicate collision is resolved?

Most of you will agree that HashMap is most favorite topic for discussion in interviews now-a-days. If anybody asks me to describe “How HashMap works?”, I simply answer: “On principles of Hashing“. As simple as it is.
Now, Hashing in its simplest form, is a way to assigning a unique code for any variable/object after applying any formula/ algorithm on its properties.


No comments:

Post a Comment