Thursday, December 31, 2015

Hibernate write-behind technique

Hibernate implements a technique known as write-behind, to minimize the impact of network latency and duration of database lock.  This enables hibernate makes DML calls as late as possible.

What it actually means is: When objects associated with a persistence context are modified (by update/delete), the changes are not propagated immediately to the database.

Benefits of this technique

  1. If you made two updates to an entity in a session; hibernate doesn't have to make two SQL updates. It can manage both in the same update. 
  2. Hibernate can make use of JDBC batch update when it executes multiple INSERT, UPDATE or DELETE.
  3. Repeated flushing (synchronization of a persistence context with the database) of the persistence context also impacts performance. All dirty objects in the persistence context need to be detected (at the flush time), so if the size of persistent context is large then dirty checking can cause a lot of performance penalty. 

Wednesday, December 30, 2015

Entity States

Java applications contain a mix of transient and persistent objects. Transient (or normal objects) has a limited lifetime and is bounded by life of the process that instantiated it.  But persistent objects (or Entity) can be stored on disk or file system to create again in the future. 

The Java Persistence API (JPA) is part of EJB 3.0 specification (EJB 3.0 itself is part of Java Enterprise Edition). JPA refers to persisted or persistable  classes as Entity.  Technically, it's  just a POJO class which maps to a database table/view. Instance of an entity can represent a single row of a table. This post will cover different states an instance of an Entity could be in. In context of JPA, object and entity refers to the same thing (more details here)

Entity States 

  1. New/Transient Object which got instantiated using new operator is in transient state as it's not yet associated with any persistence context. It's not mapped yet to a record/row in database. It's just another object; and in fact JPA specification doesn't give any name for this state. 
  2. Managed/Persistent Object has a database identity. This means the instance has a valid primary key value to uniquely identity it in the database (or more specifically in a table). These instances are associated with a persistence context. 
  3. Detached As long as persistence context is active entity is in managed state. Once transaction (or unit of work) completes, persistence context is closed but the application still has handle to the entity. So such entities are in detached state. 
  4. Removed During the transaction we can delete or remove an entity. It's still associated with persistence context but it get's scheduled for deletion (at the end of transaction). So a removed object shouldn'd be reused and any reference holding it should be discarded. 
Image Reference : http://openjpa.apache.org

Let's Code

Let's code to explain the above states:

New

Student student = new EngineeringStudent();
student.setName(..);
student.setGrade(..);
student.setXX(..);

Managed

entityManager.persist(student);    //JPA
session.save(student);                  //Hibernate 

Delete
session.delete(student);
entityManager.remove(student);

Detached
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();

Student student = fetchStudentWithIdFromDb(id);
student.setGrade(..);
tx.commit();
session.close();

student.setXX(..);   //student is detached here

Detaching Inside a transaction
session.evict(student);  //detaches one object
session.clear(); //detaches all objects

Monday, December 28, 2015

Persistence Context

Java Persistence API uses javax.persistence.EntityManager to manage Entity instances and their life cycle(and hibernate does it using org.hibernate.Session). Each EntityManager instance is associated with a Persistence Context. 

EntityManager begines a new Persistence Context with each transaction and once the transaction ends (with commit or rollback) Context also ends. Within the transaction, entities retrieved from DB are managed entities (or instances which get saved become managed as well). When transaction completes, all entities loose their association from context and become detached.  

So, Persistence Context is cache of managed entity instances attached with your unit of work (or transaction). We don't need to do anything to enable it, it's always there (and we can't turn it off)! This Context has scope of a unit of work and it gets processed in a single thread (so it doesn't have issues like lock management or concurrent access).




How does it help

  • If we ask to load an entity using a primary key, EntityManager/Session checks first in the Context- If the entity is found there, there will be no DB hit. It's repeatable read for the application. So we get repeatable read absolutely free!
  • At most single object (entity) can represent any database row; there is no conflict. And all changes made to that row can be safely written back. 
  • Changes made to a managed entity is immediately visible to other (managed) entities in the context. 
  • At the end of transaction, JPA providers like Hibernate scans persistence context to find out which all entities got modified and only entities with any modification (or dirty attribute) gets propagated to the database. This is known as automatic-dirty-checking

Final Note

Persistence Context hold a copy/snapshot of each persistence object. The snapshot is used by JPA provider to do dirty checking (detect any modification done to the object). So if you carelessly load large number of objects you might run out of memory (OutOfMemoryException).  So be mindful of the impact on memory when you load records from DB (put proper condition in queries to avoid un-necessary load). 


References
https://docs.jboss.org/hibernate/orm/4.0/devguide/en-US/html/ch03.html

Sunday, December 20, 2015

Find if a word exists in a 2D grid

This problem is also known as Word Search Problem, found this on leetcode.

Problem:

Given a 2D board and a word, find if the word exists in the grid. The word can be constructed from the sequentially adjacent cell, where adjacent cells are those horizontally or vertically neighboring. The same letter may not be used more than once. 

[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

word : ABCCED -> true
              ABCB   -> false


Approach:

An initial glance at the 2D array confirms that at a given position there is more than one option to select next character. And if a given selected path fails to find the word then the search needs to backtrack and try out other options.  Below diagram illustrates this point - At S (row:1, col:3), we can start with either of E (up or down). But If we are looking for SEE, then choosing upper E will fail. 



We can apply Graph, depth-first traversal to check if the given input word exists in the 2D array. So we can start with the first character of the word and keep on checking if the next character of the input word is one of the neighbors of that character. Also, note that, if a neighbor is already considered then we need to discard that. 

Note: Characters can repeat in the 2D array. We need to abstract individual entries in the Node class which will keep row and column value along with the character. 


Implementation

Java implementation:


package backtracking;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Searches for a word in a 2-D character array. Same character can be present at two different locations in the array.
 * Uses DFS to search the input array in the board.
 */
public class WordSearch {
 private char[][] board;
 private int ROW, COL;
 
 public WordSearch(char[][] board) {
  super();
  this.board = board;
  this.ROW = board.length;
  this.COL = board[0].length;
 }

 /**
  * DFS search.
  * 
  * @param yetToBeSearchedInputStr
  *            string which is yet to get searched in the 2-D array
  * @param currPos
  *            abstracts the character and it's row, col in the 2-D board
  * @param alreadyTravelled
  *            stores nodes which are already covered/travelled
  * @return true if the word was found in the board; false otherwise
  */
 private boolean search(String yetToBeSearchedInputStr, Node currPos,
   Set<Node> alreadyTravelled) {
  if (Objects.isNull(yetToBeSearchedInputStr)
    || yetToBeSearchedInputStr.length() == 0) {
   return true;
  }

  alreadyTravelled.add(currPos);
  List<Node> neighbors = getNeighbors(currPos);
  for (Node node : neighbors) {
   if (!alreadyTravelled.contains(node)
     && node.ch == yetToBeSearchedInputStr.charAt(0)) {
    return search(yetToBeSearchedInputStr.substring(1), node,
      alreadyTravelled);
   }
  }
  return false;
 }

 /**
  * Returns all valid neighbors (left, right, up, down) of the given node
  * @param currPos node for which all neighbors needs to be found
  * @return list of neighbors
  */
 private List<Node> getNeighbors(Node currPos) {
  int row = currPos.row;
  int col = currPos.col;

  List<Node> neighbors = new ArrayList<>();
  if (col - 1 >= 0) {
   neighbors.add(new Node(board[row][col - 1], row, col - 1));
  }
  if (col + 1 < COL) {
   neighbors.add(new Node(board[row][col + 1], row, col + 1));
  }
  if (row - 1 >= 0) {
   neighbors.add(new Node(board[row - 1][col], row - 1, col));
  }
  if (row + 1 < ROW) {
   neighbors.add(new Node(board[row + 1][col], row + 1, col));
  }
  return neighbors;
 }

 @Override
 public String toString() {
  for (int i = 0; i < ROW; i++) {
   System.out.println();
   for (int j = 0; j < COL; j++) {
    System.out.print(board[i][j] + " ");
   }
  }
  return "\n ROW=" + ROW + ", COL=" + COL;
 }

 /**
  * Abstracts the character and it's position (row and col) in the board.
  * This is required as same character can be present at two different
  * locations.
  */
 private class Node {
  char ch;
  int row;
  int col;

  public Node(int r, int c) {
   this.row = r;
   this.col = c;
  }

  public Node(char ch, int r, int c) {
   this(r, c);
   this.ch = ch;
  }
  
  @Override
  public int hashCode() {
   final int prime = 31;
   int result = 1;
   result = prime * result + getOuterType().hashCode();
   result = prime * result + ch;
   result = prime * result + col;
   result = prime * result + row;
   return result;
  }

  @Override
  public boolean equals(Object obj) {
   if (this == obj)
    return true;
   if (obj == null)
    return false;
   if (getClass() != obj.getClass())
    return false;
   Node other = (Node) obj;
   if (!getOuterType().equals(other.getOuterType()))
    return false;
   if (ch != other.ch)
    return false;
   if (col != other.col)
    return false;
   if (row != other.row)
    return false;
   return true;
  }

  @Override
  public String toString() {
   return "Node [ch=" + ch + ", row=" + row + ", col=" + col + "]";
  }

  private WordSearch getOuterType() {
   return WordSearch.this;
  }
 }

 /**
  * Test method
  */
 public static void main(String[] args) {
  char[][] board = { { 'A', 'B', 'C', 'E' }, { 'S', 'F', 'C', 'S' },
    { 'A', 'D', 'E', 'E' } };
  WordSearch wordSearch = new WordSearch(board);
  System.out.println(wordSearch);
  Set<Node> alreadyTravelled = new HashSet<>();
  String inputString = "ABCCED";

  //first find if the first character exists in the board. Start below search for all the positions where it could be found
  //Not given logic to find the first character in the board.
  boolean f = wordSearch.search(inputString.substring(1),
    wordSearch.new Node('A', 0, 0), alreadyTravelled);
  System.out.println("Input String, "+ inputString +" exists in the 2-D character array? " + f);
 }
}



Note:
  • search method performs the DFS search until the word becomes empty or the search fails. It takes the substring of the word which is yet to be verified.
  • If you understand DFS properly, then this approach is quite straightforward. 

---
keep coding !!!

Wednesday, December 9, 2015

Transform collection of one object to another using Java 8 Streams

Few days back, I wanted to convert a list of value objects to another list of ORM/entity objects.  It's a very commonly occurring scenario; oh BOY, streams API works like a charm!

If you are working on application having layered or distributed architecture, this scenario is quite common. When data moves from client/UI to get persisted it gets transformed multiple times. Let's see how it can be done effectively in Java 8 using streams API.



public class City {
 private String name;
 private String zipCode;
 
 //other attribute, setter/getters
}

public class CityOrm {
 private String name;
 private String zipCode;
 private long id;
 
 public CityOrm(City city){
  //construct this using City instance
 }
 //other attribute, setter/getters
}


Please note that CityOrm has a constructor. So transforming or converting a City instance to CityOrm instance is not an issue.  

Problem is:

You have a collection of City; you need to convert it into a collection of CityOrm. 


Before Java 8

 List<City> cities = getItFromSomeWhere();
List<CityOrm> citiesOrm = new ArrayList<>();
for(City city : cities){
citiesOrm.add(new CitiyOrm(city));
}


Java 8 / Streams API

   List<City> cities = getItFromSomeWhere();
   List<CityOrm> citiesOrm = cities.stream()
          .map(city -> new CityOrm(city))                   .collect(Collectors.toList());


stream() method converts the list of City instances into a stream and then map() method goes through each city and by calling appropriate constructor converts it to another type (i.e. CityOrm). And finally, collect() method converts the stream back to a list. 
So Stream API definitely saved a couple of lines (excuse the spread due to formatting). 
                  

Sunday, August 30, 2015

Integer to Binary Using Recursion

Problem:
Get binary equivalent of a number using Recursion.
getBinary(2)       = 10
getBinary(5)       = 101
getBinary(1024) = 10000000000

Iterative implementation of this problem is quite trivial. But here it's expected to be done recursively!

Approach 1

The approach is quite simple -  Divide the decimal value by 2 and write down the remainder. Repeat this process until you can't divide anymore

Calculate for 13,
 13/2 = 6 and remainder = 1
 6/2   = 3 and remainder = 0
 3/2   = 1 and remainder = 1
 1/2   = 0 and remainder = 1        

To get binary, we write down the value of reminder from bottom to top. So it gives 1101. Let's apply recursive thinking to solve this problem. 

Subproblem will be dividing the number by 2 in each iteration. 
Base Case - binary of 1 is 1 (or 0 is 0) . 
Combining subproblem result might be tricky as it needs to be done in a reverse way. This can be achieved if the method is called first (and then the remainder operation is performed). This will ensure that the remainder is performed only when base case is reached.

public static String getBinary(int num) {
 if (num < 2) {
  return "" + num;
 }

 return getBinary(num / 2) + num % 2;
}

Stack Progress
getBinary(13)
    --> getBinary(13/2) + 13%2
             --> getBinary(6/2) + 6%2
                     -->getBinary(3/2) + 3%2
                             -->getBinary(1)    //base case, return 1
                     --> ""+ 1+ 1
             --> ""+1+1+0
     -->""+1+1+0+1   

Approach 2

Let's explore on another approach which uses bit manipulation to generate a binary equivalent. 

Binary of 5 is 101. Now let's see if we can get the bit values (1, 0 and 1) of the number by some bit manipulation technique. 

5 & 100 = 100   
5 & 010 = 000
5 & 001 = 001

Notice that, And operation (&) is performed with a number whose all values are 0 except leftmost position. And then that keeps on shifting to the right side. And the output will be 1 at that position if the bit value is 1 in the number (and 0 otherwise).

When you apply recursive thinking, it's quite clear that method needs another argument which will help in getting bit value at a given position. Integer in Java is 32 bit long, so that number will take the initial value of 1 << 31 (i.e. leftmost bit is 1 and rest all are 0). And when all bit positions (from MSB to LSB) are explored the recursion should stop. 

public static String getBinary2(int num, int and){
 if(and == 0){
      return "";   //if all bits are checked; just return
 }

 /**
  * If value at position is 1 in num; it will give and value
  */
 int t = (num & and) == and ? 1 : 0;
 
 return ""+ t + getBinary2(num, and >>> 1);
}

String binary = getBinary2(5, 1<<31);
//binary = 00000000000000000000000000000101


Can you try to come up with stack progress as shown for first approach?
Do post your feedback/doubts below!
---
keep coding !!!

Friday, August 28, 2015

Recursive Thinking

Usually, most of the programmers (poor ones like me :p) think iteratively to solve a problem. This works, until you get a problem which is expected to be solved recursively or even worse what if non-recursive solution is bit tricky. Take a classic example of binary tree traversal, it's a breeze if it needs to be done recursively (just few lines would do the job). You are not going to always get such commonly occurring or well known problems. What if you land to a brand new problem to be solved recursively? How you going to check if recursion can be applied or not ?

Your ability to come up with multiple solutions to a problem will be limited if you don't try to come up with recursive solution. It takes time to develop the recursive thinking, and ofcourse with lots of persistent hard work. 

Let's go through some of the fundamental aspects which can be invaluable to develop recursive thinking (cap). In this post, I will cover recursion,  rules for solving a problem recursively and finally explain the concept through couple of problems.

Recursion

Recursion is another approach to solve problems which require repetition. Problem is solved by reducing it to a smaller problem of the same kind. This process is continued until we reach to a very small problem (base case) which can be solved directly. Base condition stops the further method call. 

Let's start with a simple problem of printing all numbers between two given numbers(both inclusive).

//Java Implementation
public void print(int a, int b){
      if(a == b){
          System.out.println(a);
          return;
      }
      else{
            System.out.println(a);
            print(a+1, b);
      }
}

Above recursive algorithm reduces the problem to a smaller problem in each call (until base condition is reached). So, print(2,5) becomes print(3,5) after first call and so on until both a and b are same.

print(2,5)
   -->print(3,5)
           -->print(4,5)
                   -->print(5,5) //base case


Basic idea in recursion is to reduce problem to smaller problem of the same kind. 

Recursive Thinking

Developing recursive thinking is about your ability to ask few (important) questions for solving any problem. 
  1. How can the problem be broken down to one or more subproblems (smaller problem)?
  2. What is the base case?
  3. Does each subproblem has a (partial) solution? How that should be combined to get final result?
You need to have answer to all questions to solve a problem. Over a period of time, this pattern becomes very obvious and smart programmers can find it quite easily. You need to practice a lot to make recursive thinking part of your (algorithmic) problem solving toolkit. 

Let's apply recursive thinking on above method, print(a,b) -
  1. Problem can be broken down to smaller subproblem - Yes. Print first argument and then print all numbers between first argument + 1 and second argument
  2. Base case - print numbers until first argument becomes second argument (i.e. a==b)
  3. Does each subproblem has a solution -No. They just print the value on console so there is no intermediate answer or partial solution. 

Problems

Let's apply recursive thinking on few problems. I will use RT#1, RT#2, RT#3 to look for valid answer to the three Recursive Thinking questions:

p1: Find the length of a string

RT#1: How can this problem be divided into subproblems? So instead of finding length of complete string, can we find length of a smaller string to somehow get the full length ?
      
         length("abc") = can we find the full length if we know, length("bc")
    or, length("abc") = can we find the full length if we know, length("ab")

RT#2: Base case is something whose answer we already know. 
        length("") = 0
   or, length("a") = 1  

RT#3: Yeah subproblem has a solution. 
              length("abc") = 1 + length("bc")
         or, length("abc") = 1 + length("ab");

algorithm:
    int length(str){
           if(str.hasOneChar())
                return 1;
            else
                return 1 + length(str.substring(1));
     }  


p2: Compute power(X,n) (i.e. X^n = X*X*X.....*X, n of them)

RT#1: Quite clear, power(X, n-1) can be one of the subproblem (let's stick with this for now).
RT#2: Base case, n = 0 then power(X,n)  would be 1
RT#3: X^n = X* X^(n-1)

algorithm:
    int power(x,n){
         if(n == 0)
            return 1;
         else return x*power(x,n-1);             
     }

Complexity of above problem = O(n). Subproblem reduces the length by 1 in each call.

Above is a legitimate recursive solution, but it can be improved to a better recursive solution with complexity of O(log n).  Can we reduce size of problem to half in each recursive call (something like binary search) ?

algorithm:
    int power(x,n){
         if(n == 0)
            return 1;
         else 
              int p = power(x,n/2)
              if ( n is even ) return p*p;             
              else x*p*p;
     }

Backtrackinghttp://www.thegeekstuff.com/2014/12/backtracking-example/

Do post your feedback below.
---
think recursion, thank recursion !!!
keep coding !

Saturday, August 22, 2015

Longest Substring Without Repeating Characters

Problem:
Given a string, find the longest substring without repeating characters.
"abcabcd"  --> "abcd"
"aaaaaa"    --> "a"
"abcad"     --> "bcad"

Solution

This problem might be trivial if there is no restriction on time complexity. But if the expected time complexity is linear then it becomes quite interesting. Let's see how we going to approach to solve it. 

Once you start moving from left to right in the given input string (one character each time), there will be a need to find if the character already exists before? 

if the character doesn't exist earlier - continue further.
if the character exists earlier - this substring (starting from a given index) could be a potential answer. 

So we need a start index which points to the beginning of the current potential answer. And another index which keeps on incrementing to find that maximum substring. 

how to check if character is already found ?
str = "abac"
Assume, startIndex = 0, currentIndex = 2

The character at currentIndex(i.e. 'a') will have to be checked if it's already there in the substring before it (i.e. "ab"). Brute force approach to check if the character exists in the substring will result in complexity O(substring.length()).

We can optimize it by using hashing mechanism, but keep in mind that hashing technique will increase the space overhead. 

Java Implementation


 public static String longestSubstringWithoutRepeatingCharars(String str) {
  if (str == null || str.length() < 2) {
   return str;
  }

  Set<Character> unique = new HashSet<>();
  int startIndex = 0, endIndex = 0;
  char ch;
  String max = " ";

  while (endIndex < str.length()) {
   ch = str.charAt(endIndex);
   if (unique.contains(ch)) {

    // check if max can be optimized
    if (str.substring(startIndex, endIndex).length() >= max
      .length()) {
     max = str.substring(startIndex, endIndex);
    }

    // reset both indexes to find the next substring
    startIndex++;
    endIndex = startIndex;

    // reset set so that it can again store all unique chars
    unique.clear();
   } else {
    endIndex++;
    unique.add(ch);
   }
  }

  // check if max can be optimized
  if (str.substring(startIndex, endIndex).length() >= max.length()) {
   max = str.substring(startIndex, endIndex);
  }
  return max;
 }

longestSubstringWithoutRepeatingCharars("abcad");

Sunday, July 26, 2015

Why EJB (3+)

I have heard people mentioning, why do you need EJBs; my project is great without them. In early days, I too wasn't very convinced. What value it adds ? Can't we leave without EJBs ?

The answer to most of such questions would be; may be!

It's not that you can't implement a distributed application without EJBs. I have worked on couple of quite successful distributed applications which didn't use EJB at all. For that matter, there is no framework/technology which is must in a given situation. There are always few alternatives, but the question is what's the cost or advantages for making a particular choice?

Let's try to understand EJB and other server side Java components:

Where it fits

EJBs runs inside EJB container (of application server) for abstracting your business logic. Below diagram shows different server side components and their relationship with EJB (just shown some of them). When EJB is not there the line gets blurred and the business logic is spread across servlet and other middle layer components like JPA, JDBC, JMS etc.





Why do we need it ?

Business logic shouldn't be performed by web interface component and similarly by persistence layer as well. Web-interface should specialize in handling http request and delegating it appropriately to business component and persistence layer should focus on CRUD operations.  If your business logic is spread across multiple component, it's not easy to manage it. You are violating loose coupling and separation of concern design principles (not following MVC architectural pattern).

If your business logic is light-weight then you might go on with this approach. But are you sure, that it's going to remain light weight forever? Change is inevitable!

When you have a truly distributed application with multiple server side components and business logic is not so trivial, you will feel the need to bring in an specialized component sooner or later. EJB integrates quite easily with other server side components like JPA (for persistence services), JTA (for transaction services), JMS (for providing messaging services), JNDI (for providing directory services) etc. EJB helps scaling out your application.


Arguments given here are generic, but have written this article keeping in mind features and power of EJB 3+.  Development with EJB 3+ is quite simple - no complex configuration in XML, simple POJO class, uses annotation, and makes development quite a breeze. 

---
happy learning !

Saturday, July 25, 2015

Insertion Sort

Insertion sort is one of the most fundamental comparison based stable sorting algorithm. It is also known as playing card sort. It is based on a fundamental principle that a single element array is already sorted.  A two element array requires single comparison to sort it. A three element array can be visualized as two sub arrays (first with 2 elements and second with one element). So in each iteration, a new value is added to an already sorted sublist. 

a1 = {101}   // already sorted
a2 = {101, 2} // can visualize it as, add 2 to a already sorted sub-array having 101
       {2, 101} // one comparison required to put 2 in proper place
a3 = {101, 2, 5} // a new number added to a2
        {2, 101, 5}
        {2, 5, 101}  // put 5 in proper place

To visualize how it works, check out animation on wikipedia.

Java Implementation


/**
 * Insertion sort implementation
 * 
 * @author Siddheshwar
 *
 */
public class InsertionSort {
 /**
  * Insertion sort in ascending order
  * 
  * @param arr
  * @return arr
  */
 public int[] sort(int[] arr) {
  int tmp = 0;
  for (int i = 1; i < arr.length; i++) {
   for (int j = i; j > 0 && arr[j] < arr[j - 1]; j--) {
    tmp = arr[j];
    arr[j] = arr[j - 1];
    arr[j - 1] = tmp;
   }
   print(arr);
  }
  return arr;
 }

 // print current state of array
 private void print(int[] arr) {
  System.out.println();
  for (int i = 0; i < arr.length; i++) {
   System.out.print(arr[i] + "  ");
  }
 }

 public static void main(String[] args) {
  int[] arr = { 12, 11, 13, 5, 6 };
  InsertionSort is = new InsertionSort();
  arr = is.sort(arr);
  // is.print(arr);
 }
}

Output:
11  12  13  5  6  
11  12  13  5  6  
5  11  12  13  6  
5  6  11  12  13 

Performs ideal when array is nearly sorted or size is small. It can also be used as base sorting algorithm in recursive divide and conquer quick sort and merge sort algorithms.

Important Points

  • If the array is already sorted, swapping will never be performed and hence time complexity will be O(n). Adaptive sorting algorithm. 
  • Average and worst case time complexity is O(n^2). Space complexity is O(1)
  • Worst performance when array is reverse sorted. 
  • Not ideal approach if data is random.
  • In the best case (when already sorted), all the elements are in proper place so it takes linear time. 
  • In-efficient for value based data with large memory footprint as amount of memory shift/swap will be high. Performs good when sorting on pointer based data. 
keep coding !

Monday, July 20, 2015

What is Java EE container

For Java SE (or J2SE) applications JVM provides runtime environment, but the moment you switch to Java EE (or earlier known J2EE), runtime environment is provided by web or application servers.

JVM executes/runs Java applications and also provides some of the runtime services like lifecycle management for objects and API support etc. Life is not so rosy in the distributed environment and that's why we have servers for specific jobs. These servers basically fall into two categories, application servers like JBoss(Wildfly) and Glassfish and web servers like Tomcat and Jetty. These servers are also referred to as containers (in a more technical sense). So what are containers?

Java EE Container

Java EE containers are runtime environments for Java Enterprise Edition applications. As containers are implemented on top of JVM, they provide all services provided by JVM (to Java SE applications) and along with that they also provide services specific to the distributed environment. Java EE containers refer to two different types of containers known as Web/Servlet container and EJB container. They are classified in terms of what technologies they support. Let's go through both these containers in more detail:

Web Container:
Web containers run web applications which use Servlet, JSP and JSF pages and respond to HTTP calls from HTTP clients like browsers, mobile devices or other Java (SE or EE) applications. It can also host RESTful and SOAP web services. Now a subset of EJB 3.1 (added in Java EE 6), known as EJB lite can also be deployed in web containers (in fact EJB lite can also run on JVM). So, it intercepts HTTP(S) request from the client and then identifies, instantiates, initializes appropriate servlet/service endpoint; and then returns back the appropriate HTML page or response in JSON/XML/Text format. 

EJB Container:
EJB containers run enterprise applications made up of Enterprise Java Beans within the Application server. It abstracts business logic of your Java EE application and usually takes request from Servlets,  web services,  queue or other application servers. And just like servlet containers, EJB containers manages lifecycle of EJBs and provides services like transaction management, security, concurrency, naming services or ability to be invoked asynchronously.

Please note that Java EE compliant application servers support Servlet containers along with EJB containers; you can run full stack Java Enterprise Edition application. I have come across situations where people (loosely) refer to Applications servers as EJB containers. 
In the application server, web container and EJB container both share the same JVM instance. 

---

happy learning !!!