Saturday, March 14, 2015

String, StringBuilder, StringBuffer

Difference between String and StringBuffer/StringBuilder

  • String is immutable objects means once created it cannot be changed, reference will point to new object.
  • If our application has string manipulation activity, then there will be many discarded string object in heap memory which might result in performance impact.
  • StringBuffer/StringBuilder is mutable
  • StringBuffer/StringBuilder can have characters/strings may be inserted in between or appended at end for which the StringBuffer/StringBuilder automatically grow


Difference between StringBuffer & StringBuilder

  • Methods in StringBuilder are not synchronized hence better performance over StringBuffer
  • Methods in StringBuilder are not synchronized hence it is not thread safe
Examples with basic methods
String

public class StringDemo {
public static void main (String[] args)
{
// Following are 2 ways to instantiate String object
String s=new String("ABCDMNOP");
String s1="PqRS";
Date e=new Date();
System.out.println("Current time: " + new Timestamp(e.getTime()));
System.out.println(s); // Print ABCDMNOP
System.out.println(s1); // Print PqRS
System.out.println(s.length());
System.out.println(s.toLowerCase());
System.out.println(s.charAt(1));
System.out.println(s1.charAt(3));
//System.out.println(s1.charAt(4)); // Throws IndexOutOfBoundsException since length of s1 is 4
System.out.println(s.substring(1)); // Return the substring starting from index 1
System.out.println(s.substring(1,4)); /* Return the substring starting from index 1 
upto (endIndex-1) index i.e. BCD*/
System.out.println(s.subSequence(1, 4)); /* works similar to substring except the difference  that return type of this method is CharSequence while return type for substring is String */
}
}
StringBuffer
public class StringBufferDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub
String s=new String("ABCDMNOP");
StringBuffer sb=new StringBuffer(s); /* StringBuffer works same as StringBuilder with a difference that methods in StringBuffer are synchronized while methods in StringBuilder are non-synchronized hence StringBuilder is not thread safe so better performance */ 
System.out.println(sb);
System.out.println(sb.deleteCharAt(2));
System.out.println(sb.delete(4, 6)); /* delete the substring starting from startIndex  upto (endIndex-1) index i.e. NO  */
System.out.println(sb.replace(1, 3, "XYZQ")); /* replace the substring starting from index 1 upto (endIndex-1) index with the specified string pattern i.e. BD with "XYZQ"  */
System.out.println(sb.reverse());
System.out.println(sb);//Original String is also changed with the last operation
System.out.println(sb.charAt(3));
System.out.println(sb.substring(4, 7)); /* Return the substring starting from index 1 upto (endIndex-1) index i.e. YXA*/
System.out.println(sb.insert(2, 'x'));/* Insert the specified character on given index i.e. x on index 2 */
System.out.println(sb.insert(3, true)); /* Insert the specified boolean on given index i.e. x on index 3 */
System.out.println(sb.insert(3, "Test")); /* Insert the specified string on given index i.e. x on index 3 */

}

}

StringBuilder
public class StringBuilderDemo {

public static void main(String[] args) {
// TODO Auto-generated method stub

String s=new String("ABCDMNOP");
StringBuilder sb=new StringBuilder(s);
System.out.println(sb);
System.out.println(sb.deleteCharAt(2));
System.out.println(sb.delete(4, 6)); /* delete the substring starting from startIndex  upto (endIndex-1) index i.e. NO  */
System.out.println(sb.replace(1, 3, "XYZQ")); /* replace the substring starting from index 1 upto (endIndex-1) index with the specified string pattern i.e. BD with "XYZQ"  */
System.out.println(sb.reverse());
System.out.println(sb);//Original String is also changed with the last operation
System.out.println(sb.charAt(3));
System.out.println(sb.substring(4, 7)); /* Return the substring starting from index 1 upto (endIndex-1) index i.e. YXA*/
System.out.println(sb.insert(2, 'x'));/* Insert the specified character on given index i.e. x on index 2 */
System.out.println(sb.insert(3, true)); /* Insert the specified boolean on given index i.e. x on index 3 */
System.out.println(sb.insert(3, "Test")); /* Insert the specified string on given index i.e. x on index 3 */
}

}




Thursday, March 12, 2015

Test Strategy Vs Test Plan

Test Strategy

  • Set of guide lines which describes test design for the project
  • Can be either on organization level prepared by QA Manager/Director OR on project level prepared by QA Manger/Lead
  • Pre-requisite for this document is Business Requirement Document (BRD)
  • Often a static document i.e. not much changes happen in this document during the project life cycle
  • Contain generic information about what should be covered/used as testing. Few key points can be (Not limited to)- 
    • Business scope & objective
    • QA Best Practices 
    • Test Automation tools (Used at organization level OR Proposed for the project)
    • Defect Management tools (Used at organization level OR Proposed for the project)
    • Change & configuration management tool (Used at organization level OR Proposed for the project)
    • Test Deliverables
    • Test status communication 
    • Test metrics reporting
    • Training requirements

Test Plan

  • Details out test methodology for a particular project release or phase 
  • Prepared by QA Manager or QA Lead
  • Pre-requisite for a Test plan is Business Requirement Document (FRD) Or Software requirement specification (SRS)
  • Mostly a dynamic document where changes can happen during release cycle and all these changes are tracked in a different version e.g. There can be certain features which can be discovered as out of scope in the current release due to ANY reason. Such features should be scoped out from QA perspective as well in the Test plan
  • Can contain following information (Not limited to)
    • Feature/Release introduction
    • Features in scope 
    • Features not is scope 
    • Entry/Exit/Resumption Criteria
    • Testing in/out scope, can be a combination of functional / non- functional testing 
      • Functional Testing
        • Unit
        • Integration 
        • System
        • UAT
        • DB Testing
      • Non-functional Testing
        • Performance
        • Load
        • Stress
    • Schedule & responsibilities
    • Test tools (Used in the particular release based on the consent with client or group)
      • Automation tools
      • Defect Management tool
      • Change & configuration management tool
    • Test data strategy
    • Test Scenarios/ Test Case
    • Test Environments
    • Test Deliverables
      • Test Plan
      • Test Cases
      • Test Results
      • Test Status/Report (Daily/Weekly)
      • User document
      • Test Sign-off report
    • Risks & contingencies
    • Test plan Approvals

Saturday, March 7, 2015

Algorithm Complexity Analysis

What it is?
Big O notation and Algorithm complexity analysis is a way to formally measure that how  fast a program or an algo runs

Complexity analysis also helps to identify how fast an algo will run for the given input or how the algo behaves if the input grows larger
How to do that?
There are tools available, known as profilers which determine the run time of an algo in milliseconds and help us to optimize the code by identify bottlenecks

Asymptotic Behaviour
Out of an algo's complexity dropping the all the other factors and keeping only the largest growing term is known as asymptotic behavior

following examples shows asymptotic behavior of  dropping the constant terms and keeping only the one which grows fastest

  1. f( n ) = 5n + 12 gives f( n ) = n.

  2. f( n ) = 109 gives f( n ) = 1.
    We're dropping the multiplier 109 * 1, but we still have to put a 1 here to indicate that this function has a non-zero value.
  3. f( n ) = n2 + 3n + 112 gives f( n ) = n2
    Here, n2 grows larger than 3n for sufficiently large n, so we're keeping that.
  4. f( n ) = n3 + 1999n + 1337 gives f( n ) = n
  5. f( n ) = n + sqrt( n ) gives f( n ) = n
  6. Any program that doesn't have any loops will have f( n ) = 1, since the number of instructions it needs is just a constant (unless it uses recursion)
  7. Any program with a single loop which goes from 1 to n will have f( n ) = n, since it will do a constant number of instructions before the loop, a constant number of instructions after the loop, and a constant number of instructions within the loop which all run n times

Key Point to note about Asymptotic Behavior-
1. Any program that doesn't have any loop will have f(n)=1
2. Any program which has a single loop goes from 1 to n will have f(n)=n
3. When we have two nested loop within each other, we will have asymptotic behavior as f(n)= n2
4. A loop within a loop within a loop will yield f(n)= n3
5. Given a series of for loops that are sequential, the slowest of them determines the asymptotic behavior of the program. Two nested loops followed by a single loop is asymptotically the same as the nested loops alone, because the nested loops dominate the simple loop. e.g. Two nested loop followed by another single loop will have asymptotic behavior as f(n)= n2

Θ( here )

  • When we've figured out the exact such f asymptotically, we'll say that our program is Θ( f( n ) )  e.g. O(1), O(n), O(n2) etc. 
  • We call this function i.e. O(here) as complexity of our algorithm
  • Program with bigger O() run slower than program having smaller O() 

Complexity of Binary Search- O(log n)
Complexity of Merge Sort- O(n log n)
Complexity of Selection sort- O(n2 )

Reference-
Material in this blog is referenced from http://discrete.gr/complexity/. Visit it for explanation of computing the complexity of different popular search & sorting algos