Saturday, December 31, 2011

Java Interview Questions - 87


What is the purpose of classpath?
classpath is an environment variable that helps the JVM's classloader locate class and jar files.

Get Current Thread

 package org.best.example;

   /*
            Get Current Thread Example
            This Java example shows how to get reference of current thread using
            currentThread method of Java Thread class.
    */
   
    public class GetCurrentThreadExample {
   
            public static void main(String[] args) {
                 
                    /*
                     * To get the reference of currently running thread, use
                     * Thread currentThread() method of Thread class.
                     *
                     * This is a static method.
                     */
                 
                    Thread currentThread = Thread.currentThread();
                    System.out.println(currentThread);
                 
            }
    }
   
    /*
    Output of the example would be
    Thread[main,5,main]
    */

Friday, December 30, 2011

Java Interview Questions - 86


What is the unnamed package?

The unnamed package is the package to which a source file's classes/interfaces belong when their source file lacks a package directive. From an implementation perspective, the unnamed package corresponds to whatever directory is current when you invoke the java command.

Create New Thread Using Runnable

package org.best.example;

    /*
            Create New Thread Using Runnable Example
            This Java example shows how to create a new thread by implementing
            Java Runnable interface.
    */
    
    /*
     * To create a thread using Runnable, a class must implement
     * Java Runnable interface.
     */
    public class CreateThreadRunnableExample implements Runnable{
    
            /*
             * A class must implement run method to implement Runnable
             * interface. Signature of the run method is,
             *
             * public void run()
             *
             * Code written inside run method will constite a new thread.
             * New thread will end when run method returns.
             */
            public void run(){
                  
                    for(int i=0; i < 5; i++){
                            System.out.println("Child Thread : " + i);
                          
                            try{
                                    Thread.sleep(50);
                            }
                            catch(InterruptedException ie){
                                    System.out.println("Child thread interrupted! " + ie);
                            }
                    }
                  
                    System.out.println("Child thread finished!");
            }
          
            public static void main(String[] args) {
                  
                    /*
                     * To create new thread, use
                     * Thread(Runnable thread, String threadName)
                     * constructor.
                     *
                     */
                  
                    Thread t = new Thread(new CreateThreadRunnableExample(), "My Thread");
                  
                    /*
                     * To start a particular thread, use
                     * void start() method of Thread class.
                     *
                     * Please note that, after creation of a thread it will not start
                     * running until we call start method.
                     */
                  
                    t.start();
                  
                    for(int i=0; i < 5; i++){
                          
                            System.out.println("Main thread : " + i);
                          
                            try{
                                    Thread.sleep(100);
                            }
                            catch(InterruptedException ie){
                                    System.out.println("Child thread interrupted! " + ie);
                            }
                    }
                    System.out.println("Main thread finished!");
            }
    }
    
    /*
    Typical output of this thread example would be
    
    Main thread : 0
    Child Thread : 0
    Child Thread : 1
    Main thread : 1
    Main thread : 2
    Child Thread : 2
    Child Thread : 3
    Main thread : 3
    Main thread : 4
    Child Thread : 4
    Child thread finished!
    Main thread finished!
    
    */

Thursday, December 29, 2011

Java Interview Questions - 85


When you need to create strings dynamically, what should you use performance wise, String or StringBuffer? I thought StringBuffer performs better than String. So I always start with a StringBuffer, and after completing the String, return a buffer.toString().

The answer to your question depends on the nature of the string. If it is immutable (that is, unchangeable), use String. You could use StringBuffer, but doing so would allow code to directly change the immutable string's characters, and the string would no longer be immutable. Similarly, if the string is mutable, use StringBuffer. You could use String, but then you would end up creating additional String objects during string modification—because String methods that could potentially modify a string create additional String objects that contain modified strings. Eventually, the garbage collector would see the additional (and probably unreferenced) Strings and perform a collection—possibly affecting the program's performance. StringBuffer does not suffer from that performance problem because it does not create additional StringBuffer (or String) objects. Additional Strings that arise from using String (instead of StringBuffer) to represent a mutable string are one performance problem. A second problem, which can prove just as serious, could occur when you use StringBuffer to represent a mutable string. StringBuffer's character array (which holds a mutable string) has finite length. Any modification that results in a mutable string whose length exceeds the character array's length causes StringBuffer to create a new character array of appropriate length, copy characters from the old character array to the new character array, and erase the reference to the old character array (making that character array eligible for garbage collection). Because array creation, array copying, and garbage collection take time, how do you solve this potential performance problem? Either create a StringBuffer object with large enough initial capacity—character array length—or call StringBuffer's ensureCapacity() method to set an appropriate character array length prior to changing the array. That way, you minimize the number of extra activities. Both performance problems manifest themselves during looped string concatenation. Consider the following code fragment:
String s = "a";
for (int i = 0; i < 2000; i++)
    s = s + "b";.
The code fragment translates into this byte code equivalent:
String s = "a";
for (int i = 0; i < 2000; i++)
    s = new StringBuffer ().append (s).append ("b").toString ();
The code fragment above creates a StringBuffer and a String (via toString()) during each loop iteration. These objects are temporary and disappear after each loop iteration (although the last-created String is still referenced after the loop completes). Eventually, the garbage collector will probably run. How do you solve this potential performance problem? Consider the following code fragment:
String s = "a";
StringBuffer sb = new StringBuffer (2500); // Assume a maximum character array length of 2500 characters.
sb.append (s);
for (int i = 0; i < 2000; i++)
    sb.append ("b");
s = sb.toString ();
The code fragment does not create any StringBuffer or String objects during the loop. Therefore, the potential for garbage collection is quite low. (Garbage collection can still occur because the garbage collector thread runs at various times and there may be unreferenced objects from previously-executed code to collect.) To sum up, understanding whether strings should be immutable or mutable will lead you to select the appropriate String/StringBuffer classes, which benefits performance. Furthermore, performance improves when you set an appropriate StringBuffer capacity prior to making many modifications and use care when dealing with looped string concatenation.

Packaging In Java


Create a shapes package with classes Point, Circle, Rectangle, and Square. Of those classes, ensure that Point is the only class not accessible outside its package. Use implementation inheritance to derive Circle from Point and Rectangle from Square. Provide an Area interface with a double getArea() method that returns the area of a Circle, a Square, or a Rectangle. Once you finish creating the package, create a TestShapes program that imports class and interface names from shapes, creates objects from shape classes, and computes the area of the shape each object represents. After compiling and running TestShapes (successfully), move shapes to another location on your hard drive and change classpath so that a second attempt to run TestShapes results in the same output as the previous run.
Complete the following steps:
1.      Ensure no classpath environment variable exists.
2.      Create a shapes directory.
3.      Copy the following source code into an Area.java file that appears in shapes:
// Area.java
package shapes;
public interface Area
{
   double getArea ();
}

4.      Copy the following source code into a Circle.java file that appears in shapes:
// Circle.java
package shapes;
public class Circle extends Point implements Area
{
   private int radius;
   public Circle (int x, int y, int radius)
   {
      super (x, y);
      this.radius = radius;
   }
   // Why do I need to redeclare getX () and getY ()? Hint: Comment
   // out both methods and try to call them from TestShapes.
   public int getX () { return super.getX (); }
   public int getY () { return super.getY (); }
   public int getRadius () { return radius; }
   public double getArea () { return 3.14159 * radius * radius; }
}

5.      Copy the following source code into a Point.java file that appears in shapes:
// Point.java
package shapes;
class Point
{
   private int x, y;
   Point (int x, int y)
   {
      this.x = x;
      this.y = y;
   }
   int getX () { return x; }
   int getY () { return y; }
}

6.      Copy the following source code into a Rectangle.java file that appears in shapes:
// Rectangle.java
package shapes;
public class Rectangle extends Square
{
   private int length;
   public Rectangle (int width, int length)
   {
      super (width);
      this.length = length;
   }
   public int getLength () { return length; }
   public double getArea () { return getWidth () * length; }
}

7.      Copy the following source code into a Square.java file that appears in shapes:
// Square.java
package shapes;
public class Square implements Area
{
   private int width;
   public Square (int width)
   {
      this.width = width;
   }
   public int getWidth () { return width; }
   public double getArea () { return width * width; }
}

8.      Copy the following source code into a TestShapes.java file that appears in shapes's parent directory:
// TestShapes.java
import shapes.*;
class TestShapes
{
   public static void main (String [] args)
   {
      Area [] a = { new Circle (10, 10, 20),
                    new Square (5),
                    new Rectangle (10, 15) };
      for (int i = 0; i < a.length; i++)
           System.out.println (a [i].getArea ());
   }
}

9.      Assuming the directory that contains TestShapes.java is the current directory, execute javac TestShapes.java to compile TestShapes.java and all files in the shapes directory. Then execute java TestShapes to run this application.
10.  Move shapes to another directory and set classpath to refer to that directory and the current directory. For example, under Windows, move shapes \temp moves shapes into the temp directory. set classpath=\temp;. points classpath to the temp directory (just below the root directory) and current directory so java TestShapes still runs.