Java Interview Questions - 9

Below are few java interview questions where candidate need to be more clear on basics and how it works when they asked simples questions. All these questions are programmatic questions and need to answer whether program will compile and run without any error and next what will be the out?


package com.pract;

import java.lang.reflect.Method;

class DeclaredMethodsPractBase {

 public void myParent1(){};
 protected void myParent2(){};
 private void myParent3(){};
}

public class DeclaredMethodsPract extends DeclaredMethodsPractBase{
 
 public void myChild11(){};
 protected void myChild12(){};
 private void myChild13(){};
 
 public static void main(String[] args) throws ClassNotFoundException {
  
  Class<?> classs = Class.forName("com.pract.DeclaredMethodsPract");
  
  Method[] methods = classs.getDeclaredMethods();
  
  for (Method method : methods) {
   System.out.print(method.getName() + ", ");
  }
 }
}

1. Runtime error
2. main, myChild11, myChild12, myChild13, myParent1,
3. main, myChild11, myChild12, myChild13, myParent1, myParent2,
4. main, myChild11, myChild12, myChild13, myParent1, myParent2, myParent3,



public class EnumPract {

 enum Numbers{ONE, TWO, THREE};
 
 public static void main(String[] args) {
  
  System.out.print((Numbers.ONE == Numbers.ONE) + ", ");
  System.out.print(Numbers.ONE.equals(Numbers.ONE));
 }
}

1. Compile time error
2. true, false
3. false, false
4. false, true
5. true, true



public class InternPract {

 public static void main(String[] args) {
  String a1 = "Java";
  String a2 = new String("Java");
  String a3 = a1.intern();
  
  System.out.print((a1 == a2) + ", "+(a1 == a3));
 } 
}

1. false, true
2. true, true
3. true, false
4. false, false



import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

public class MapObjectPract {

 public static void main(String[] args) {
  
  Map<String, String> map = new HashMap<String, String>();
  
  System.out.print((map instanceof Object) + ", ");
  System.out.print((map instanceof Map) + ", ");
  System.out.print((map instanceof HashMap) + ", ");
  System.out.print(map instanceof Collection);
 }
}

1. true, false, true, false
2. false, true, true, false
3. true, true, true, false
4. false, false, true, false



public class OperatorPract {

 public static void main(String[] args) {
  
  int i = 0;
  i = i++ + method(i);
  System.out.print(i);
 }
 
 static int method(int i){
  System.out.print(i+":");
  return 0;
 }
}

1. 1:0
2. 1:1
3. 0:1
4. 0:0



class Recursion{
 int method(int n){
  int result = method(n - 1);
  return result;
 }
}

public class RecuPract {

 public static void main(String[] args) {
  Recursion obj = new Recursion();
  int val = obj.method(10);
  System.out.println("completed : "+ val);
 }
}

1. completed : 0
2. compile time error
3. Runtime error
4. completed : -1



class Test implements Runnable{
 
 @Override
 public void run() {
  System.out.print("HELLO : "+Thread.currentThread().getName() + ", ");
 }
}

public class RunnablePract {

 public static void main(String[] args) {

  Test obj = new Test();
  
  Thread t1 = new Thread(obj, "T1");
  Thread t2 = new Thread(obj, "T2");
  
  t1.start();
  t1.join();
  t2.start();
 }
}

1. Runtime error
2. HELLO : T1, HELLO : T2,
3. HELLO : T2, HELLO : T1,
4. Compile time error



import java.util.HashSet;

public class SetPract {

 public static void main(String[] args) {
  
  HashSet<Integer> set = new HashSet<Integer>();
  for(int i=0;i<100;i++){
   set.add(i);
   set.remove(i - 1);
  }
  
  System.out.println("SET SIZE ::: "+set.size());
 }
}

1. SET SIZE ::: 100
2. SET SIZE ::: 1
3. SET SIZE ::: 99
4. SET SIZE ::: 0



public class StringArrayPract {

 private String[] array;
 
 public StringArrayPract() {
  array = new String[10];
 }
 
 public void setArray(String val, int i){
  array[i] = val;
 }
 
 public String getArray(int i){
  return array[i];
 }
 
 public static void main(String[] args) {
  
  StringArrayPract obj = new StringArrayPract();
  System.out.println("VALUE IS : "+obj.getArray(5));
 }
}

1. Runtime error
2. VALUE IS : null
3. Compile time error
5. VALUE IS :



import java.util.TreeSet;

public class TreeSetPract {

 public static void main(String[] args) {
  
  TreeSet<String> tSet = new TreeSet<String>();
  tSet.add("one");
  tSet.add("two");
  tSet.add("three");
  tSet.add("one");
  
  for (String string : tSet) {
   System.out.print(string+", ");
  }
 }
}

1. one, two, three,
2. one, two, three, one
3. one, one, three, two,
4. one, three, two, 

Spring - Sending E-Mail with MailSender

 
Sending email using Spring "org.springframework.mail.javamail.JavaMailSenderImpl" class simplifies the process with JavaMail API. Below example will give step by step to send email by using Gmail SMTP server configurations.

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>org.springframework.samples</groupId>
 <artifactId>SendingEmail</artifactId>
 <version>0.0.1-SNAPSHOT</version>

 <dependencies>

  <!-- Spring framework -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring</artifactId>
   <version>2.5.6.SEC03</version>
  </dependency> 

  <!-- Java Mail API -->
  <dependency>
   <groupId>javax.mail</groupId>
   <artifactId>mail</artifactId>
   <version>1.4.3</version>
  </dependency>

 </dependencies>
</project>

email.xml

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 <bean id="emailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
  <property name="host" value="smtp.gmail.com" />
  <property name="port" value="587" />
  <property name="username" value="USERNAME" />
  <property name="password" value="PASSWORD" />

  <property name="javaMailProperties">
   <props>
    <prop key="mail.smtp.auth">true</prop>
    <prop key="mail.smtp.starttls.enable">true</prop>
   </props>
  </property>
 </bean>

 <bean id="emailBean" class="com.app.email.Mailer">
  <property name="emailSender" ref="emailSender" />
 </bean>

</beans>

Mailer.java

package com.app.email;

import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;

public class Mailer {

 private MailSender emailSender;
 
 //Setter for emailSender
 public void setEmailSender(MailSender emailSender) {
  this.emailSender = emailSender;
 }
 
 //Method to send email
 public void sendMail(String from, String to, String subject, String msg) {

  SimpleMailMessage simpleMsg = new SimpleMailMessage();
  
  simpleMsg.setFrom(from);
  simpleMsg.setTo(to);
  simpleMsg.setSubject(subject);
  simpleMsg.setText(msg);
  
  //Finally sending email using MailSender
  emailSender.send(simpleMsg); 
 }
}

SendEmail.java

package com.app.email;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SendEmail {

 public static void main(String[] args) {

  String from = "from@gmail.com";
  String to = "to@gmail.com";
  String subject = "Hello World !";
  String msg = "Hello World, How are you ???";

  ApplicationContext context = new ClassPathXmlApplicationContext("email.xml");

  try {
   Mailer mailer = (Mailer) context.getBean("emailBean");
   mailer.sendMail(from, to, subject, msg);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }
}


Spring - Sending E-Mail with MailSender


Log4j + Separate Logger for specific classes or package

We may seen writing logger for entire application or separate DEBUG or ERROR log files. In this tutorial we will see how to set separate logger for specific package or specific class using log4j API.

Log4j + Separate Logger for specific classes or package

In above snapshot we can see 2 packages called "com.SeparateLoggerTest" and "com.newpackage". Where "newpackage" having 2 classes and we are trying to route logs of these classes to separate log file. Lets see simple sample how to achieve this.

log4j.properties

#------------------------------------------------
# Root logger option
#------------------------------------------------

log4j.rootLogger=DEBUG, applogger

# Redirect log messages to a log file, support file rolling.
log4j.appender.applogger=org.apache.log4j.RollingFileAppender
log4j.appender.applogger.File=C:\\log\\mainlog.log
log4j.appender.applogger.MaxFileSize=1MB
log4j.appender.applogger.MaxBackupIndex=5
log4j.appender.applogger.layout=org.apache.log4j.PatternLayout
log4j.appender.applogger.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

#------------------------------------------------
# Package logger option
#------------------------------------------------

log4j.logger.com.newpackage=DEBUG, packageLogger
log4j.additivity.com.newpackage=false

log4j.appender.packageLogger=org.apache.log4j.RollingFileAppender
log4j.appender.packageLogger.File=C:\\log\\separatepackage.log
log4j.appender.packageLogger.MaxFileSize=1MB
log4j.appender.packageLogger.MaxBackupIndex=5
log4j.appender.packageLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.packageLogger.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n


In above log4j.properties file we can see section under "Package logger option" separate logger for complete package classes "com.newpackage". Also log4j.additivity.com.newpackage will used to manage logger write options.
If we set "false" then it will write logs only in separate log file which mentioned under package logger.
If we set "true" then logs will written in both root log file as well under package logger.

MainClass.java

package com.SeparateLoggerTest;

import org.apache.log4j.Logger;

import com.newpackage.SpecialPackageClass_1;
import com.newpackage.SpecialPackageClass_2;


public class MainClass {
 
 final static Logger logger = Logger.getLogger(MainClass.class);
 
    public static void main( String[] args ) {
     
     logger.info("Hello Logger ::::::::::::: "+new MainClass().getClass());
     
        new SpecialPackageClass_1().myMethod();
        new SpecialPackageClass_2().myMethod();
    }
}


SpecialPackageClass_1.java

package com.newpackage;

import org.apache.log4j.Logger;

public class SpecialPackageClass_1 {
 
 final static Logger logger = Logger.getLogger(SpecialPackageClass_1.class);
 
    public void myMethod() {
     
     logger.info("Hello Logger ::::::::::::: "+new SpecialPackageClass_1().getClass());
     
    }
}


SpecialPackageClass_2.java

package com.newpackage;

import org.apache.log4j.Logger;

public class SpecialPackageClass_2 {
 
 final static Logger logger = Logger.getLogger(SpecialPackageClass_2.class);
 
    public void myMethod() {
     
     logger.info("Hello Logger ::::::::::::: "+new SpecialPackageClass_2().getClass());
     
    }
}



OUTPUT:

mainlog.log

Log4j + Separate Logger for specific classes or package


separatepackage.log

Log4j + Separate Logger for specific classes or package

Static Vs Volatile variables in Multi-threading

We all know that Static variables and methods will be associated with the class, rather than with any object. Every instance of the class shares a class variable (static), which is in one fixed location in memory. Any object can change the value of a class variable, but class variables can also be manipulated without creating an instance of the class.

In that case how Static differs from Volatile under Multi-threading?

Declaring static variable means there will be only copy associated with class it doesn’t matter how many object get created for that class. The static variable will be accessible even with no Objects created at all. Thread may have locally cached values of it.

This means that if two threads update a variable of the same Object concurrently, and the variable is not declared volatile, there could be a case in which one of the threads has in cache an old value. Even if you access a static value through multiple threads, each thread can have its local cached copy!

But a volatile variable will keep only one copy in memory and shared across the threads.

Lets assume a class with static and volatile variables, with 2 threads accessing it.

public class MyTestClass {

 int normalInt;
 static int staticInt;
 volatile int volatileInt;

}


Static Vs Volatile variables in Multithreading

Default Method in Interface - Java 8

 
Java 8 comes lots of new features and in one important feature is Default method in Interface. Till Java 7 we can have only abstract methods in interface and we can't have any method definition in interfaces. In Java 8 we can have default method nothing but method with definition, following example will show you how to write those methods.

Next we can ask, why we need Default method in interface?

Lets assume we need to introduce new method in interface and then it breaks all classes implementing those interfaces by compile time error. For example if interface used in hundreds of classes which can break millions of line code by asking to implement new method introduced in Interface.
Even in JDK we can see foreach default method introduced to entire collection classes by giving definition in Iterable interface. Below is the Oracle API docs snapshot for Iterable interface.

Interface Default method in Java 8

Suppose if we don't have default method feature then JDK need to come-up with millions of code change in all collection classes by giving those method implementation.

Next we may ask whats the difference between Java 8 interface and Abstract method?

Interfaces cannot have state associated with them but Abstract classes can have state associated with them.

Next how to solve Multiple Inheritance Ambiguity Problems with default methods?

Since we can implement multiple interface, also we can have same default method (with same name) in 2 different interface. When we implement those interfaces in concrete class compile will give a warning that

"Duplicate default methods named <method_name> with the parameters () and () are inherited from the types <Interface1> and <Interface2>"

To solve this we can Override default method from any 1 interface. Below example will give detail about how to use default method in interface and to solve Ambiguity Problems with 2 interface have same default method.

FirstInterface.java

public interface FirstInterface {

 public void method();
 
 default public String methodName(){
  return "FirstInterface";
 }
}


SecondInterface.java

public interface SecondInterface {
 
 public void method();
 
 public default String methodName(){
  return "SecondInterface";
 }
}


TestClass.java

public class TestClass implements FirstInterface, SecondInterface {

 @Override
 public void method() {
  System.out.println("Hello Java Discover :) ");
 }
 
 /*
  * To solve Ambiguity Problems we can override 
  * default method as below.
  */
 @Override
 public String methodName(){
  return FirstInterface.super.methodName();
 }

 
 public static void main(String[] args) {
  new TestClass().testInterface();
 }
 
 private void testInterface(){
  method();
  System.out.println(FirstInterface.super.methodName());
  System.out.println(SecondInterface.super.methodName());
 }
 
}


OUTPUT:

Hello Java Discover :) 
FirstInterface
SecondInterface

If we see above example 2 interfaces having default method with same name. When we implement those interfaces in our concrete class (TestClass.java) we will get compile time error as

"Duplicate default methods named methodName with the parameters () and () are inherited from the types SecondInterface and FirstInterface"

To overcome this we need to override default method in our class as above. Next we can call default methods by using Interface names as we called in testInterface() method.
  • FirstInterface.super.methodName()
  • SecondInterface.super.methodName()



MySQL import and export commands

MySQL is an open-source relational database management system (RDBMS). World's second most widely used open-source client–server RDBMS. The MySQL development project has made its source code available under the terms of the GNU General Public License and owned by Oracle Corporation.
MySQL import and export commands


Now lets see simple command line examples for exporting and importing MySQL database(s). All examples are shown under Windows machines. So when we try in different OS only path(s) will change rather than commands shown below.


Export Commands:

Open command prompt and goto MySQL installed bin folder as shown below location. NOTE: Installation directory path may change from system to system.

C:\Program Files\MySQL\MySQL Server 5.6\bin>


1. Export all databases

> mysqldump -u{username} -p{password} -h{host} --all-databases > C:\Backup\all-databases.sql

* username - MySQL username
* password - MySQL password
* host - MySQL server host. If MySQL running in local then please mention as 'localhost' else give remote MySQL server IP address. When we give remote server IP, need to make sure that we have access to remote MySQL server.


2. Export single database

> mysqldump -u{username} -p{password} -h{host} {database_name} > C:\Backup\database.sql

* database_name - MySQL database name to export to file.


3. Export more than 1 database

> mysqldump -u{username} -p{password} -h{host} --databases {database_name_1} {database_name_2} > C:\Backup\databases_1_2.sql


4. Export only specific tables from database

> mysqldump -u{username} -p{password} -h{host} {database_name} {table_name_1} {table_name_2} > C:\Backup\database_table_1_2.sql


mysqldump supports the various options, which can be specified on the command. For more informations on options please refer to MySQL site link under Table 4:11


Import Command:

Similar to mysqldump command please goto MySQL installed bin folder [C:\Program Files\MySQL\MySQL Server 5.6\bin>].

1. Import all databases

mysql -u{username} -p{password} -h{host} < C:\Backup\all-databases.sql


2. Import particular database

> mysql -u{username} -p{password} -h{host} {database_name} < C:\Backup\database.sql

* NOTE: Database with name mentioned must exist already, else create empty database with the name mentioned before importing.


3. Import tables into particular database

> mysql -u{username} -p{password} -h{host} {database_name} < C:\Backup\database_table_1_2.sql

* NOTE: Database with name mentioned must exist already, else create empty database with the name mentioned before importing.

Custom Annotation with Example

Annotations are only metadata and they do not contain any business logic. Prior to annotation introduced XML were used for metadata and somehow XML maintenance was getting troublesome. So something we need very loosely coupled from code and then annotations came into picture.
Custom Annotation with Example

Java by default provides built-in annotations like @Override, @Deprecated, @SuppressWarnings, @SafeVarargs and @FunctionalInterface.

  • @Override  - Used when overriding a method from super class. 
  • @Deprecated - Used to indicate a method is deprecated. When we use this annotation recommendedto provide information for why particular method deprecated and alternative solution to use it. 
  • @SuppressWarnings - Used to ignore specific warnings shown in code. 
  • @SafeVarargs - Suppress warnings for all callers of a method or constructor with a generics varargs parameter, since Java 7.
  • @FunctionalInterface - Specifies that the type declaration is intended to be a functional interface, since Java 8.

Now lets see simple example to write custom annotation which is as simple as writing interfaces. Just we need to prefix @ symbol to "interface" keyword. Some of the properties of annotation class must follow are

There a 5 types of meta annotations which gives information about the annotation which we create and they are @Documented, @Target, @Inherited, @Retention and @Repeatable

  • @Retention - Specifies how the marked annotation is stored—Whether in code only, compiled into the class, or available at run-time through reflection. Various Retention policies like
    1. RetentionPolicy.CLASS (Annotations are to be recorded in the class file by the compiler but need not be retained by the VM at run time. This is the default behavior.)
    2. RetentionPolicy.RUNTIME (Annotations are to be recorded in the class file by the compiler and retained by the VM at run time, so they may be read reflectively.)
    3. RetentionPolicy.SOURCE (Annotations are to be discarded by the compiler.)
  • @Documented - Marks another annotation for inclusion in the documentation.
  • @Target - Marks another annotation to restrict what kind of Java elements the annotation may be applied to. Various ElementTypes like 
    1. ElementType.TYPE (class, interface, enum)
    2. ElementType.TYPE_USE (Since 1.8)
    3. ElementType.TYPE_PARAMETER (Since 1.8)
    4. ElementType.FIELD (instance variable)
    5. ElementType.METHOD
    6. ElementType.PARAMETER
    7. ElementType.CONSTRUCTOR
    8. ElementType.LOCAL_VARIABLE
    9. ElementType.ANNOTATION_TYPE (on another annotation)
    10. ElementType.PACKAGE 
  • @Inherited - Marks another annotation to be inherited to subclasses of annotated class (by default annotations are not inherited to subclasses).
  • @Repeatable - Specifies that the annotation can be applied more than once to the same declaration, since Java 8.

Simple annotation example:

MethodInfo.java

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodInfo{
    String createdBy() default "Anand";
    String createdDate();
    String comments();
}



AnnotationTest.java

public class AnnotationTest {

 @MethodInfo(createdBy = "Anand", createdDate = "20th Nov 2015", comments = "Just saying Hello :)")
 public void sayHello(String name){
  System.out.println("Hello "+name);
 }
 
 public static void main(String[] args) {

  new AnnotationTest().sayHello("Java Discover");
  
 }
}


Spring + @PropertySource with @Value and Environment

 
In Spring we can configure our application properties in property file and by @PropertySource annotation we can configure externalized configuration file. Those property values can be read by using @Value annotation or by using Environment class.
In below lets see simple example how to use @PropertySource to read property file and to fetch those values using @Value and Environment class. Simple example that we need to serve static resources from different locations to configure in Spring and that too separate location for images and separate for text files etc., Those locations are configured in "myConfig.properties" file.

myConfig.properties

staticresourceloader.imageFileLocation.path:file:C:\\images\\

staticresourceloader.txtFileLocation.path:file:C:\\txtfiles\\



Reading values using @Value annotation

package com.app.staticresourceloader;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@ComponentScan
@EnableAutoConfiguration
@PropertySource("classpath:myConfig.properties")
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter  {

 @Value("${staticresourceloader.imageFileLocation.path}")
    private String staticImageFilePath;
 
 @Value("${staticresourceloader.txtFileLocation.path}")
    private String staticTxtFilePath;
 
 public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        
    }
    
 @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        
  System.out.println("IMAGE FILE PATH :::: "+staticImageFilePath);
  System.out.println("TEXT FILE PATH  :::: "+staticTxtFilePath);
  
  registry.addResourceHandler("/api/image/**").addResourceLocations(staticImageFilePath);
        registry.addResourceHandler("/api/txt/**").addResourceLocations(staticTxtFilePath);
        
    }   
}



Reading values using Environment

package com.app.staticresourceloader;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@ComponentScan
@EnableAutoConfiguration
@PropertySource("classpath:myConfig.properties")
@SpringBootApplication
public class Application extends WebMvcConfigurerAdapter  {

 @Autowired
 private Environment pathDetails;
 
 public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        
    }
    
 @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
  
  String imagePath = pathDetails.getProperty("staticresourceloader.imageFileLocation.path");
  String txtPath = pathDetails.getProperty("staticresourceloader.txtFileLocation.path");
  
  System.out.println("IMAGE FILE PATH :::: "+imagePath);
  System.out.println("TEXT FILE PATH  :::: "+txtPath);
  
  registry.addResourceHandler("/api/image/**").addResourceLocations(imagePath);
        registry.addResourceHandler("/api/txt/**").addResourceLocations(txtPath);
        
    }   
}


OUTPUT:

Spring + @PropertySource with @Value and Environment