Saturday, December 29, 2012

Struts

The term "MVC" originated with the SmallTalk Model-View-Controller framework. Under MVC, an application is seen as having three distinct parts. The problem domain is represented by the Model. The output to the user is represented by the View. And, the input from the user is represented by Controller.

The Model portion of an MVC-based system can be often be divided into two major subsystems -- the internal state of the system and the actions that can be taken to change that state.

we strongly recommend that you separate the business logic ("how it's done") from the role that Action classes play ("what to do"). 'nuff said.

The framework includes a set of custom tag libraries that facilitate creating user interfaces that are fully internationalized and interact gracefully with ActionFormbeans. ActionForms capture and validate whatever input is required by the application.

Struts provides the Controller portion of the application. The Controller is focused on receiving requests from the client (typically a user running a web browser), deciding what business logic function is to be performed, and then delegating responsibility for producing the next phase of the user interface to an appropriate View component. The primary component of the Controller in the framework is a servlet of class ActionServlet. This servlet is configured by defining a set ofActionMappings. An ActionMapping defines a path that is matched against the request URI of the incoming request and usually specifies the fully qualified class name of an Action class. All Actions are subclassed from [org.apache.struts.action.Action]. Actions encapsulate calls to business logic classes, interpret the outcome, and ultimately dispatch control to the appropriate View component to create the response. While the framework dispatches to a View, actually rendering the View is outside its scope.
The framework also supports the ability to use ActionMapping classes that have additional properties beyond the standard ones required to operate the controller. This allows you to store additional information specific to your application and still utilize the remaining features of the framework. In addition, the framework lets you define logical "names" to which control should be forwarded so that an action method can ask for the "Main Menu" page (for example), without knowing the location of the corresponding JSP page. These features greatly assist you in separating the control logic (what to do) with the view logic (how it's rendered).

Most of the business logic in an application can be represented using JavaBeans. An Action can call the properties of a JavaBean without knowing how it actually works. This encapsulates the business logic, so that the Action can focus on error handling and where to forward control.

In a database application, for example:

  • A business-logic bean will connect to and query the database,
  • The business-logic bean returns the result to the Action,
  • The Action stores the result in a form bean in the request,
  • The JavaServer Page displays the result in a HTML form.
Neither the Action nor the JSP need to know (or care) from where the result comes. They just need to know how to package and display it.

The framework provides its own web Controller component and integrates with other technologies to provide the Model and the View.
The framework's Controller acts as a bridge between the application's Model and the web View. When a request is received, the Controller invokes an Action class. The Action class consults with the Model (or, preferably, a Facade representing your Model) to examine or update the application's state. The framework provides anActionForm class to help transfer data between Model and View.
Most often, the Model is represented as a set of JavaBeans. Typically, developers will use the Commons BeanUtils to transfer data between ActionForms and the Model objects (or a Facade). Preferably, the Model will do the "heavy lifting", and the Action will act as a "traffic cop" or adapter.

Java HashMap

HashMap:
DEFAULT_INITIAL_CAPACITY = 16;
DEFAULT_LOAD_FACTOR = 0.75f;
1. put(key,value)
HashMap implementation calls hashCode method on Key object and applies returned hashcode into its own hashing function to find a bucket location for storing Entry object, HashMap in Java stores both key and value object as Map.Entry in bucket which is essential to understand the retrieving logic.
Since hashcode is same, bucket location would be same and collision will occur in HashMap, Since HashMap use LinkedList to store object, this entry (object of Map.Entry comprise key and value )  will be stored in LinkedList.
       if (size++ >= threshold)
           resize(2 * table.length);
there is potential race condition exists while resizing HashMap in Java


2. get(key)
HashMap uses Key Object's hashcode to find out bucket location and retrieves Value object
If two Value objects are stored in same bucket, we will call keys.equals() method to identify correct node in LinkedList and return associated value object for that key in Java HashMap.

hashcode() is used in all situations and equals() come in picture only in case of retrieving value object from HashMap in Java. Using immutable, final object with proper equals() and hashcode() implementation would act as perfect Java HashMap  keys and improve performance of Java HashMap  by reducing collision. Immutability also allows caching there hashcode of different keys which makes overall retrieval process very fast and suggest that String and various wrapper classes e.g. Integer very good keys in Java HashMap.

if key object return different hashCode during insertion and retrieval than it won't be possible to get object from HashMap. Immutability is best as it offers other advantages as well like thread-safety

3. ConcurrentHashMap and Hashtable
ConcurrentHashMap only locked certain portion of Map while Hashtable lock full map while doing iteration.
ConcurrentHashMap like Hashtable but unlike HashMap, this class does not allow null to be used as a key or value.



Why String is immutable or final in Java

1.
String A = "Test"
String B = "Test"
Now String B called "Test".toUpperCase() which change the same object into "TEST" , so A will also be "TEST" which is not desirable.
2.
In case if String is not immutable , this would lead serious security threat
3.
Immutability also makes String instance thread-safe in Java, means you don't need to synchronize String operation externally.

All constant strings that appear in a class are automatically interned. You only need to intern strings when they are not constants, and you want to be able to quickly compare them to other interned strings.
String str1 = "Test";
String str2 = "Test";
System.out.println(str1==str2);
System.out.println(str1.intern()==str2.intern());
String str3 = new String("Test");//created in heap and not added into string pool
String str4 = new String("Test");
System.out.println(str3==str4);
System.out.println(str3.intern()==str4.intern());
System.out.println("Hel"+"lo"=="Hello");
When we create string with new() Operator, it’s created in heap and not added into string pool while String created using literal are created in String pool itself which exists in PermGen area of heap.
String s = new String("Test");
does not  put the object in String pool , we need to call String.intern() method which is used to put  them into String pool explicitly.

Jakarta Struts for Dummies

In JSP and Stuts, scope can be one of four values:
1. Page
2. Request
3. Session
4. Application
Struts provides this unification by implementing the Model-View-Controller(MVC) design pattern for Web applications.
Struts->Controller: ActionServlet
mapping.findForward("Success")

ThreadLocal

http://www.ibm.com/developerworks/java/library/j-threads1/index.html

In the absence of synchronization, it is allowable (according to the JMM) for two threads to see different values in the same memory location. When synchronizing on a monitor (lock), the JMM requires that this cache be invalidated immediately after the lock is acquired, and flushed (writing any modified memory locations back to main memory) before it is released. It's not hard to see why synchronization can have a significant effect on program performance; flushing the cache frequently can be expensive.

A race condition is a situation in which two or more threads or processes are reading or writing some shared data, and the final result depends on the timing of how the threads are scheduled. Race conditions can lead to unpredictable results and subtle program bugs.

A thread-local variable effectively provides a separate copy of its value for each thread that uses it. Each thread can see only the value associated with that thread, and is unaware that other threads may be using or modifying their own copies.
Java compilers offer no special language support for thread-local variables; instead, they are implemented with the ThreadLocal class, which has special support in the core Threadclass.
it's clear that the object stored in the ThreadLocal isnot shared between threads, simplifying the task of determining whether a class is thread-safe or not.

garbage collection in java

The vast majority of objects are allocated in a pool dedicated to young objects (the young generation), and most objects die there. When the young generation fills up it causes a minor collection in which only the young generation is collected; garbage in other generations is not reclaimed. Minor collections can be optimized assuming the weak generational hypothesis holds and most objects in the young generation are garbage and can be reclaimed. The costs of such collections are, to the first order, proportional to the number of live objects being collected; a young generation full of dead objects is collected very quickly. Typically some fraction of the surviving objects from the young generation are moved to the tenured generation during each minor collection. Eventually, the tenured generation will fill up and must be collected, resulting in a major collection, in which the entire heap is collected. Major collections usually last much longer than minor collections because a significantly larger number of objects are involved.

The young generation consists of eden and two survivor spaces. Most objects are initially allocated in eden. One survivor space is empty at any time, and serves as the destination of any live objects in eden and the other survivor space during the next copying collection. Objects are copied between survivor spaces in this way until they are old enough to be tenured (copied to the tenured generation).

A third generation closely related to the tenured generation is the permanent generation which holds data needed by the virtual machine to describe objects that do not have an equivalence at the Java language level. For example objects describing classes and methods are stored in the permanent generation.

  1. Throughput is the percentage of total time not spent in garbage collection, considered over long periods of time. Throughput includes time spent in allocation (but tuning for speed of allocation is generally not needed).
  2. Pauses are the times when an application appears unresponsive because garbage collection is occurring.
Users have different requirements of garbage collection. For example, some consider the right metric for a web server to be throughput, since pauses during garbage collection may be tolerable, or simply obscured by network latencies. However, in an interactive graphics program even short pauses may negatively affect the user experience.

The parallel collector will throw an OutOfMemoryError if too much time is being spent in garbage collection: if more than 98% of the total time is spent in garbage collection and less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. This feature is designed to prevent applications from running for an extended period of time while making little or no progress because the heap is too small. If necessary, this feature can be disabled by adding the option -XX:-UseGCOverheadLimit to the command line.

Before removing an object from memory Garbage collection thread invokes finalize () method of that object and gives an opportunity to perform any sort of cleanup required.

There are methods like System.gc () and Runtime.gc () which is used to send request of Garbage collection to JVM but it’s not guaranteed that garbage collection will happen.

Java objects are created in Heap and Heap is divided into three parts or generations for sake of garbage collection in Java, these are called as Young generation, Tenured or Old Generation and Perm Area of heap.
New Generation is further divided into three parts known as Eden space, Survivor 1 and Survivor 2 space. When an object first created in heap its gets created in new generation inside Eden space and after subsequent Minor Garbage collection if object survives its gets moved to survivor 1 and then Survivor 2 before Major Garbagecollection moved that object to Old or tenured generation.

Permanent generation of Heap or Perm Area of Heap is somewhat special and it is used to store Meta data related to classes and method in JVM, it also hosts String pool provided by JVM as discussed in my string tutorial why String is immutable in Java. There are many opinions around whether garbage collection in Java happens in perm area of java heap or not, as per my knowledge this is something which is JVM dependent and happens at least in Sun's implementation of JVM.

Throughput Garbage Collector: This garbage collector in Java uses a parallel version of the young generation collector. It is used if the -XX:+UseParallelGC option is passed to the JVM via command line options . The tenured generation collector is same as the serial collector.

2) Concurrent low pause Collector: This Collector is used if the -Xingc or -XX:+UseConcMarkSweepGC is passed on the command line. This is also referred as Concurrent Mark Sweep Garbage collector. The concurrent collector is used to collect the tenured generation and does most of the collection concurrently with the execution of the application. The application is paused for short periods during the collection. A parallel version of the young generation copying collector is sued with the concurrent collector. Concurrent Mark Sweep Garbage collector is most widely used garbage collector in java and it uses algorithm to first mark object which needs to collected when garbage collection triggers.

3) The Incremental (Sometimes called train) low pause collector: This collector is used only if -XX:+UseTrainGC is passed on the command line. This garbage collector has not changed since the java 1.4.2 and is currently not under active development. It will not be supported in future releases so avoid using this and please see 1.4.2 GC Tuning document for information on this collector.

Oracle Note

1. Left join and right join
--left join example
SELECT a.department_name,
 b.first_name,
 a.department_id dep_a,
 b.department_id dep_b
FROM departments a,
 employees b
WHERE a.department_id =b.department_id(+) AND
b.department_id(+)=10;

2. record type
Can not define schema-level record type and cannot reference %type when creating object type.
Object type is "known and visible" to Oracle SQL engine AND PL/SQL engine.
Record Type is "known and visible" to PL/SQL engine only.

3. Oracle Optimization
The difference between the two optimizers is relatively clear: The CBO chooses the best path for your queries, based on what it knows about your data and
by leveraging Oracle database features such as bitmap indexes, function-based indexes, hash joins, index-organized tables, and partitioning, whereas the RBO
just follows established rules (heuristics). With the release of Oracle Database 10g, the RBO's obsolescence is official and the CBO has been significantly improved yet again.

4. For update
You can lock the rows with the FOR UPDATE clause in the cursor query. NO WAIT means not to wait if requested rows have been locked by another user.
declare
    cursor emp_cursor is
    select employee_id,last_name from employees where department_id = 80 FOR UPDATE OF salary NOWAIT;
WHERE CURRENT OF clause is used in conjunction with the FOR UPDATE clause to refer to the current row in an explicit cursor.

5. raise_application_error
raise_application_error(error_number,message[,{TRUE|FALSE}]);
error_number: is a user specified number for the exception between -20000 and -20999
TRUE|FALSE: optional. default is false, the error replaces all previous errors.
   
6. bulk binding
forall i in id.first .. id.last
    update employees set salary = salary*1.1 where manager_id = id(i) returning salary bulk collect into new_sals;    
  
7. Collection
Functions: exists,count,limit,first,next,prior
Procedures: extended,trim,delete
a. Use forall and indices of to skip null example:
declare
type id_table_type is table of number(6);
id_table id_table_type;
begin   
id_table := id_table_type(1,null,3,null,5);
forall i in indices of id_table
    delete from demo where id=id_table(i);
end;
/
b. use forall and values of example
declare
type id_table_type is table of demo.id%type;
type name_table_type is table of demo.name%type;
id_table id_table_type;
name_table name_table_type;
type index_pointer_type is table of pls_integer;
index_pointer index_pointer_type;
begin
select * bulk collect into id_table,name_table from demo;
index_pointer := index_pointer_type(6,8,10);
forall i in values of index_pointer
    insert into new_demo values(id_table(i),name_table(i));
end;
/
1) Indexed TABLE
DECLARE
TYPE ename_table_type IS TABLE OF emp.ename%TYPE
    INDEX BY BINARY_INTEGER;
ename_table ename_table_type;
BEGIN
SELECT ename INTO ename_table(-1) FROM emp WHERE empno = 7788;
DBMS_OUTPUT.PUT_LINE('The name is:'||ename_table(-1));
END;
/   
2) Nested table
declare
type ename_table_type is table of emp.ename%type;
ename_table ename_table_type;
begin
ename_table:=ename_table_type('MARY','MARY','MARY');
select ename into ename_table(2) from emp where empno = &no;
dbms_output.put_line('The employee name: '||ename_table(2));
end;
/
3) VARRAY
CREATE TYPE article_type AS OBJECT (
title VARCHAR2(30), pubdate DATE
);
CREATE TYPE article_array IS VARRAY(20) OF article_type;
CREATE TABLE author(
id NUMBER(6),name VARCHAR2(10),article article_array
);

8.
UNION, INTERSECT and MINUS are ordered by the first column while UNION ALL is not ordered.

9. With statement
SQL>with summary as (select dname,sum(sal) as dept_total from emp,dept where emp.deptno = dept.deptno group by dname)
   select dname,dept_total from summary where dept_total>( select sum(dept_total)*1/3 from summary);
      
10. Use rowtype variable
declare
dept_record dept%ROWTYPE;
begin
dept_record.deptno := 50;
dept_record.dname := 'ADMINISTRATOR';
dept_record.loc := 'BEIJING';
INSERT INTO dept VALUES dept_record;
end;
/
declare
dept_record dept%ROWTYPE;
begin
dept_record.deptno := 50;
dept_record.dname := 'SALES';
dept_record.loc := 'SHANGHAI';
UPDATE dept SET ROW=dept_record where deptno = 50;
end;
/      

11. Exception
a. Use self defined exception
declare
e_integrity exception;
pragma exception_init(e_integrity,-2291);--Hold ORA-02291:?????????
begin
update emp set deptno = &dno where empno = &eno;
exception
when e_integrity then
    dbms_output.put_line('The department does not exist!');
end;
/
b. Raise self defined exception
declare
e_integrity exception;
pragma exception_init(e_integrity,-2291);
e_no_employee exception;
begin
update emp set deptno=&dno where empno = &eno;--10 1111
if sql%notfound then
    raise e_no_employee;
end if;
exception
when e_integrity then
    dbms_output.put_line('The department does not exist!');
when e_no_employee then
    dbms_output.put_line('The employee does not exist!');
end;
/
c. Raise application error
create or replace procedure raise_comm(eno number,commission number)
is
v_comm emp.comm%type;
begin
select comm into v_comm from emp where empno = eno;
if v_comm is null then
    raise_application_error(-20001,'The employee has no complementary!');
end if;
exception
when no_data_found then
    dbms_output.put_line('The employee does not exist!');
end;
/

12. Top N
select the N element order asc:
select * from (select t.*,dense_rank() over (PARTITION BY deptno order by sal) rank from employee t) where rank = N;