Google

Mar 21, 2012

Java Interview Questions and Answers - performance testing your Java application

I have never been in a project or organization that is yet to have any performance or scalability issues. It is a safe bet to talk up your achievements in fixing performance or resource leak issues in job interviews.  It is a pet subject of many job interviewers and if you are in an interview with an organization that is facing performance issue, you will be quizzed on it. Refer to


Q. How would you go about performance testing your Java application?
A.

1. Using a profiler on your running code. It should help you identify the bottlenecks. For example, jprofiler or Netbeans profiler. A profiler is a program that examines your application as it runs. It provides you with useful run time information such as time spent in particular code blocks, memory / heap, etc. In Java 6, you could use the JConsole.


2. You also need to set up performance test scripts with JMeter to simulate the load. Most issues relating to performance bottlenecks, memory leaks, thread-safety, deadlocks, etc only surface under certian load. The performance testing scripts can be recorded while the application is being used and then manually refined. The tools like JMeter HTTP Proxy or Badboy software can be used to trace the script.

3. You could provide a custom solution with the help of AOP (aspect oriented programming) or dynamic proxies to intercept your method calls. Dynamic proxies allow you to intercept method calls so you can interpose additional behavior between a class caller and its "callee".

For example, without AOP or dynamix proxy


public interface Customer {
 
 public abstract void getDetails(String customerId) ;

}

public class CustomerImpl implements Customer{

 public void getDetails(String customerId) {
  long startTime = System.currentTimeMillis();
  try {
   // Actual method body...
   Thread.sleep(2000);
  } catch (InterruptedException e) {
   e.printStackTrace();
  } finally {
   long endTime = System.currentTimeMillis();
   System.out.println("method took: " + (endTime - startTime) + "ms");
  }
 }

}


The above approach is very intrusive. Imagine if you have to add this to 30 to 40 other methods. How do you turn this metrics monitoring on and off without commenting and uncommenting your actual method. With dynamic proxy or Spring based AOP, you can alleviate this problem. Here is an example of the dynamic proxy class.


import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

//uses Java  reflection
public class PerformanceLogger implements InvocationHandler {

 protected Object delegate; //actual object that performs a function

 public PerformanceLogger(Object delegate) {
  this.delegate = delegate;
 }

 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {

  long startTime = System.currentTimeMillis();
  
  try {
   Object result = method.invoke(delegate, args); // invoke the delegate
   return result;
  }

  finally {
   long endTime = System.currentTimeMillis();
   System.out.println("method took: " + (endTime - startTime) + "ms");
  }
 }

}


Note: If you are using Java 5 or higher use the System.nanoTime( ) instead of System.currentTimeMillis(). For example,


long start = System.nanoTime(); // requires java 1.5
//some process
double elapsedTimeInSec = (System.nanoTime() - start) * 1.0e-9;

The test class that tests the above code

import java.lang.reflect.Proxy;


public class PerformanceTest {
 
 
 public static void main(String[] args) {
    Customer cust = new CustomerImpl();  
    PerformanceLogger pl = new PerformanceLogger(cust); 
    cust = (Customer)Proxy.newProxyInstance(CustomerImpl.class.getClassLoader(), new Class[] {Customer.class}, pl);
    cust.getDetails("8");
      
 }

}


With this approach, you don't need to put the System.currentTimeMillis( ) in your delegate classes. It only needs to be in PerformanceLogger, and it will intercept actual calls to the delegates to print performance metrics. If you want to make changes as to how the metrics are collected or want to turn off System.currentTimeMillis( ), you will only have to do it in one class, that is the dynamic proxy class PerformanceLogger.

If you are using Spring, you could use the AOP based interceptors. The AOP based deadlock retry using Spring is using a very similar approach for dead lock retry.

Note:I have been in interviews where the interviewer was more interested in the custom solution by asking

Q. If you did not have a profiling tool, how would you go about gathering performance metrics?
A. AOP or dynamic proxy based solution as discussed above. You could also mention the built-in command-line and graphical tools that come with Java  like JConsole, jstack, jmap, hprof, vmstat, etc. But the main focus must be via interceptors.

Design pattern: If you are asked to describe or talk about a design pattern, you could mention this dynamic proxy class as a proxy design pattern. Many pick either singleton or factory design pattern. It would be nicer to pick something other than these two common patterns. Some interviewers specifically ask you to pick anything except factory and singleton design pattern.

Q. What tips do you give someone regarding Java performance?
A.



1. Don't compromise on design: You should not compromise on architectural principles for just performance. You should make effort to write architecturally sound programs as opposed to writing only fast programs. If your architecture is sound enough then it would allow your program not only to scale better but also allows it to be optimized for performance if it is not fast enough. If you write applications with poor architecture but performs well for the current requirements, what will happen if the requirements grow and your architecture is not flexible enough to extend and creates a maintenance nightmare where fixing a code in one area would break your code in another area. This will cause your application to be re-written. So you should think about extendibility (i.e. ability to evolve with additional requirements), maintainability, ease of use, performance and scalability (i.e. ability to run in multiple servers or machines) during the design phase. List all possible design alternatives and pick the one which is conducive to sound design architecturally (i.e. scalable, easy to use, maintain and extend) and will allow it to be optimized later if not fast enough. Once you get the correct design, then measure with a profiler and optimize it.

2. Be aware of the death by thousand-cuts: Having said not to compromise on the design,  one needs to be mindful of  performance inefficiencies that can creep in throughout the software development. For example, an inefficient method being called 50-100 times can adversely impact performance. A real-life example would be a JSF application that invokes its life-cycle methods many times. So, having a long-running subroutine within the life-cycle method might end up calling it more than once. So, know your best practices and potential pitfalls. Here are a few things to keep in mind.

  • Use immutable objects where applicable. Immutable objects are inherently thread-safe and can also be reused. A good candidate for implementing the flyweight design pattern. The following Java method is an example of flyweight.

Integer.valueOf(String s)

        It keeps some amount of the created Integers internally, so, when you pass the String that you have
        passed before - it returns you an existing instance.


  • Check your regexes and SQL queries for backtracking and Cartesian joins respectively.


  • Define your objects and variables with the right scopes. The variables need to be defined at the lowest scope possible (e.g local --> instance --> static)
  • Use proven libraries, frameworks, built-in algorithms, and data structures as opposed to creating your own. For example, when handing concurrency use java.util.concurrent package.

3. Always have a performance focus by developing proper load testing scripts and benchmarks. The non-functional requirements should cover the relevant SLAs (i.e. Service Level Agreements). Tune your application server, database server, application, etc where required with proper bench marking and load testing scripts. The mission critical applications must have run time metrics gathering in place commercial tools. There are tools that can be used in production environment like YourKit for Java, JProfiler for Java, etc and for larger distributed and clustered systems with large number of nodes there are profilers like CA Wiley Introscope for Java, ClearStone for Java, and HP Performance managers. These tools are handy for proactive detection and isolation of server/application bottlenecks, historical performance trend tracking for capacity planning, and real-time monitoring of system performance.

Q. When designing your new code, what level of importance would you give to the following attributes? Rank the above attributes in order of importance?  

-- Performance
-- Maintainability
-- Extendibility
-- Ease of use
-- Scalability


Rank the above attributes in order of importance?  

A. This is an open-ended question. There is no one correct order for this question. The order can vary from application to application, but typically if you write 1 - extendable, 2 - maintainable and 3 – ease of use code with some high level performance considerations, then it should allow you to  optimize/tune for 4 - performance and 5 - scalability. But if you write some code, which only perform fast but not flexible enough to grow with the additional requirements, then you may end up re-writing or carrying out a major revamp to your code.

Note: These types of questions have no right or wrong answers, but can reveal a lot about your experience, passion, and attitude towards building a quality software. Good software developers and architects are opinionated based on their past experiences.

For writing  load/performance/stress testing scripts, the JMeter is a very useful free tool. Learn more about Java performance testing with JMeter

Labels: ,

7 Comments:

Blogger Unknown said...

Hi Arul, Thanks for your solution

4:04 PM, May 16, 2012  
Anonymous Resumes to you said...

Wow ! I have read your blog & surfing for Java related questions, It'll help me a lot in my interview which scheduled after 15 days.

5:45 PM, July 19, 2012  
Anonymous Performance Testing said...

hi blog owner thank you sharing java application performance testing solution this article provide the great help for performance testing good job

4:54 PM, August 10, 2012  
Blogger nasri said...

Hi

Tks very much for post:

I like it and hope that you continue posting.

Let me show other source that may be good for community.

Source: Hewlett-Packard interview questions

Best rgs
David

5:57 PM, August 14, 2012  
Blogger RK CLOTHING DESIGNS said...

This is really a great blog, might you be involved in doing an interview about how you created it? If so e-mail me!

Testing interview questions

3:37 AM, August 18, 2012  
Anonymous Ramu said...

I am an avid reader of this blog,thanks for posting java interview questions and answers on performance testing a java application.The questions helped me pass my technical round for a job interview.

3:45 AM, February 27, 2014  
Anonymous Anonymous said...

Thanks yaar

8:18 PM, December 06, 2014  

Post a Comment

Subscribe to Post Comments [Atom]

<< Home