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:
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.
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.
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.
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.
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:
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.
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.
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