Monday, August 25, 2014

Core Java Interview questions

1. Difference between shallow copying and deep copying?

Shallow copy:
All the primitives are copied
All the references are pointed to the existing object
So if the data in original object references are changed, new object data also gets effected, as it is also pointing to the same reference.

How to create shallow copy of an object:
Object's class clone() method does shallow copying.

  public Object clone() {
    try {
      return super.clone();
    } catch (CloneNotSupportedException e) {
      return null;
    }
  }

Deep copy:
All the primitives are copied
All the references to objects are created again.
This is like creating an object again.
So even if the data in original object references are changed, new copy data will not be effected.

How to create deep copy:

public Object() {
   Person person = new Person("Suresh", 26);
 
   return person;
}

2. Given two .java files:
A.java
class A {
     static public void main(String[] args) {
          System.out.println("main() method of class A");
     }
}

B.java
class B extends A {
}

Both the classes are compiled and they do not have any compilation errors.
What is the output of the following command?
> java B

Answer: main() method of class A
Since class B inherits from A, it looks for main() method in its superclass, when it is not found in it.

3. What does the SOP prints here?
int b = 10;
System.out.println((b=3) + b);

Answer:
6
Rule is that: binary operator has left associative, means LHS operand of binary operator is fully evaluated before the right hand operand.

4. Given:
int[] a = {10, 20, 30, 40, 50};
int index = 4;
a[index] = index = 2;

What is the value of index and array "a" elements?

Answer:
index = 2;
array: a = {10, 20, 30, 40, 2}

Its evaluated as:
a[index] = index = 2;
a[4] = index = 2;
a[4] = 2;

Rule is that assignment operator has right associative.

5. What is the value of the b after the following statements?
byte b = 28;
b = b + 10;

Ans: Compilation Error
Any arithmetic operation with Integer variables will give an "int" result, which can't be assigned directly to "byte" here. We must use explicit casting.

6. How to create a immutable class (like String, Wrapper classes)?

a. Class should not have any setter methods
b. make all the fields private and final. private makes them not to be accessed by outside the class. final ensures even accidentally also the fields data wont be changed
c. Dont allow subclasses to override the class methods. So make the class as final.
d. If there is any field which is mutable, its getter should return a new object of that field. So that its value wont be changed in our actual immutable object.

7. Whats the output of the following program?
public class ThreadDemo {
static public void main(String[] args) {
Thread.currentThread().setDaemon(true);
System.out.println(Thread.currentThread().isDaemon());
}
}

Answer:
Runtime Exception: IllegalThreadStateException.

main() thread is already started and it is running state.
we cannot use setDaemon() on a thread which is already in running state.

8. Method Overloading/Overriding possibilities?
class A {
  public void nonSt() { }
  public static void st() { }
}

class B {
 public void nonSt() { } //valid
 public static void st() { } //valid

 public static void nonSt() { } //invalid
 public void st() { } //invalid
}

Sunday, August 24, 2014

log4j

log4j: Logging for Java
-open source logging tool from apache.

Log Levels:

There are 8 levels
  • ALL
  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR
  • FATAL
  • OFF

The specified level and all higher level messages will be printed.
For example, if the level is set to INFO, then only INFO,WARN, ERROR and FATAL messages are printed and TRACE, DEBUG messages are skipped.

Steps to configure Logger in your class programmatically:
1. Get logger instance on your class
Logger logger = Logger.getLogger(Test.class);

2. Create a Layout(determines the format of the print message)
Layout layout = new PatternLayout();

3. Create an Appender passing the layout
Appender appender = new FileAppender(layout, "file.log");

4. Add the Appender reference to the class Logger
logger.addAppender(appender);

5. Set the log level of the Logger
logger.setLevel(Level.INFO);

Thats it...Now you can write log messages, with different levels.
logger.info("This is an info message");
logger.warn("This is a warning message");

Main Components:
1. org.apache.log4j.Logger(class)
It is the main class to handle log messages
2. org.apache.log4j.Layout(abstract class)
It is used to display log messages in our own styles and formats
3. org.apache.log4j.Appender(interface)
It is used to display logger messages in different repositories.

If no appenders added to Logger, then we get a warning message saying "No appenders could be found for logger (<class>)."
Layouts:
1. SimpleLayout (%p - %m%n)
2. HtmlLayout
3. XmlLayout
4. PatternLayout (we can use any customized pattern here)

Patterns:
Few useful pattern strings:
%d  : Date
%m : Message
%n  : new line
%p  : Priority/Level
%t  : Thread
%c  : Class name 
%L  : Line number

Please have a look at the below link, for all available patterns:
http://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns

Appenders:
1. ConsoleAppender
2. FileAppender
3. RollingFileAppender (Controls number of log files and size of each file)
4. JDBCAppender (Writes messages to database)
5. JMSAppender (sends messages over queues)
6. SMTPAppender (Sends mail for each message)

Declarative Approach to configure Log4j:
Two ways
1. log4j.xml
2. log4j.properties

If both xml and properties files are present, then log4j.xml takes higher priority.

1. log4j.xml:
eg:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
    <appender name="ConsoleApp" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%L [%m][%p][%d]%n" />
        </layout>
    </appender>
    <appender name="FileApp" class="org.apache.log4j.FileAppender">
        <param name="file" value="profile.log" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%m][%p][%d][%t]%n" />
        </layout>
    </appender>
    <root>
        <level value="trace" />
        <appender-ref ref="FileApp" />
        <appender-ref ref="ConsoleApp" />
    </root>
    <logger name="com.Log4jTest">
        <level value="warn" />
        <appender-ref ref="ConsoleApp" />
    </logger>
    <logger name="com.test">
        <level value="trace" />
        <appender-ref ref="ConsoleApp" />
    </logger>
</log4j:configuration>


2. log4j.properties:
eg:

# Define the root logger with appender file
log4j.rootLogger = DEBUG, FileApp

# Define the file appender with file name
log4j.appender.FileApp=org.apache.log4j.FileAppender
log4j.appender.FileApp.File=log.out

# Define the layout for file appender
log4j.appender.FileApp.layout=org.apache.log4j.PatternLayout
log4j.appender.FileApp.layout.conversionPattern=%L [%d] [%t] [%p] %m%n



Adding multiple appenders:

<root>
   <level value="trace" />
   <appender-ref ref="FileApp" />
   <appender-ref ref="ConsoleApp" />
</root>


Different log level for different packages:

<logger name="com.Log4jTest">
   <level value="warn" />
   <appender-ref ref="ConsoleApp" />
</logger>
<logger name="com.test">
   <level value="trace" />
   <appender-ref ref="ConsoleApp" />
</logger>


Configurators:

1. BasicConfigurator:
This does not require any log4j file.

Logger logger = Logger.getLogger(Log4jTest.class);
BasicConfigurator.configure();


This used ConsoleAppender and PatternLayout with pattern "%r [%t] %p %c %x - %m%n"

2. DomConfigurator:
This is used to specify the log4j xml configuration file.
File name can be anything


3. PropertyConfigurator:
This is used to specify the log4j properties configuration file.
File name can be anything.