Tuesday, 24 June 2014

Java scenario based interview questions

Consider a scenario in which the admin want to sure that if some one has written System.exit() at some part of application then before system shutdown all the resources should be released. How is it possible?

 
Ans:
       This is possible using Runtime.getRuntime().addShutdownHook(Thread hook).

Straight from Java Spec:
This method registers a new virtual-machine shutdown hook.

The Java virtual machine shuts down in response to two kinds of events:
1. The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
2. The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
A shutdown hook is simply an initialized but unstarted thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled. Finally, the virtual machine will halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if shutdown was initiated by invoking the exit method.
Once the shutdown sequence has begun it can be stopped only by invoking the halt method, which forcibly terminates the virtual machine.


How does Java allocate stack and heap memory?


Ans:
      Each time an object is created in Java it goes into the area of memory known as heap. The primitive variables like int and double are allocated in the stack, if they are local method variables and in the heap if they are member variables (i.e. fields of a class). In Java methods local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed.
In a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is threadsafe (each thread will have its own stack) but the heap is not threadsafe unless guarded with synchronisation through your code. 


Explain re-entrant, recursive and idempotent methods/functions?


Ans: 
       A method in stack is re-entrant allowing multiple concurrent invocations that do not interfere with each other.
A function is recursive if it calls itself. Given enough stack space, recursive method calls are perfectly valid in Java though it is tough to debug. Recursive functions are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive.  

Idempotent methods are methods, which are written in such a way that repeated calls to the same method with the same arguments yield same results. For example clustered EJBs, which are written with idempotent methods, can automatically recover from a server failure as long as it can reach another server.


What is Java Reflection?

 
Ans: 
         Reflection is commonly used by programs which require the ability to examine or modify the runtime behavior of applications running in the Java virtual machine.

Drawbacks of Reflection: Reflection is powerful, but should not be used indiscriminately. If it is possible to perform an operation without using reflection, then it is preferable to avoid using it. The following concerns should be kept in mind when accessing code via reflection.

Performance Overhead: Because reflection involves types that are dynamically resolved, certain Java virtual machine optimizations can not be performed. Consequently, reflective operations have slower performance than their non-reflective counterparts, and should be avoided in sections of code which are called frequently in performance-sensitive applications.

Security Restrictions: Reflection requires a runtime permission which may not be present when running under a security manager. This is in an important consideration for code which has to run in a restricted security context, such as in an Applet.

Exposure of Internals: Since reflection allows code to perform operations that would be illegal in non-reflective code, such as accessing private fields and methods, the use of reflection can result in unexpected side-effects, which may render code dysfunctional and may destroy portability. Reflective code breaks abstractions and therefore may change behavior with upgrades of the platform.

Composition over Inheritance ?

Ans:


      Prefer composition over inheritance as it is more malleable / easy to modify later, but do not use a compose-always approach. With composition, it's easy to change behavior on the fly with Dependency Injection / Setters. Inheritance is more rigid as most languages do not allow you to derive from more than one type.. So the goose is more or less cooked once you derive from Class A.
My acid test for the above is:

  • Does TypeB want to expose the complete interface (all public methods no less) of TypeA such that TypeB can be used where TypeA is expected? Indicates Inheritance.

e.g. A Cessna biplane will expose the complete interface of an airplane, if not more. So that makes it fit to derive from Airplane.

  • Does TypeB only want only some/part of the behavior exposed by TypeA? Indicates need for Composition.

e.g. A Bird may need only the fly behavior of an Airplane. In this case, it makes sense to extract it out as an interface / class / both and make it a member of both classes.

The importance of Composition

With composition, the programmer no longer has to extend from the parent class. You are able to expose only the methods you are interested in. Many of us find inheritance easier and we often use it without thinking about the repercussions it may bring to us.

I would like to just give a quick example of composition. If you have some sort of base class that your application will be inheriting from, lots of times you just extend it.


public class BaseClass{
    public void doStuff(){...} 
}

public class NewBaseClass extends BaseClass{...}

Nothing wrong with that and it is quite common to use. Another way we could do this is:

public class NewBaseClass{
    private BaseClass _baseClass;
    public void setBaseClass(BaseClass baseClass){
        _baseClass = baseClass;
    }
    public void doStuff(){
        _baseClass.doStuff();
    } 
}

Using the typical example of “IS-A” vs “HAS-A”, the first example IS a BaseClass. The second example HAS a BaseClass. From this example, it is difficult to see the advantages that something like this has to offer us. The laziness factor that almost all programmers have kicks in when they see we have to write functions that call the same functions on the BaseClass. While on the outside, it may seem like we are just doing extra work for no reason, there are many advantages that this approach has to offer. 


     When you use inheritance, you acquire the functionality of your baseclass at compile time. Note that in my short composition example, we have a setter for our BaseClass. This is because with composition, you acquire your functionality at runtime. Once again this might difficult to see the importance. When we assign something at run-time, it gives us the ability to swap out implementations without having to recompile our code. In fact, the decorator pattern, amongst many other design patterns, takes advantage of composition by this technique alone. You are able to just write however many BaseClasses you want and swap out the implementation at runtime. 


     In case of Interface new methods get added, old methods get removed, types change, etc. It is the standard rule of thumb that when using an interface, make sure you have done it right the first time. Once that interface is published and goes to the client that is it. Once you change that interface, everyone else code breaks. Now if instead of using inheritance, we took advantage of composition, we would not have to worry about it. The interface can add as many methods as it wants, there is much less of a change that it will break (if they remove the function, then not much you can do about it). With composition, we only expose the methods that we want to use. We no longer have to worry about relying on the parent class or implementing their functions. 


     When designing out projects, it is very easy to design things while you are thinking a problem through. When you are doing this at the design level, lots of people will just inherit from parents classes. A implements B, C extends B, etc. But what if D needs some functions from C but not from B? Surely you could always just implement what is in C that you dont need and not do anything with it, but that is just poor design. You could create another hierarchal level and go from here, but this is where trouble begins. You now have this extremely large, tightly coupled and difficult design to follow. The alternative approach would be to use composition. Using this, we will have fewer classes to worry about in our design and we will have much more diverse objects. Following this, when we have fewer classes, our hierarchy becomes smaller and more focused, thus easier to follow.

     Now this is not to say inheritance is bad and should be avoided. There are many instances required. However, I do feel that it is often abused. Partly because programmers are naturally lazy and it’s much easier to extends a class rather than expose the methods on a class. The other reason though is, it’s a methodology that is often overlooked. With the use of composition in your code, you will be able to produce a much more flex and stable application. 



No comments:

Post a Comment