Thursday, January 10, 2013

Java Interview Questions - 2

Q: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).
  • ObjectOriented(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 standardised APIs (Application Program Interfaces).
 Q:What is the main difference between the Java platform and the other software platforms?

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.
  • JavaApplicationProgrammingInterface(JavaAPI)-
Q: What is the difference between C++ and Java?
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. 
  • Java does not support destructors but rather 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 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 resources through the finalize() method.
  • Java does not include structures or unions because the traditional data structures are implemented as an object oriented framework.
  • 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.
Q:Explain Java class loaders? Explain dynamic class loading? 
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 specially 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.



todo







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.
The following code gives an Output of A=5, B=10.

public class StaticInitilaizer {
public static final int A = 5;
public static final int B;
//Static initializer block, which is executed only once when the class is loaded.
static {
if(A == 5)
B = 10;
else
B = 5;
}
public StaticInitilaizer(){} // constructor is called only after static initializer block
}
public class Test {
System.out.println("A =" + StaticInitilaizer.A + ", B =" + StaticInitilaizer.B);
}
Q: What are the advantages of Object Oriented Programming Languages (OOPL)? 
The Object Oriented Programming Languages directly represent the real life objects like Car, Jeep, AccountCustomer etc. The features of the OO programming languages like polymorphism, inheritance and encapsulation make it powerful. 

Q: How does the Object Oriented approach improve software development? The key benefits are:
  • Reuse of previous work : using implementation inheritance and object composition
  • Real mapping to the problem domain: Objects map to real world and represent vehicles, customers, products etc: with encapsulation
  • ModularArchitecture: Objects, systems, frameworks etc are the building blocks of largersystems.
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.

Q: 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?
The is arelationship is expressed with inheritance and has arelationship 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.
Which one to use? The guide is that inheritance should be only used when subclass is asuperclass.
  • 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 Q8 in Java section for interface inheritance).
What is the difference between aggregation and composition?
Aggregation: Aggregation is an association in which one class belongs to a collection. This is a part of a whole relationship where a part can exist without a whole. a line item is a whole and product is a part. If a line item is deleted then corresponding product need not be deleted. So aggregation has a weaker relationship.

Composition: Composition is an association in which one class belongs to a collection. This is a part of a whole relationship where a part cannot exist without a whole. If a whole is deleted then all parts are deleted. An order is a whole and line items are parts. If an order deleted then all corresponding line items for that order should be deleted. So composition has a stronger relationship.

Q: What do you mean by polymorphism, inheritance, encapsulation, and dynamic binding? 
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

Inheritance – is the inclusion of behaviour (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:

Implementation inheritance (aka class inheritance): You can extend an applications’ 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 behaviour of the superclass, not on the actual implementation. For example in the above diagram the subclasses should only be concerned about the behaviour known as area() but not how it is implemented.

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 favours interface inheritance to implementation inheritance.

Encapsulation – refers to keeping all the related members (variables and methods) together in an object. Specifying members 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.

Q: What is the difference between an abstract class and an interface and when should you use them?
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 behaviour), 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:
  • Capturesimilaritiesamongunrelatedclasseswithoutartificiallyforcingaclassrelationship.
  • 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.
Abstract class
  • Have executable methods and abstract methods.
  • Can only subclass one abstract class.
  • Can have instance variables, constructors and any visibility: public, private, protected, none (aka package).
Interface
  • Have no implementation code. All methods are abstract.
  • A class can implement any number of interfaces.
  • Cannot have instance variables, constructors and can have only public and none (aka package) visibility.
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 behaviour and force subclasses to provide any specific behaviour.

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. Coding to an interface reduces coupling and interface inheritance can achieve code reuse with the help of object composition. 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 inheritances. Java only supports multiple interface inheritance. Interface will solve all the ambiguities caused by this ‘diamond problem’.

Q:Why there are some interfaces with no defined methods (i.e. marker interfaces) in Java?
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. Serializable, Cloneable etc

Q:When is a method said to be overloaded and when is a method said to be overridden?
Method Overloading:
Overloading deals with multiple methods in the same class with the same name but different method signatures.
class MyClass {
public void getInvestAmount(int rate) {...}
public void getInvestAmount(int rate, long principal)
{...}
}
Both the above methods have the same method names but different method signatures, which mean the methods are overloaded.

Overloading lets you define the same operation in different ways for different data.
Method Overriding: Overriding deals with two methods, one in the parent class and the other one in the child class and has the same name and signatures.

class BaseClass{
   public void getInvestAmount(int rate) {...}
}
class MyClass extends BaseClass {
   public void getInvestAmount(int rate) { ...}
}
Both the above methods have the same method names and the signatures but the method in the subclass MyClass overrides the method in the superclass BaseClass.
Overriding lets you define the same operation in different ways for different object types.

Q: Explain the Java Collection framework?
The key interfaces used by the collection 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.

A Set is a collection with unique elements and prevents duplication within the collection. HashSet and TreeSet are implementations of a Set interface. 
A List is a collection with an ordered sequence of elements and may contain duplicates. ArrayList, LinkedList and Vector are implementations of a List interface.
The Collection 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.

How to implement collection ordering? SortedSet and SortedMap interfaces maintain sorted order. The classes, which implement the Comparable interface, impose natural order. 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.

Design pattern: 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 behavioural design pattern that provides a way to access elements of a collection sequentially without exposing its internal representation.

What are the benefits of the Java collection framework? Collection framework provides flexibility, performance, and robustness.
  • Polymorphic algorithms–sorting,shuffling,reversing,binarysearchetc.
  • 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. 
  • 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 some of the best practices relating to Java collection?
  • Use ArrayLists, 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);    List myList = Collections.synchronizedList (myList);
  • 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 minimise 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. UseList list = new ArrayList(100); //program in terms of interface & set the initial capacity. Instead ofArrayList list = new ArrayList();
  • Avoid storing unrelated or different types of objects into same collection: This is analogous to storing items in pigeonholes without any labelling. To store items use value objects or data objects (as oppose to storing every attribute in an ArrayList or HashMap). Provide wrapper classes around your collection 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. 
Q: 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)? 
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 colour 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. Points to consider:
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.

Q: What is the main difference between a String and a StringBuffer class?

String: String is immutable: you can’t modify a string object but can replace it by creating a new instance. Creating a new instance is rather expensive.
//Inefficient version using immutable String

String output = “Some text”

Int count = 100;
for(int I =0; i<count; i++) {

    output += i;
return output;

The above code would build 99 new String objects, of which 98 would be thrown away immediately. Creating new objects is not efficient.
StringBuffer/StringBuilder: StringBuffer is mutable: use StringBuffer or StringBuilder when you want to modify the contents. StringBuilder was added in Java 5 and it is identical in all respects to StringBuffer except that it is not synchronised, which makes it slightly faster at the cost of not being thread-safe.

//More efficient version using mutable StringBuffer

StringBuffer output = new StringBuffer(110);
Output.append(“Some text”);
for(int I =0; i<count; i++) {
    output.append(i);
}
return output.toString();

The above code creates only two new objects, the StringBuffer and the final String that is returned. StringBuffer expands as needed, which is costly however, so it would be better to initialise the StringBuffer with the correct size
from the start as shown.

Another important point is that creation of extra strings is not limited to 'overloaded mathematical operators' (“+”) 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 the main difference between pass-by-reference and pass-by-value? 
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 passed- in 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 marshalling and unmarshalling cost.

Q: 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?
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 or a database connection. 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 dataformat.
  • Is very easy to send surplus data.
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.Deep cloning or copy can be achieved through serialization. This may be fast to code but will have performance implications. The objects stored in an HTTP session should be serializable to support in-memory replication of sessions to achieve scalability. Objects are passed in RMI (Remote Method Invocation) across network using serialization.Q:How can you improve Java I/O performance?
Java applications that utilise 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
  • Minimise accessing the harddisk.
  • Minimise accessing the underlying operating system.
  • Minimise processing bytes and characters individually.
Q: What is the difference between an instance variable and a static variable? Give an example where you might use a static variable?
Static Variable: Class variables are called static variables. There is only one occurrence of a class variable per JVM per class loader. When a class is loaded the class variables (aka static variables) are initialized.
Instance Variable: Instance variables are non-static and there is one occurrence of an instance variable in each class instance (i.e. each object).

A static variable is used in the singleton pattern. A static variable is used with a final modifier to define constants.

Q:Where and how can you use a private constructor?
Private constructor is used if you do not want other classes to instantiate the object. The instantiation is done by a public static method within the same class.
  • Used in the singleton pattern. 
  • Used in the factory method pattern
  • Used in utility classes e.g. StringUtils etc.
Q: What is the difference between final, finally and finalize() in Java?
  • final - constant declaration. 
  • 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.  
  • 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.
Q: How does Java allocate stack and heap memory? Explain re-entrant, recursive and idempotent methods/functions? 
Each time an object is created in Java it goes into the area of memory known as heap. The primitive variables like int and double are allocated in the stack, if they are local method variables and in the heap if they are member variables (i.e. fields of a class). In Java methods local variables are pushed into stack when a method is invoked and stack pointer is decremented when a method call is completed. In a multi-threaded application each thread will have its own stack but will share the same heap. This is why care should be taken in your code to avoid any concurrent access issues in the heap space. The stack is threadsafe (each thread will have its own stack) but the heap is not threadsafe unless guarded with synchronisation through your code.

A method in stack is re-entrant allowing multiple concurrent invocations that do not interfere with each other. A function is recursive if it calls itself. Given enough stack space, recursive method calls are perfectly valid in Java though it is tough to debug. Recursive functions are useful in removing iterations from many sorts of algorithms. All recursive functions are re-entrant but not all re-entrant functions are recursive. Idempotent methods are methods, which are written in such a way that repeated calls to the same method with the same arguments yield same results. For example clustered EJBs, which are written with idempotent methods, can automatically recover from a server failure as long as it can reach another server.

No comments:

Post a Comment