Top
20 Core Java Interview Questions and Answers asked on Investment Banks
Core Java
Why non static variable
can not be called from static method
Read more: http://javarevisited.blogspot.com/2012/02/why-non-static-variable-cannot-be.html#ixzz2C0QE5Ok1
To create a
object immutable You need to make the class
final and all its member final so that once objects gets crated no one can modify its state.
You can achieve same functionality by making member as non final but private and not modifying them except in constructor. Also its NOT necessary to have all the
properties final since you can achieve same functionality by making member as
non final but private and not modifying
them except in constructor.
Why Immutable objects:
1. Immutable objects do indeed make life simpler in many cases.
2. They are especially
applicable for value types, where objects don't have an identity so they
can be easily replaced. And
3. they can make concurrent
programming way safer and cleaner (most of the notoriously hard to find
concurrency bugs are ultimately caused by mutable state shared between
threads).
4. large and/or complex objects, creating a new copy of the object for every single change can be very
costly and/or tedious. And for objects with a distinct identity, changing
an existing objects is much more simple and intuitive than creating a new,
modified copy of it.
5. Immutable objects are simply objects whose state (the object's
data) cannot change after construction. Examples of immutable objects from the
JDK include String and Integer.
Immutable
objects greatly simplify your program, since they :- are simple to construct, test, and use
- are automatically thread-safe and have no synchronization issues
- do not need a copy constructor
- do not need an implementation of clone
- allow hashCode to use lazy initialization, and to cache its return
value
- do not need to be copied defensively when used as a field
- make good Map keys and Set elements (these objects must
not change state while in the collection)
- have their class invariant established once upon construction, and it never needs to be
checked again
- always have "failure atomicity" (a
term used by Joshua Bloch) : if an immutable object throws an exception,
it's never left in an undesirable or indeterminate state
Immutable:
What is Immutable:
Immutable objects are simply objects
whose state (the object's data) cannot changed after construction or
initialization.
How:
1. Make the class final
2. make all members final, set
them explicitly, in a static block, or in the constructor
3. Make all members private
4. No Methods that modify
state
5.
Be extremely careful to
limit access to mutable member components(remember the field may be final but
the object can still be mutable. ie private final Date imStillMutable) - See
defensive copying or its cousin copy constructors for more info
Advantage
immutable objects can safely be shared among
multiple thread
Thread Safe - because the state cannot be
changed, no synchronization is required
·
Thread Safety: Immutable
objects cannot be changed nor can its internal state change, thus there's no
need to synchronize it.
·
It also guarantees that whatever I send through (through a
network) has to come in the same state as previously sent. It means that nobody (eavesdropper) can come and add random data
in my immutable set.
·
It's also simpler to
develop. You guarantee that no
subclasses will exist if an object is immutable. E.g. a String class.
Hashmaps are a classic example. It's
imperative that the key to a map be
immutable. If the key is not immutable, and you change a value on the key
such that hashCode() would result in a new value, the map is now broken (a key
is now in the wrong location in the hash table.).
The main benefit of immutable classes however is that you can expose internal data members
that are immutable because the caller can't modify them.
·
java.lang.String
(already mentioned)
·
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
·
java.lang.StackTraceElement
(used in building exception stacktraces)
- java.lang.Math (this too - the
random number generator)
- java.lang.reflect.Array
- java.util.Collections
- java.util.Arrays
What is difference
between String, StringBuffer and StringBuilder? When to use them?
The main difference between the three most
commonly used String classes as follows.
·
StringBuffer and StringBuilder objects are mutable whereas
String class objects are immutable.
·
StringBuffer class
implementation is synchronized while StringBuilder class is not synchronized.
·
Concatenation operator "+" is internally implemented
by Java using either StringBuffer or StringBuilder.
Criteria to choose among String, StringBuffer and
StringBuilder
·
If the Object value will
not change in a scenario use String Class because a String object is
immutable.
·
If the Object value can
change and will only be modified from a single thread, use a StringBuilder
because StringBuilder is unsynchronized(means faster).
·
If the Object value may
change, and can be modified by multiple threads, use a StringBuffer because
StringBuffer is thread safe(synchronized).
It is very
useful to have strings implemented as final or immutable objects. Below are
some advantages of String Immutability in Java
·
Immutable objects are thread-safe. Two threads can both work on
an immutable object at the same time without any possibility of conflict.
·
Immutable objects are good fit for becoming Hashtable keys. If
you change the value of any object that is used as a hash table key without
removing it and re-adding it you will lose the object mapping.
·
If String were not final,
you could create a subclass and have two strings that look alike when
"seen as Strings", but that are actually different.
·
Security: the system can pass on sensitive bits of read-only
information without worrying that it will be altered
·
You can share duplicates by pointing them to a single instance.
·
You can create
substrings without copying. You just create a pointer into an existing base
String guaranteed never to change. Immutability is the secret that makes Java
substring implementation very fast.
·
Since String is
immutable, inside each String is a char[] exactly the correct length. Unlike a
StringBuilder there is no need for padding to allow for growth.
·
.
What is
OutOfMemoryError in java? How to deal with java.lang.OutOfMemeryError error?
This Error is thrown when the Java Virtual
Machine cannot allocate an object because it is out of memory, and no more
memory could be made available by the garbage collector. Note: Its an Error
(extends java.lang.Error) not Exception. Two important types of
OutOfMemoryError are often encountered
1.
java.lang.OutOfMemoryError:
Java heap space
The quick solution is
to add these flags to JVM command line when Java runtime is started:
1.
-Xms1024m -Xmx1024m
2.
java.lang.OutOfMemoryError:
PermGen space
The solution is to add
these flags to JVM command line when Java runtime is started:
1.
-XX:+CMSClassUnloadingEnabled-XX:+CMSPermGenSweepingEnabled
Long Term Solution: Increasing the Start/Max Heap size or changing Garbage
Collection options may not always be a long term solution for your Out Of
Memory Error problem. Best approach is to understand the memory needs of your
program and ensure it uses memory wisely and does not have leaks. You can use a
Java memory profiler to determine
what methods in your program are allocating large number of objects and then
determine if there is a way to make sure they are no longer referenced, or to
not allocate them in the first place.
What is the use of the
finally block? Is finally block in Java guaranteed to be called? When finally
block is NOT called?
Finally is the
block of code that executes always. The code in finally block will execute even
if an exception is occurred. Finally
block is NOT called in following conditions
·
If the JVM exits while
the try or catch code is being executed, then the finally block may not
execute. This may happen due to System.exit()
call.
·
if the thread executing the try or catch code is interrupted or
killed, the finally block may not execute even
though the application as a whole continues.
·
If a exception is thrown in finally block and not handled then
remaining code in finally block may not be executed
The marker interface is a design pattern, used with languages that provide
run-time type information about objects. It provides a way to associate metadata with a class where the language
does not have explicit support for such metadata. To use this pattern, a class implements a marker interface, and
code that interact with instances of that class test for the existence of the
interface. Whereas a typical interface specifies methods that an implementing
class must support, a marker interface does not do so. The mere presence of such an interface indicates specific behavior on
the part of the implementing class. There can be some hybrid interfaces,
which both act as markers and specify required methods, are possible but may
prove confusing if improperly used. Java utilizes this pattern very well and
the example interfaces are
·
java.io.Serializable - Serializability of a class is enabled by
the class implementing the java.io.Serializable interface. The Java Classes
that do not implement Serializable interface will not be able to serialize or
deserializ their state. All subtypes of
a serializable class are themselves serializable. The serialization
interface has no methods or fields and serves only to identify the semantics of
being serializable.
·
java.rmi.Remote - The Remote interface serves to identify
interfaces whose methods may be invoked from a non-local virtual machine.
Any object that is a remote object must directly or indirectly implement this
interface. Only those methods specified in a "remote interface", an
interface that extends java.rmi.Remote are available remotely.
·
java.lang.Cloneable - A
class implements the Cloneable interface to indicate to the Object.clone()
method that it is legal for that method to make a field-for-field copy of instances of that class. Invoking
Object's clone method on an instance that does not implement the Cloneable
interface results in the exception CloneNotSupportedException being thrown.
·
javax.servlet.SingleThreadModel - Ensures that servlets handle only one request at a time. This
interface has no methods.
·
java.util.EvenListener - A
tagging interface that all event listener interfaces must extend.
The
"instanceof" keyword in java can be used to test if an object is of a
specified type. So this keyword in combination with Marker interface can be
used to take different actions based on type of interface an object implements.
Why Marker or Tag interface do in Java
1) Looking carefully on
marker interface in Java e.g. Serializable, Clonnable and Remote it
looks they are used to indicate something to compiler or JVM. So if JVM
sees a Class is Serializable it done some special operation on it,
similar way if JVM sees one Class is implement Clonnable it performs some operation to
support cloning. Same is true for RMI
and Remote interface. So in short Marker interface indicate, signal or a
command to Compiler or JVM.
Where Should I use Marker interface in Java
Apart from using built in
marker interface for making a class Serializable or Clonnable. One can also develop his own
marker interface. Marker interface is a good way to classify code. You can create marker interface to logically divide your code and if you have your own tool than you can perform some pre-processing operation on those classes. Particularly useful for developing API and framework
like Spring or Struts.
After introduction of
Annotation on Java5, Annotation is better choice than marker interface and
JUnit is a perfect example of using Annotation e.g. @Test for specifying a Test Class. Same can also be achieved by using Test marker
interface.
Why main() in java is
declared as public static void main? What if the main method is declared as
private?
Public - main method is
called by JVM to run the method which is outside the scope of project therefore
the access specifier has to be public to permit call from anywhere outside the
application static - When the JVM
makes are call to the main method there is not object existing for the class
being called therefore it has to have static method to allow invocation from
class. void - Java is platform
independent language therefore if it will return some value then the value may
mean different to different platforms so unlike C it can not assume a
behavior of returning value to the operating system. If main method is declared
as private then - Program will compile properly but at run-time it will give
"Main method not public."
error.
If you are a college graduate with no job experience then as a Java developer you need to understand the following basic things.
1.
How Java Virtual
Machine works? e.g. (Platform Independence, Garbage Collection, class files
etc)
2.
What are the Object
Oriented Programming Concepts Implemented in Java?
3.
Multi-threading
4.
Java Collection
framework
5.
Good understanding of
data types and few java.lang classes like String, Math, System etc. java.io
stream concepts.
6.
Understand concept of
Swing/AWT event based programming.
7.
Servlets & JSP
concepts.
If you are a experienced professional then as a Java developer you may also need to understand the following basic things in addition to the ones listed above.
1.
Understand design
patterns and its usage in Java
2.
Improvements on
language from major version changes (Generics, Annotations, Enums, ...).
3.
Coding Conventions.
4.
Build tool (Ant) or
Project Management Tool (Maven).
5.
Version control System
like CVS/SVN/Perforce/Clearcase.
6.
Apache Commons
Libraries & few other common open source libraries.
7.
Continuous Integration
Tools and Unit testing.
8.
Fundamental
understanding of XML
9.
Understand Business
layer frameworks - like Spring
If you are a experienced professional working on Web based development then as a JEE developer you also need to understand the following basic things in addition to the ones (7+9) listed above.
1.
Understanding of MVC
Frameworks - Open source J2EE frameworks like - Struts, Webwork, Spring MVC,
Tapestry.
2.
Fundamental
understanding of Web Services.
3.
Good understanding of
Web/Application server like Tomcat, Glassfish, WebLogic, WebSphere, Jetty etc.
4.
Unix environment - A
working knowledge of Unix environment can be beneficial as most of the Java
servers are hosted on Unix based environment in production.
Why multiple inheritances are not supported in Java
Read more: http://javarevisited.blogspot.com/2011/07/why-multiple-inheritances-are-not.html#ixzz2HNjcQr4A
Read more: http://javarevisited.blogspot.com/2011/07/why-multiple-inheritances-are-not.html#ixzz2HNjcQr4A
class D derive from B and C using multiple inheritance and if we refer just foo() compiler
will not be able to decide which foo() it should invoke. This is also called Diamond problem
multiple inheritances does complicate the design and creates problem during casting,
constructor chaining etc
HashMap is fast
its stores key and value pairs etc.
How HashMap works in Java
"HashMap works on principle of hashing, we
have put(key,
value) and get(key) method for storing and
retrieving Objects from HashMap. When
we pass Key and Value object to put() method on Java HashMap, HashMap implementation calls hashCode
method on Key object and applies returned hashcode
into its own hashing function to find a bucket location for storing Entry
object, important point to mention is that HashMap in Java stores both key and value object as Map.Entry in bucket which is essential to understand the retrieving logic. If
people fails to recognize this and say it only stores Value in the bucket they
will fail to explain the retrieving logic of any object stored in Java HashMap
Read more: http://javarevisited.blogspot.com/2011/02/how-hashmap-works-in-java.html#ixzz2SjyFFXLR
Read more: http://javarevisited.blogspot.com/2011/02/how-hashmap-works-in-java.html#ixzz2SjyFFXLR
HashMap works on principle of hashing, we have put() and get() method for storing and
retrieving object form HashMap .When we pass an both key and value to put()
method to store on HashMap , it uses key
object hashcode() method to calculate hashcode and they by applying hashing on
that hashcode it identifies bucket location for storing value object. While
retrieving it uses key object equals
method to find out correct key value pair and return value object associated
with that key. HashMap
uses linked list in case of collision and object will be stored in next
node of linked list.
Also HashMap stores both key+value tuple in every node
of linked list.
using immutable, final object with proper equals() and hashcode() implementation would act as perfect Java HashMap keys and improve performance of Java
HashMap by reducing
collision. Immutability also allows caching there
hashcode of different keys which makes
overall retrieval process very fast and suggest that String and various
wrapper classes e.g. Integer very good keys in Java HashMap.
"What will happen if two different objects have same
hashcode?”
"Since hashcode is same, bucket location would be same and collision will occur in HashMap, Since HashMap use LinkedList to store object, this entry (object of Map.Entry comprise key and value ) will be stored in LinkedList.
"Since hashcode is same, bucket location would be same and collision will occur in HashMap, Since HashMap use LinkedList to store object, this entry (object of Map.Entry comprise key and value ) will be stored in LinkedList.
"How will
you retrieve Value object if two Keys will have same hashcode?”
Read more: http://javarevisited.blogspot.com/2011/02/how-hashmap-works-in-java.html#ixzz2Sk1iXfS6
Read more: http://javarevisited.blogspot.com/2011/02/how-hashmap-works-in-java.html#ixzz2Sk1iXfS6
Interviewee will say we will call get() method and then HashMap uses
Key Object's hashcode to find out bucket location and retrieves Value object
but then you need to remind him that there are two Value objects are stored in
same bucket , so they will say about traversal
in LinkedList until we find the value object
, then you ask how do you identify value object
because you don't have value object to compare ,Until they know that HashMap
stores both Key and Value in LinkedList node or as Map.Entry they won't be able to resolve
this issue and will try and fail.
But those bunch of people who remember this key information
will say that after finding bucket location , we will call keys.equals() method to identify correct node in LinkedList
and return associated value object for that key in Java HashMap . Perfect this
is the correct answer.
In many cases interviewee fails at this stage because they
get confused between hashCode() and equals() or keys and values object in
Java HashMap which is pretty obvious because they are dealing with the hashcode()
in all previous questions and equals() come in picture only in case of retrieving value object from
HashMap in Java. Some good developer point out here that using
immutable, final
object with
proper equals() and hashcode() implementation would act as
perfect Java HashMap keys and improve
performance of Java HashMap by reducing collision. Immutability also allows caching
there hashcode of different keys which makes overall retrieval process very
fast and suggest that String and various wrapper classes e.g. Integer
very good keys in Java HashMap.
"What happens On HashMap in Java if the size of the
HashMap exceeds a given threshold defined by load factor ?".
If the size of the Map exceeds a given threshold defined by
load-factor e.g. if load factor is .75 it will act to re-size the map once it filled
75%. Similar to other collection classes like ArrayList,
Java HashMap re-size itself by
creating a new bucket array of size twice of previous size of HashMap , and
then start putting every old element into that new bucket array. This process
is called rehashing because it also applies hash function to find
new bucket location.
"do you see any problem with resizing of HashMap
in Java" ,
you might not be able
to pick the context and then he will try to give you hint about multiple thread
accessing the Java HashMap and potentially looking for race condition on HashMap in
Java.
So the answer is Yes there
is potential race
condition exists
while resizing HashMap in Java, if two thread at the same
time found that now HashMap needs resizing and they both
try to resizing. on the process of resizing of HashMap in Java , the element in bucket which is
stored in linked list get reversed in order during there migration to new
bucket because java HashMap doesn't append the new element at tail
instead it append new element at head to
avoid tail traversing. If
race condition happens then you will end up with an infinite loop. Though
this point you can potentially argue that what the hell makes you think to use
HashMap in multi-threaded environment to interviewer :)
What will happen if two different HashMap key objects
have same hashcode?
They will be stored in same bucket but no next node of
linked list. And keys
equals () method will be used to identify correct key value pair in HashMap .
1) Why String, Integer and other wrapper classes are
considered good keys ?
String, Integer and other wrapper classes are
natural candidates of HashMap key, and String is most frequently used key as
well because String is
immutable and final,and
overrides equals and hashcode() method. Other wrapper class also
shares similar property. Immutabiility is required, in order to prevent changes
on fields used to calculate hashCode() because if key object return
different hashCode during insertion and retrieval than it won't be possible to
get object from HashMap.
Immutability is best as it offers other advantages as well like thread-safety, If you
can keep your hashCode same
by only making certain fields final, then
you go for that as well. Since equals() and hashCode() method is used during reterival
of value object from HashMap, its important that key object
correctly override these methods and follow contact. If unequal object return
different hashcode than chances of collision will be less which subsequently
improve performance of HashMap.
2) Can we use any custom object as key in HashMap ?
This is an extension of previous questions. Ofcourse you can
use any Object as key in Java HashMap provided it follows equals and hashCode contract and
its hashCode should not vary once the object is inserted into Map. If
custom object is Immutable than this
will be already taken care because you can not change it once created.
Synchronized collection class (HashTable) replacement -Ã ConcurrentHashMap
only locked certain portion of Map while Hashtable lock full map while doing iteration.
several factors make them unsuitable for use in highly
concurrent applications -- their single collection-wide lock is an
impediment to scalability and it often becomes necessary to lock a collection
for a considerable time during iteration to prevent
ConcurrentModificationExceptions
How to
overload a method in Java
To overload a Java
method
just changes its signature.
either need to change
number of argument, type of argument or order of argument in Java if they are of different types.
Since return type
is not part of method signature
simply changing return type will result in duplicate method and you will get compile
time error in Java
How
to override a method in Java
override a method in Java its signature remains exactly same including return type
Rules
of Method Overriding in Java
·
Method signature must be same including return type, number of method parameters,
type of parameters and order of parameters
·
Overriding method
can not throw higher Exception than original or overridden
method. means if original method throws IOException than overriding method can
not throw super
class of IOException e.g. Exception but it can throw
any sub class of IOException or simply does not throw any Exception. This
rule only applies to checked
Exception in Java, overridden method is free to
throw any unchecked Exception.
·
Overriding method can not reduce accessibility of overridden method , means if original or overridden
method is public than overriding method can not make it protected.
Difference between method overloading vs overriding in Java
1) First
and most important difference between method overloading and overriding is
that, In case of method overloading in Java, Signature
of method changes while in case of method overriding it remain same.
2) Second major difference
between method overloading vs overriding in Java is that
You can overload method in one class but overriding can only be done on subclass.
3) You can not override static, final and private
method in Java but you can overload static, final or private method in Java.
4) Overloaded method in Java is bonded by static binding and overridden methods are subject to dynamic binding.
4) Overloaded method in Java is bonded by static binding and overridden methods are subject to dynamic binding.
5) Private and final method can also be not overridden in Java
Difference between Checked vs Unchecked Exception in Java
Checked Exception in Java is all those
Exception which requires being catches and handled during compile time. If Compiler doesn’t see try or catch block handling
a Checked Exception, it throws
Compilation error. Now Which Exception
is checked Exception and Why Checked Exception
are introduced in first place? All the Exception which are direct sub Class of
Exception but not
inherit RuntimeException areChecked Exception.
Checked Exception is a reminder by compiler to programmer to handle
failure scenario
Example of checked Exception in Java API
Following are some Examples of Checked Exception in Java library:
Following are some Examples of Checked Exception in Java library:
IOException
DataAccessException
InvocationTargetException
What
is Unchecked Exception in Java?
Unchecked Exception in Java is those
Exceptions whose handling is not verified during Compile time. Unchecked
Exceptions mostly arise due to programming errors like accessing method of a null object, accessing element outside an array bonding or invoking
method with illegal arguments. In
Java, Unchecked Exception is direct sub
Class of RuntimeException. What is major benefit of Unchecked
Exception is that it doesn't reduce code readability and keeps
the client code clean.
When
to use UnCheckedException in Java
A good strategy of Exception
handling in Java is wrapping
a checked Exception into UnCheckedException. Since most of Database
operation throws SQLException but it’s not good to let SQLException
propagate from your DAO layer to up higher on business layer and client code
provide exception handling you can handle SQLException in DAO layer and you can
wrap the cause in a RuntimeException to propagate through client code.
Difference
between Checked and Unchecked Exception in Java
Now we have enough information
to differentiate Checked Exception with Unchecked Exception:
1) Checked Exception
is required to be handled by compile time while Unchecked Exception doesn't.
2) Checked Exception is direct sub-Class of Exception while Unchecked
Exception are of RuntimeException.
3) CheckedException represent
scenario with higher failure rate while UnCheckedException are mostly
programming mistakes.
How to override
equals and hashCode method in Java - Example, Tips
Few
Thump rules:
· If two objects are
same then they must return same value in hashcode() and equals() method
whenever invoked.
· It is not necessary
that two different object must have different hashcode values. it might be
possible that they share common hash bucket.
JVM assigns unique hashcode
value to each object when they are created in memory and if developers don’t
override the hashcode method then there is no way the two object returns same
hashcode value.
hashcode is used to narrow
the search result.
When we try to insert any key in HashMap first it checks
whether any other object present with same hashcode and if yes then it checks
for the equals() method. If two objects are same then HashMap will not add that
key instead it will replace the old value by new one.
Why:
1) Override equals when your class models some sort of type in
which different instances can be considered equal, depending on the values they
have.
2) Override hashCode when you override equals, and only if you override equals.
2) Override hashCode when you override equals, and only if you override equals.
2)
3)
Read more: http://javarevisited.blogspot.com/2011/02/how-to-write-equals-method-in-java.html#ixzz2DkRtvCYb
Read more: http://javarevisited.blogspot.com/2011/02/how-to-write-equals-method-in-java.html#ixzz2DkRtvCYb
Although
there are lots of materials are available on internet and API document about
the necessity of the overriding the hashcode() and equals() method
in Java but lots of new developers still not able to understand the necessity
of hashcode() method.
In this article, I will try to explain step by step the need of overriding hashcode() method in Java.
In this article, I will try to explain step by step the need of overriding hashcode() method in Java.
Few
Thump rules:
· If two objects are
same then they must return same value in hashcode() and equals() method
whenever invoked.
· It is not necessary
that two different object must have different hashcode values. it might be
possible that they share common hash bucket.
JVM assigns unique hashcode value to each object when they
are created in memory and if developers don’t override the hashcode method then
there is no way the two object returns same hashcode value.
As
the question comes in your mind that equals() method is used to compare objects
that they are having same value or not but why should we override the
hashcode method ?
The answer to the question is for the hash technique based data
structures like HashMap and HashTable.
How Hashcode works
in java
As
you can see in above diagram that every object is placed in Hash bucket
depending on the hashcode they have. It is not necessary that every different
object must have different hashcode. hashcode is used to narrow the search result. When
we try to insert any key in HashMap first it checks whether any other object
present with same hashcode and if yes then it checks for the equals() method.
If two objects are same then HashMap will not add that key instead it will
replace the old value by new one.
What
will happen if I don’t override the hashcode method?
Ans : If the object does not implement hashcode() method and used as key then we will not get the object back as shown in below code.
Ans : If the object does not implement hashcode() method and used as key then we will not get the object back as shown in below code.
Code
without implementation of equals() and hashcode()
1
|
package com.G2.Collections;
|
|
2
|
||
3
|
import java.util.HashMap;
|
|
4
|
||
5
|
class Movie {
|
|
6
|
private String name, actor;
|
|
7
|
||
8
|
public String getName() {
|
|
9
|
return name;
|
||
10
|
}
|
||
11
|
||
12
|
public void setName(String name)
{
|
|
13
|
this.name
= name;
|
|
14
|
}
|
|
15
|
||
16
|
public String getActor() {
|
|
17
|
return actor;
|
|
18
|
}
|
|
19
|
||
20
|
public void setActor(String
actor) {
|
|
21
|
this.actor
= actor;
|
|
22
|
}
|
|
23
|
||
24
|
public int getReleaseYr() {
|
|
25
|
return releaseYr;
|
|
26
|
}
|
|
27
|
||
28
|
public void setReleaseYr(int releaseYr) {
|
|
29
|
this.releaseYr
= releaseYr;
|
|
30
|
}
|
|
31
|
||
32
|
private int releaseYr;
|
|
33
|
}
|
|
34
|
||
35
|
public class HashMapDemo {
|
|
36
|
||
37
|
public static void main(String[] args)
{
|
|
38
|
||
39
|
Movie m
= new Movie();
|
|
40
|
m.setActor("Akshay");
|
|
41
|
m.setName("Thank
You");
|
|
42
|
m.setReleaseYr(2011);
|
|
43
|
||
44
|
Movie m1
= new Movie();
|
|
45
|
m1.setActor("Akshay");
|
46
|
m1.setName("Khiladi");
|
47
|
m1.setReleaseYr(1993);
|
|
48
|
||
49
|
Movie m2
= new Movie();
|
|
50
|
m2.setActor("Akshay");
|
|
51
|
m2.setName("Taskvir");
|
52
|
m2.setReleaseYr(2010);
|
53
|
||
54
|
Movie m3
= new Movie();
|
|
55
|
m3.setActor("Akshay");
|
56
|
m3.setName("Taskvir");
|
57
|
m3.setReleaseYr(2010);
|
|
58
|
||
59
|
HashMap<Movie,
String> map = new HashMap<Movie, String>();
|
|
60
|
map.put(m, "ThankYou");
|
|
61
|
map.put(m1, "Khiladi");
|
|
62
|
map.put(m2, "Tasvir");
|
|
63
|
map.put(m3, "Duplicate
Tasvir");
|
|
64
|
||
65
|
//Iterate
over HashMap
|
|
66
|
for (Movie mm :
map.keySet()) {
|
|
67
|
System.out.println(map.get(mm).toString());
|
|
68
|
}
|
|
69
|
||
70
|
Movie m4
= new Movie();
|
|
71
|
m4.setActor("Akshay");
|
72
|
m4.setName("Taskvir");
|
73
|
m4.setReleaseYr(2010);
|
|
74
|
||
75
|
/* We are trying to retrieve m2, by creating object m4
with exact values as of m2, However Hashcode method is not implemented and
that why we are not able to get Object m2 */
|
|
76
|
if(map.get(m4)
== null ){
|
|
77
|
System.out.println("----------------");
|
78
|
System.out.println("Object
not found");
|
79
|
System.out.println("----------------");
|
|
80
|
}else{
|
|
81
|
System.out.println(map.get(m4).toString());
|
|
82
|
}
|
|
83
|
}
|
|
84
|
}
|
|
Output:
Khiladi
Tasvir
ThankYou
Duplicate Tasvir
—————-
Object not found
—————-
Khiladi
Tasvir
ThankYou
Duplicate Tasvir
—————-
Object not found
—————-
As
you can see in above program :
1.
Duplicate objects are
added in Hashmap as a key (Because we have not overided the hashcode and equals
method)
2.
We are not able to get
back object from map (Because hashcode is not implemented)
Same
program with equals and hashcode implementation:
1
|
package com.G2.Collections;
|
|
2
|
||
3
|
import java.util.HashMap;
|
|
4
|
||
5
|
class Movie {
|
|
6
|
private String name, actor;
|
|
7
|
||
8
|
@Override
|
|
9
|
public boolean equals(Object o) {
|
||
10
|
Movie
m = (Movie) o;
|
||
11
|
return m.actor.equals(this.actor)
&& m.name.equals(this.name) && m.releaseYr
== this.releaseYr;
|
|
12
|
}
|
|
13
|
||
14
|
@Override
|
|
15
|
public int hashCode() {
|
|
16
|
return actor.hashCode() +
name.hashCode() + releaseYr;
|
|
17
|
}
|
|
18
|
||
19
|
public String getName() {
|
|
20
|
return name;
|
|
21
|
}
|
|
22
|
||
23
|
public void setName(String name)
{
|
|
24
|
this.name
= name;
|
|
25
|
}
|
|
26
|
||
27
|
public String getActor() {
|
|
28
|
return actor;
|
|
29
|
}
|
|
30
|
||
31
|
public void setActor(String
actor) {
|
|
32
|
this.actor
= actor;
|
|
33
|
}
|
|
34
|
||
35
|
public int getReleaseYr() {
|
|
36
|
return releaseYr;
|
|
37
|
}
|
|
38
|
||
39
|
public void setReleaseYr(int releaseYr) {
|
|
40
|
this.releaseYr
= releaseYr;
|
|
41
|
}
|
|
42
|
||
43
|
private int releaseYr;
|
|
44
|
}
|
|
45
|
||
46
|
public class HashMapDemo {
|
|
47
|
||
48
|
public static void main(String[] args)
{
|
|
49
|
||
50
|
Movie m
= new Movie();
|
|
51
|
m.setActor("Akshay");
|
|
52
|
m.setName("Thank
You");
|
|
53
|
m.setReleaseYr(2011);
|
|
54
|
||
55
|
Movie m1
= new Movie();
|
|
56
|
m1.setActor("Akshay");
|
|
57
|
m1.setName("Khiladi");
|
58
|
m1.setReleaseYr(1993);
|
59
|
||
60
|
Movie m2
= new Movie();
|
|
61
|
m2.setActor("Akshay");
|
62
|
m2.setName("Taskvir");
|
63
|
m2.setReleaseYr(2010);
|
|
64
|
||
65
|
Movie m3
= new Movie();
|
|
66
|
m3.setActor("Akshay");
|
|
67
|
m3.setName("Taskvir");
|
68
|
m3.setReleaseYr(2010);
|
69
|
||
70
|
HashMap<Movie,
String> map = new HashMap<Movie, String>();
|
|
71
|
map.put(m, "ThankYou");
|
72
|
map.put(m1, "Khiladi");
|
73
|
map.put(m2, "Tasvir");
|
|
74
|
map.put(m3, "Duplicate
Tasvir");
|
|
75
|
||
76
|
// Iterate
over HashMap
|
|
77
|
for (Movie mm :
map.keySet()) {
|
|
78
|
System.out.println(map.get(mm).toString());
|
|
79
|
}
|
|
80
|
||
81
|
Movie m4
= new Movie();
|
|
82
|
m4.setActor("Akshay");
|
|
83
|
m4.setName("Taskvir");
|
84
|
m4.setReleaseYr(2010);
|
85
|
||
86
|
if (map.get(m4) == null)
{
|
|
87
|
System.out.println("----------------");
|
88
|
System.out.println("Object
not found");
|
89
|
System.out.println("----------------");
|
|
90
|
} else {
|
|
91
|
System.out.println("----------------");
|
|
92
|
System.out.println(map.get(m4).toString());
|
|
93
|
System.out.println("----------------");
|
|
94
|
}
|
|
95
|
}
|
|
96
|
}
|
|
Output:
Khiladi
Duplicate Tasvir
ThankYou
—————-
Duplicate Tasvir
—————-
As you can see :
Khiladi
Duplicate Tasvir
ThankYou
—————-
Duplicate Tasvir
—————-
As you can see :
·
Duplicate Keys are not
added instead there values are replaced.
·
Now the object is
retrieved from the Map.
Java Thread
Interview Questions and answers
implementing Runnable is better because in Java we can only extend one class so if we
extend Thread class we can not extend any other class while by implementing Runnable interface we still have that option open
with us.
Second reason which make sense to me is more on OOPS concept according to OOPS if we extend a class we provide some new feature or functionality , So if the purpose is just to use the run() method to define code its better to use Runnable interface.
Second reason which make sense to me is more on OOPS concept according to OOPS if we extend a class we provide some new feature or functionality , So if the purpose is just to use the run() method to define code its better to use Runnable interface.
When we call start () method Java Virtual machine execute run ()
method of that Thread class into separate Thread other than calling thread.
there would be
no Error or Exception run() method will simply be executed in the
same Thread and new Thread will not be
created. Another follow up question would be what will happen if you call start() method twice in same Thread object e.g.
mythread.start();
mythread.start(); //this line will throw IllegalThreadStateException
mythread.start(); //this line will throw IllegalThreadStateException
you can call run() method twice
Reason Why Wait , Notify and NotifyAll are in Object Class.
Wait and notify is not just normal methods or
synchronization utility, more than that they are communication
mechanism between two threads in Java. And Object class is correct place to make them available for every
object if this mechanism
Locks are made
available on per Object basis, which is another reason wait and notify is declared in Object class rather then
Thread class.
In Java in order to enter critical section of
code, Threads needs lock and they wait
for lock, they don't know which
threads holds lock instead they just know the lock is hold by some thread
and they should wait for lock instead of knowing which
thread is inside the synchronized block and asking them to release lock.
this analogy fits with wait and notify being on object class rather than thread
in Java
Difference between yield and sleep in java
Major difference between yield and sleep
in Java is that
1. yield() method pauses the currently
executing thread temporarily
for giving a chance to the remaining waiting threads of the same priority to
execute.
2. If there is no
waiting thread or all the waiting threads have a lower priority then the same
thread will continue its execution.
3. The yielded
thread when it will get the chance for execution is decided by the thread scheduler whose behavior is vendor
dependent.
4. Yield method
doesn’t guarantee that current thread will pause or stop but it guarantee
that CPU will be relinquish by current Thread as a result of call to Thread.yield() method in java.
Sleep method in Java has two variants one which
takes millisecond as sleeping time while
other which takes both mill and nano second for sleeping duration.
sleep(long millis)
or
sleep(long millis,int nanos)
Cause the currently
executing thread to sleep for the specified number of milliseconds plus the specified
number of nanoseconds.
5) sleep() method throws Interrupted Exception if another thread interrupt a sleeping thread in java.
There is a misconception about sleep method in Java that
calling t.sleep() will put Thread "t" into sleeping state, that's not
true because Thread.sleep method is a
static method it always put current thread into Sleeping state and not thread
"t".
Wait vs Sleep vs Yield in
Java
Wait
|
Sleep
|
|
wait() method release the acquired monitor when it is called.
|
Thread.sleep() method keeps the lock or monitor even if thread is waiting.
|
|
1
|
wait is called from synchronized context only
|
sleep can be called without synchronized block
|
2
|
wait is called on Object
|
sleep is called on Thread
|
3
|
waiting thread can be awake by calling notify and notifyAll
|
sleeping thread can not be awaken by calling notify method.
|
4
|
wait is normally done on condition,Thread wait until a condition is
true
|
sleep is just to put your thread on sleep
|
5
|
wait release lock on object while waiting
|
sleep doesn’t release lock while waiting.
|
7
|
wait() is an instance specific method and only got wake up if some
other thread calls notify method on same object.
|
Thread.sleep() method is a static method and applies on current
thread,
|
8
|
waiting thread first acquires the lock and then goes into Runnable
state
|
sleeping thread immediately goes to Runnable state after waking up
|
9
|
if you want to implement inter-thread communication use wait method.
|
if you require a specified second of pause use sleep()
|
I hope this will clear some doubts.
notify() : The notify() method wakes up one thread
waiting for the lock (the first thread
that called wait() on that lock).
notifyAll() : The notifyAll() method wakes up all the
threads waiting for the lock; the JVM
selects one of the threads from the list of threads waiting for the lock
and wakes that thread up.
In the case of a single thread waiting for a lock, there is no significant
difference between notify() and notifyAll(). However, when there is more than
one thread waiting for the lock, in both notify() and notifyAll(), the exact
thread woken up is under the control of the JVM and you cannot programmatically
control waking up a specific thread.
At first
glance, it appears that it is a good idea to just call notify() to wake up one
thread; it might seem unnecessary to wake up all the threads. However, the
problem with notify()
is that the thread woken up might not be the suitable one to be woken up (the thread might be waiting for some
other condition, or the condition is still not satisfied for that thread etc). In
that case, the notify() might be lost and no other thread will wake up potentially
leading to a type of deadlock (the notification is lost and all other threads are
waiting for notification—forever).
To avoid this problem, it is
always better to call notifyAll() when there is more than one thread waiting
for a lock (or more than one condition on which waiting is done). The
notifyAll() method wakes up all threads, so it is not very efficient. however, this performance loss
is negligible in real world applications.
Important points about Thread-Safety in Java
Here is some points worth
remembering to write thread safe code in Java, these knowledge also helps you to avoid some serious
concurrency issues in Java like race condition or deadlock
in Java:
1) Immutable objects are by
default thread-safe because there state can not be modified once created. Since
String is immutable in Java, its inherently thread-safe.
3) Locking is one way of
achieving thread-safety in Java.
5) Example of thread-safe
class in Java: Vector, Hashtable, ConcurrentHashMap, String etc.
6) Atomic operations in Java are
thread-safe e.g. reading a 32 bit int from memory because its an atomic operation it
can't interleave with other thread.
7) local variables are also thread-safe because each thread
has there own copy and using local variables is good way to writing
thread-safe code in Java.
8) In order to avoid
thread-safety issue minimize sharing of objects between multiple thread.
9) Volatile
keyword in Java can also be used to instruct thread not to cache variables
and read from main memory and can also instruct JVM not to reorder or optimize
code from threading perspective.
To fix "check and act" race conditions
is to synchronized keyword and enforce locking which will make this operation
atomic and guarantees that block or method will only be executed by
one thread and result of operation will be visible to all threads once synchronized
blocks completed or thread exited form synchronized block.
Important
points about Daemon threads in Java
1. Any thread created by main thread, which runs main
method in Java is by
default non daemon because Thread inherits its
daemon nature from the Thread which creates it i.e. parent Thread
and since main thread is a non daemon thread, any other thread created from it
will remain non-daemon until explicitly made daemon by calling setDaemon(true).
2. Thread.setDaemon(true) makes a Thread daemon but it
can only be called before starting Thread in Java. It will throw IllegalThreadStateException if corresponding Thread is
already started and running.
3. Daemon Threads are suitable for doing
background jobs like housekeeping, Though I have yet to use it for any
practical purpose in application code.
let us know if you have used daemon thread in your java application for any practical purpose.
Difference
between Daemon and Non Daemon thread in Java
here are couple of differences
between daemon and user thread in Java:
2) Daemon Thread are treated differently than User Thread
when JVM terminates, finally blocks are not called, Stacks are not unwounded
and JVM just exits
How Synchronization works in Java ? Example of synchronized
block
Synchronization in
Java is possible by using java keyword "synchronized" and "volatile”.
you need synchronization for objects which are shared among multiple threads to avoid any corruption of state or any
kind of unexpected behavior
Synchronization in Java will only be needed if shared object is mutable. if your shared object is read only or immutable object you don't need synchronization despite running multiple threads. Same is true with what threads are doing with object if all the threads are only reading value then you don't require synchronization in java. JVM guarantees that Java synchronized code will only be executed by one thread at a time.
Synchronization in Java will only be needed if shared object is mutable. if your shared object is read only or immutable object you don't need synchronization despite running multiple threads. Same is true with what threads are doing with object if all the threads are only reading value then you don't require synchronization in java. JVM guarantees that Java synchronized code will only be executed by one thread at a time.
synchronized keyword involve locking and unlocking. before
entering into synchronized method or block thread needs to acquire the lock at
this point it reads data from main memory than cache and when it release the
lock it flushes write operation into main memory which eliminates memory inconsistency errors.
Any code written in synchronized block in java will be mutual exclusive and can only be executed
by one thread at a time
volatile variable, which will instruct JVM threads to read value of volatile variable from main memory and don’t cache it locally
Block synchronization in java is preferred over method synchronization in java
volatile variable, which will instruct JVM threads to read value of volatile variable from main memory and don’t cache it locally
Block synchronization in java is preferred over method synchronization in java
static synchronized
method locked on class object lock and non static synchronized method locks on current object (this)
Example of Static synchronized method in Java
Using synchronized keyword along with method is easy just apply
synchronized keyword in front of method. What we need to take care is that static synchronized method locked on class object
lock and non static synchronized method locks on current object (this). So
it’s possible that both static and non static java synchronized method running in parallel. This is the
common mistake a naive developer do while writing
java synchronized code.
public class Counter{
private static int count = 0;
public static
synchronized int getCount(){
return count;
}
public synchoronized setCount(int count){
this.count = count;
}
}
In this example of java synchronization code is not properly synchronized because
both getCount() and setCount() are not getting locked on same object and can run in parallel which
results in getting incorrect count. Here getCount() will lock in Counter.class object while
setCount() will lock on
current object (this). To make this code properly synchronized in java you need to either make both
method static or non static or use java synchronized block instead of java
synchronized method
Example of
synchronized block in Java
Using synchronized
block in java is also similar to using synchronized keyword in methods. Only important thing
to note here is that if object used to lock synchronized block of code, Singleton.class in below example is null
then java synchronized block will throw a NullPointerException.
public class Singleton{
private static volatile Singleton _instance;
public static Singleton getInstance(){
if(_instance == null){ ///-- otherwise NullPointerException
synchronized(Singleton.class){
if(_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
This is a classic example of double checked locking in Singleton.
Important points of synchronized keyword in Java
1. Synchronized keyword in Java is used to provide mutual exclusive
access of a shared resource with multiple threads in Java. Synchronization in java guarantees that no two threads
can execute a synchronized method which requires same lock simultaneously or
concurrently.
2. You can use java synchronized keyword only on synchronized method or
synchronized block.
3. When ever a
thread enters into java synchronized method or block it acquires a lock and
whenever it leaves java synchronized method or block it releases the lock. Lock is released even if thread leaves
synchronized method after completion or due to any Error or Exception.
4. Java Thread acquires an object level lock when it enters into an instance
synchronized java method and acquires a class
level lock when it enters into static synchronized java method.
5.java synchronized keyword is re-entrant in nature it means if a java
synchronized method calls another synchronized method which requires same lock then current thread which is holding lock can enter into that method
without acquiring lock.
6. Java Synchronization will throw NullPointerException if object used in java synchronized block is null e.g. synchronized (myInstance)
will throws NullPointerException if myInstance is null.
7. One Major disadvantage
of java synchronized keyword is that it doesn't allow concurrent
read which you can implement
using java.util.concurrent.locks.ReentrantLock.
8. One limitation
of java synchronized keyword is that it can only be used to control
access of shared object within the same JVM. If you have more than one JVM and need
to synchronized access to a shared file system or database, the java
synchronized keyword is not at all sufficient. You need to implement a kind of global lock for that.
9. Java
synchronized keyword incurs performance cost. Synchronized method in Java is very
slow and can degrade performance. So use synchronization in java when it absolutely requires
and consider using java synchronized block for synchronizing critical section
only.
10. Java
synchronized block is better than java synchronized method in java because by using synchronized
block you can only lock critical section of code and avoid locking whole method
which can possibly degrade performance. A good example of java synchronization around this concept is getInstance()
method Singleton class. See here.
11. Its possible that both
static synchronized and non static synchronized method can run simultaneously or concurrently because they lock on
different object.
12. From java 5 after change in Java memory model reads and writes are atomic for all
variables declared using volatile keyword (including long and double variables)
and simple atomic variable access is more efficient instead of accessing these
variables via synchronized java code. But it requires more care and attention
from the programmer to avoid memory consistency errors.
13. Java
synchronized code could result in deadlock or starvation while accessing by multiple thread if
synchronization is not implemented correctly. To know how
to avoid deadlock in java see
here.
14. According to the Java language specification you can not use java synchronized
keyword with constructor it’s
illegal and result in compilation error.
So you can not synchronized constructor in Java which seems logical because other threads cannot see the object
being created until the thread creating it has finished it.
15. You
cannot apply java synchronized keyword with variables and can not use java volatile
keyword with method.
16. Java.util.concurrent.locks extends capability provided
by java synchronized keyword for writing more sophisticated programs since they
offer more capabilities e.g. Reentrancy and interruptible locks.
17. java
synchronized keyword also synchronizes memory. In fact java synchronized synchronizes the whole of
thread memory with main memory.
18. Important method related
to synchronization in Java are
wait(), notify() and notifyAll() which
is defined in Object class.
19. Do not synchronize on non final field on synchronized block in Java. because reference of non final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all. example of synchronizing on non final field :
19. Do not synchronize on non final field on synchronized block in Java. because reference of non final field may change any time and then different thread might synchronizing on different objects i.e. no synchronization at all. example of synchronizing on non final field :
private
String lock = new String("lock");
synchronized(lock){
System.out.println("locking on :" + lock);
synchronized(lock){
System.out.println("locking on :" + lock);
}
any if you write synchronized code like above in java you may get warning "Synchronization on non-final field" in IDE like Netbeans and InteliJ
20. Its not recommended to use String object as lock in java synchronized block because string is immutable object and literal string and interned string gets stored in String pool. so by any chance if any other part of code or any third party library used same String as there lock then they both will be locked on same object despite being completely unrelated which could result in unexpected behavior and bad performance. instead of String object its advised to use new Object() for Synchronization in Java on synchronized block.
private static final String LOCK = "lock"; //not recommended
private static final Object OBJ_LOCK = new Object(); //better
public void process() {
synchronized(LOCK) {
........
}
}
21. From Java library Calendar and SimpleDateFormat classes are not thread-safe and requires external synchronization in Java to be used in multi-threaded environment.
any if you write synchronized code like above in java you may get warning "Synchronization on non-final field" in IDE like Netbeans and InteliJ
20. Its not recommended to use String object as lock in java synchronized block because string is immutable object and literal string and interned string gets stored in String pool. so by any chance if any other part of code or any third party library used same String as there lock then they both will be locked on same object despite being completely unrelated which could result in unexpected behavior and bad performance. instead of String object its advised to use new Object() for Synchronization in Java on synchronized block.
private static final String LOCK = "lock"; //not recommended
private static final Object OBJ_LOCK = new Object(); //better
public void process() {
synchronized(LOCK) {
........
}
}
21. From Java library Calendar and SimpleDateFormat classes are not thread-safe and requires external synchronization in Java to be used in multi-threaded environment.
Probably
most important point about synchronization in Java is that in the absence of
synchronized keyword or construct compiler, JVM and hardware are free to make
optimization, assumption, reordering or caching of code and variable which can
cause subtle concurrency bugs in code. By introducing synchronization may be
either using volatile or synchronized keyword we instruct compiler or JVM to
not to do that
"What is deadlock ?"
answer is simple , when two or more threads waiting for each other to release lock and get stuck for infinite time , situation is called deadlock . it will only happen in case of multitasking.
answer is simple , when two or more threads waiting for each other to release lock and get stuck for infinite time , situation is called deadlock . it will only happen in case of multitasking.
How
do you detect deadlock in Java ?
though this could have many answers , my version is first I would look the code if I see nested synchronized block or calling one synchronized method from other or trying to get lock on different object then there is good chance of deadlock if developer is not very careful.
though this could have many answers , my version is first I would look the code if I see nested synchronized block or calling one synchronized method from other or trying to get lock on different object then there is good chance of deadlock if developer is not very careful.
write code which will result in
deadlock ?
here is one of my version
public void method1(){
synchronized(String.class){
System.out.println("Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
}
}
}
public void method2(){
synchronized(Integer.class){
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}
If method1() and method2() both will be called by two or many threads , there is a good chance of deadlock because if thead 1 aquires lock on Sting object while executing method1() and thread 2 acquires lock on Integer object while executing method2() both will be waiting for each other to release lock on Integer and String to proceed further which will never happen.
here is one of my version
public void method1(){
synchronized(String.class){
System.out.println("Aquired lock on String.class object");
synchronized (Integer.class) {
System.out.println("Aquired lock on Integer.class object");
}
}
}
public void method2(){
synchronized(Integer.class){
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {
System.out.println("Aquired lock on String.class object");
}
}
}
If method1() and method2() both will be called by two or many threads , there is a good chance of deadlock because if thead 1 aquires lock on Sting object while executing method1() and thread 2 acquires lock on Integer object while executing method2() both will be waiting for each other to release lock on Integer and String to proceed further which will never happen.
How to fix deadlock
? or How to avoid deadlock in Java ?
if you have looked above code carefully you may have figured out that real reason for deadlock is not multiple threads but the way they access lock , if you provide an ordered access then problem will be resolved , here is
the fixed version.
public void method1(){
synchronized(Integer.class){//First
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {//Second
System.out.println("Aquired lock on String.class object");
}
}
}
public void method2(){
synchronized(Integer.class){//First
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {//Second
System.out.println("Aquired lock on String.class object");
}
}
}
Now there would not be any deadlock because both method is accessing lock on Integer and String object in same order . so if thread A acquires lock on Integer object , thread B will not proceed until thread A releases Integer lock , same way thread A will not be blocked even if thread B holds String lock because now thread B will not expect thread A to release Integer lock to proceed further.
if you have looked above code carefully you may have figured out that real reason for deadlock is not multiple threads but the way they access lock , if you provide an ordered access then problem will be resolved , here is
the fixed version.
public void method1(){
synchronized(Integer.class){//First
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {//Second
System.out.println("Aquired lock on String.class object");
}
}
}
public void method2(){
synchronized(Integer.class){//First
System.out.println("Aquired lock on Integer.class object");
synchronized (String.class) {//Second
System.out.println("Aquired lock on String.class object");
}
}
}
Now there would not be any deadlock because both method is accessing lock on Integer and String object in same order . so if thread A acquires lock on Integer object , thread B will not proceed until thread A releases Integer lock , same way thread A will not be blocked even if thread B holds String lock because now thread B will not expect thread A to release Integer lock to proceed further.
When
InvalidMonitorStateException is thrown? Why?
This exception is thrown when you try to call
wait()/notify()/notifyAll() any of these methods for an Object from a point in
your program where u are
NOT having a lock on that object.
That is not from synchronized method.
What happens when I
make a static method as synchronized?
Synchronized static methods have a lock on the class "Class", so when a thread enters a
synchronized static method, the class itself gets locked by the
thread monitor and no other thread can enter any static synchronized methods on
that class.
This is unlike instance methods, as multiple threads can access "same
synchronized instance methods" at same time for different instances
How to find a deadlock has occurred in Java?
How to detect a Deadlock in Java?
Earlier versions of Java had no mechanism to
handle/detect deadlock. Since JDK 1.5 there are some powerful methods added in
the java.lang.management package to diagnose and detect deadlocks. The
java.lang.management.ThreadMXBean interface is management interface for the
thread system of the Java virtual machine. It has two methods which can
leveraged to detect deadlock in a Java application.
·
findMonitorDeadlockedThreads() - This method can
be used to detect cycles of threads that are in deadlock waiting to acquire
object monitors. It returns an array of thread IDs that are deadlocked waiting
on monitor.
·
findDeadlockedThreads() - It returns an
array of thread IDs that are deadlocked waiting on monitor or ownable
synchronizers.
How
to use Comparator and Comparable in Java? With example
Comparator
vs Comparable in Java
Here are some of the common differences, which is worth remembering
to answer this question if asked during a telephonic or face to face interview:
If you see then logical difference between these two is Comparator in Java compare two objects provided to him, while Comparable interface compares "this" reference with the object specified
1) Comparator in Java is defined in java.util package while Comparable interface in Java is defined in java.lang package, which very much says that Comparator should be used as an utility to sort objects which Comparable should be provided by default.
1) Comparator in Java is defined in java.util package while Comparable interface in Java is defined in java.lang package, which very much says that Comparator should be used as an utility to sort objects which Comparable should be provided by default.
2) Comparator interface in Java has method public int compare (Object o1, Object o2) which returns a negative
integer, zero, or a positive integer as the first argument is less than, equal
to, or greater than the second. While Comparable interface has method public int compareTo(Object o) which returns a negative
integer, zero, or a positive integer as this object is less than, equal to, or
greater than the specified object.
If any class implement Comparable interface in Java then collection of that object either List or Array can be sorted automatically by using Collections.sort() or Arrays.sort() method and object will be sorted based on there natural order
defined by CompareTo method.
in simple words
inner
join retrieve the matched rows only
where as
outer
join retrieve the matched rows from one table
and all rows in other table ....the result depend on which one you are using
LEFT ( MATCHED ROWS IN RIGHT TABLE AND ALL ROWS IN LEFT TABLE )
RIGHT ( MATCHED ROWS IN LEFT TABLE AND ALL ROWS IN RIGHT TABLE )
or
FULL ( ALL ROWS IN ALL TABLES IT DOESN'T MATTERS EVEN MATCH IS
THERE OR NOT )
Inner and outer
joins SQL examples and the Join block
In this post I'll show you how to do all the main types of Joins with clear SQL examples. The examples are written for Microsoft SQL Server, but very similar syntax is used in Oracle, MySQL and other databases.
Joins can be said to be INNER or OUTER joins,
and the two tables involved are referred to as LEFT and RIGHT. By combining
these two concepts you get all the various types of joins in join land: Inner,
left outer, right outer, and the full outer join.
Tables used for SQL Examples
In the screen shots
I've configured Datamartist to only show the name columns to save space. The
SQL code shown is "Select *" so it will return all the columns. You
can see that in the Datamartist tool the type of join is
selected by just checking the parts of the venn diagram that contain the rows
you want.
1) Inner Join SQL Example
select * from
dbo.Students S INNER JOIN dbo.Advisors A ON S.Advisor_ID=A.Advisor_ID
2) Left Outer Join SQL Example
select * from
dbo.Students S LEFT OUTER JOIN dbo.Advisors A ON S.Advisor_ID=A.Advisor_ID
4) Full Outer Join SQL Example
select * from
dbo.Students S FULL OUTER JOIN dbo.Advisors A ON S.Advisor_ID=A.Advisor_ID
5) SQL example for
just getting the rows that don't join
select * from
dbo.Students S FULL OUTER JOIN dbo.Advisors A ON S.Advisor_ID=A.Advisor_ID
where A.Advisor_ID is null or S.Student_ID is null
6) SQL example for just rows from one table that don't join
select * from
dbo.Students S FULL OUTER JOIN dbo.Advisors A ON S.Advisor_ID=A.Advisor_ID
where A.Advisor_ID is null
But what about the duplicate row thing?
Now, since in this case we had a simple one to
one relationship, the number of rows that were returned made the venn diagrams
make sense, and add up pretty normally with table one and two.
What happens if the
data in the tables are not a simple one to one relationship? What happens if we
add one duplicate advisor with the same ID, but a different name?
A join will create a row for every combination
of rows that join together. So if there are two advisors with the same key, for
every student record that has that key, you will have two rows in the inner
part of the join. The advisor duplicate makes duplicate student records for
every student with that advisor.
You can see how this could add up to a lot of
extra rows. The number of rows is the product of the two sets of joining rows.
If the tables get big, just a few duplicates will cause the results of a join
to be much larger than the total number of rows in the input tables- this is
something you have to watch very carefully when joining- check your row counts.
So there you have it.
If you want to try joining tables with the Datamartist tool- give it a try. It's a super fast install, and you'll
be joining like a pro in no time.
Self Join
Description
A SELF JOIN is another type of join in sql which is used to join
a table to itself, specially when the table has a FOREIGN KEY which references
its own PRIMARY KEY.
What is a self join? Explain it with an
example
|
|||||||||||||||||
Let’s illustrate
the need for a self join with an example. Suppose we have the following table
– that is called employee. The employee table has 2 columns – one for the
employee name (called employee_name), and one for the employee location
(called employee_location):
Now, suppose we want to find out
which employees are from the same location as the employee named Joe.
In this example, that location would be New York. What we could do is write a
nested SQL query (basically a query within another query – which is also
called a subquery) like this:
A nested subquery
for such a simple question is inefficient. Is there a more efficient and
elegant solution to this problem?
It turns out that
there is – we can use something called a self join. A self join is basically
when a join is done on the same table – the best way to think of it is that
we have 2 identical copies of the table, and we want to join them based on
some condition that we define. That condition will be our join predicate. If
you need a refresher on join predicates (or just joins in general) then check
this link out: Inner vs. Outer joins
Now, the key
question is what would be our join predicate in this example? Well, we want
to find all the employees who have the same location as Joe – so if we are
doing a join we would want to make sure that the location is the same and
that the employee name is Joe. So, our join predicate would be where
e1.employee_location = e2.employee_location AND employee_name =
"Joe". Note that e1 and e2 will represnt the 2 employee tables that
we are doing a self join on. Now, here is what the SQL for a self join would
look like to solve this problem:
This query will
return the names Joe and Jack – since Jack is the only other person who lives
in New York like Joe.
Generally, queries
that refer to the same table can be greatly simplified by re-writing the
queries as self joins. And, there is definitely a performance benefit for
this as well.
|
Java Programming: Explore the advanced coding features of JDK 1.5
Metadata
(Annotations)
Takeaway: The Java programming language is getting a
much needed upgrade to the Java Development Kit 1.5. Examine several Java
coding specifications and features of JDK 1.5 and get ahead of the programming
curve.
Sun is planning to release a major revision of the Java programming language in summer 2004. This release is code named "Tiger," but it will receive the official designation of JDK 1.5.
This version of the Java language will incorporate Java Specification Requests 14 and 175 (JSR-14, JSR-175). It will also have major enhancements for runtime performance, scalability, manageability, and monitoring.
In this article, we'll discuss several of the new language features of JDK 1.5, including:
- Generics—Provides compile-time type safety for
collections and eliminates the need for casting every time you get an
object out of Collections.
- Enhanced For loop—Eliminates error-proneness
of iterators.
- Autoboxing/unboxing—Eliminates need of manual conversion between primitive types
(such as double) and wrapper types (such as Double).
- Typesafe enums—Provides all benefits of
the Typesafe enum pattern.
- Static import—Eliminates the need for
using class names prior to using
the static member variables of other classes. This will make the code
a bit neater.
- Metadata—Allows programmers to avoid
writing boiler plate code and gives the opportunity for declarative programming.
Let's discuss each feature in detail and take a look at some examples.
Generics
Generics is one of the coolest features of JDK 1.5. By introducing generics, we will have compile-time type safety and possibly fewer ClassCastExceptions during run time. In JDK 1.5, you can declare the type of objects one collection will accept/return. In JDK 1.4, creating a List of employee names requires a collection object like the following statement:
List listOfEmployeeName = new ArrayList();
In JDK 1.5, you would use this statement:
List<String> listOfEmployeeName = new ArrayList<String>();
The cool part is that if you try to insert something that's not a string, you will find out at compile time and then you can fix the problem. Without generics, you discover such a bug when your customer calls and tells you that the program you shipped crashed with a ClassCastException.
The other cool thing is that you don't have to cast when you get an element out of the collection. So instead of this type of statement:
String employeeName = ((String) listOfEmployee.get(i));
It's simply:
String employeeName = listOfEmployee.get(i);
Casting objects without knowing the type of object is not good, and more importantly, it can fail at run time. Suppose the user accidentally passes in a collection that contains string buffers rather than strings. In Listing A, the client is required to pass in a collection of strings that the compiler can't enforce.Listing B shows how the same method looks with generics.
Now it's clear from the method signature that the input collection must contain only strings. If the client tries to pass in a collection of string buffers, the program won't compile. And notice that the method doesn't contain any casts. It's one line shorter and, once you get used to reading generics, it's clearer too.
Enhanced For Loop
Here's the syntax for the For loop in the current version of the JDK:
void printAll(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); ) {
Employee emp = (Employee)i.next();
System.out.println(emp.getName());
}
}
Now here's the same method with an enhanced For statement:
void printAll(Collection c) {
for (Object o : c)
System.out.println((TimerTask)o).getName());
}
In this For loop, you should read the ":" as "in," so the example reads "for Object o in c". You can see this For loop has more readability.
Autoboxing and unboxing
In Java, we have primitive data types and wrapper classes around these primitive types. Most often programmers need to convert one type to another. Take a look at the code snippet in Listing C.
Notice how messy the inner-loop code that calculates ageAfterTenYear looks. Now take a look at the same program rewritten with autoboxing, as shown in Listing D.
One thing worth noting: Previously, if you unboxed Null, it became zero. In this code, the compiler would automatically convert Integer to int and add 10 to it, then convert that back to Integer.
Typesafe enums
Typesafe enums provide the following features:
- They provide compile-time type safety.
- They are objects, so you can put them
in collections.
- They are implemented as a class, so
you can add some methods.
- They
provide a proper name space for the enumerated type.
- Their
printed values are informative—if you print an int enum, you just
see a number, which may not be that informative.
Example 1:
enum Season { winter, spring, summer, fall }
Example 2:
public enum Coin {
penny(1), nickel(5), dime(10), quarter(25);
Coin(int value) { this.value = value; }
private final int value;
public int value() { return value; }
}
Static imports
Static imports make code more readable. Currently, you use constants defined in other classes, like this:
import org.yyy.pkg.Increment;
class Employee {
public Double calculateSalary(Double salary{
return salary + Increment.INCREMENT * salary;
}
}
But with static import, we can use those constants without providing the name of the class prior to constant name, like this:
import static org.yyy.pkg.Increment;
class Employee {
public Double calculateSalary(Double salary{
return salary + INCREMENT * salary;
}
}
Note that we are able to call the INCREMENT constant without using the class name Increment.
Metadata
The metadata feature is focused on making a developer's life simpler with the support of tools provided by vendors. Take a look at the code in Listing E.
With metadata support, you can write the code in Listing E like this:
import org.yyy.hr;
public class Employee {
@Remote public String getName() {
...
}
@Remote public public String getLocation() {
...
}
}
As you can see, all the boilerplate's code is gone.
The new features and specifications that will be implemented in JDK 1.5 offer the Java programming community many more options for writing robust, scalable code. Serious Java programmers would do well to begin familiarizing themselves with the pending version of the Java programming language.
Java 1.5
Generics: -
it provides compile time type-safety and ensures that you only insert correct Type in
collection and avoids ClassCastException in runtime.What is Bounded and Unbounded wildcards in Generics ?
Bounded Wildcards are those which impose bound on Type. there are two kinds of Bounded wildcards <? extends T> which impose an upper bound by ensuring that type must be sub class of T and <? super T> where its imposing lower bound by ensuring Type must be super class of T
5. How to write a generic method which accepts generic argument and return Generic Type?
instead of using raw type you need to use Generic Type like T, E or K,V which are well known placeholders for Type, Element and Key, Value. Look on Java Collection framework for examples of generics methods.
public V put(K key, V value) {
return cache.put(key, value);
}
9. Can we use Generics with Array?
Array doesn't support Generics . prefer List over Array because List can provide compile time
type-safety over Array.
10. How can you suppress unchecked warning in Java ?
javac compiler for Java 5 generates unchecked warnings if you use combine raw types and generics types e.g.
10. How can you suppress unchecked warning in Java ?
javac compiler for Java 5 generates unchecked warnings if you use combine raw types and generics types e.g.
List<String> rawList = new ArrayList()
Note: Hello.java uses unchecked or unsafe operations.;
Note: Hello.java uses unchecked or unsafe operations.;
which can be suppressed by using @SuppressWarnings("unchecked") annotation.
Difference between
List<?> and List<Object> in Java?
List<?> listOfAnyType;
List<Object> listOfObject = new ArrayList<Object>();
List<String> listOfString = new ArrayList<String>();
List<Integer> listOfInteger = new ArrayList<Integer>();
listOfAnyType = listOfString; //legal
listOfAnyType = listOfInteger; //legal
listOfObjectType = (List<Object>) listOfString; //compiler error - in-convertible types
7. Write a program to implement LRU cache using Generics ?
List<Object> listOfObject = new ArrayList<Object>();
List<String> listOfString = new ArrayList<String>();
List<Integer> listOfInteger = new ArrayList<Integer>();
listOfAnyType = listOfString; //legal
listOfAnyType = listOfInteger; //legal
listOfObjectType = (List<Object>) listOfString; //compiler error - in-convertible types
7. Write a program to implement LRU cache using Generics ?
This is an exercise for anyone who like Coding
in Java. One hint is that LinkedHashMap can be used implement fixed
size LRU cache where one needs to remove eldest entry when Cache is full. LinkedHashMap provides a method called removeEldestEntry() which is called by put() and putAll() and can be used to instruct to remove
eldest entry. you are free to come up with your own implementation as
long as you have a written a working version along with JUnit
test.
Read more: http://javarevisited.blogspot.com/2012/06/10-interview-questions-on-java-generics.html#ixzz2RzKTZEbK
Question 6 – When does an Object becomes
eligible for Garbage collection in Java ?
Answer : An object becomes eligible for garbage collection when there is no live
reference for that object or it can not be reached by any live thread. Cyclic reference doesn’t count as
live reference and if two objects are pointing to each other and there is no
live reference for any of them, than
both are eligible for GC. Also Garbage collection thread is a daemon thread which will
run by JVM based upon GC algorithm and when runs it collects all objects which
are eligible for GC.
Question 7 - What is finalize method in Java ?
When does Garbage collector calls finalize method in Java ?
Answer : Finalize method in Java also called
finalizer is a method defined in java.lang.Object and called by Garbage
collector before collecting any object which is eligible for GC. Finalize() method provides last
chance to object to do cleanup and free any remaining resource
Question 9 -Can we force Garbage collector to run at any time ?
Answer :
No, you can not force Garbage collection in Java. Though you can request it by calling Sytem.gc() or its cousin Runtime.getRuntime().gc(). It’s not guaranteed that GC will run immediately as result of
calling these method.
Question 1 - What is structure of Java Heap ? What is Perm Gen space in Heap ?
Answer : In order to better perform in Garbage
collection questions in any Java interview, It’s important to have basic
understanding of Java Heap space. To learn more about heap, see my
post 10 points on Java heap space.
By the way Heap is divided into different generation e.g. new generation,
old generation and PermGen space.PermGen space
is used to store class’s metadata and
filling of PermGen space can cause java.lang.OutOfMemory:PermGen
space. Its also worth noting to remember JVM option to configure PermGen space in Java.
Question 2 - How do you identify minor and major garbage collection in Java?
Answer: Minor collection prints “GC” if garbage collection logging is enable
using –verbose:gc or -XX:PrintGCDetails, while Major collection prints “Full GC”.
Question 3 - What is difference between ParNew and DefNew Young Generation Garbage collector?
Answer : ParNew and DefNew is two young
generation garbage collector. ParNew is a
multi-threaded GC used along with
concurrent Mark Sweep while DefNew is single threaded GC used
along with Serial Garbage Collector.
Question 5 - What is difference between Serial
and Throughput Garbage collector?
Answer : Serial Garbage collector is a stop
the world GC which stops application thread from running during
both minor and major collection.
Throughput garbage collector is parallel collector where minor and major collection happens in parallel taking full advantage of all the system resources available like multiple processor.
Question 10 - Does Garbage collection
occur in permanent generation space in JVM?
Garbage Collection does occur in PermGen space and if PermGen space is full or cross a threshold, it can trigger Full GC. If you look at output of GC you will find that PermGen space is also garbage collected. This is why correct sizing of PermGen space is important to avoid frequent full GC. You can control size of PermGen space by JVM options -XX:PermGenSize and -XX:MaxPermGenSize.
Question 11 : How to you monitor garbage collection activities?
Garbage Collection does occur in PermGen space and if PermGen space is full or cross a threshold, it can trigger Full GC. If you look at output of GC you will find that PermGen space is also garbage collected. This is why correct sizing of PermGen space is important to avoid frequent full GC. You can control size of PermGen space by JVM options -XX:PermGenSize and -XX:MaxPermGenSize.
Question 11 : How to you monitor garbage collection activities?
Answer : You can monitor garbage
collection activities either offline or
real-time. You can use tools like JConsole and VisualVM VM
with its Visual GC plug-in to monitor real time garbage collection activities and memory status of JVM or you can
redirect Garbage collection output to a log file for offline analysis by
using -XlogGC=<PATH> JVM
parameter. Anyway you should always enable GC options like -XX:PrintGCDetails -X:verboseGC and -XX:PrintGCTimeStamps as
it doesn't impact application performance much
but provide useful states for performance monitoring.
JAVA HEAP Space:
10 Points about Java Heap Space
1. Java
Heap Memory is part of memory allocated to JVM by Operating System.
2.
Whenever we create objects they are created inside Heap in Java.
3. Java
Heap space is divided into three regions or generation for sake of garbage
collection called New Generation, Old or tenured Generation or Perm Space.
Permanent generation is garbage collected during full gc in hotspot JVM.
4. You can increase or change size of Java Heap space by using JVM command
line option -Xms, -Xmx and
-Xmn. don't forget to add word "M" or
"G" after specifying size to indicate Mega or Gig. for example you
can set java heap size to 258MB by executing following command java -Xmx256m HelloWord.
5. You can use either JConsole or Runtime.maxMemory(), Runtime.totalMemory(), Runtime.freeMemory() to
query about Heap size programmatic in Java. See my post How to find memory usage in Java program for more details.
6. You can use command "jmap" to
take Heap dump in Java and "jhat" to analyze that
heap dump.
7. Java Heap space is different than Stack which
is used to store call hierarchy and local variables.
8. Java Garbage
collector is responsible for reclaiming memory from dead object and
returning to Java Heap space.
9. Don’t panic when you get java.lang.OutOfMemoryError,
sometimes its just matter of increasing heap size but if it’s recurrent then
look for memory leak in Java.
10. Use
Profiler and Heap dump Analyzer tool to understand Java Heap space and how much
memory is allocated to each object.
What is Heap space in Java?
When a Java program started Java Virtual
Machine gets some memory from Operating System. Java Virtual
Machine or JVM uses this memory for all its need and part of
this memory is call java heap memory. Heap in Java generally located at bottom of address space
and move upwards. whenever we create object using new operator or by any
another means object is allocated memory
from Heap and When object dies or garbage collected ,memory goes back to Heap
space in Java,
How to increase size of Java Heap
Default size of Heap space in
Java is 128MB on most of 32 bit
Sun's JVM but
its highly varies from JVM to JVM e.g. default maximum and start heap
size for the 32-bit Solaris Operating System (SPARC Platform Edition) is -Xms=3670K and -Xmx=64M and Default
values of heap size parameters on 64-bit systems have been increased up by
approximately 30%. Also if you are using throughput garbage collector in Java
1.5 default maximum heap size of JVM would be Physical Memory/4 and
default initial heap size would be Physical Memory/16. Another way to find
default heap size of JVM is to start an application with default heap
parameters and monitor in using JConsole which is available on JDK
1.5 onwards, on VMSummary tab you will be able to see maximum heap size.
By the way you can increase size of java
heap space based on your application need and I always
recommend this to avoid using default JVM heap values. if
your application is large and lots of object created you can change size of heap space by using
JVM options -Xms and -Xmx.
Xms denotes starting size of Heap while -Xmx denotes maximum size
of Heap in Java. There is another
parameter called -Xmn which denotes Size of new generation of Java Heap
Space. Only thing is you can not change the size of Heap in Java
dynamically, you can only provide Java Heap Size parameter while starting JVM.
I have shared some more useful JVM options related to Java Heap space and
Garbage collection on my post 10 JVM options Java programmer must know, you may find useful.
HEAP SPACE DIVISION:
As we know objects are created inside heap memory and Garbage collection is a process which removes
dead objects from Java Heap space and returns memory back to Heap in Java. For the sake
of Garbage collection Heap is divided into three main regions named as New Generation, Old or Tenured Generation
and Perm space.
New Generation
of Java Heap is part of Java Heap memory where newly
created object are stored,
During the course of application many objects created and died but those remain live they got moved to Old or Tenured Generation by Java Garbage collector thread on Major or full garbage
collection.
Perm space of Java Heap
is where JVM stores Meta data about classes and methods, String pool and Class
level details.
"java.lang.OutOfMemoryError:
PermGen space" error message comes when the permanent generation of
Java Heap is full, the application will fail to load a class or to
allocate an interned string.
Java Heap dump
Java Heap dump is a snapshot of
Java Heap Memory at a particular time. This is very useful to analyze or
troubleshoot any memory leak in Java or any Java.lang.OutOfMemoryError.
There are tools available inside JDK which helps you to take heap dump and
there are heap analyzer available tool which helps you to analyze java heap
dump. You can use "jmap" command to get java heap dump, this will
create heap dump file and then you can use "jhat - Java Heap
Analysis Tool" to analyze those heap dumps.
Steps to increase PermGen Heap Space in Tomcat:
1) Go to Tomcat installation directory i.e C:\Program
Files\Apache Software Foundation\Apache
Tomcat 7.0.14\bin in Windows and something similar in linux.
2) Add JAVA_OPTS in your
catalina.bat or Catalina.sh
In Windows:
set
JAVA_OPTS="-Xms1024m -Xmx10246m -XX:NewSize=256m -XX:MaxNewSize=356m -XX:PermSize=256m
-XX:MaxPermSize=356m"
3) Restart Tomcat.
Permanent Generation
JVM has an internal representation of
those Java
objects and those internal representations are stored in the heap (in the young
generation or the tenured generation).
Our JVM also has an internal representation of
the Java classes and those are stored in the permanent generation
Conclusion
·
Permanent generation of heap is used to store String pool and
various Meta data required by JVM related to Class, method and other java
primitives. The
permanent generation can be garbage collected like other generations.
·
The permanent generation is additional memory to the java heap.
·
in most of JVM default size of Perm Space is around
"64MB"
·
-XX:MaxPermSize controls the maximum
memory used by the permanent generation.
·
-XX:PermSize controls the initial
memory used by the permanent generation.
Read
more: http://javarevisited.blogspot.com/2011/09/javalangoutofmemoryerror-permgen-space.html#ixzz2S4PvC7pC
What is java.lang.OutOfMemoryError in Java
Types
of OutOfMemoryError in Java
I have seen mainly two types of OutOfMemoryError in Java:
1) Java.lang.OutOfMemoryError: Java heap space
2) Java.lang.OutOfMemoryError: PermGen space
Though both of them occur because JVM ran out of memory they are quite different to each other and there solutions are independent to each other.
1) Java.lang.OutOfMemoryError: Java heap space
2) Java.lang.OutOfMemoryError: PermGen space
Though both of them occur because JVM ran out of memory they are quite different to each other and there solutions are independent to each other.
2) Java.lang.OutOfMemoryError:
PermGen space (Reasons Below)
1. you can easily ran out of memory if you have too many classes or huge number of Strings in your project
1. you can easily ran out of memory if you have too many classes or huge number of Strings in your project
2. Another
reason of "java.lang.OutOfMemoryError: PermGen" is memory leak through
Classloaders
3. Another reason
of OutOfMemoryError in PermGen space is if any thread started by application doesn't exit
when you undeploy your application.
4. avoid using "-Xnoclassgc" in J2EE environment especially with AppServer
4. avoid using "-Xnoclassgc" in J2EE environment especially with AppServer
How to Solve:
increase heap memory
of tomcat in catalina.bat or catalina.sh.
Tomcat
to Solve OutOfMemoryError in PermGen Space
From tomcat
> 6.0 onward tomcat provides memory leak detection feature which can
detect many common memory leaks on web-app perspective e.g ThreadLocal memory
leaks, JDBC driver registration, RMI targes, LogFactory and Thread spawned by
web-apps. You can check complete details on
htp://wiki.apache.org/tomcat/MemoryLeakProtection you can also detect memory
leak by accessing manager application which comes with tomcat, in case you are
experiencing memory leak on any java web-app its good idea to run it on tomcat.
Tools to investigate and fix OutOfMemoryError in Java
1) Visualgc
2)
Jmap
3) Jhat
4) Eclipse memory analyzer
Difference
between "java.lang.OutOfMemoryError: Java heap space" and
"java.lang.OutOfMemoryError: PermGen space"
If you are familiar with different generations on heap and How
garbage collection works in java and
aware of new, old and permanent generation of heap space then you would have
easily figured out this OutOfMemoryError in Java. Permanent
generation of heap is used to store String pool and various Meta data required
by JVM related to Class, method and other java primitives. Since in most of JVM default size of Perm
Space is around "64MB" you can
easily ran out of memory if you have too many classes or huge number of Strings
in your project. Important point to remember is that it doesn't depends
on –Xmx value so no matter how big your
total heap size you can ran OutOfMemory in perm space. Good think is you can
specify size of permanent
generation using JVM options "-XX:PermSize" and "-XX:MaxPermSize" based on your project need.
One small thing to remember is that "=" is used to separate parameter and value while specifying size of perm space in heap while "=" is not required while setting maximum heap size in java, as shown in below example.
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
One small thing to remember is that "=" is used to separate parameter and value while specifying size of perm space in heap while "=" is not required while setting maximum heap size in java, as shown in below example.
export JVM_ARGS="-Xmx1024m -XX:MaxPermSize=256m"
Another reason of "java.lang.OutOfMemoryError: PermGen"
is memory leak
through Classloaders and it’s very often surfaced in WebServer and application
server like tomcat, webshere, glassfish or weblogic. In Application server different
classloaders are used to load different web application so that you can deploy
and undeploy one application without affecting other application on same
server, but while undeploying if container some how keeps reference of any class loaded by application
class loader than that class and all other related class will not be garbage
collected and can quickly fill the PermGen space if you deploy and
undeploy your application many times. "java.lang.OutOfMemoryError:
PermGen” has been observed many times in tomcat in our last project but
solution of this problem are really tricky because first you need to know which
class is causing memory leak and then you need to fix that. Another reason of
OutOfMemoryError in PermGen space is if any thread started by application
doesn't exit when you undeploy your application.
Another rather unknown but interesting cause of
"java.lang.OutOfMemoryError: PermGen" we found is introduction of JVM
options "-Xnoclassgc".
This option sometime used to avoid loading and unloading of classes when there
is no further live references of it just to avoid performance hit due to
frequent loading and unloading, but using this option is J2EE environment can
be very dangerous because many framework e.g. Struts, spring etc uses
reflection to create classes and with frequent deployment and undeployment you
can easily ran out of space in PermGen if earlier references was not
cleaned up. This instance also points out that some time bad JVM arguments or
configuration can cause OutOfMemoryError in Java.
So conclusion is avoid using "-Xnoclassgc" in J2EE environment especially with
AppServer.
What
exactly are class loaders in Java?
1. A class
loader is an object in Java
responsible for finding binary representations of Java classes and loading them
into the JVM.
2. All
JVMs begin with a boot class loader responsible for
loading the user's initial class, along with
some of the built-in types like
Class and SecurityManager.3 But users can
provide their own class loaders by extending ClassLoader or any of it's derivatives to find classes from other sources. For example, a custom class
loader could generate its own classes by composing its own bytecode, or it
could find classes from a networked source.
CLASS LOADING INITIALIZATION:
When Class is loaded in Java
Class loading is done by ClassLoaders in Java which
can be implemented to
1. eagerly load a class as soon as another class references it or
If Class is loaded before its actually being used it can sit inside
before being initialized. I believe this may vary from JVM to JVM. While its guaranteed by JLS that a class
will be loaded when there is a need of static
initialization.
When a Class is initialized in Java
After class loading, initialization of class
takes place which means initializing all static members of
class. A Class is initialized in Java when :
1) an Instance of class is
created using either new() keyword or using reflection using class.forName(), which may
throw ClassNotFoundException in Java.
2) an
static method of Class is invoked.
3) an
static field of Class is assigned.
4) an
static field of class is used which is not a constant variable.
Reflection can also
cause initialization of class. Some methods of java.lang.reflect package may
cause class to be initialized. JLS Strictly says that a class should not be
initialized by any reason other than above.
How
Class is initialized in Java
1) Classes are initialized from top to bottom so field declared on top initialized
before field declared in bottom
2) Super
Class is initialized before Sub Class or derived class in Java
3) If Class initialization is triggered due to access of static
field, only Class which has declared static field is initialized and it
doesn't trigger initialization of super class or sub class even if static field
is referenced by Type of Sub Class, Sub
Interface or by
implementation class of interface.
5) static fields are initialized during static
initialization of class while non static fields are initialized when instance
of class is created. It means static
fields are initialized before non static fields in Java.
6)non
static fields are initialized by constructors
in Java. sub
class constructor implicitly call super class constructor before doing any
initialization, which guarantees that non static or instance variables of super
class is initialized before sub class.
Why String is
immutable or final in Java
1.
For
StringPool
facility- same string referenced by many references. No problem because of
immutable
2.
String is
immutable, no one can change its contents once created which guarantees hashCode of String to be
same on multiple invocation
1)Imagine StringPool facility without making string immutable , its
not possible at all because in case of string pool one string object/literal e.g. "Test"
has referenced by many reference variables , so if any one of them change the value others
will be automatically gets affected i.e. lets say
String A = "Test"
String B = "Test"
Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.
2.Another reason of Why String is immutable in Java is to allow String to cache its hashcode , being immutable String in Java caches its hashcode and do not calculate every time we call hashcode method of String, which makes it very fast as hashmap key to be used in hashmap in Java. This one is also suggested by Jaroslav Sedlacek in comments below. In short because String is immutable, no one can change its contents once created which guarantees hashCode of String to be same on multiple invocation.
3) Another good reason of Why String is immutable in Java suggested by Dan Bergh Johnsson on comments is: The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects.
Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"
String A = "Test"
String B = "Test"
Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.
2.Another reason of Why String is immutable in Java is to allow String to cache its hashcode , being immutable String in Java caches its hashcode and do not calculate every time we call hashcode method of String, which makes it very fast as hashmap key to be used in hashmap in Java. This one is also suggested by Jaroslav Sedlacek in comments below. In short because String is immutable, no one can change its contents once created which guarantees hashCode of String to be same on multiple invocation.
3) Another good reason of Why String is immutable in Java suggested by Dan Bergh Johnsson on comments is: The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects.
Had String been mutable, a request to load "java.io.Writer" could have been changed to load "mil.vogoon.DiskErasingWriter"
Why character array is better than String for Storing
password in Java
1) Since Strings
are immutable in Java if you store password as plain text it will
be available in memory until Garbage collector clears it and
since String are used in String pool for
reusability there is pretty high chance that it will be remain in memory
for long duration, which pose a security threat. Since any one
who has access to memory dump can find the password in clear text and that's
another reason you should always used an encrypted password than plain text.
Since Strings are immutable there is no way contents of Strings can be changed
because any change will produce new String, while if you char[] you can still set all his
element as blank or zero. So Storing password in character array
clearly mitigates security risk of stealing password.
2) Java itself recommends using getPassword() method of JPasswordField which
returns a char[] and deprecated getText() method which returns password in clear text
stating security reason. Its good to
follow advice from Java team and adhering to standard
rather than going against it.
What
is Marker interfaces in Java and why required
Why Marker or Tag interface
do in Java
1) Looking carefully on
marker interface in Java e.g. Serializable, Clonnable and Remote it
looks they are used to indicate something to compiler or JVM. So if JVM
sees a Class is Serializable it done some special operation on it, similar way
if JVM sees one Class is implement Clonnable it performs some operation to support cloning.
Same is true for RMI and Remote interface. So in short Marker interface
indicate, signal or a command to Compiler or JVM.
Where Should I use Marker interface in Java
Apart from using built in
marker interface for making a class Serializable or Clonnable. One can also
develop his own marker interface. Marker interface is a good way to classify
code. You can create marker interface to logically divide your code and if you
have your own tool than you can perform some pre-processing operation on those
classes. Particularly useful for developing API and framework like Spring or Struts.
Annotation is better choice than marker interface and JUnit
is a perfect example of using Annotation e.g. @Test for specifying a Test Class. Same can also
be achieved by using Test marker interface.
After introduction of
Annotation on Java5, Annotation is better choice than marker interface and
JUnit is a perfect example of using Annotation e.g. @Test for specifying a Test
Class. Same can also be achieved by using Test marker interface.
New
features in Java SE 7
- Strings in switch Statement
- Type Inference for Generic Instance Creation
- Multiple Exception Handling
- Support for Dynamic Languages
- Try with Resources
- Java nio Package
- Binary Literals, underscore
in literals
- Diamond Syntax
- Automatic null Handling
New Java 7 Feature: String in Switch support
With Java 6, or less
1. String color = "red";
2.
3. if (color.equals("red")) {
4. System.out.println("Color is Red");
5. } else if (color.equals("green")) {
6. System.out.println("Color is Green");
7. } else {
8. System.out.println("Color not found");
9. }
With Java 7:
1. String color = "red";
2.
3. switch (color) {
4. case "red":
5. System.out.println("Color is Red");
6. break;
7. case "green":
8. System.out.println("Color is Green");
9. break;
10. default:
11. System.out.println("Color not found");
12. }
Conclusion
The switch statement when used with a
String uses the equals() method to compare the
given expression to each value in the case statement and is therefore case-sensitive
and will throw a NullPointerException if the expression is null. It is a small but useful feature which not
only helps us write more readable code but the compiler will likely generate more efficient bytecode as compared to the if-then-else statement.
A
switch works with the byte, short, char, andint primitive data types. It also works with enumerated types (discussed in Enum Types), the String class, and a few special classes that wrap
certain primitive types:Character, Byte, Short, and Integer (discussed in Numbers and Strings)
2. Type Inference for Generic Instance Creation
Java 6 : Map<String, List<String>> myMap = new
HashMap<String, List<String>>();
In
Java SE 7, you can substitute transferred the parameterized type of the
constructor with an empty set of type parameters (<>):
Java 7 : Map<String, List<String>> myMap = new HashMap<>();
Map<String, List<String>> myMap = new HashMap(); // unchecked conversion warning
4.
Multiple Exception
Handling
1) Improved catch block
01.try
02.{
03.//Do some processing
which throws NullPointerException; I am sending directly
04.throw new NullPointerException();
05.}
06.
07.//You can catch
multiple exception added after 'pipe' character
08.catch(NullPointerException |
IndexOutOfBoundsException ex)
09.{
10.throw ex;
11.}
Remember: If a
catch block handles more than one
exception type, then the catch parameter is implicitly final. In this example, the catch parameter ex is final and therefore you cannot assign any values to it within the catch block.
3.2 Rethrowing Exceptions with Improved Type Checking
Basically, you can list specific exceptions in
the throws clause of your method, even if they are not explicitly handled by a
catch block if:
1. The try block actually throws that specific
exception at some point in time.
2. The specific Exception isn't already handled at any point by a preceding catch block
3. The exception named in the throws clause of the method signature must be on the class hierarchy of at least one exception being handled and rethrown by a catch block (subtype or supertype)
2. The specific Exception isn't already handled at any point by a preceding catch block
3. The exception named in the throws clause of the method signature must be on the class hierarchy of at least one exception being handled and rethrown by a catch block (subtype or supertype)
public static void main(String
args[]) throws
OpenException,
CloseException {
boolean flag
= true;
try {
if (flag){
throw new OpenException();
}
else {
throw new CloseException();
}
}
catch (Exception e) {
System.out.println(e.getMessage());
e = new OpenException(); //
Do not do this parameter should be final.
throw e;
}
}
In Java 7, the compiler will look at a method and figure out what the most specific
exception is that might get thrown, as opposed to simply looking at the Exception which is the most general. The Java 7 compiler will then allow you to list the
specialized exceptions that might get thrown from the method. In this case, our
method that only ever throws the very generic java.lang.Exception from the
catch block will be allowed to list the specific OpenException and
CloseException in the method signature, because the JVM realizes that in fact, even though the
exception being thrown from the catch block is caught in the very general
Exception for, the Java 7 JVM also realizes that in reality, this exception has
to be an instance of either an OpenException or CloseException.
5.
The Try-with-resources Language Enhancement
1. Implement AutoCloseable
and override close() method.
2.
Close
method will be called automatically
after try block regardless of exception or not.
class OpenDoor implements AutoCloseable
{
public void close()
throws Exception {
System.out.println("The
door is closed.");
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class TryWithResources {
public static void main(String[] args) throws Exception {
try (OpenDoor door = new OpenDoor();
OpenWindow
window = new OpenWindow()) {
}
}
}
class OpenDoor implements AutoCloseable {
public void close() throws Exception{
System.out.println("The
door is closed.");
}
}
class OpenWindow implements AutoCloseable {
public void close() throws Exception {
System.out.println("The
window is closed.");
}
}
|
Answer : reverse order to which they
were created
The
window is closed.
The door is closed.
The door is closed.
Constructor invocation order in try-with-resource
blocks:
Constructor left to right order.
Close method reverse order.
public class TryWithResources {
public static void main(String[]
args) throws Exception
{
try
(OpenDoor door = new OpenDoor();
OpenWindow window = new OpenWindow() ) {
}
catch(Exception e) {}
finally {}
}
}
class OpenDoor implements AutoCloseable {
public OpenDoor() { System.out.println("The door is open.");};
public void close()
throws Exception{
System.out.println("The door
is closed.");
}
}
class OpenWindow implements AutoCloseable {
public OpenWindow() { System.out.println("The window is
open.");};
public void close()
throws Exception{
System.out.println("The
window is closed.");
}
}
|
When this class is compiled and executed, the output is:
The door is open.
The window is open.
The window is closed.
The door is closed.
The window is open.
The window is closed.
The door is closed.
Automatic Resource Management (ARM) and the AutoCloseable
Interface Tutorial
class OpenException
extends Exception{}
class SwingException extends Exception{}
class CloseException extends Exception{}
class OpenDoor implements AutoCloseable {
public OpenDoor() throws Exception {
System.out.println("The door
is open.");
//throw new OpenException()
};
public void swing()
throws Exception
{
System.out.println("The door
is becoming unhinged.");
//throw new SwingException();
}
public void close()
throws Exception
{
System.out.println("The door
is closed.");
// throw new CloseException();
}
}
<b>The TryWithResources runnable class</b>
|
And
here's the runnable TryWithResources class. References to the OpenWindow class
from the previous tutorial have been removed. Notice the additional call
to e.getClass() in the catch block.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public class TryWithResources {
public static void
main(String[] args) throws
Exception {
try ( OpenDoor door = new OpenDoor() ) {
door.swing();
}
catch (Exception e) {
System.out.println("Is
there a draft? " +
e.getClass());
}
finally {
System.out.println("I'm
putting a sweater on, regardless. ");
}
}
}
|
when no exceptions are thrown, the output is as follows:
The
door is open.
The door is becoming unhinged.
The door is closed.
I'm putting a sweater on, regardless.
The door is becoming unhinged.
The door is closed.
I'm putting a sweater on, regardless.
Exceptions in a constructor in a
try-with-resources initialization block
When an exception is thrown in the resource
declaration phase, the object that throws the exception is not considered to have been
initialized properly, and as a result, the close method is not invoked on it.
public OpenDoor() throws Exception
{
System.out.println("The
door is open.");
throw new
OpenException();
}
When we run the code, we get the following output:
The
door is open.
Is there a draft? class OpenException
I'm putting a sweater on, regardless.
Is there a draft? class OpenException
I'm putting a sweater on, regardless.
Exceptions in the body of a try-with-resources
block
public void swing()
throws Exception {
System.out.println("The
door is becoming unhinged.");
throw new SwingException();
}
The
door is open.
The door is becoming unhinged.
The door is closed.
Is there a draft? class SwingException
I'm putting a sweater on, regardless.
The door is becoming unhinged.
The door is closed.
Is there a draft? class SwingException
I'm putting a sweater on, regardless.
Looking at the code, we see that:
1. The OpenDoor constructor is invoked, triggering "The door is open." to output to the console.
2. The door is swung, causing "The door is becoming unhinged" to be written to the console.
3. A SwingException is thrown
4. The close() method is invoked, causing "The door is closed." to be output to the console.
5. The exception is handled, generating the following console output: Is there a draft? class SwingException
6. The finally block is executed, outputting: "I'm putting a sweater on, regardless."
1. The OpenDoor constructor is invoked, triggering "The door is open." to output to the console.
2. The door is swung, causing "The door is becoming unhinged" to be written to the console.
3. A SwingException is thrown
4. The close() method is invoked, causing "The door is closed." to be output to the console.
5. The exception is handled, generating the following console output: Is there a draft? class SwingException
6. The finally block is executed, outputting: "I'm putting a sweater on, regardless."
Exceptions in a close() method of an
AutoCloseable resource
public void close()
throws Exception {
System.out.println("The
door is closed.");
throw new CloseException();
}
The door is open.
The door is becoming unhinged.
The door is closed.
Is there a draft? class CloseException
I'm putting a sweater on, regardless.
The door is becoming unhinged.
The door is closed.
Is there a draft? class CloseException
I'm putting a sweater on, regardless.
Exceptions with multiple resources in
try-with-resources blocks
But what happens if there are two objects
that are initialized in the resource declaration, and one of them throws an
exception during creation?
The
rule is that if any resources are initialized in the resource declaration block
before an exception is thrown, the close method will be invoked on those
objects, but not on the object that threw the Exception during initialization.
6.
Diamond syntax
1.
The compiler will infer/assume the type of the right
side expression argument automatically.
2.
This make our code simpler and more readable and by
using the diamond syntax the
3.
compiler will ensure that we
have the generic type safe checking available in our code. This will make any
error due to type incompatibility captured at the compile time.
Java 6:
List<String> names = new ArrayList<String>();
Map<String, List<Integer>> map = new HashMap<String, List<Integer>>();
Java 7:
List<String> names = new ArrayList<>();
Map<String, List<Integer>> map = new HashMap<>();
7.
null handling
The null-default operator ?: returns the LHS unless that is null in
which case it returns the RHS:
// today
String str = getStringMayBeNull();
str = (str != null ? str : "");
// with null-default operator
String str = getStringMayBeNull() ?: "";
The null-default operator also works particularly well with
auto-unboxing.
Integer value = getIntegerMayBeNull();
int val = value ?: -1;
The null-safe operator ?. is an alternative form of method/field
invocation. If the LHS is null, then the result of the whole method/field
invocation is null:
// today
String result = null;
Foo foo = getFooMayBeNull();
if (foo != null) {
Bar bar = foo.getBarMayBeNull();
if (bar != null) {
result = bar.getResult();
}
}
// with null-safe operator
String result = getFooMayBeNull()?.getBarMayBeNull()?.getResult();
Java Version SE 6
Code named Mustang and released on December 11, 2006.
New features in Java SE 6
- Scripting Language Support
- JDBC 4.0 API
- Java Compiler API
- Pluggable Annotations
- Native PKI, Java GSS,
Kerberos and LDAP support.
- Integrated Web Services.
- Lot more enhancements.
J2SE Version 5.0
Code named Tiger and released on September 30, 2004.
New features in J2SE 5.0
- Generics
- Enhanced for Loop
- Autoboxing/Unboxing
- Typesafe Enums
- Varargs
- Static Import
- Metadata (Annotations)
- Instrumentation
JAVA Thread and LOCK interfaces Qs:
10 Object Oriented Design principles Java programmer should
know
JAVA 1.5 :
JAVA 1.5 :
COLLECTION FRAMEWORK
OBJECT Class:
Constructor Summary
|
|
Method Summary
|
|
boolean |
|
protected void |
finalize
() Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. |
int |
|
void |
|
void |
|
void |
wait
() Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. |
void |
wait
(long timeout) Causes current thread to wait until either another thread invokes the notify() method or the notifyAll() method for this object, or a specified amount of time has
elapsed. |
void |
wait
(long timeout,
int nanos) Causes current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the
current thread, or a certain amount of real time has elapsed |
Rules of Method
Overriding in Java
Following are rules of method
overriding in java which must be followed while overriding any method. as
stated earlier private, static and final method can not be overridden.
- Method signature must be same including return type, number of
method parameters, type of parameters and order of parameters
- Overriding method can not throw
higher Exception than original or overridden
method. means if original method throws IOException than overriding method
can not throw super class of IOException e.g. Exception but it can throw
any sub class of IOException or simply does not throw any Exception. This rule only applies to checked Exception
in Java,
overridden method is free to throw any unchecked
Exception.
- Overriding method can not reduce
accessibility of overridden method , means if original or overridden
method is public than overriding method can not make it protected.
Difference:
1) First
and most important difference between method overloading and overriding is
that, In case of method overloading in Java, Signature of method
changes while in case of method overriding it
remain same.
2) Second major difference between
method overloading vs overriding in Java is that You can overload method in one
class but overriding can only be done on subclass.
3) You can not override static, final and private
method in Java but you can overload static,
final or private method in Java.
4) Overloaded method in Java is bonded by static binding and overridden
methods are subject to dynamic binding.
5) Private
and final method can also be not overridden in Java.
Summary
1) In case of method
overloading method signature gets changed while in case of overriding signature remains
same.
2) Return type is
not part of method signature in Java.
3) Overloaded method can be subject
to compile time binding but overridden method can only be bind at run-time.
4) Both overloaded and
overridden method has same name in Java.
5) Static method
can not be overridden in Java.
6) Since private
method is also not visible outside of class, it can not be overridden and
method binding happens during compile time.
7) From Java5 onwards
you can use annotation in Java to declare overridden method just like we did with @override. @override annotation allows compiler, IDE like NetBeans and Eclipse to cross verify or
check if this method is really overrides super class method or not.
What
are the non-final methods in Java Object class, which are meant primarily for
extension?
The non-final methods are equals(), hashCode(), toString(), clone(), and
finalize(). The other methods like wait(), notify(), notifyAll(), getClass()
etc are final methods and therefore cannot be overridden. Let us look at
these non-final methods, which are meant primarily for extension (i.e.
inheritance).
Important: The equals() and hashCode() methods prove to be very important, when objects implementing these two methods are added to collections. If implemented incorrectly or not implemented at all then your objects stored in a collection like a Set, List or Map may behave strangely and also is hard to debug.
Important: The equals() and hashCode() methods prove to be very important, when objects implementing these two methods are added to collections. If implemented incorrectly or not implemented at all then your objects stored in a collection like a Set, List or Map may behave strangely and also is hard to debug.
What are the primary considerations
when implementing a user defined key?
- If a class overrides equals(), it
must override hashCode().
- If 2 objects are equal, then their
hashCode values must be equal as well.
- If a field is not used in
equals(), then it must not be used in hashCode().
- If
it is accessed often, hashCode() is a candidate for caching to enhance
performance.
- It
is a best practice to implement the user defined key class as an immutable
object.
Why do you get a
ConcurrentModificationException when using an iterator?
Problem: The
java.util.Collection classes are fail-fast,
which means that if one thread changes a collection while another thread is
traversing it through with an iterator the iterator.hasNext() or iterator.next() call will throw
ConcurrentModificationException. Even the synchronized collection wrapper
classes SynchronizedMap and SynchronizedList are only conditionally
thread-safe, which means all individual operations are thread-safe but compound
operations where flow of control depends on the results of previous operations
may be subject to threading issues. Collection myCollection = new ArrayList(10);myCollection.add("123");myCollection.add("456");myCollection.add("789");for
(Iterator it = myCollection.iterator(); it.hasNext();) {String
myObject = (String)it.next();System.out.println(myObject);if
(someConditionIsTrue) {myCollection.remove(myObject);
//can throw ConcurrentModificationException in single as//well
as multi-thread access situations.}}- You
can convert your list to an array with list.toArray() and iterate on the
array. This approach is not recommended if the list is large.
- You
can lock the entire list while iterating by wrapping your code within a
synchronized block. This approach adversely affects scalability of your
application if it is highly concurrent.
- If
you are using JDK 1.5 then you can use the ConcurrentHashMap and
CopyOnWriteArrayList classes, which provide much better scalability and
the iterator returned by ConcurrentHashMap.iterator() will not throw
ConcurrentModificationException while preserving thread-safety.
What
are some of the best practices relating to Java collection?
- Use ArrayList, HashMap etc as opposed to Vector,
Hashtable etc, where possible to avoid any synchronization overhead. Even
better is to use just arrays where possible. If multiple threads
concurrently access a collection and at least one of the threads either
adds or deletes an entry into the collection, then the collection must be
externally synchronized.
This is achieved by:
Map myMap = Collections.synchronizedMap (myMap); //conditional thread-safety
List myList = Collections.synchronizedList (myList); //conditional thread-safety - Set the initial capacity of a
collection appropriately (e.g. ArrayList, HashMap etc). This is because Collection
classes like ArrayList, HashMap etc must grow periodically to accommodate
new elements. But if you have a very large array, and you know the size in
advance then you can speed things up by setting the initial size
appropriately.
For example: HashMaps/Hashtables need to be created with sufficiently large capacity to minimize rehashing (which happens every time the table grows). HashMap has two parameters initial capacity and load factor that affect its performance and space requirements. Higher load factor values (default load factor of 0.75 provides a good trade off between performance and space) will reduce the space cost but will increase the lookup cost of myMap.get("") and myMap.put("") methods. When the number of entries in the HashMap exceeds the current capacity * loadfactor then the capacity of the HasMap is roughly doubled by calling the rehash function. It is also very important not to set the initial capacity too high or load factor too low if iteration performance or reduction in space is important. - Program
in terms of interface not implementation: For example you might decide a LinkedList
is the best choice for some application, but then later decide ArrayList
might be a better choice for performance reason.
Use:
List list = new ArrayList(100); // program in terms of interface & set the initial capacity.
Instead of:
ArrayList list = new ArrayList(); - Return zero length collections or
arrays as opposed to returning null: CO Returning null instead of zero length collection
(use Collections.EMPTY_SET, Collections.EMPTY_LIST, Collections.EMPTY_MAP)
is more error prone, since the programmer writing the calling method might
forget to handle a return value of null.
- Immutable objects should be used
as keys for the HashMap: CO Generally you use a java.lang.Integer or a
java.lang.String class as the key, which are immutable Java objects. If you
define your own key class then it is a best practice to make the key class
an immutable object (i.e. do not provide any setXXX() methods etc). If a
programmer wants to insert a new key then he/she will always have to
instantiate a new object (i.e. cannot mutate the existing key because
immutable key object class has no setter methods).
- Encapsulate
collections: CO In general collections are not immutable objects. So care
should be taken not to unintentionally expose the collection fields to the
caller.
- Avoid
storing unrelated or different types of objects into same collection: This
is analogous to storing items in pigeonholes without any labeling. To
store items use value objects or data objects (as opposed to storing every
attribute in an ArrayList or HashMap). Provide wrapper classes around your
collections API classes like ArrayList, HashMap etc as shown in better
approach column. Also where applicable consider using composite design
pattern, where an object may represent a single object or a collection of
objects.
Immutable Class Example in Java
·
public final class Contacts {
·
·
private final String name;
·
private final String mobile;
·
·
public Contacts(String name, String mobile) {
·
this.name = name;
·
this.mobile = mobile;
·
}
·
·
public String getName(){
·
return name;
·
}
·
·
public String getMobile(){
·
return mobile;
·
}
·
}
Hashtable performance
Hashtable(int initialCapacity)
|
and
Hashtable(int initialCapacity, float loadFactor)
|
To get better performance from your java Hashtable, you need to
1) use the initialCapacity and loadFactor arguments
2) use them wisely
while instantiating a Hashtable.
1) use the initialCapacity and loadFactor arguments
2) use them wisely
while instantiating a Hashtable.
initialCapacitiy is the number of
buckets to be created at the time of Hashtable instantiation. The number of buckets and
probability of collision is inversly proportional. If you have more
number of buckets than needed then you have lesser possibility for a collision.
For example, if you are going to store 10 elements and if you are
going to have initialCapacity as 100 then you will have 100 buckets. You are
going to calculate hashCoe() only 10 times with a spectrum of 100 buckets. The
possibility of a collision is very very less.
But if you are going to supply initialCapacity for the Hashtable
as 10, then the possibility of collision is very large. loadFactor decides when to automatically
increase the size of the Hashtable. The default size of initialCapacity is 11 and loadFactor
is .75 That if the Hashtable is 3/4 th full then the size of the Hashtable is
increased.
New capacity in java Hashtable is calculated as follows:
int newCapacity
= oldCapacity * 2 + 1; |
If you give a lesser
capacity and loadfactor and often it does the rehash() which will cause you
performance issues. Therefore for efficient performance for Hashtable in java, give
initialCapacity as 25% extra than you need and loadFactor as 0.75 when you
instantiate.
Java Collections framework
API is a unified architecture for representing and manipulating collections.
The API contains Interfaces, Implementations & Algorithm to help java
programmer in everyday programming. In nutshell, this API does 6 things at high
level
·
Reduces programming efforts. - Increases program speed and
quality.
·
Allows interoperability among unrelated APIs.
·
Reduces effort to
learn and to use new APIs.
·
Reduces effort to design new APIs.
·
Encourages &
Fosters software reuse.
To be specific, There are six
collection java interfaces. The most basic interface is Collection. Three
interfaces extend Collection: Set, List,
and SortedSet. The other two collection interfaces, Map and SortedMap, do not extend Collection, as they represent mappings
rather than true collections.
Some
of the collection classes provide traversal
of their contents via a java.util.Iterator interface. This interface allows
you to walk through a collection of objects, operating on each object in turn. Remember when using Iterators that they
contain a snapshot of the collection at the time the Iterator was obtained;
generally it is not advisable to modify the collection itself while traversing
an Iterator.
What is the difference between
java.util.Iterator and java.util.ListIterator?
Iterator : Enables you to traverse
through a collection in the forward direction
only, for obtaining or removing elements
ListIterator : extends Iterator, and allows bidirectional traversal of list and also allows the modification of elements.
What is HashMap and Map?
Map is Interface which is part of Java
collections framework. This is to store
Key Value pair, and Hashmap is class
that implements that using hashing technique.
Both Hashtable & HashMap
provide key-value access to data. The Hashtable is one of the original
collection classes in Java (also called as legacy classes). HashMap is part of
the new Collections Framework, added with Java 2, v1.2. There are several
differences between HashMap and Hashtable in Java as listed below
·
The HashMap class is roughly equivalent to
Hashtable, except that it is
unsynchronized and permits nulls. (HashMap
allows null values as key and value whereas Hashtable doesn’t allow nulls).
·
HashMap does not guarantee that the order of the map
will remain constant over time. But 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 can easily swap out the HashMap for a LinkedHashMap. This wouldn't be as
easy if you were using Hashtable.
·
HashMap is non
synchronized whereas Hashtable is synchronized.
·
Iterator in the HashMap
is fail-fast while the enumerator for the Hashtable isn't. So this could be a
design consideration
HashMap
|
HasTable
|
|
1
|
non synchronized
|
Synchronized
|
2
|
allow nulls values
|
not allowed
|
3
|
Lincked hashmap(subclass)- is ordered.
Can be converted to hashmap. |
not possible
|
What does synchronized means in Hashtable
context?
Synchronized means only one thread can
modify a hash table at one point of time. Any thread before performing an
update on a hashtable will have to acquire a lock on the object while others
will wait for lock to be released.
How can we make Hashmap synchronized?
HashMap can be synchronized by Map m = Collections.synchronizedMap(hashMap);
Where will you use Hashtable and where will
you use HashMap?
There are multiple aspects to this decision:
1. The basic difference between a
Hashtable and an HashMap is that,
Hashtable is synchronized while HashMap is not. Thus whenever there is a
possibility of multiple threads accessing the same instance, one should use
Hashtable. While if not multiple threads are going to access the same instance
then use HashMap. Non synchronized data
structure will give better performance than the synchronized one.
2. If there is a possibility in future that - there can be a scenario
when you may require to retain the order of objects in the Collection with key-value
pair then HashMap can be a good choice. As 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 can easily swap out the HashMap for a LinkedHashMap.
This wouldn't be as easy if you were using Hashtable. Also if you have multiple thread accessing you HashMap then
Collections.synchronizedMap() method can be leveraged. Overall HashMap gives
you more flexibility in terms of possible future changes.
HashMap
|
HasTable
|
|
1
|
non synchronized
|
synchronized
|
2
|
allow nulls values
|
not allowed
|
3
|
Lincked hashmap(subclass)- is ordered.
Can be converted to hashmap. |
not possible
|
4
|
Collections.synchronizedMap()
-for multiple thread accessing
|
|
5
|
HashMap gives you more flexibility in terms of possible future
changes.
|
|
6
|
Non synchronized data structure will give better performance
than the synchronized one
|
Vector & ArrayList both classes are implemented using dynamically resizable arrays, providing fast random access and fast traversal. ArrayList and Vector class both implement the List interface. Both the classes are member of Java collection framework, therefore from an API perspective, these two classes are very similar. However, there are still some major differences between the two. Below are some key differences
·
Vector is a legacy
class which has been retrofitted to implement the List interface since Java 2
platform v1.2
·
Vector is synchronized whereas ArrayList is not. Even though Vector class is synchronized, still when you want
programs to run in multithreading environment using ArrayList with Collections.synchronizedList() is recommended over
Vector.
·
ArrayList has no default size while vector has a default size of
10.
·
The Enumerations returned by Vector's elements
method are not fail-fast. Whereas ArraayList does not have any method
returning Enumerations.
Vector
|
ArrayList
|
|
1
|
• Vector is synchronized
|
Collections.synchronizedList()
|
2
|
vector has a default size of 10.
|
• ArrayList has no default size
|
3
|
Enumerations returned by Vector's elements method are not
fail-fast
|
Fail-fast
|
Enumeration and Iterator are the interface available in java.util package. The functionality of Enumeration interface is duplicated by the Iterator interface. New implementations should consider using Iterator in preference to Enumeration. Iterators differ from enumerations in following ways:
1.
Enumeration contains 2 methods namely hasMoreElements() &
nextElement() whereas Iterator contains three methods namely hasNext(),
next(),remove().
2.
Iterator adds an optional remove operation, and has shorter method names. Using remove() we can delete the
objects but Enumeration interface does not support this feature.
3.
Enumeration interface
is used by legacy classes. Vector.elements() & Hashtable.elements() method
returns Enumeration. Iterator is returned by all Java Collections Framework
classes. java.util.Collection.iterator() method returns an instance of Iterator
Enumeration
|
Iterator
|
|
The functionality of Enumeration interface is duplicated
by the Iterator interface |
||
1
|
Enumeration acts as Read-only interface
|
has a remove() method while Enumeration doesn't
|
4. Which implementation of the List interface provides for the
fastest insertion of a new element into the middle of the list?
5.
a. Vector b. ArrayList c. LinkedList ArrayList and Vector both use an array to store the elements of the list. When an element is inserted into the middle of the list the elements that follow the insertion point must be shifted to make room for the new element. The LinkedList is implemented using a doubly linked list; an insertion requires only the updating of the links at the point of insertion. Therefore, the LinkedList allows for fast insertions and deletions.
a. Vector b. ArrayList c. LinkedList ArrayList and Vector both use an array to store the elements of the list. When an element is inserted into the middle of the list the elements that follow the insertion point must be shifted to make room for the new element. The LinkedList is implemented using a doubly linked list; an insertion requires only the updating of the links at the point of insertion. Therefore, the LinkedList allows for fast insertions and deletions.
What is the difference between ArrayList and LinkedList?
(ArrayList vs LinkedList.)
java.util.ArrayList and java.util.LinkedList are two Collections classes used for storing lists of object references Here are some key differences:
·
ArrayList uses primitive
object array for storing objects whereas LinkedList is made up of a chain of
nodes.
Each node stores an element and the pointer to the next node. A singly linked
list only has pointers to next. A doubly linked list has a pointer to the next
and the previous element. This makes walking the list backward easier.
·
ArrayList implements
the RandomAccess interface, and LinkedList does not. The commonly used
ArrayList implementation uses primitive Object array for internal storage.
Therefore an ArrayList is much faster than a LinkedList for random access, that
is, when accessing arbitrary list elements using the get method. Note that the
get method is implemented for LinkedLists,
but it requires a sequential scan from
the front or back of the list. This scan is very slow. For a LinkedList,
there's no fast way to access the Nth element of the list.
·
Adding and deleting at
the start and middle of the ArrayList is slow, because all the later elements
have to be copied forward or backward. (Using System.arrayCopy()) Whereas Linked
lists are faster for inserts and deletes anywhere in the list, since all you do is update a few next and
previous pointers of a node.
·
Each element of a linked list (especially a doubly linked list)
uses a bit more memory than its equivalent in array list, due to the need for
next and previous pointers.
·
ArrayList may also have a performance issue when the internal
array fills up. The arrayList has to create a new array and copy all the
elements there. The ArrayList has a growth algorithm of (n*3)/2+1, meaning that
each time the buffer is too small it will create a new one of size (n*3)/2+1
where n is the number of elements of the current buffer. Hence if we can guess
the number of elements that we are going to have, then it makes sense to create
a arraylist with that capacity during object creation (using construtor new
ArrayList(capacity)). Whereas LinkedLists should not have such capacity issues.
Where will you use ArrayList and Where will you use LinkedList?
Or Which one to use when (ArrayList / LinkedList).
Below is a snippet from SUN's site. The Java SDK contains 2 implementations of the List interface - ArrayList and LinkedList. If you frequently add elements to the beginning of the List or iterate over the List to delete elements from its interior, you should consider using LinkedList. These operations require constant-time in a LinkedList and linear-time in an ArrayList. But you pay a big price in performance. Positional access requires linear-time in a LinkedList and constant-time in an ArrayList.
What is performance of various Java
collection implementations/algorithms? What is Big 'O' notation for each of
them ?
Each java collection implementation class have different performance for different methods, which makes them suitable for different programming needs.
Performance of Map interface implementations
Hashtable
An instance of Hashtable has two
parameters that affect its performance: initial capacity and load factor. The
capacity is the number of buckets in the hash table, and the initial capacity
is simply the capacity at the time the hash table is created. Note that the
hash table is open: in the case of a "hash collision", a single
bucket stores multiple entries, which must be searched sequentially. The load
factor is a measure of how full the hash table is allowed to get before its
capacity is automatically increased. The initial capacity and load factor
parameters are merely hints to the implementation. The exact details as to when
and whether the rehash method is invoked are implementation-dependent.
HashMap
This implementation
provides constant-time [ Big O Notation is O(1) ] performance for the basic
operations (get and put), assuming the hash
function disperses the elements properly among the buckets. Iteration over
collection views requires time proportional to the "capacity" of the HashMap instance (the number of buckets)
plus its size (the number of key-value mappings). Thus, it's very important not to set the initial
capacity too high (or the load factor too low) if iteration performance is
important.
TreeMap
The TreeMap implementation provides
guaranteed log(n) [ Big O
Notation is O(log N) ] time cost for the containsKey, get, put and remove
operations.
LinkedHashMap
A linked hash map has two parameters that
affect its performance: initial capacity
and load factor. They are defined precisely as for HashMap. Note, however,
that the penalty for choosing an excessively high value for initial capacity is
less severe for this class than for HashMap, as iteration times for this class are unaffected by capacity.
Performance of Set interface implementations
HashSet
The
HashSet class offers constant-time [ Big O Notation is O(1) ] performance for
the basic operations (add, remove, contains and size), assuming the hash function disperses the elements properly
among the buckets. Iterating over this set requires time proportional to the
sum of the HashSet instance's size (the number of elements) plus the
"capacity" of the backing HashMap instance (the number of buckets).
Thus, it's very important not to set the initial capacity too high (or the load
factor too low) if iteration performance is important.
TreeSet
The TreeSet implementation provides guaranteed log(n) time cost for
the basic operations (add, remove and contains).
LinkedHashSet
A linked hash set has two parameters that
affect its performance: initial capacity
and load factor. They are defined precisely as for HashSet. Note, however,
that the penalty for choosing an excessively high value for initial capacity is
less severe for this class than for HashSet, as iteration times for this class
are unaffected by capacity.
Performance of List interface implementations
LinkedList
- Performance of get and remove methods is linear time [
Big O Notation is O(n) ] - Performance of add and Iterator.remove methods is constant-time [ Big O
Notation is O(1) ]
ArrayList
-
The size, isEmpty, get, set, iterator,
and listIterator operations run in constant time. [ Big O Notation is O(1)
] - The add operation runs in amortized constant
time [ Big O Notation is O(1) ] , but in worst case (since the array must be resized and copied) adding
n elements requires linear time [ Big O Notation is O(n) ] - Performance
of remove method is linear time [ Big O Notation is O(n) ] - All of the other
operations run in linear time [ Big O Notation is O(n) ]. The constant factor
is low compared to that for the LinkedList implementation.
Can you think of a questions which is not part of this post? Please don't forget to share it with me in comments section & I will try to include it in the list.
Can you think of a questions which is not part of this post? Please don't forget to share it with me in comments section & I will try to include it in the list.
HashMap ht = new
HashMap();
ht.put("11","12");
ht.put("11",null);
Iterator it = ht.entrySet().iterator();
while (it.hasNext()){
System.out.println(it.next());
System.out.println(ht.get("11"));
}
ArrayList<String> myArr = new
ArrayList<String>();
myArr.add("Italian Riviera");
System.out.println(myArr.get(0)); //
starting position is 0 not 1
LinkedList <Integer>list = new
LinkedList<Integer>();
list.add(1);
list.add(2);
list.addFirst(0);
list.addLast(4);//Adding last or append
list.add(2,99); //Adding data at 3rd position
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.get(3);
list.removeFirst();
list.removeLast();
list.remove(1);
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next()+"
");
}
String myName = "Here we go";
StringBuilder sb = new StringBuilder();
sb = recursiveMethod(myName,sb);
System.out.println(sb);
}
public static StringBuilder recursiveMethod(String myName,StringBuilder
sb)
{
int index = myName.lastIndexOf("
");
sb.append(myName.substring(index));
System.out.println(sb);
myName
= myName.substring(0,index);
if(myName.indexOf(" ")==-1)
{
sb.append("
"+myName.substring(0));
return sb;
}
return recursiveMethod(myName,sb);
}
No comments:
Post a Comment