Sunday, 22 February 2015

Java Serialization Part 1

I would not be shy away to say that I feel difficulty while questions or coding from java IO package comes in front of me. May be the reason is I haven't got that much coding exposure of IO operations. So things become confusing when we go into depth of java IO package.

Java serialization is also a small bit of that Java IO package, where our understanding is less.

I remember 2-3 years before one of my friend asked for real time usage of serialization and I told him that we can persist objects in a flat file instead of database. May be that was somehow correct answer but he was not convinced with that.

Today I am pretty much comfortable to answer his questions with example of EJB remote beans or high speed trading application where things cannot work without serialization.

Also mostly people get stuck when they have been asked to write a code which can serialize an object. 

So here I am going to share some real time example of serialization usage and code example related to serialization.

As I told earlier here are some real time example where serialization comes into picture:

1. May be few of you have worked on EJB and used it's remote bean. Now by saying any java class as remote bean, we mean that the class is available in some other JVM and client which want to invoke method of that remote bean exists in some other JVM. 
      Suppose if that method invocation need some object as parameter then somehow the object need to be passed from one JVM to other JVM via network. As network doesn't understand anything else 0 and 1, so this is done using serialization. There is complete cycle of java object serialization and de-serialization while invoking EJB remote method.

2. My next example will be stock exchange high speed trading application. As we know share price changes in fraction of seconds, so delay of millisecond in placing order will affect purchase cost tremendously. Trading application cannot go for relational database to store live trading transactions because of latency associated with it. Such kind of applications heavily rely on memory mapped file where serialization comes into picture.

Below picture can better explain definition of Serialization rather than words.


   


Code example for Serialization:

Here is my version of Serialization utility which can serialize and de-serialize an object:

 import java.io.FileInputStream;  
 import java.io.FileNotFoundException;  
 import java.io.FileOutputStream;  
 import java.io.IOException;  
 import java.io.ObjectInputStream;  
 import java.io.ObjectOutputStream;  
 import java.util.Arrays;  
 import java.util.logging.Level;  
 import java.util.logging.Logger;  
 public class SerializationUtils<E> {  
      Logger logger = Logger.getLogger("SerializationUtils.class");  
      private String filePath;  
      public SerializationUtils(String filePath){  
           this.filePath = filePath;  
      }  
      public void writeObject(E object){  
           FileOutputStream fos=null;   
           ObjectOutputStream oos= null;   
           try{  
                fos = new FileOutputStream(this.filePath);  
                oos = new ObjectOutputStream(fos);  
                oos.writeObject(object);  
           }catch(FileNotFoundException fnfe){  
                logger.log(Level.INFO, filePath+" not found");  
           }catch(IOException ioe){  
                logger.log(Level.SEVERE, Arrays.toString(ioe.getStackTrace()));  
           }finally{  
                try{if(null != oos)oos.close();}catch(IOException ioe)  
                     {logger.log(Level.SEVERE, Arrays.toString(ioe.getStackTrace()));}  
           }  
      }  
      @SuppressWarnings("unchecked")  
      public E readObject(){  
           FileInputStream fis = null;  
           ObjectInputStream ois = null;  
           E e = null;  
           try{  
                fis = new FileInputStream(this.filePath);  
                ois = new ObjectInputStream(fis);  
                e = (E)ois.readObject();  
           }catch(ClassNotFoundException cnfe){  
                logger.log(Level.INFO, Arrays.toString(cnfe.getStackTrace()));  
           }catch(FileNotFoundException fnfe){  
                logger.log(Level.INFO, filePath+" not found");  
           }catch(IOException ioe){  
                logger.log(Level.SEVERE, Arrays.toString(ioe.getStackTrace()));  
           }finally{  
                try{if(null != ois)ois.close();}catch(IOException ioe)  
                {logger.log(Level.SEVERE, Arrays.toString(ioe.getStackTrace()));}  
           }  
           return e;  
      }  
 }  

Now let us use this utility to serialize an object of employee class object.

Employee class(must implement Serializable interface):

 import java.io.Serializable;  
 public class Employee implements Serializable{  
      private static final long serialVersionUID = 1L;  
      private String employeeId;  
      private String name;  
      public String getEmployeeId() {  
           return employeeId;  
      }  
      public void setEmployeeId(String employeeId) {  
           this.employeeId = employeeId;  
      }  
      public String getName() {  
           return name;  
      }  
      public void setName(String name) {  
           this.name = name;  
      }  
      @Override  
      public String toString() {  
           return "Employee [employeeId=" + employeeId + ", name=" + name + "]";  
      }  
 }  

Main class using serialization for object of employee class:

 public class SerializationTest {  
      public static void main(String[] args){  
           SerializationUtils<Employee> utils = new SerializationUtils<Employee>("E:\\WrkSpace\\Test\\serialized_object.txt");  
           Employee emp = new Employee();  
           emp.setEmployeeId("123");  
           emp.setName("shashi");  
           utils.writeObject(emp);  
           System.out.println("done with serialization");  
           Employee deserializedEmployee = utils.readObject();  
           System.out.println(deserializedEmployee.toString());  
      }  
 }  

Here is the output which comes in console as expected:

 done with serialization  
 Employee [employeeId=123, name=shashi]  

If you are curious about what have been written in flat file, here it is:


That's all from my end in this part of serialization. We will cover more of serialization in second part where we will override standard writeObject and readObject method of ObjectOutputStream and ObjectInputStream respectively.



Wednesday, 18 February 2015

Find second highest number in an array

Nowadays technical interview involves writing small small code to judge whether candidate is aware of java APIs or not and how he/she using APIs in different scenarios.

For any such scenario, there can be 10 ways in which you can code a given problem but among those only 2-3 ways will solve the problem efficiently.

Take an example to "find out second highest number in a given array."

My version of solving this problem statement would be using stack with size 2. It will hold highest and second highest number by traversing on given array.

Pseudo Code:
1. Create a stack with size limit 2.
2. Start traversing on given array arr[n] from i=0 to n-1, step 1.
3. If arr[i] is greater than HEAD element of stack then push arr[i] into stack, so that HEAD element       will go one level down and arr[i] will become HEAD.
    Else if arr[i] is greater than TAIL element of stack then replace TAIL element with arr[i].

This diagram will be helpful to understand stack push operation:



As we know that Stack class of Java has no size limitation so somehow we have to limit the size to 2. Therefore I created customized stack to store elements. As you can see I overridden push method and if stack size becomes equal to max size(in our case its 2), then I am removing bottom element before doing any push operation to stack.

 import java.util.Stack;  
 @SuppressWarnings("serial")  
 public class SizedStack<E> extends Stack<E> {  
      private int maxSize;  
      public SizedStack(int maxSize){  
           super();  
           this.maxSize = maxSize;  
      }  
      @Override  
      public E push(E item){  
           if(this.size() == maxSize){  
                this.remove(0);  
           }  
           return super.push(item);  
      }  
 } 


Class which is implementing discussed pseudo code:

 public class FindSecondLargest {  
      public static void main(String[] args) {  
           int[] arr = {4,3,2,9,4,5,3,7};  
           System.out.println(getSecondLargest(arr));  
      }  
      public static int getSecondLargest(int[] arr){  
           SizedStack<Integer> stack = new SizedStack<Integer>(2);  
           int head = stack.push(0);  
           int tail = stack.get(0);  
           for(int i=0; i<arr.length; i++){  
                if(arr[i] > head){  
                     head = stack.push(arr[i]);  
                }else if(arr[i] > tail){  
                     tail = stack.set(0, arr[i]);  
                }  
           }  
           return stack.get(0);  
      }  
 }  

As you can see that each element in the array will be compared against 2 elements at most which resides in stack.

Since this operation is repeated exactly n times(size of array), hence we can say that time complexity of this algorithm will be O(n).

At the same time I cannot say that my version is best approach for given problem statement, but one of efficient way to solve the problem.

If you can give some solution and time complexity in terms of some logarithmic function then definitely your solution would be more efficient that mine version.


Saturday, 14 February 2015

Prefer Primitive over Wrapper classes

I was going through "Effective Java" book by Joshua Bloch and encountered a very interesting fact discussed on performance. So I thought, I must share this with you people.

It is about how you can optimize your code tremendously by just using primitive variable.

Here we are going to do the same thing in 2 different program, one using Wrapper Long class and one using primitive long.

We will take an example of doing sum from 1 to Integer.MAX_VALUE and analyze total execution time.

Example 1: Sum using wrapper Long class.

 import java.util.concurrent.TimeUnit;  
 public class LongTest {  
      public static void main(String[] args) {  
           Long sum= new Long(0);  
           long startTime = System.nanoTime();  
           for(long i=0; i<Integer.MAX_VALUE;i++){  
                sum+=i;  
           }  
           long endTime= System.nanoTime();  
           System.out.println(sum+" in "+TimeUnit.SECONDS.convert(endTime-startTime, TimeUnit.NANOSECONDS)+" seconds");  
      }  
 }  

If you execute above code snippet, total execution time will come around approximately 7 second.


Example 2: Sum using primitive long

 import java.util.concurrent.TimeUnit;  
 public class LongTest {  
      public static void main(String[] args) {  
           long sum=0;  
           long startTime = System.nanoTime();  
           for(long i=0; i<Integer.MAX_VALUE;i++){  
                sum+=i;  
           }  
           long endTime= System.nanoTime();  
           System.out.println(sum+" in "+TimeUnit.SECONDS.convert(endTime-startTime, TimeUnit.NANOSECONDS)+" seconds");  
      }  
 }  

If you execute above code snippet, total execution time will come around approximately 1 second.

Example 2 differs from example 1 just by variable declaration. It uses primitive long instead of Wrapper Long class.

So bottom line is by just using primitives, we saw huge performance gain. Here it is 6 seconds which is huge difference.

Conclusion: Always try to use primitive as much as possible over Wrapper class, because that reduces unnecessary overhead of auto boxing and un-boxing from JVM end.