Showing posts with label Java/J2EE. Show all posts
Showing posts with label Java/J2EE. Show all posts

Java scenario based questions and its answers

 

Question 1: The "Payment Gateway" Scenario (Abstraction vs. Encapsulation)

"Imagine you are designing a Payment Processing System for an e-commerce platform. You need to support multiple payment methods like Credit Cards, PayPal, and Bitcoin.

From a design perspective, how would you use Abstraction to handle these different payment methods? Additionally, how would you use Encapsulation to ensure that sensitive data, like a user's Credit Card CVV or a Private Key, is handled securely within those classes?" 

Interviewer Feedback & Correct Answer

Abstraction: Your approach using an abstract class (or an interface) is spot on. By defining makePayment() at a high level, the calling code (the checkout service) doesn't need to know how a payment is processed, only that it can be processed.

Encapsulation: You correctly identified the use of private fields.

Pro-Tip for Interviews: Mentioning immutability and defensive copying (returning a copy of a mutable object) shows a senior level of understanding.

One small correction: In a real-world high-security scenario, you might actually avoid providing setters for sensitive data like a CVV. You would ideally pass that data via a constructor and use it immediately, never storing it longer than necessary or allowing it to be changed.


Question 2: The "Overcrowded Library" Scenario (Inheritance vs. Composition)

"You are building a Library Management System. You have a class Book. You now need to implement EBook and PhysicalBook.

Initially, you might think of using Inheritance (EBook extends Book). However, many experienced developers prefer Composition (Has-A relationship) over Inheritance (Is-A relationship).

Can you explain a scenario in this Library system where deep inheritance might cause issues (the 'Fragile Base Class' problem), and how you might use Composition instead to make the system more flexible?"

Interviewer Feedback & Correct Answer

While interfaces solve the "multiple inheritance" problem, the Composition vs. Inheritance debate usually focuses on how we reuse code.

  • The Inheritance Trap: If you use EBook extends Book, and later you want to add a RareBook or a DigitalAudioBook, your inheritance tree can become a "Deep Hierarchy." If you change a method in the base Book class, it might accidentally break logic in EBook or PhysicalBook—this is the Fragile Base Class problem.

  • The Composition Solution: Instead of saying an EBook is a Book, you could say a LibraryItem has a Format (Electronic, Physical) and has a Content (The Book details). This allows you to swap behaviors at runtime without changing the class structure.


Question 3: The "Global Shipping" Scenario (Polymorphism)

"You are working for a shipping company like FedEx. You have a method calculateShippingCost(Package pkg).

  1. How would you use Method Overriding (Runtime Polymorphism) to handle different shipping rules for InternationalPackage and DomesticPackage?

  2. Now, suppose you also need to calculate costs differently based on the input provided: one version of the method takes just weight, and another takes weight, dimensions, and priority. How does Method Overloading (Compile-time Polymorphism) help you here, and why is it useful for the developer using your API?"

Interviewer Feedback & Correct Answer

Method Overriding (Runtime):
You nailed the core concept. By calling calculateShippingCost() on a Shipping reference that points to either an InternationalPackage or DomesticPackage instance, the JVM decides which method to run at runtime based on the actual object type.

Method Overloading (Compile-time): You mentioned the input parameters, which is the key. Overloading allows the same method name to exist with different signatures (e.g., calculate(weight) vs calculate(weight, dimensions)). This is determined at compile-time.

Benefit: It makes the API "cleaner." The developer doesn't have to remember names like calculateByWeight() and calculateByWeightAndDim(); they just call calculate() and the compiler picks the right one.

Question 4: The "Final Security" Scenario (The final Keyword)

"In a high-security banking application, you have a class called InterestCalculator.

  1. Why might you mark the calculateBaseRate() method as final? What specific risk are you trying to prevent?

  2. If you decide to make the entire InterestCalculator class final, how does that change the way other developers can interact with your code, and when is this a better choice than just marking methods as final?"Final Method: By marking the method final, you ensure the integrity of the calculation. No matter how many subclasses you create for different regions (e.g., USInterestCalculator), the core "Base Rate" logic remains immutable.

Interviewer Feedback & Correct Answer

Final Class:
Marking the entire class final prevents Inheritance altogether.

Why use it? This is often done for "Utility" classes (like java.lang.Math) or "Immutable" classes (like java.lang.String).

The Benefit: It ensures that no one can ever create a "fake" version of your calculator. If your class is final, you can be 100% sure that any InterestCalculator object in the system behaves exactly as you wrote it, with no hidden subclass behavior.

Question 5: The "Smart Home" Scenario (Interface vs. Abstract Class)

"You are designing a Smart Home Controller. You have various devices: SmartLight, SmartThermostat, and SmartSecurityCamera.

  1. All devices need to have a powerOn() and powerOff() method.

  2. However, some devices (like the Thermostat) need to keep track of a currentTemperature state, whereas the Light doesn't care about temperature.

In this scenario, would you use an Abstract Class or an Interface to define the 'Device'? Explain your choice based on how you would handle the shared state (like a deviceID or status) versus shared behavior."

Interviewer Feedback & Correct Answer

The Interface Approach: You are correct that an interface like SmartDeviceActions is perfect for defining what the devices do (powerOn, powerOff).

The Missing Piece (Shared State): If every device needs a deviceID, manufacturerName, and connectionStatus, using only an interface would force you to declare those variables in every single class (SmartLight, SmartThermostat, etc.). This leads to code duplication.

  • The Hybrid Solution (Best Practice): In a real-world interview, the "pro" answer is often a mix:

    1. Interface: Defines the contract (Switchable).

    2. Abstract Class: Implements the interface and holds the common state (private fields like id and status).

    3. Concrete Classes: Extend the abstract class.

Key takeaway: Use an Abstract Class when you want to share code and state (fields). Use an Interface when you only want to share method signatures (behavior).

 

Question 6: The "Memory Leak" Scenario (Static vs. Instance)

"You are building a Logging Utility for a large application. You decide to create a class Logger.

  1. If you make the log(String message) method static, how does that change how other classes call it compared to making it an instance method?

  2. From a Memory Management perspective, if you have a static List<String> logHistory inside that class that stores every log message ever created, what is the risk as the application runs for several days? How does the JVM Garbage Collector treat static variables?"

Interviewer Feedback & Correct Answer

Static Access: Correct. Using Logger.log() is convenient because it doesn't require state, making it a perfect candidate for a utility method.
The Memory Risk (Static Analysis): You accurately identified the "Memory Leak" risk.

The GC Behavior: Since static variables are stored in the Metaspace (specifically within the Class object) and are reachable as long as the ClassLoader is active, the Garbage Collector will not reclaim the memory used by your logHistory list.

The Consequence: If the list grows indefinitely, you will eventually hit an OutOfMemoryError. In a real-world scenario, you would use a "Circular Buffer" or a file-based appender to prevent this.

Question 7: The "Order Processing" Scenario (Exception Handling & OOP)

"Now, let's talk about how OOP handles errors. You are designing an Order Placement System.

  1. If a user tries to buy an item that is out of stock, should you throw a Checked Exception (e.g., extends Exception) or an Unchecked Exception (e.g., extends RuntimeException)? Why?

  2. How does the 'Catch-or-Specify' requirement of Checked Exceptions influence the design of your service layer? Does it make the code more robust or just 'noisier'?"


Clarification on "Compile-time": Actually, all exceptions happen at runtime. The difference is that for Checked Exceptions, the compiler forces you to acknowledge them before the code will even run. For Unchecked (Runtime) Exceptions, the compiler lets you ignore them.

The "Out of Stock" Choice: * The Case for Unchecked: Many modern frameworks (like Spring) prefer RuntimeExceptions because they keep the code clean and avoid "Exception Plumbing" (passing throws declarations through 10 layers of code).

The Case for Checked: Traditionally, an "Out of Stock" scenario is a recoverable business condition. By making it a Checked Exception, you force the developer writing the UI to handle it (e.g., show a "Notify Me" button) rather than letting the whole application crash.

The "Noisiness": Checked exceptions make the code "noisier" because of the mandatory try-catch blocks, but they act as a form of API Documentation—telling the next developer, "Hey, you must handle this specific scenario."

Interviewer Feedback & Correct Answer
  • Constructor Overloading: Correct. It provides flexibility. One tip: to avoid duplicating code, you can use this(...) to have one constructor call another (Constructor Chaining). This ensures your validation logic stays in one place.

  • Private Constructors: You correctly identified the Singleton Pattern.

    • How to get the instance: Since the constructor is private, the class provides a public static method (usually named getInstance()). Inside that method, the class checks if an instance already exists; if not, it creates one and returns it.

    • Other use cases: Private constructors are also used in Utility Classes (like java.lang.Math) where you only have static methods and want to prevent anyone from ever creating an object of that class.


Interviewer Feedback & Correct Answer
  • instanceof Syntax: In Java, the syntax is actually object instanceof ClassName. So, it would be if (result instanceof WebPage). Since Java 14, we have Pattern Matching for instanceof, which allows you to check and cast in one line: if (result instanceof WebPage wp) { wp.display(); }. This avoids the extra step of manual casting.

  • The Risk of Downcasting: You mentioned "inconsistent behavior," but specifically, the risk is a ClassCastException.

    • If you tell the JVM "Treat this Object as a VideoResult" but the object is actually a WebPage, the JVM will throw that exception at runtime and crash your program.

    • The Best Practice: Always guard your downcasts with an instanceof check or use Polymorphism (an interface) to avoid casting altogether.


Question 10: The "Final Challenge" (Composition & Encapsulation in a System)

"This is a common 'System Design Lite' question to wrap up OOP.

Imagine you are designing an Email Notification System. You have a User class and an EmailService class.

  1. Should the User class extend EmailService, or should the User class have a private field of type EmailService? Why?

  2. If the EmailService needs to change its provider from 'SendGrid' to 'AWS SES', which of the two designs (Inheritance vs. Composition) makes it easier to update the code without touching the User class?"

Interviewer Feedback & Correct Answer

  • Composition vs. Inheritance: You are 100% correct. If User extended EmailService, every User object would "be" a mailer, which makes no sense semantically. By making it a private field, you keep the User class focused on user data (Single Responsibility Principle).

  • The Provider Switch: Your suggestion of using an Interface is the "Senior Developer" answer.

    • If User depends on an EmailService interface, you can swap the implementation from SendGridProvider to AwsSesProvider at runtime or via configuration (Dependency Injection).

    • The User class doesn't even need to know the provider changed because it only interacts with the interface's send() method.

 


in Java, what are the ways to create an object?

Hi Folks,

After a long time I am back with the new post to discuss about the ways of creating a new object in java.

Basically there are multiple ways in which you can create an object instance in java and those are as below:

1. Using new keyword




2. Using class.newInstance()



3. Using class.getConstructors()


4. Using clone()



5. Using Object de-serialization
Make sure the employee class implements Serializable interface

So these are some of the ways in which we create objects in java. Let me know what did you felt about this blog in comments section.

In java how does HasSet enures unique values?

Let us discuss on how the HashSet in java prevents adding the duplicate values. First let us understand how to create a HashSet and add some values to it.

public class HashSetTest{
    
    public static void main(String[] args)
    {
        HashSet<String> hashset = new HashSet>();
        hashset.add("Bangalore");
        hashset.add("Mysore");
        hashset.add("Hubli");
        System.out.println("Set is "+hashset);
    }
} 


Output would be : Hubli, Bangalore,Mysore

What about the insertion order in the above output? Does the insertion order not maintained? Yes in a HashSet the insertion order is not maintained also the values in a HashSet are not sorted.

Now to the above code let us try to add some duplicates as below:

public class HashSetTest{
    
    public static void main(String[] args)
    {
        HashSet<Object> hashset = new HashSet<Object>();
        hashset.add("Bangalore");
        hashset.add("Hubli");
        hashset.add("Mysore");
        hashset.add("Hubli");          // duplicate elements
        hashset.add("Bangalore");      // duplicate elements
        System.out.println("Set is "+hashset);
    }
}

Now the output would be: Bangalore, Mysore, Hubli
Did you notice add() method of HashSet ignored the duplicates? Now the question is how?
When you pass duplicate elements in the  add() method of the Set object, It will return false and do not add to the HashSet, as the element is already present.

Let us go into further deep:


public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable

{
    private transient HashMap<E,Object> map;
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();
    
    
    public HashSet() {
        map = new HashMap<>();
    }
    
    // SOME CODE ,i.e Other methods in Hash Set
      
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }  
    
    // SOME CODE ,i.e Other methods in Hash Set
}

So , we are achieving uniqueness in Set internally in java through HashMap . Whenever you create an object of HashSet it will create an object of HashMap as you can see in the italic lines in the above code .

Learning OpenJPA step by step


 Hi Folks,

Java persistence framework is high on demand now days. If you mention JPA in your resume, it will catch hold of the interviewer and can influence in fetching you the job. (Ha ha I am not joking here! though some of you might be thinking :)-)

Ok lets come back to our topic JPA i.e. Java Persistence API.The Java Persistence API provides an object/relational mapping for managing relational data in enterprise beans, web components, and application clients. It can also be used in Java SE applications, outside of the Java EE environment.

Now we will try to understand practically how this will work.

1> Download and install latest eclipse IDE. In my case I have used Eclipse Indigo.
2> Download the latest apache tomcat. I have tomcat7.0
3> Once you have downloaded the tomcat extract it and keep it in a folder.
4> Now in eclipse IDE, select File > New > other and pick Server from the list.  

Click Next and select Tomcat v6.0 Server for the server definition. You'll need to
select a run time.

 Click on Add link and you will be prompted for the next window to add server runtime configurations.
Click on Browse button to add the location of tomcat directory where you have extracted the tomcat. Then click finish. Upon clicking finish it will take back you to previous window. In that also you click on Finish button.
Now you are done with server configurations. Now let’s start building a dynamic web project to learn JPA.
5> Click on File->New->Dynamic Web Project
Name your project and click on Next button.
No need to do anything, just click Next button.
Check generate web.xml checkbox and click on Finish.
Now you are done with creating dynamic web application! Congratulations! Now let’s add the required library files to the build path. Below are the required jar files.
ü       persistence-api-1.0.2.jar
ü       openjpa-all-2.2.0.jar
ü      mysql-connector-java-5.1.21-bin.jar (Off course I am using MySQL as my DB!)

To add these libraries to the build path of your project (off course you should download them before from the links provided and add them into you WEB-INF/lib location.) just right click on your project->Properties->Java Build Path.
Then click on add Add JARs button and then click on your project->Web Content->WEB-INF->lib then select the jars and click OK button.
Next go to Order and Export tab click on Select All button and then click on OK button.
6> Now let’s create our first entity. Note that we have used Java Annotations in this class.
Right click on the project->New->Class
Give the package name as com and class name as User and click on Finish button.

Now the contents of the class User is as below.

package com;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

/**
@Author              : Sanjeev Kulkarni
@Created on          : 05-Oct-201212:25:13 PM
@Project             : a
@Package             :
@File                : User.java
@Comments            :

Revision History     :
Sl No. | Revision Date      | Changed By               | Reasons           
------------------------------------------------------------------------------------

 **/
@Entity(name="User")
public class User implements Serializable{
      
       private static final long serialVersionUID = 975983410088693889L;
      
       public User(){
             
       }

       @Column(name="id")
        @GeneratedValue(strategy=GenerationType.AUTO)

       private int id;
      
       @Column(name="name")
       private String name;

       public int getId() {
              return id;
       }

       public void setId(int id) {
              this.id = id;
       }

       public String getName() {
              return name;
       }
      

       public void setName(String name) {
              this.name = name;
       }
}


Now lets create a JSP page to print list of users from the database using openjpa.

Right click on project->New->Other->Web->JSP File and then click on Next button. Give the name of the file as NewFile.jsp and click Finish button.

Now copy and paste the content of NewFile.jsp as below.


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<%@page import="javax.persistence.EntityManager"%>
<%@page import="javax.persistence.EntityManagerFactory"%>
<%@ page import="com.User" %>
<%@page import="javax.persistence.Persistence"%>
<%@page import= "javax.persistence.Query"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>::</title>
</head>
<body>

<%
 final EntityManagerFactory emf;
 final EntityManager em;
 final String PERSISTENCE_UNIT_NAME = "projectjpa";

try{
 emf = Persistence.createEntityManagerFactory("projectjpa");
 em = emf.createEntityManager();

 em.getTransaction().begin();

 User user = new User();
 Query query = em.createQuery("select x from User x ");

 out.println("Query returned: " + query.getResultList().size());
 em.getTransaction().commit();
 em.close();
 emf.close();
}
catch(Exception e){
       out.println(e);
       e.printStackTrace();
      
}

 %>
</body>
</html>


Modify the web.xml descriptor file. Mention NewFile.jsp as a welcome file.


xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>LearningOpneJPA</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>NewFile.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>


In the src folder create a folder called META-INF and inside that create a file called persistence.xml.
Copy and paste the below content into the persistence.xml file.



xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
       http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

       <persistence-unit name="projectjpa">
           <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
              <class>com.User</class>

              <properties>
                     <property name="openjpa.ConnectionURL" value="jdbc:mysql://localhost:3306/test"/>
                     <property name="openjpa.ConnectionDriverName" value="com.mysql.jdbc.Driver"/>
                     <property name="openjpa.ConnectionUserName" value="root"/>
                     <property name="openjpa.ConnectionPassword" value="root"/>
                     <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
                    
                      <property name="openjpa.DynamicEnhancementAgent" value="false"/>
                     <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/> 
              </properties>
       </persistence-unit>
</persistence>


7> Now open MySQL command prompt and create a database called test.
Mysql> create database test;
Mysql>use test;
Mysql>create table user (id int not null primary key, name varchar(200));
Mysql> insert into user vales(1,’ABC’);
Mysql> insert into user vales(2,’XYZ’);
8> Now right click on the project->Run As->Run on Server
9> You should be able to open the eclipse internal web browser and should be showed the result as below:
Query returned: 2