Types (Hierarchy) of Java Class Loaders
Java class loaders can be broadly classified into below categories:

Bootstrap Class Loader
Bootstrap class loader loads java’s core classes like java.lang, java.util etc. These are classes that are part of java runtime environment. Bootstrap class loader is native implementation and so they may differ across different JVMs.

Extensions Class Loader
JAVA_HOME/jre/lib/ext contains jar packages that are extensions of standard core java classes. Extensions class loader loads classes from this ext folder. Using the system environment propery java.ext.dirs you can add ‘ext’ folders and jar files to be loaded using extensions class loader.

System Class Loader
Java classes that are available in the java classpath are loaded using System class loader.

Why you need class Loaders
Applications written in statically compiled programming languages, such as C and C++, are compiled into native, machine-specific instructions and saved as an executable file. The process of combining the code into an executable native code is called linking – the merging of separately compiled code with shared library code to create an executable application. This is different in dynamically compiled programming languages such as Java. In Java, the .class files generated by the Java compiler remain as-is until loaded into the Java Virtual Machine (JVM) — in other words, the linking process is performed by the JVM at runtime. Classes are loaded into the JVM on an ‘as needed’ basis. And when a loaded class depends on another class, then that class is loaded as well.

When a Java application is launched, the first class to run (or the entry point into the application) is the one with public static void method called main(). This class usually has references to other classes, and all attempts to load the referenced classes are carried out by the class loader.

java.lang.ClassLoader
The java.lang.ClassLoader is an abstract class that can be subclassed by applications that need to extend the manner in which the JVM dynamically loads classes. Constructors in java.lang.ClassLoader (and its subclasses) allow you to specify a parent when you instantiate a new class loader. If you don’t explicitly specify a parent, the virtual machine’s system class loader will be assigned as the default parent.

  1. Include directive includes the file at translation time (the phase of JSP life cycle where the JSP gets converted into the equivalent servlet) whereas the include action includes the file at runtime.
  2. If the included file is changed but not the JSP which is including it then the changes will reflect only when we use include action tag. The changes will not reflect if you are using include directive as the JSP is not changed so it will not be translated for request processing and hence the changes will not reflect.
  3. When using include action tag we can also pass the parameters to the included page by using param action tag but in case of include directive it’s not possible.
    <jsp:include page="file_name" />
     <jsp:param name="parameter_name" value="parameter_value" />
    </jsp:include>
    

JSP Include Action tag

<html>
<head>
<title>JSP include Action example</title>
</head>
<body>
<jsp:include page="display.jsp" />
</body>
</html>

JSP Include Directive

<html>
<head>
<title>JSP include Directive example</title>
</head>
<body>
<%@ include file="display.jsp" %>
</body>
</html>
Posted in JSP.

SessionId is used to keep track of request coming from the same client during a time duration.

URL rewriting
URL rewriting is a method of session tracking in which some extra data (session ID) is appended at the end of each URL. This extra data identifies the session. The server can associate this session identifier with the data it has stored about that session. This method is used with browsers that do not support cookies or where the user has disabled the cookies. If you need to track Session from JSP pages, then you can use tag for URL-rewriting. It automatically encodes session identifier in URL.

Cookies
A cookie is a small amount of information sent by a servlet to a Web browser. A cookie is saved by the browser and later sent back to the server in subsequent requests. A cookie has a name, a single value, expiration date and optional attributes. A cookie’s value can uniquely identify a client. Since a client can disable cookies, this is not the most secure and fool-proof way to manage the session. If Cookies are disabled then you can fallback to URL rewriting to encode Session id e.g. JSESSIOINID into the URL itself.

Hidden Form fields
Similar to URL rewriting. The server embeds new hidden fields in every dynamically generated form page for the client. When the client submits the form to the server the hidden fields identify the client.

HTTPS and SSL
Web browsers that support Secure Socket Layer communication can use SSL’s support via HTTPS for generating a unique session key as part of the encrypted conversation. Modern days online internet banking website, ticket booking websites, e-commerce retailers like Amazon and e-bay all use HTTPS to security transfer data and manage the session.

  1. The difference between synchronized method and synchronized block is selection of lock on which critical section is locked. Synchronized method depending upon whether its a static method or non static locks on either class level lock or object lock.
  2. Class level lock is one for each class and represented by class literal e.g. String.class. Object level lock is provided by current object e.g. this instance, You should never mix static and non static synchronized method in Java
  3. On the other hand synchronized block locks on monitor evaluated by expression provided as parameter to synchronized block.
  4. One significant difference between synchronized method and block is that, Synchronized block generally reduce scope of lock. As scope of lock is inversely proportional to performance, its always better to lock only critical section of code. One of the best example of using synchronized block is double checked locking in Singleton pattern where instead of locking whole getInstance() method we only lock critical section of code which is used to create Singleton instance.
  5. Synchronized block provide granular control over lock(“very detailed control”, meaning you can control a lot of specific aspects), as you can use arbitrary any lock to provide mutual exclusion to critical section code. On the other hand synchronized method always lock either on current object represented by this keyword or class level lock, if its static synchronized method.
  6. Synchronized block can throw throw java.lang.NullPointerException if expression provided to block as parameter evaluates to null, which is not the case with synchronized methods.
  7. In case of synchronized method, lock is acquired by thread when it enter method and released when it leaves method, either normally or by throwing Exception. On the other hand in case of synchronized block, thread acquires lock when they enter synchronized block and release when they leave synchronized block.
public class SycnronizationExample 
{

	public synchronized void lockedByThis()
        {
        System.out.println(" This synchronized method is locked by current" instance of object i.e. this");
        }

	public static synchronized void lockedByClassLock() 
        {
	System.out.println("This static synchronized method is locked by class level lock of this class i.e. SychronizationExample.class");
	}

	public void lockedBySynchronizedBlock()
        {
           System.err.println("This line is executed without locking");     
           Object obj = String.class; //class level lock of Stirng class
     
          synchronized(obj)
          {
            System.out.println("synchronized block, locked by lock represented using obj variable");
          }
         }
}

Why not use for(int i=0; i< v.size();i++){}?

For loops are expensive to the processor when the collection reaches large sizes, as many operations are done just to compute the first line:

For Loop

  1. int i = 0 is an assignment and creation (2 operations)
  2. i get size, check value of i, and compare (3 operations)
  3. i++ gets i then adds 1 to it [++i is only 2 operations] this one (3 operations)
  4. 7/8 operations in total, each time the loop runs through

While Loop

  1. where an enumeration or iterator uses a while(){}
  2. while(v.hasNext()) has next true or false (1 operation)
  3. while(v.hasMoreElements()) has more true or false (1 operation)
  4. Only one operation per repeat of this loop

Iterator
Iterator is the interface and found in the java.util package.It has three methods

  1. hasNext()
  2. next()
  3. remove()

Enumeration
Enumeration is also an interface and found in the java.util package .An enumeration is an object that generates elements one at a time. It is used for passing through a collection, usually of unknown size.The traversing of elements can only be done once per creation.

It has following methods

  1. hasMoreElements()
  2. nextElement()

An iterator over a collection. Iterator takes the place of Enumeration in the Java collections framework.Iterators differ from enumerations by allowing the caller to remove elements from the underlying collection during the iteration.

HashMap vs HashTable

  1. HashMap is non synchronized and not thread safe.On the other hand, HashTable is thread safe and synchronized.
  2. Hashmap allows one null key and any number of null values, while Hashtable do not allow null keys and null values in the HashTable object.
  3. Hashmap object values are iterated by using iterator .HashTable is the only class other than vector which uses enumerator to iterate the values of HashTable object.The iterator in Hashmap is fail-fast iterator while the enumerator for Hashtable is not.if the Hashtable is structurally modified at any time after the iterator is created in any way except the iterator’s own remove method , then the iterator will throw ConcurrentModification Exception.
    Structural modification means adding or removing elements from the Collection object (here hashmap or hashtable) . Thus the enumerations returned by the Hashtable keys and elements methods are not fail fast.
  4. Hashmap is much faster and uses less memory than Hashtable as former is unsynchronized . Unsynchronized objects are often much better in performance in compare to synchronized object like Hashtable in single threaded environment.

Similarities Between HashMap and Hashtable

  1. Insertion Order :Both HashMap and Hashtable does not guarantee that the order of the map will remain constant over time. Instead use LinkedHashMap, as the order remains constant over time.
  2. Map interface :Both HashMap and Hashtable implements Map interface .
  3. Put and get method :Both HashMap and Hashtable provides constant time performance for put and get methods assuming that the objects are distributed uniformly across the bucket.
  4. Internal working :Both HashMap and Hashtable works on the Principle of Hashing . We have already discussed how hashmap works in java .

When to use HashMap and Hashtable?
Single Threaded Application
HashMap should be preferred over Hashtable for the non-threaded applications. In simple words , use HashMap in unsynchronized or single threaded applications .

Multi Threaded Application
We should avoid using Hashtable, as the class is now obsolete in latest Jdk 1.8 . Oracle has provided a better replacement of Hashtable named ConcurrentHashMap. For multithreaded application prefer ConcurrentHashMap instead of Hashtable.

An instance is eligible for garbage collection when null is assigned to it. These are choices made by the JVM implementer.

class Animal 
{
    public static void main(String[] args) 
    {
        Animal lion = new Animal();
        System.out.println("Main is completed.");
    }

    protected void finalize() {
        System.out.println("Rest in Peace!");
    }
}

During compilation process as an optimization technique the Java compiler can choose to assign null value to an instance, so that it marks that instance can be evicted.

In the above class, lion instance is never uses beyond the instantiation line. So the Java compiler as an optimzation measure can assign lion = null just after the instantiation line. So, even before SOP’s output, the finalizer can print ‘Rest in Peace!’. We cannot prove this deterministically as it depends on the JVM implementation and memory used at runtime.

Being an automatic process, programmers need not initiate the garbage collection process explicitly in the code. System.gc() and Runtime.gc() are hooks to request the JVM to initiate the garbage collection process.

When we are writing a performance benchmark we may call System.gc() in between runs

Just before evicting an instance and reclaiming the memory space, the Java garbage collector invokes the finalize() method of the respective instance so that the instance will get a chance to free up any resources held by it. Though there is a guarantee that the finalize() will be invoked before reclaiming the memory space, there is no order or time specified. The order between multiple instances cannot be predetermined, they can even happen in parallel. Programs should not pre-mediate an order between instances and reclaim resources using the finalize() method.Any uncaught exception thrown during finalize process is ignored silently and the finalization of that instance is cancelled.

Final Example]

  1. Final is used to apply restrictions on class, method and variable. Final class can’t be inherited, final method can’t be overridden and final variable value can’t be changed.
  2. Final is a keyword.
class FinalEg
{
   public static void main(String[] args) 
   {
      final int x = 600;
      x = 400;// Compile Time Error
    }
}

Finally Example

  1. Finally is used to place important code, it will be executed whether exception is handled or not.
  2. Finally is a block.
class FinallyEg
{
	public static void main(String[] args) 
	{
		try {
			int x = 500;
		} catch (Exception e) {
			System.out.println(e);
		} finally {
			System.out.println("finally block is executed");
		}
	}
}

Finalize Example

  1. Finalize is used to perform clean up processing just before object is garbage collected.
  2. Finalize is a method.
class FinalizeEg 
{
	public void finalize() 
        {
	   System.out.println("finalize called");
	}

	public static void main(String[] args) 
        {
		FinalizeExample f1 = new FinalizeExample();
		FinalizeExample f2 = new FinalizeExample();
		f1 = null;
		f2 = null;
		System.gc();
	}
}

Difference between throw and throws in Java

void doCalc() throws ArithmeticException
{  
   .
   .
   throw new ArithmeticException("sorry");  
}  

throw

  1. Java throw keyword is used to explicitly throw an exception.
  2. Checked exception cannot be propagated using throw only.
  3. Throw is followed by an instance.
  4. Throw is used within the method.
  5. You cannot throw multiple exceptions.

throws

  1. Java throws keyword is used to declare an exception.
  2. Checked exception can be propagated with throws.
  3. Throws is followed by class.
  4. Throws is used with the method signature.
  5. You can declare multiple exceptions e.g.
    public void method()throws IOException,SQLException.