Users Online

· Guests Online: 2

· Members Online: 0

· Total Members: 185
· Newest Member: meenachowdary055

Forum Threads

Newest Threads
No Threads created
Hottest Threads
No Threads created

Latest Articles

FAQ: Java Job Interview Questions

FAQ (Frequently Asked Questions) >Java Job Interview Questions
Q 01: Give a few reasons for using Java?Q 02: What is the main difference between the Java platform and the other software platforms?Q 03: What is the difference between C++ and Java?Q 04: What are the usages of Java packages?
Q 05: Explain Java class loaders? If you have a class in a package, what do you need to do to run it? Explain dynamic class loading?Q 06: What is the difference between constructors and other regular methods? What happens if you do not provide a constructor? Can you call one constructor from another? How do you call the superclass’s constructor?</strong>Q 07: What are the advantages of Object Oriented Programming Languages (OOPL)?Q 08: How does the Object Oriented approach improve software development?
Q 09: How do you express an ‘is a’ relationship and a ‘has a’ relationship or explain inheritance and composition? What is the difference between composition and aggregation?Q 10: What do you mean by polymorphism, inheritance, encapsulation, and dynamic binding?Q 11: What is design by contract? Explain the assertion construct?Q 12: What is the difference between an abstract class and an interface and when should you use them?
Q 13: Why there are some interfaces with no defined methods (i.e. marker interfaces) in Java?Q 14: When is a method said to be overloaded and when is a method said to be overridden?Q 15: What is the main difference between an ArrayList and a Vector? What is the main difference between HashMap and Hashtable? What is the difference between a stack and a queue?Q 16 Explain the Java Collections Framework?
Q 17: What are some of the best practices relating to Java collection?Q 18: What is the difference between “==” and equals(…) method? What is the difference between shallow comparison and deep comparison of objects?Q 19: What are the non-final methods in Java Object class, which are meant primarily for extension?Q 20: When providing a user defined key class for storing objects in the HashMaps or Hashtables, what methods do you have to provide or override (i.e. method overriding)? LF PI CO FAQ
Q 21: What is the main difference between a String and a StringBuffer class? LF PI CI CO FAQQ 22: What is the main difference between pass-by-reference and pass-by-value? LF PI FAQQ 23: What is serialization? How would you exclude a field of a class from serialization or what is a transient variable? What is the common use? What is a serial version id? LF SI PI FAQQ 24: Explain the Java I/O streaming concept and the use of the decorator design pattern in Java I/O? LF DP PI SI
Q 25: How can you improve Java I/O performance? PI BPQ 26: What is the main difference between shallow cloning and deep cloning of objects? DC LF MI PIQ 27: What is the difference between an instance variable and a static variable? How does a local variable compare to an instance or a static variable? Give an example where you might use a static variable? LF FAQQ 28: Give an example where you might use a static method? LF FAQ
Q 29: What are access modifiers? LF FAQQ 30: Where and how can you use a private constructor? LF FAQQ 31: What is a final modifier? Explain other Java modifiers? LF FAQQ 32: What is the difference between final, finally and finalize() in Java? LF FAQ
Q 33: Why would you prefer a short circuit “&&, ||” operators over logical “& , |” operators? LFQ 34: How does Java allocate stack and heap memory? Explain re-entrant, recursive and idempotent methods/functions? MI CIQ 35: Explain Outer and Inner classes (or Nested classes) in Java? When will you use an Inner Class? LF SEQ 36: What is type casting? Explain up casting vs. down casting? When do you get ClassCastException? LF DP FAQ
Q 37 What do you know about the Java garbage collector? When does the garbage collection occur? Explain different types of references in Java? LF MI FAQQ 38: If you have a circular reference of objects, but you no longer reference it from an execution thread, will this object be a potential candidate for garbage collection? LF MIQ 39: Discuss the Java error handling mechanism? What is the difference between Runtime (unchecked) exceptions and checked exceptions? What is the implication of catching all the exceptions with the type “Exception”? EH BP FAQQ 40: What is a user defined exception? EH
Q 01: Give a few reasons for using Java?
Java is a fun language. Let’s look at some of the reasons:
􀂃 Built-in support for multi-threading, socket communication, and memory management (automatic garbage
collection).
􀂃 Object Oriented (OO).
􀂃 Better portability than other languages across operating systems.
􀂃 Supports Web based applications (Applet, Servlet, and JSP), distributed applications (sockets, RMI, EJB etc)
and network protocols (HTTP, JRMP etc) with the help of extensive standardized APIs (Application
Programming Interfaces).
Top
Q 02: What is the main difference between the Java platform and the other software platforms?
A 02: Java platform is a software-only platform, which runs on top of other hardware-based platforms like UNIX, NT etc.
















The Java platform has 2 components:
􀂃 Java Virtual Machine (JVM) – ‘JVM’ is a software that can be ported onto various hardware platforms. Byte codes are the machine language of the JVM.
􀂃 Java Application Programming Interface (Java API) – set of classes written using the Java language and run on the JVM.

Top
Q 03: What is the difference between C++ and Java?
A 03: Both C++ and Java use similar syntax and are Object Oriented, but:
􀂃 Java does not support pointers. Pointers are inherently tricky to use and troublesome.
􀂃 Java does not support multiple inheritances because it causes more problems than it solves. Instead Java
supports multiple interface inheritance, which allows an object to inherit many method signatures from
different interfaces with the condition that the inheriting object must implement those inherited methods. The multiple interface inheritance also allows an object to behave polymorphically on those methods. [Refer Q9 and Q10 in Java section.]
􀂃 Java does not support destructors but adds a finalize() method. Finalize methods are invoked by the garbage
collector prior to reclaiming the memory occupied by the object, which has the finalize() method. This means
you do not know when the objects are going to be finalized. Avoid using finalize() method to release nonmemory resources like file handles, sockets, database connections etc because Java has only a finite
number of these resources and you do not know when the garbage collection is going to kick in to release
these resources through the finalize() method.
􀂃 Java does not include structures or unions because the traditional data structures are implemented as an object oriented framework (Java Collections Framework – Refer Q16, Q17 in Java section).

All the code in Java program is encapsulated within classes therefore Java does not have global variables or functions.
􀂃 C++ requires explicit memory management, while Java includes automatic garbage collection. [Refer Q37 in Java section].
Top
Q 04: What are the usages of Java packages?
A 04: It helps resolve naming conflicts when different packages have classes with the same names. This also helps you organize files within your project. For example: java.io package do something related to I/O and java.net package do something to do with network and so on. If we tend to put all .java files into a single package, as the project gets bigger, then it would become a nightmare to manage all your files.
You can create a package as follows with package keyword, which is the first keyword in any Java program
followed by import statements. The java.lang package is imported implicitly by default and all the other packages must be explicitly imported.

package com.xyz.client ;
import java.io.File;
import java.net.URL;

Top
Q 05: Explain Java class loaders? If you have a class in a package, what do you need to do to run it? Explain dynamic class loading?
A 05: Class loaders are hierarchical. Classes are introduced into the JVM as they are referenced by name in a class that is already running in the JVM. So, how is the very first class loaded? The very first class is especially loaded with the help of static main( ) method declared in your class. All the subsequently loaded classes are loaded by the classes, which are already loaded and running. A class loader creates a namespace. All JVMs include at least one class loader that is embedded within the JVM called the primordial (or bootstrap) class loader. Now let’s look at non-primordial class loaders. The JVM has hooks in it to allow user defined class loaders to be used in place of primordial class loader. Let us look at the class loaders created by the JVM.































Class loaders are hierarchical and use a delegation model when loading a class. Class loaders request their
parent to load the class first before attempting to load it themselves. When a class loader loads a class, the child class loaders in the hierarchy will never reload the class again. Hence uniqueness is maintained. Classes loaded by a child class loader have visibility into classes loaded by its parents up the hierarchy but the reverse is not true as explained in the above diagram.

Q. What do you need to do to run a class with a main() method in a package?

A Example: Say, you have a class named “Pet” in a project folder “c:myProject” and package named
com.xyz.client, will you be able to compile and run it as it is?

package com.xyz.client;
public class Pet {
public static void main(String[] args) {
System.out.println("I am found in the classpath");
}
}

To run 􀃆 c:myProject> java com.xyz.client.Pet

The answer is no and you will get the following exception: “Exception in thread "main" java.lang.-
NoClassDefFoundError: com/xyz/client/Pet”. You need to set the classpath. How can you do that? One of the
following ways:
1. Set the operating system CLASSPATH environment variable to have the project folder “c:myProject”. [Shown in the above diagram as the System –classpath class loader]
2. Set the operating system CLASSPATH environment variable to have a jar file “c:/myProject/client.jar”, which has the Pet.class file in it. [Shown in the above diagram as the System –classpath class loader].
3. Run it with –cp or –classpath option as shown below:
c:>java –cp c:/myProject com.xyz.client.Pet
OR
c:>java -classpath c:/myProject/client.jar com.xyz.client.Pet
Important: Two objects loaded by different class loaders are never equal even if they carry the same values, which mean a class is uniquely identified in the context of the associated class loader. This applies to singletons too, where each class loader will have its own singleton. [Refer Q51 in Java section for singleton design pattern]


Q. Explain static vs. dynamic class loading?

































Q What are “static initializers” or “static blocks with no function names”?

When a class is loaded, all blocks
that are declared static and don’t have function name (i.e. static initializers) are executed even before the
constructors are executed. As the name suggests they are typically used to initialize static fields. CO
public class StaticInitializer {
public static final int A = 5;
public static final int B; //note that it is not 􀃆 public static final int B = null;
//note that since B is final, it can be initialized only once.
//Static initializer block, which is executed only once when the class is loaded.
static {
if(A == 5)
B = 10;
else
B = 5;
}
public StaticInitializer(){} //constructor is called only after static initializer block
}
The following code gives an Output of A=5, B=10.
public class Test {
System.out.println("A =" + StaticInitializer.A + ", B =" + StaticInitializer.B);
}

Top
Q 06: What is the difference between constructors and other regular methods? What happens if you do not provide a constructor? Can you call one constructor from another? How do you call the superclass’s constructor?</strong>
A)








Q. What happens if you do not provide a constructor?

Java does not actually require an explicit constructor in the class description. If you do not include a constructor, the Java compiler will create a default constructor in the byte code with an empty argument. This default constructor is equivalent to the explicit “Pet(){}”. If a class includes one or more explicit constructors like “public Pet(int id)” or “Pet(){}” etc, the java compiler does not create the default constructor “Pet(){}”.

Q. Can you call one constructor from another?
Yes, by using this() syntax. E.g.

public Pet(int id) {
this.id = id; // “this” means this object
}
public Pet (int id, String type) {
this(id); // calls constructor public Pet(int id)
this.type = type; // ”this” means this object
}

Q. How to call the superclass constructor?

If a class called “SpecialPet” extends your “Pet” class then you can use the keyword “super” to invoke the superclass’s constructor. E.g.

public SpecialPet(int id) {
super(id); //must be the very first statement in the constructor.
}
To call a regular method in the super class use: “super.myMethod( );”. This can be called at any line. Some
frameworks based on JUnit add their own initialization code, and not only do they need to remember to invoke
their parent's setup() method, you, as a user, need to remember to invoke theirs after you wrote your initialization code:

public class DBUnitTestCase extends TestCase {
public void setUp() {
super.setUp();
// do my own initialization
}
}
public void cleanUp() throws Throwable
{
try {
… // Do stuff here to clean up your object(s).
}
catch (Throwable t) {}
finally{
super.cleanUp(); //clean up your parent class. Unlike constructors
// super.regularMethod() can be called at any line.
}
}

Top
Q 07: What are the advantages of Object Oriented Programming Languages (OOPL)?
A 07: The Object Oriented Programming Languages directly represent the real life objects like Car, Jeep, Account, Customer etc. The features of the OO programming languages like polymorphism, inheritance and encapsulation make it powerful. [Tip: remember pie which, stands for Polymorphism, Inheritance and Encapsulation are the 3 pillars of OOPL]
Top
Q 08: How does the Object Oriented approach improve software development?
A 08: The key benefits are:
1􀂃) Re-use of previous work: using implementation inheritance and object composition.
2) Real mapping to the problem domain: Objects map to real world and represent vehicles, customers, products etc: with encapsulation.
􀂃3) Modular Architecture: Objects, systems, frameworks etc are the building blocks of larger systems.

The increased quality and reduced development time are the by-products of the key benefits discussed above.
If 90% of the new application consists of proven existing components then only the remaining 10% of the code have to be tested from scratch.
Top
Q 09: How do you express an ‘is a’ relationship and a ‘has a’ relationship or explain inheritance and composition? What is the difference between composition and aggregation?
A 09: The ‘is a’ relationship is expressed with inheritance and ‘has a’ relationship is expressed with composition. Both inheritance and composition allow you to place sub-objects inside your new class. Two of the main techniques for code reuse are class inheritance and object composition.












Inheritance is uni-directional. For example House is a Building. But Building is not a House. Inheritance uses extends key word. Composition: is used when House has a Bathroom. It is incorrect to say House is a Bathroom. Composition simply means using instance variables that refer to other objects. The class House will have an instance variable, which refers to a Bathroom object.

Q. Which one to favor, composition or inheritance?
The guide is that inheritance should be only used when
subclass ‘is a’ superclass.
􀂃 Don’t use inheritance just to get code reuse. If there is no ‘is a’ relationship then use composition for code
reuse. Overuse of implementation inheritance (uses the “extends” key word) can break all the subclasses, if
the superclass is modified.
􀂃 Do not use inheritance just to get polymorphism. If there is no ‘is a’ relationship and all you want is
polymorphism then use interface inheritance with composition, which gives you code reuse (Refer Q10
in Java section for interface inheritance).

Q What is the difference between aggregation and composition?















Top
Q 10: What do you mean by polymorphism, inheritance, encapsulation, and dynamic binding?
A 10: Polymorphism – means the ability of a single variable of a given type to be used to reference objects of
different types, and automatically call the method that is specific to the type of object the variable references. In a nutshell, polymorphism is a bottom-up method call. The benefit of polymorphism is that it is very easy to add new classes of derived objects without breaking the calling code (i.e. getTotArea() in the sample code shown below) that uses the polymorphic classes or interfaces. When you send a message to an object even though you don’t know what specific type it is, and the right thing happens, that’s called polymorphism. The process used by object-oriented programming languages to implement polymorphism is called dynamic binding. Let us look at some sample code to demonstrate polymorphism




































Inheritance – is the inclusion of behavior (i.e. methods) and state (i.e. variables) of a base class in a derived class so that they are accessible in that derived class. The key benefit of Inheritance is that it provides the formal mechanism for code reuse. Any shared piece of business logic can be moved from the derived class into the base class as part of refactoring process to improve maintainability of your code by avoiding code duplication. The existing class is called the superclass and the derived class is called the subclass. Inheritance can also be defined as the process whereby one object acquires characteristics from one or more other objects the same way children acquire characteristics from their parents. There are two types of inheritances:
1. Implementation inheritance (aka class inheritance): You can extend an application’s functionality by reusing functionality in the parent class by inheriting all or some of the operations already implemented. In Java, you can only inherit from one superclass. Implementation inheritance promotes reusability but improper use of class inheritance can cause programming nightmares by breaking encapsulation and making future changes a problem. With implementation inheritance, the subclass becomes tightly coupled with the superclass. This will make the design fragile because if you want to change the superclass, you must know all the details of the subclasses to avoid breaking them. So when using implementation inheritance, make sure that the subclasses depend only on the behavior of the superclass, not on the actual implementation. For example in the above diagram, the subclasses should only be concerned about the behavior known as area() but not how it is implemented.
2. Interface inheritance (aka type inheritance): This is also known as subtyping. Interfaces provide a mechanism for specifying a relationship between otherwise unrelated classes, typically by specifying a set of common methods each implementing class must contain. Interface inheritance promotes the design concept of program to interfaces not to implementations. This also reduces the coupling or implementation dependencies between systems. In Java, you can implement any number of interfaces. This is more flexible than implementation inheritance because it won’t lock you into specific implementations which make subclasses difficult to maintain. So care should be taken not to break the implementing classes by modifying the interfaces.
Which one to use? Prefer interface inheritance to implementation inheritance because it promotes the design concept of coding to an interface and reduces coupling. Interface inheritance can achieve code reuse with the help of object composition. If you look at Gang of Four (GoF) design patterns, you can see that it favors interface inheritance to implementation inheritance.

































Q. Why would you prefer code reuse via composition over inheritance?

Both the approaches make use of polymorphism and gives code reuse (in different ways) to achieve the same results but:
􀂃 The advantage of class inheritance is that it is done statically at compile-time and is easy to use. The disadvantage ofclass inheritance is that because it is static, implementation inherited from a parent class cannot be changed at runtime. In object composition, functionality is acquired dynamically at run-time by objects collecting references to other objects. The advantage of this approach is that implementations can be replaced at run-time. This is possible because objects are accessed only through their interfaces, so one object can be replaced with another just as long as they have the same type. For example: the composed class AccountHelperImpl can be replaced by another more efficient implementation as shown below if required:


public class EfficientAccountHelperImpl implements AccountHelper {
public void deposit(double amount) {
System.out.println("efficient depositing " + amount);
}
public void withdraw(double amount) {
System.out.println("efficient withdrawing " + amount);
}
}


Another problem with class inheritance is that the subclass becomes dependent on the parent class implementation. This makes it harder to reuse the subclass, especially if part of the inherited implementation is no longer desirable and hence can break encapsulation. Also a change to a superclass can not only ripple down the inheritance hierarchy to subclasses, but can also ripple out to code that uses just the subclasses making the design fragile by tightly coupling the subclasses with the super class. But it is easier to change the interface/implementation of the composed class.

Due to the flexibility and power of object composition, most design patterns emphasize object composition over inheritance whenever it is possible. Many times, a design pattern shows a clever way of solving a common problem through the use of object composition rather then a standard, less flexible, inheritance based solution.

Encapsulation – refers to keeping all the related members (variables and methods) together in an object. Specifying member variables as private can hide the variables and methods. Objects should hide their inner workings from the outside view. Good encapsulation improves code modularity by preventing objects interacting with each other in an unexpected way, which in turn makes future development and refactoring efforts easy.























Being able to encapsulate members of a class is important for security and integrity. We can protect variables from unacceptable values. The sample code above describes how encapsulation can be used to protect the MyMarks object from having negative values. Any modification to member variable “vmarks” can only be carried out through the setter method setMarks(int mark). This prevents the object "MyMarks” from having any negative values by throwing an exception.

Top
Q 11: What is design by contract? Explain the assertion construct?
A 11: Design by contract specifies the obligations of a calling-method and called-method to each other. Design by contract is a valuable technique, which should be used to build well-defined interfaces. The strength of this
programming methodology is that it gets the programmer to think clearly about what a function does, what pre and post conditions it must adhere to and also it provides documentation for the caller. Java uses the assert statement to implement pre- and post-conditions. Java’s exceptions handling also support design by contract especially checked exceptions (Refer Q39 in Java section for checked exceptions). In design by contract in addition to specifying programming code to carrying out intended operations of a method the programmer also specifies:

1. Preconditions – This is the part of the contract the calling-method must agree to. Preconditions specify the
conditions that must be true before a called method can execute. Preconditions involve the system state and the arguments passed into the method at the time of its invocation. If a precondition fails then there is a bug in the calling-method or calling software component.











2. Postconditions – This is the part of the contract the called-method agrees to. What must be true after a
method completes successfully. Postconditions can be used with assertions in both public and non-public
methods. The postconditions involve the old system state, the new system state, the method arguments and the method’s return value. If a postcondition fails then there is a bug in the called-method or called software
component.

public double calcRate(int rate) {
if(rate <= 0 || rate > MAX_RATE){
throw new IllegalArgumentException(“Invalid rate !!! ”);
}
//logic to calculate the rate and set it goes here
assert this.evaluate(result) < 0 : this; //message sent to AssertionError on failure
return result;
}

3. Class invariants - what must be true about each instance of a class? A class invariant as an internal invariant that can specify the relationships among multiple attributes, and should be true before and after any method completes. If an invariant fails then there could be a bug in either calling-method or called-method. There is no particular mechanism for checking invariants but it is convenient to combine all the expressions required for checking invariants into a single internal method that can be called by assertions. For example if you have a class, which deals with negative integers then you define the isNegative() convenient internal method:

class NegativeInteger {
Integer value = new Integer (-1); //invariant
//constructor
public NegativeInteger(Integer int) {
//constructor logic goes here
assert isNegative();
}
// rest of the public and non-public methods goes here. public methods should call
// assert isNegative(); prior to its return
// convenient internal method for checking invariants.
// Returns true if the integer value is negative
private boolean isNegative(){
return value.intValue() < 0 ;
}
}


The isNegative() method should be true before and after any method completes, each public method and
constructor should contain the following assert statement immediately prior to its return.
assert isNegative();

Explain the assertion construct?

The assertion statements have two forms as shown below:

assert Expression1;
assert Expression1 : Expression2;


Where:
􀂃 Expression1 􀃆 is a boolean expression. If the Expression1 evaluates to false, it throws an AssertionError without any detailed message.
􀂃 Expression2 􀃆 if the Expression1 evaluates to false throws an AssertionError with using the value of the Expression2 as the error’s detailed message.
Note: If you are using assertions (available from JDK1.4 onwards), you should supply the JVM argument to
enable it by package name or class name.

java -ea[:packagename...|:classname] or java -enableassertions[:packagename...|:classname]
java –ea:Account

Top
Q 12: What is the difference between an abstract class and an interface and when should you use them?
A 12: In design, you want the base class to present only an interface for its derived classes. This means, you don’t want anyone to actually instantiate an object of the base class. You only want to upcast to it (implicit upcasting, which gives you polymorphic behavior), so that its interface can be used. This is accomplished by making that class abstract using the abstract keyword. If anyone tries to make an object of an abstract class, the compiler prevents it.
The interface keyword takes this concept of an abstract class a step further by preventing any method or function implementation at all. You can only declare a method or function but not provide the implementation. The class, which is implementing the interface, should provide the actual implementation. The interface is a very useful and commonly used aspect in OO design, as it provides the separation of interface and implementation and enables you to:
􀂃 Capture similarities among unrelated classes without artificially forcing a class relationship.
􀂃 Declare methods that one or more classes are expected to implement.
􀂃 Reveal an object's programming interface without revealing its actual implementation.
􀂃 Model multiple interface inheritance in Java, which provides some of the benefits of full on multiple
inheritances, a feature that some object-oriented languages support that allow a class to have more than one
superclass.























Q. When to use an abstract class?:
In case where you want to use implementation inheritance then it is usually provided by an abstract base class. Abstract classes are excellent candidates inside of application frameworks. Abstract classes let you define some default behavior and force subclasses to provide any specific behavior. Care should be taken not to overuse implementation inheritance as discussed in Q10 in Java section.

Q. When to use an interface?:
For polymorphic interface inheritance, where the client wants to only deal with a type and does not care about the actual implementation use interfaces. If you need to change your design frequently, you should prefer using interface to abstract. CO Coding to an interface reduces coupling and interface inheritance can achieve code reuse with the help of object composition. For example: The Spring framework’s dependency injection promotes code to an interface principle. Another justification for using interfaces is that they solve the ‘diamond problem’ of traditional multiple inheritance as shown in the figure. Java does not support multiple inheritance. Java only supports multiple interface inheritance. Interface will solve all the ambiguities caused by this ‘diamond problem’.
Design pattern: Strategy design pattern lets you swap new algorithms and processes into your program without altering the objects that use them. Strategy design pattern: Refer Q11 in How would you go about… section.

Top
Q 13: Why there are some interfaces with no defined methods (i.e. marker interfaces) in Java?
A 13: The interfaces with no defined methods act like markers. They just tell the compiler that the objects of the classes implementing the interfaces with no defined methods need to be treated differently. Example java.io.Serializable (Refer Q23 in Java section), java.lang.Cloneable, java.util.EventListener etc. Marker interfaces are also known as “tag” interfaces since they tag all the derived classes into a category based on their purpose.
Top
Q 14: When is a method said to be overloaded and when is a method said to be overridden?


Top
Q 15: What is the main difference between an ArrayList and a Vector? What is the main difference between HashMap and Hashtable? What is the difference between a stack and a queue?
A)







Q. So which is better?

As a general rule, prefer ArrayList/HashMap to Vector/Hashtable. If your application is a multithreaded application and at least one of the threads either adds or deletes an entry into the collection then use new Java collections API‘s external synchronization facility as shown below to temporarily synchronize your collections as needed:

Map myMap = Collections.synchronizedMap (myMap); // single lock for the entire map
List myList = Collections.synchronizedList (myList); // single lock for the entire list

J2SE 5.0: If you are using J2SE5, you should use the new “java.util.concurrent” package for improved performance because the concurrent package collections are not governed by a single synchronized lock as shown above. The “java.util.concurrent” package collections like ConcurrentHashMap is threadsafe and at the same time safely permits any number of concurrent reads as well as tunable number of concurrent writes. The “java.util.concurrent” package also provides an efficient scalable thread-safe non-blocking FIFO queue like ConcurrentLinkedQueue.

J2SE 5.0: The “java.util.concurrent” package also has classes like CopyOnWriteArrayList, CopyOnWrite-ArraySet, which gives you thread safety with the added benefit of immutability to deal with data that changes infrequently. The CopyOnWriteArrayList behaves much like the ArrayList class, except that when the list is modified, instead of modifying the underlying array, a new array is created and the old array is discarded. This means that when a caller gets an iterator (i.e. copyOnWriteArrayListRef.iterator() ), which internally holds a reference to the underlying CopyOnWriteArrayList object’s array, which is immutable and therefore can be used for traversal without requiring either synchronization on the list copyOnWriteArrayListRef or need to clone() the copyOnWriteArrayListRef list before traversal (i.e. there is no risk of concurrent modification) and also offers better performance.




Top
Q 16 Explain the Java Collections Framework?
A 16: The key interfaces used by the collections framework are List, Set and Map. The List and Set extends the Collection interface. Should not confuse the Collection interface with the Collections class which is a utility class.











The Collections API also supports maps, but within a hierarchy distinct from the Collection interface. A Map is an object that maps keys to values, where the list of keys is itself a collection object. A map can contain duplicate values, but the keys in a map must be distinct. HashMap, TreeMap and Hashtable are implementations of a Map interface. A TreeMap is an ordered HashMap, which implements the SortedMap interface.

Q. How to implement collection ordering?
SortedSet and SortedMap interfaces maintain sorted order. The classes, which implement the Comparable interface, impose natural order. By implementing Comparable, sorting an array of objects or a collection (List etc) is as simple as:

Arrays.sort(myArray);
Collections.sort(myCollection); // do not confuse “Collections” utility class with the
// “Collection” interface without an “s”.


For classes that don’t implement Comparable interface, or when one needs even more control over ordering based on multiple attributes, a Comparator interface should be used.













Important: The ordering imposed by a java.util.Comparator “myComp” on a set of elements “mySet” should be consistent with equals() method, which means for example:

if compare(o1,o2) == 0 then o1.equals(o2) should be true.
if compare(o1,o2) != 0 then o1.equals(o2) should be false.

If a comparator “myComp” on a set of elements “mySet” is inconsistent with equals() method, then SortedSet or SortedMap will behave strangely and is hard to debug. For example if you add two objects o1, o2 to a TreeSet (implements SortedSet) such that o1.equals(o2) == true and compare(o1,o2) != 0 the second add operation will return false and will not be added to your set because o1 and o2 are equivalent from the TreeSet’s perspective. TIP: It is always a good practice and highly recommended to keep the Java API documentation handy and refer to it as required while coding. Please refer to java.util.Comparator interface API for further details.

Design pattern: Q. What is an Iterator?

An Iterator is a use once object to access the objects stored in a collection.
Iterator design pattern (aka Cursor) is used, which is a behavioral design pattern that provides a way to access elements of a collection sequentially without exposing its internal representation.

Q. 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.
}
}

Solutions 1-3: for multi-thread access situation:

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

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

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

Solution 4: for single-thread access situation:

Use:
it.remove(); // removes the current object via the Iterator “it” which has a reference to
// your underlying collection “myCollection”. Also can use solutions 1-3.

Avoid:
myCollection.remove(myObject); // avoid by-passing the Iterator. When it.next() is called, can throw the exception
// ConcurrentModificationException

Note: If you had used any Object to Relational (OR) mapping frameworks like Hibernate, you may have encountered this exception “ConcurrentModificationException” when you tried to remove an object from a collection such as a java.util Set with the intention of deleting that object from the underlying database. This exception is not caused by Hibernate but rather caused by your java.util.Iterator (i.e. due to your it.next() call). You can use one of the solutions given above.

Q. What is a list iterator?
The java.util.ListIterator is an iterator for lists that allows the programmer to traverse the list in either direction (i.e. forward and or backward) and modify the list during iteration.




















What are the benefits of the Java Collections Framework? Collections framework provides flexibility, performance, and robustness.
􀂃 Polymorphic algorithms – sorting, shuffling, reversing, binary search etc.
􀂃 Set algebra - such as finding subsets, intersections, and unions between objects.
􀂃 Performance - collections have much better performance compared to the older Vector and Hashtable classes with the elimination of synchronization overheads.
􀂃 Thread-safety - when synchronization is required, wrapper implementations are provided for temporarily synchronizing existing collection objects. For J2SE 5.0 use java.util.concurrent package.
􀂃 Immutability - when immutability is required wrapper implementations are provided for making a collection immutable.
􀂃 Extensibility - interfaces and abstract classes provide an excellent starting point for adding functionality and features to create specialized object collections.

Q. What are static factory methods?
Some of the above mentioned features like searching, sorting, shuffling, immutability etc are achieved with
java.util.Collections class and java.util.Arrays utility classes. The great majority of these implementations are provided via static factory methods in a single, non-instantiable (i.e. private constrctor) class. Speaking of static factory methods, they are an alternative to creating objects through constructors. Unlike constructors, static factory methods are not required to create a new object (i.e. a duplicate object) each time they are invoked (e.g. immutable instances can be cached) and also they have a more meaningful names like valueOf, instanceOf, asList etc. For example:

Instead of:
String[] myArray = {"Java", "J2EE", "XML", "JNDI"};
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}

You can use:
String[] myArray = {"Java", "J2EE", "XML", "JNDI"};
System.out.println(Arrays.asList(myArray)); //factory method Arrays.asList(…)

For example: The following static factory method (an alternative to a constructor) example converts a boolean primitive value to a Boolean wrapper object.

public static Boolean valueOf(boolean b) {
return (b ? Boolean.TRUE : Boolean.FALSE)
}

Top
Q 17: What are some of the best practices relating to Java collection?
A 17:
􀂃 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
// use java.util.concurrent package for J2SE 5.0 Refer Q16 in Java section under ConcurrentModificationException

􀂃 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). Refer Q20 in Java section under “Q. Why is it a best practice to implement the user defined key class as an immutable object?”
􀂃
Encapsulate collections: 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. Refer Q61 in Java section for UML diagram of a composite design pattern. If you are using J2SE 5.0 then make use of “generics”. Refer Q55 in Java section for generics.











Q. How can you code better without nested loops? Avoid nested loops where possible (e.g. for loop within
another for loop etc) and instead make use of an appropriate java collection.


Top
Q 18: What is the difference between “==” and equals(…) method? What is the difference between shallow comparison and deep comparison of objects?
A 18: The questions Q18, Q19, and Q20 are vital for effective coding. These three questions are vital when you are using a collection of objects for Example: using a java.util.Set of persistable Hibernate objects etc. It is easy to implement these methods incorrectly and consequently your program can behave strangely and also is hard to debug. So, you can expect these questions in your interviews.




































Note: String assignment with the “new” operator follow the same rule as == and equals( ) as mentioned above.

String str = new String(“ABC”); //Wrong. Avoid this because a new String instance
//is created each time it is executed.

Variation to the above rule:

The “literal” String assignment is shown below, where if the assignment value is identical to another String assignment value created then a new String object is not created. A reference to the existing String object is returned.

String str = “ABC”; //Right because uses a single instance rather than
//creating a new instance each time it is executed.

Let us look at an example:

public class StringBasics {
public static void main(String[] args) {
String s1 = new String("A"); //not recommended, use String s1 = "A"
String s2 = new String("A"); //not recommended, use String s2 = "A"
//standard: follows the == and equals() rule like plain java objects.
if (s1 == s2) { //shallow comparison
System.out.println("references/identities are equal"); //never reaches here
}
if (s1.equals(s2)) { //deep comparison
System.out.println("values are equal"); // this line is printed
}
//variation: does not follow the == and equals rule
String s3 = "A"; //goes into a String pool.
String s4 = "A"; //refers to String already in the pool.
if (s3 == s4) { //shallow comparison
System.out.println("references/identities are equal"); //this line is printed
}
if (s3.equals(s4)) { //deep comparison
System.out.println("values are equal"); //this line is also printed
}
}
}


Design pattern: String class is designed with Flyweight design pattern. When you create a String constant as shown above in the variation, (i.e. String s3 = “A”, s4= “A”), it will be checked to see if it is already in the String pool. If it is in the pool, it will be picked up from the pool instead of creating a new one. Flyweights are shared objects and using them can result in substantial performance gains.

Q. What is an intern() method in the String class?
A pool of Strings is maintained by the String class. When the intern() method is invoked equals(…) method is invoked to determine if the String already exist in the pool. If it does then the String from the pool is returned. Otherwise, this String object is added to the pool and a reference to this object is returned. For any two Strings s1 & s2, s1.intern() == s2.intern() only if s1.equals(s2) is true.

Top
Q 19: What are the non-final methods in Java Object class, which are meant primarily for extension?
A 19: 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.






Top
Q 20: When providing a user defined key class for storing objects in the HashMaps or Hashtables, what methods do you have to provide or override (i.e. method overriding)? LF PI CO FAQ
A 20: You should override the equals() and hashCode() methods from the Object class. The default implementation of the equals() and hashcode(), which are inherited from the java.lang.Object uses an object instance’s memory location (e.g. MyObject@6c60f2ea). This can cause problems when two instances of the car objects have the same color but the inherited equals() will return false because it uses the memory location, which is different for the two instances. Also the toString() method can be overridden to provide a proper string representation of your object.























Q. 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 (refer Q21) object.


Q. Why it is a best practice to implement the user defined key class as an immutable object?
Problem: As per the code snippet shown below if you use a mutable user defined class “UserKey” as a HashMap key and subsequently if you mutate (i.e. modify via setter method e.g. key.setName(“Sam”)) the key after the object has been added to the HashMap then you will not be able to access the object later on. The original key object will still be in the HashMap (i.e. you can iterate through your HashMap and print it – both prints as “Sam” as opposed to “John” & Sam) but you cannot access it with map.get(key) or querying it with map.containsKey(key) will return false because the key “John” becomes “Sam” in the “List of keys” at the key index “345678965” if you mutate the key after adding. These types of errors are very hard to trace and fix.

Map myMap = new HashMap(10);
//add the key “John”
UserKey key = new UserKey(“John”); //Assume UserKey class is mutable
myMap.put(key, “Sydney”);
//now to add the key “Sam”
key.setName(“Sam”); // same key object is mutated instead of creating a new instance.
// This line modifies the key value “John” to “Sam” in the “List of keys”
// as shown in the diagram above. This means that the key “John” cannot be
// accessed. There will be two keys with “Sam” in positions with hash
// values 345678965 and 76854676.
myMap.put(key, “Melbourne”);
myMap.get(new UserKey(“John”)); // key cannot be accessed. The key hashes to the same position
// 345678965 in the “Key index array” but cannot be found in the “List of keys”

Solution: 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 in your key class. e.g. no setName(…) method in the UserKey class). 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).

Map myMap = new HashMap(10);
//add the key “John”
UserKey key1 = new UserKey(“John”); //Assume UserKey is immutable
myMap.put(key1, “Sydney”);
//add the key “Sam”
UserKey key2 = new UserKey(“Sam”); //Since UserKey is immutable, new instance is created.
myMap.put(key2, “Melbourne”);
myMap.get(new UserKey(“John”)); //Now the key can be accessed

Similar issues are possible with the Set (e.g. HashSet) as well. If you add an object to a “Set” and subsequently modify the added object and later on try to query the original object it may not be present.
mySet.contains(originalObject) may return false.
J2SE 5.0 introduces enumerated constants, which improves readability and maintainability of your code. Java
programming language enums are more powerful than their counterparts in other languages. Example: As shown below a class like “Weather” can be built on top of simple enum type “Season” and the class “Weather” can be made immutable, and only one instance of each “Weather” can be created, so that your Weather class does not have to override equals() and hashCode() methods.

public class Weather {
public enum Season {WINTER, SPRING, SUMMER, FALL}
private final Season season;
private static final List listWeather = new ArrayList ();
private Weather (Season season) { this.season = season;}
public Season getSeason () { return season;}
static {
for (Season season : Season.values()) { //using J2SE 5.0 for each loop
listWeather.add(new Weather(season));
}
}
}
public static ArrayList getWeatherList () { return listWeather; }
public String toString(){ return season;} //takes advantage of toString() method of Season.
}

Top
Q 21: What is the main difference between a String and a StringBuffer class? LF PI CI CO FAQ
A 21:




















Another important point is that creation of extra strings is not limited to overloaded mathematical operator “+” but there are several methods like concat(), trim(), substring(), and replace() in String classes that generate new string instances. So use StringBuffer or StringBuilder for computation intensive operations, which offer better performance.
Q. What is an immutable object?
Immutable objects whose state (i.e. the object’s data) does not change once it is instantiated (i.e. it becomes a read-only object after instantiation). Immutable classes are ideal for representing numbers (e.g. java.lang.Integer, java.lang.Float, java.lang.BigDecimal etc are immutable objects), enumerated
types, colors (e.g. java.awt.Color is an immutable object), short lived objects like events, messages etc.

Q. What are the benefits of immutable objects?
• Immutable classes can greatly simplify programming by freely allowing you to cache and share the references to the immutable objects without having to defensively copy them or without having to worry about their values becoming stale or corrupted.
• Immutable classes are inherently thread-safe and you do not have to synchronize access to them to be used in a multi-threaded environment. So there is no chance of negative performance consequences.
• Eliminates the possibility of data becoming inaccessible when used as keys in HashMaps or as elements in
Sets. These types of errors are hard to debug and fix. Refer Q20 in Java section under “Q. Why it is a best
practice to implement the user defined key class as an immutable object? “

Q. How will you write an immutable class? CO
Writing an immutable class is generally easy but there can be some tricky situations. Follow the following guidelines:
1. A class is declared final (i.e. final classes cannot be extended).
public final class MyImmutable { … }
2. All its fields are final (final fields cannot be mutated once assigned).
private final int[] myArray; //do not declare as 􀃆 private final int[] myArray = null;
3. Do not provide any methods that can change the state of the immutable object in any way – not just setXXX methods, but any methods which can change the state.
4. The “this” reference is not allowed to escape during construction from the immutable class and the immutable class should have exclusive access to fields that contain references to mutable objects like arrays, collections and mutable classes like Date etc by:
• Declaring the mutable references as private.
• Not returning or exposing the mutable references to the caller (this can be done by defensive copying)













to implement correctly refer Q19 in Java section but also the default behavior of an object’s clone() method automatically yields a shallow copy. You have to deep copy the mutable objects referenced by your immutable class. Refer Q26 in Java section for deep vs. shallow cloning and Q22 in Java section for why you will be modifying the original object if you do not deep copy.
Q. How would you defensively copy a Date field in your immutable class?
public final class MyDiary {
private Date myDate = null;
public MyDiary(Date aDate){
this.myDate = new Date(aDate.getTime()); // defensive copying by not exposing the “myDate” reference
}
public Date getDate() {
return new Date(myDate.getTime); // defensive copying by not exposing the “myDate” reference
}
}

Top
Q 22: What is the main difference between pass-by-reference and pass-by-value? LF PI FAQ
A 22: Other languages use pass-by-reference or pass-by-pointer. But in Java no matter what type of argument you pass the corresponding parameter (primitive variable or object reference) will get a copy of that data, which is exactly how pass-by-value (i.e. copy-by-value) works.
In Java, if a calling method passes a reference of an object as an argument to the called method then the passedin reference gets copied first and then passed to the called method. Both the original reference that was passed-in and the copied reference will be pointing to the same object. So no matter which reference you use, you will be always modifying the same original object, which is how the pass-by-reference works as well.





















If your method call involves inter-process (e.g. between two JVMs) communication, then the reference of the
calling method has a different address space to the called method sitting in a separate process (i.e. separate JVM). Hence inter-process communication involves calling method passing objects as arguments to called method by-value in a serialized form, which can adversely affect performance due to marshaling and unmarshaling cost.
Note: As discussed in Q69 in Enterprise section, EJB 2.x introduced local interfaces, where enterprise beans that can be used locally within the same JVM using Java’s form of pass-by-reference, hence improving performance
Top
Q 23: What is serialization? How would you exclude a field of a class from serialization or what is a transient variable? What is the common use? What is a serial version id? LF SI PI FAQ
A 23: Serialization is a process of reading or writing an object. It is a process of saving an object’s state to a sequence of bytes, as well as a process of rebuilding those bytes back into a live object at some future time. An object is marked serializable by implementing the java.io.Serializable interface, which is only a marker interface -- it simply allows the serialization mechanism to verify that the class can be persisted, typically to a file.
Transient variables cannot be serialized. The fields marked transient in a serializable object will not be
transmitted in the byte stream. An example would be a file handle, a database connection, a system thread etc. Such objects are only meaningful locally. So they should be marked as transient in a serializable class.

















Serialization can adversely affect performance since it:
􀂃 Depends on reflection.
􀂃 Has an incredibly verbose data format.
􀂃 Is very easy to send surplus data.

Q. When to use serialization?
Do not use serialization if you do not have to. A common use of serialization is to use it to send an object over the network or if the state of an object needs to be persisted to a flat file or a database. (Refer Q57 on Enterprise section). Deep cloning or copy can be achieved through serialization. This may be fast to code but will have performance implications (Refer Q26 in Java section).
To serialize the above “Car” object to a file (sample for illustration purpose only, should use try {} catch {} block):

Car car = new Car(); // The “Car” class implements a java.io.Serializable interface
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(car); // serialization mechanism happens here
out.close();

The objects stored in an HTTP session should be serializable to support in-memory replication of sessions to
achieve scalability (Refer Q20 in Enterprise section). Objects are passed in RMI (Remote Method Invocation)
across network using serialization (Refer Q57 in Enterprise section).

Q. What is Java Serial Version ID?
Say you create a “Car” class, instantiate it, and write it out to an object stream. The flattened car object sits in the file system for some time. Meanwhile, if the “Car” class is modified by adding a new field. Later on, when you try to read (i.e. deserialize) the flattened “Car” object, you get the java.io.InvalidClassException – because all serializable classes are automatically given a unique identifier. This exception is thrown when the identifier of the class is not equal to the identifier of the flattened object. If you really think about it, the exception is thrown because of the addition of the new field. You can avoid this exception being thrown by controlling the versioning yourself by declaring an explicit serialVersionUID. There is also a small performance benefit in explicitly declaring your serialVersionUID (because does not have to be calculated). So, it
is best practice to add your own serialVersionUID to your Serializable classes as soon as you create them as
shown below:

public class Car {
static final long serialVersionUID = 1L; //assign a long value
}

Note: Alternatively you can use the serialver tool comes with Sun’s JDK. This tool takes a full class name on the command line and returns the serialVersionUID for that compiled class. For example:

static final long serialVersionUID = 10275439472837494L; //generated by serialver tool.
Top
Q 24: Explain the Java I/O streaming concept and the use of the decorator design pattern in Java I/O? LF DP PI SI
A 24: Java input and output is defined in terms of an abstract concept called a “stream”, which is a sequence of data.
There are 2 kinds of streams.
􀂃 Byte streams (8 bit bytes) 􀃆 Abstract classes are: InputStream and OutputStream
􀂃 Character streams (16 bit UNICODE) 􀃆 Abstract classes are: Reader and Writer
Design pattern: java.io.* classes use the decorator design pattern. The decorator design pattern attaches
responsibilities to objects at runtime. Decorators are more flexible than inheritance because the inheritance
attaches responsibility to classes at compile time. The java.io.* classes use the decorator pattern to construct
different combinations of behavior at runtime based on some basic classes.






































Q. How does the new I/O (NIO) offer better scalability and better performance?
Java has long been not suited for developing programs that perform a lot of I/O operations. Furthermore,
commonly needed tasks such as file locking, non-blocking and asynchronous I/O operations and ability to map file
to memory were not available. Non-blocking I/O operations were achieved through work around such as
multithreading or using JNI. The New I/O API (aka NIO) in J2SE 1.4 has changed this situation.
A server’s ability to handle several client requests effectively depends on how it uses I/O streams. When a server has to handle hundreds of clients simultaneously, it must be able to use I/O services concurrently. One way to cater for this scenario in Java is to use threads but having almost one-to-one ratio of threads (100 clients will have 100 threads) is prone to enormous thread overhead and can result in performance and scalability problems due to consumption of memory stacks (i.e. each thread has its own stack. Refer Q34, Q42 in Java section) and CPU context switching (i.e. switching between threads as opposed to doing real computation.). To overcome this problem, a new set of non-blocking I/O classes have been introduced to the Java platform in java.nio package.
The non-blocking I/O mechanism is built around Selectors and Channels. Channels, Buffers and Selectors are
the core of the NIO.



















A Channel class represents a bi-directional communication channel (similar to InputStream and OutputStream)
between datasources such as a socket, a file, or an application component, which is capable of performing one or
more I/O operations such as reading or writing. Channels can be non-blocking, which means, no I/O operation will
wait for data to be read or written to the network. The good thing about NIO channels is that they can be
asynchronously interrupted and closed. So if a thread is blocked in an I/O operation on a channel, another thread
can interrupt that blocked thread.
A Selector class enables multiplexing (combining multiple streams into a single stream) and demultiplexing
(separating a single stream into multiple streams) I/O events and makes it possible for a single thread to efficiently
manage many I/O channels. A Selector monitors selectable channels, which are registered with it for I/O events
like connect, accept, read and write. The keys (i.e. Key1, Key2 etc represented by the SelectionKey class)
encapsulate the relationship between a specific selectable channel and a specific selector.
Buffers hold data. Channels can fill and drain Buffers. Buffers replace the need for you to do your own buffer
management using byte arrays. There are different types of Buffers like ByteBuffer, CharBuffer, DoubleBuffer, etc.
Design pattern: NIO uses a reactor design pattern, which demultiplexes events (separating single stream into
multiple streams) and dispatches them to registered object handlers. The reactor pattern is similar to an observer pattern (aka publisher and subscriber design pattern), but an observer pattern handles only a single source of events (i.e. a single publisher with multiple subscribers) where a reactor pattern handles multiple event sources (i.e. multiple publishers with multiple subscribers). The intent of an observer pattern is to define a one-to-many dependency so that when one object (i.e. the publisher) changes its state, all its dependents (i.e. all its subscribers) are notified and updated correspondingly.
Another sought after functionality of NIO is its ability to map a file to memory. There is a specialized form of a
Buffer known as “MappedByteBuffer”, which represents a buffer of bytes mapped to a file. To map a file to
“MappedByteBuffer”, you must first get a channel for a file. Once you get a channel then you map it to a buffer and subsequently you can access it like any other “ByteBuffer”. Once you map an input file to a “CharBuffer”, you can do pattern matching on the file contents. This is similar to running “grep” on a UNIX file system. Another feature of NIO is its ability to lock and unlock files. Locks can be exclusive or shared and can be held on a contiguous portion of a file. But file locks are subject to the control of the underlying operating system.

Top
Q 25: How can you improve Java I/O performance? PI BP
A 25: Java applications that utilize Input/Output are excellent candidates for performance tuning. Profiling of Java applications that handle significant volumes of data will show significant time spent in I/O operations. This means substantial gains can be had from I/O performance tuning. Therefore, I/O efficiency should be a high priority for developers looking to optimally increase performance.
The basic rules for speeding up I/O performance are
􀂃 Minimize accessing the hard disk.
􀂃 Minimize accessing the underlying operating system.
􀂃 Minimize processing bytes and characters individually.

Let us look at some of the techniques to improve I/O performance. CO
􀂃
Use buffering to minimize disk access and underlying operating system. As shown below, with buffering
large chunks of a file are read from a disk and then accessed a byte or character at a time.





















Instead of reading a character or a byte at a time, the above code with buffering can be improved further by
reading one line at a time as shown below:
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr);
while (br.readLine() != null) count++;
By default the System.out is line buffered, which means that the output buffer is flushed when a new line character (i.e. “n”) is encountered. This is required for any interactivity between an input prompt and display of output. The line buffering can be disabled for faster I/O operation as follows:

FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);
PrintStream ps = new PrintStream(bos,false);

// To redirect standard output to a file instead of the “System” console which is the default for both “System.out” (i.e.
// standard output) and “System.err” (i.e. standard error device) variables

System.setOut(ps);

while (someConditionIsTrue)
System.out.println(“blah…blah…”);
}

It is recommended to use logging frameworks like Log4J with SLF4J (Simple Logging Façade for Java),
which uses buffering instead of using default behavior of System.out.println(…..) for better performance.
Frameworks like Log4J are configurable, flexible, extensible and easy to use.
􀂃 Use the NIO package, if you are using JDK 1.4 or later, which uses performance-enhancing features like
buffers to hold data, memory mapping of files, non-blocking I/O operations etc.
􀂃 I/O performance can be improved by minimizing the calls to the underlying operating systems. The Java runtime itself cannot know the length of a file, querying the file system for isDirectory(), isFile(), exists() etc must query the underlying operating system.
􀂃 Where applicable caching can be used to improve performance by reading in all the lines of a file into a Java Collection class like an ArrayList or a HashMap and subsequently access the data from an in-memory collection instead of the disk.

Top
Q 26: What is the main difference between shallow cloning and deep cloning of objects? DC LF MI PI
A 26: The default behavior of an object’s clone() method automatically yields a shallow copy. So to achieve a deep copy the classes must be edited or adjusted.
Shallow copy: If a shallow copy is performed on obj-1 as shown in fig-2 then it is copied but its contained objects are not. The contained objects Obj-1 and Obj-2 are affected by changes to cloned Obj-2. Java supports shallow cloning of objects by default when a class implements the java.lang.Cloneable interface.
Deep copy: If a deep copy is performed on obj-1 as shown in fig-3 then not only obj-1 has been copied but the objects contained within it have been copied as well. Serialization can be used to achieve deep cloning. Deep cloning through serialization is faster to develop and easier to maintain but carries a performance overhead.






















For example invoking clone() method on a collection like HashMap, List etc returns a shallow copy of HashMap,
List, instances. This means if you clone a HashMap, the map instance is cloned but the keys and values
themselves are not cloned. If you want a deep copy then a simple method is to serialize the HashMap to a
ByteArrayOutputSream and then deserialize it. This creates a deep copy but does require that all keys and values in the HashMap are Serializable. Main advantage of this approach is that it will deep copy any arbitrary object graph. Refer Q23 in Java section for deep copying using Serialization. Alternatively you can provide a static factory method to deep copy. Example: to deep copy a list of Car objects.


public static List deepCopy(List listCars) {
List copiedList = new ArrayList(10);
for (Object object : listCars) { //JDK 1.5 for each loop
Car original = (Car)object;
Car carCopied = new Car(); //instantiate a new Car object
carCopied.setColor((original.getColor()));
copiedList.add(carCopied);
}
return copiedList;
}



Top
Q 27: What is the difference between an instance variable and a static variable? How does a local variable compare to an instance or a static variable? Give an example where you might use a static variable? LF FAQ


Top
Q 28: Give an example where you might use a static method? LF FAQ
A 28: Static methods prove useful for creating utility classes, singleton classes and factory methods (Refer Q51, Q52 in Java section). Utility classes are not meant to be instantiated. Improper coding of utility classes can lead to procedural coding. java.lang.Math, java.util.Collections etc are examples of utility classes in Java.

Top
Q 29: What are access modifiers? LF FAQ
A 29:


Top
Q 30: Where and how can you use a private constructor? LF FAQ
A 30: Private constructor is used if you do not want other classes to instantiate the object and to prevent subclassing. The instantiation is done by a public static method (i.e. a static factory method) within the same class.
􀂃- Used in the singleton design pattern. (Refer Q51 in Java section).
􀂃- Used in the factory method design pattern (Refer Q52 in Java section). e.g. java.util.Collections class (Refer
Q16 in Java section).
􀂃- Used in utility classes e.g. StringUtils etc.

Top
Q 31: What is a final modifier? Explain other Java modifiers? LF FAQ
Q 31: What is a final modifier? Explain other Java modifiers? LF FAQ
A 31: A final class can’t be extended i.e. A final class can not be subclassed. A final method can’t be overridden when its class is inherited. You can’t change value of a final variable (i.e. it is a constant).






















Note: Be prepared for tricky questions on modifiers like, what is a “volatile”? Or what is a “const”? Etc. The
reason it is tricky is that Java does have these keywords “const” and “volatile” as reserved, which means you can’t
name your variables with these names but modifier “const” is not yet added in the language and the modifier
“volatile” is very rarely used.
The “volatile” modifier is used on instance variables that may be modified simultaneously by other threads. The
modifier volatile only synchronizes the variable marked as volatile whereas “synchronized” modifier synchronizes
all variables. Since other threads cannot see local variables, there is no need to mark local variables as volatile.
For example:
volatile int number;
volatile private List listItems = null;
Java uses the “final” modifier to declare constants. A final variable or constant declared as “final” has a value that
is immutable and cannot be modified to refer to any other objects other than one it was initialized to refer to. So
the “final” modifier applies only to the value of the variable itself, and not to the object referenced by the variable.
This is where the “const” modifier can come in very useful if added to the Java language. A reference variable
or a constant marked as “const” refers to an immutable object that cannot be modified. The reference variable
itself can be modified, if it is not marked as “final”. The “const” modifier will be applicable only to non-primitive
types. The primitive types should continue to use the modifier “final”.
Q. If you want to extend the “java.lang.String” class, what methods will you override in your extending class?
You would be tempted to say equals(), hashCode() and toString() based on Q19, Q20 in Java section but the “java.lang.String” class is declared final and therefore it cannot be extended.
Top
Q 32: What is the difference between final, finally and finalize() in Java? LF FAQ
A 32:
􀂃 final - constant declaration. Refer Q31 in Java section.
􀂃 finally - handles exception. The finally block is optional and provides a mechanism to clean up regardless of what happens within the try block (except System.exit(0) call). Use the finally block to close files or to release other system resources like database connections, statements etc. (Refer Q45 in Enterprise section)
􀂃 finalize() - method helps in garbage collection. A method that is invoked before an object is discarded by the garbage collector, allowing it to clean up its state. Should not be used to release non-memory resources like file handles, sockets, database connections etc because Java has only a finite number of these resources and you do not know when the garbage collection is going to kick in to release these non-memory resources through the finalize() method. Refer Q19 in Java Section.
Top
Q 33: Why would you prefer a short circuit “&&, ||” operators over logical “& , |” operators? LF
A 33: Firstly NullPointerException is by far the most common RuntimeException. If you use the logical operator you can get a NullPointerException. This can be avoided easily by using a short circuit “&&” operator as shown below.
There are other ways to check for null but short circuit && operator can simplify your code by not having to declare separate if clauses.
if((obj != null) & obj.equals(newObj)) { //can cause a NullPointerException if obj == null
... // because obj.equals(newObj) is always executed.
}
Short-circuiting means that an operator only evaluates as far as it has to, not as far as it can. If the variable 'obj' equals null, it won't even try to evaluate the 'obj.equals(newObj)’ clause as shown in the following example. This protects the potential NullPointerException.
if((obj != null) && obj.equals(newObj)) { //cannot get a NullPointerException because
... //obj.equals(newObj) is executed only if obj != null
}
Secondly, short-circuit “&&” and “||” operators can improve performance in certain situations. For example:
if((number <= 7) || (doComputeIntensiveAnalysis(number) <= 13)) { //the CPU intensive
.... //computational method in bold is executed only if number > 7.
}

Top
Q 34: How does Java allocate stack and heap memory? Explain re-entrant, recursive and idempotent methods/functions? MI CI
A 34: Each time an object is created in Java it goes into the area of memory known as heap. The primitive variables like int and double are allocated in the stack (i.e. Last In First Out queue), if they are local variables and in the heap if they are member variables (i.e. fields of a class). In Java methods and local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed. In a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is thread-safe because each thread will have its own stack with say 1MB RAM allocated for each thread but the heap is not thread-safe unless guarded with synchronization through your code. The stack space can be increased with the –Xss option.



































All Java methods are automatically re-entrant. It means that several threads can be executing the same method at once, each with its own copy of the local variables. A Java method may call itself without needing any special declarations. This is known as a recursive method call. Given enough stack space, recursive method calls are perfectly valid in Java though it is tough to debug. Recursive methods are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive. Idempotent methods are methods, which are written in such a way that repeated calls to the same method with the same arguments yield same results. For example clustered EJBs, which are written with idempotent methods, can automatically recover from a server failure as long as it can reach another server (i.e. scalable).
Top
Q 35: Explain Outer and Inner classes (or Nested classes) in Java? When will you use an Inner Class? LF SE
A 35: In Java not all classes have to be defined separate from each other. You can put the definition of one class inside the definition of another class. The inside class is called an inner class and the enclosing class is called an outer class. So when you define an inner class, it is a member of the outer class in much the same way as other members like attributes, methods and constructors.
Q. Where should you use inner classes? Code without inner classes is more maintainable and readable.
When you access private data members of the outer class, the JDK compiler creates package-access member functions in the outer class for the inner class to access the private members. This leaves a security hole. In general we should avoid using inner classes. Use inner class only when an inner class is only relevant in the context of the outer class and/or inner class can be made private so that only outer class can access it. Inner classes are used primarily to implement helper classes like Iterators, Comparators etc which are used in the context of an outer class.






























Note: If you have used the Spring framework with the Hibernate framework (Both are very popular frameworks,
Refer section “Emerging Technologies/Frameworks”), it is likely that you would have used an anonymous inner
class (i.e. a class declared inside a method) as shown below:
//anonymous inner classes can only access local variables if they are declared as final
public Pet getPetById(final String id) {
return (Pet) getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session) {
HibernateTemplate ht = getHibernateTemplate();
// … can access variable “id”
return myPet;
}
});
}
Q. Are the following valid java statements?
Line: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
Yes. The above line is valid. It is an instantiation of a static nested inner class.
OuterClass outerObject = new OuterClass();
Line: OuterClass.InnerClass innerObject = outerObject.new InnerClass();
Yes. The above line is valid. It is an instantiation of a member inner class. An instance of an inner class can exist
only within an instance of an outer class. The sample code for the above is shown below:
public class OuterClass {
static class StaticNestedClass {
StaticNestedClass(){
System.out.println("StaticNestedClass");
}
}
class InnerClass {
InnerClass(){
System.out.println("InnerClass");
}
}
}

Top
Q 36: What is type casting? Explain up casting vs. down casting? When do you get ClassCastException? LF DP FAQ
A 36: Type casting means treating a variable of one type as though it is another type.
When up casting primitives as shown below from left to right, automatic conversion occurs. But if you go from
right to left, down casting or explicit casting is required. Casting in Java is safer than in C or other languages that
allow arbitrary casting. Java only lets casts occur when they make sense, such as a cast between a float and an
int. However you can't cast between an int and a String (is an object in Java).
byte 􀃆 short 􀃆 int 􀃆 long 􀃆 float 􀃆 double
int i = 5;
long j = i; //Right. Up casting or implicit casting
byte b1 = i; //Wrong. Compile time error “Type Mismatch”.
byte b2 = (byte) i ; //Right. Down casting or explicit casting is required.

When it comes to object references you can always cast from a subclass to a superclass because a subclass object is also a superclass object. You can cast an object implicitly to a super class type (i.e. upcasting). If this were not the case polymorphism wouldn’t be possible.
























You can cast down the hierarchy as well but you must explicitly write the cast and the object must be a
legitimate instance of the class you are casting to. The ClassCastException is thrown to indicate that code
has attempted to cast an object to a subclass of which it is not an instance. If you are using J2SE 5.0 then
“generics” will eliminate the need for casting (Refer Q55 in Java section) and otherwise you can deal with the
problem of incorrect casting in two ways:
􀂃 Use the exception handling mechanism to catch ClassCastException.
try{
Object o = new Integer(1);
System.out.println((String) o);
}
catch(ClassCastException cce) {
logger.log(“Invalid casting, String is expected…Not an Integer”);
System.out.println(((Integer) o).toString());
}
􀂃 Use the instanceof statement to guard against incorrect casting.
if(v2 instanceof Car) {
Car c2 = (Car) v2;
}
Design pattern: The “instanceof” and “typecast” constructs are shown for the illustration purpose only.
Using these constructs can be unmaintainable due to large if and elseif statements and can affect
performance if used in frequently accessed methods or loops. Look at using visitor design pattern to avoid these constructs where applicable. (Refer Q11 in How would you go about section…).
Points-to-ponder: You can also get a ClassCastException when two different class loaders load the same class because they are treated as two different classes.
Top
Q 37 What do you know about the Java garbage collector? When does the garbage collection occur? Explain different types of references in Java? LF MI FAQ
Each time an object is created in Java, it goes into the area of memory known as heap. The Java heap is called the garbage collectable heap. The garbage collection cannot be forced. The garbage collector runs in low memory situations. When it runs, it releases the memory allocated by an unreachable object. The garbage collector runs on a low priority daemon (i.e. background) thread. You can nicely ask the garbage collector to collect garbage by calling System.gc() but you can’t force it.

What is an unreachable object?


























































An object’s life has no meaning unless something has reference to it. If you can’t reach it then you can’t ask it to do anything. Then the object becomes unreachable and the garbage collector will figure it out. Java automatically collects all the unreachable objects periodically and releases the memory consumed by those unreachable objects to be used by the future reachable objects.
We can use the following options with the Java command to enable tracing for garbage collection events.
java -verbose:gc //reports on each garbage collection event.
Explain types of references in Java? java.lang.ref package can be used to declare soft, weak and phantom references.
􀂃 Garbage Collector won’t remove a strong reference.
􀂃 A soft reference will only get removed if memory is low. So it is useful for implementing caches while
avoiding memory leaks.
􀂃 A weak reference will get removed on the next garbage collection cycle. Can be used for implementing canonical maps. The java.util.WeakHashMap implements a HashMap with keys held by weak references.
􀂃 A phantom reference will be finalized but the memory will not be reclaimed. Can be useful when you want to be notified that an object is about to be collected.







































Top
Q 38: If you have a circular reference of objects, but you no longer reference it from an execution thread, will this object be a potential candidate for garbage collection? LF MI
A 38: Yes. Refer diagram below.



Top
Q 39: Discuss the Java error handling mechanism? What is the difference between Runtime (unchecked) exceptions and checked exceptions? What is the implication of catching all the exceptions with the type “Exception”? EH BP FAQ
A 39:
Errors: When a dynamic linking failure or some other “hard” failure in the virtual machine occurs, the virtual
machine throws an Error. Typical Java programs should not catch Errors. In addition, it’s unlikely that typical Java programs will ever throw Errors either.
Exceptions: Most programs throw and catch objects that derive from the Exception class. Exceptions indicate
that a problem occurred but that the problem is not a serious JVM problem. An Exception class has many
subclasses. These descendants indicate various types of exceptions that can occur. For example,
NegativeArraySizeException indicates that a program attempted to create an array with a negative size. One
exception subclass has special meaning in the Java language: RuntimeException. All the exceptions except
RuntimeException are compiler checked exceptions. If a method is capable of throwing a checked exception it
must declare it in its method header or handle it in a try/catch block. Failure to do so raises a compiler error. So checked exceptions can, at compile time, greatly reduce the occurrence of unhandled exceptions surfacing at runtime in a given application at the expense of requiring large throws declarations and encouraging use of poorlyconstructed try/catch blocks. Checked exceptions are present in other languages like C++, C#, and Python.




































Runtime Exceptions (unchecked exception)
A RuntimeException class represents exceptions that occur within the Java virtual machine (during runtime). An example of a runtime exception is NullPointerException. The cost of checking for the runtime exception often outweighs the benefit of catching it. Attempting to catch or specify all of them all the time would make your code unreadable and unmaintainable. The compiler allows runtime exceptions to go uncaught and unspecified. If you like, you can catch these exceptions just like other exceptions. However, you do not have to declare it in your “throws" clause or catch it in your catch clause. In addition, you can create your own RuntimeException subclasses and this approach is probably preferred at times because checked exceptions can complicate method signatures and can be difficult to follow.
Q. What are the exception handling best practices: BP
1. Q. Why is it not advisable to catch type “Exception”? CO
Exception handling in Java is polymorphic in nature. For example if you catch type Exception in your code then it can catch or throw its descendent types like IOException as well. So if you catch the type Exception before the type IOException then the type Exception block will catch the entire exceptions and type IOException block is never reached. In order to catch the type IOException and handle it differently to type Exception, IOException should be caught first (remember that you can’t have a bigger basket above a smaller basket).






























The diagram above is an example for illustration only. In practice it is not recommended to catch type
“Exception”. We should only catch specific subtypes of the Exception class. Having a bigger basket (i.e.
Exception) will hide or cause problems. Since the RunTimeException is a subtype of Exception, catching the type Exception will catch all the run time exceptions (like NullPointerException, ArrayIndexOutOfBoundsException) as well.

Example: The FileNotFoundException is extended (i.e. inherited) from the IOException. So (subclasses have to
be caught first) FileNotFoundException (small basket) should be caught before IOException (big basket).
2. Q. Why should you throw an exception early? CO
The exception stack trace helps you pinpoint where an exception occurred by showing you the exact sequence of method calls that lead to the exception. By throwing your exception early, the exception becomes more accurate and more specific. Avoid suppressing or ignoring exceptions. Also avoid using exceptions just to get a flow control. Instead of:

// assume this line throws an exception because filename == null.
InputStream in = new FileInputStream(fileName);


if(filename == null) {
throw new IllegalArgumentException(“file name is null”);
}
InputStream in = new FileInputStream(fileName);

3. Why should you catch a checked exception late in a catch {} block?
You should not try to catch the exception before your program can handle it in an appropriate manner. The natural tendency when a compiler complains about a checked exception is to catch it so that the compiler stops reporting errors. It is a bad practice to sweep the exceptions under the carpet by catching it and not doing anything with it.
The best practice is to catch the exception at the appropriate layer (e.g. an exception thrown at an integration layer can be caught at a presentation layer in a catch {} block), where your program can either meaningfully recover from the exception and continue to execute or log the exception only once in detail, so that user can identify the cause of the exception.
4. Q. When should you use a checked exception and when should you use an unchecked exception?
Due to heavy use of checked exceptions and minimal use of unchecked exceptions, there has been a hot debate in the Java community regarding true value of checked exceptions. Use checked exceptions when the client code can take some useful recovery action based on information in exception. Use unchecked exception when client code cannot do anything. For example Convert your SQLException into another checked exception if the client code can recover from it. Convert your SQLException into an unchecked (i.e. RuntimeException) exception, if the client code can not recover from it. (Note: Hibernate 3 & Spring uses RuntimeExceptions prevalently).
Important: throw an exception early and catch an exception late but do not sweep n exception under the carpet by catching it and not doing anything with it. This will hide problems and it will be hard to debug and fix. CO
A note on key words for error handling:
throw / throws – used to pass an exception to the method that called it.
try – block of code will be tried but may cause an exception.
catch – declares the block of code, which handles the exception.
finally – block of code, which is always executed (except System.exit(0) call) no matter what program flow, occurs when dealing with an exception.
assert – Evaluates a conditional expression to verify the programmer’s assumption.
Top
Q 40: What is a user defined exception? EH
A 40: User defined exceptions may be implemented by defining a new exception class by extending the Exception class.
public class MyException extends Exception {
/* class definition of constructors goes here */
public MyException() {
super();
}
public MyException (String errorMessage) {
super (errorMessage);
}
}
Throw and/or throws statement is used to signal the occurrence of an exception. To throw an exception:
throw new MyException(“I threw my own exception.”)
To declare an exception: public myMethod() throws MyException {…}
Top
Render time: 0.34 seconds
7,458,377 unique visits