ST Java Questions & Answers

Answer (as an 8+ years QA Automation Engineer – Interview Style)

HashMap is one of the most commonly used data structures in Java, and understanding its internal architecture is important not just for developers, but also for QA engineers—especially when validating performance, memory issues, or concurrency problems.

At a high level, HashMap stores data in key–value pairs and internally uses an array of buckets. Each bucket can hold multiple entries. The core internal components are:

  1. Node (or Entry) Each key–value pair is stored as a Node object. A Node contains:
  • hash – hash value of the key
  • key – actual key
  • value – associated value
  • next – reference to the next Node (used in collision handling)
  1. Hashing Mechanism When we put a key into a HashMap:
  • The key’s hashCode() method is called.
  • HashMap applies an internal hashing function to spread bits uniformly.
  • The final hash is used to calculate the index = (n – 1) & hash, where n is the array size.

This index decides which bucket the entry will go into.

  1. Buckets and Collision Handling Initially, HashMap uses an array of size 16 (default).
    If two keys generate the same index, a collision occurs.
  • Before Java 8: collisions were handled using a Linked List.
  • From Java 8 onwards:
    • If a bucket has more than 8 entries, the linked list is converted into a Red-Black Tree, improving lookup time from O(n) to O(log n).

Real-time example:
In one API performance test, we noticed response degradation. Root cause analysis showed a poorly implemented hashCode() method, causing heavy collisions in HashMap and turning lookups into linear searches.

  1. Load Factor and Rehashing
  • Default load factor = 0.75
  • When (current size / capacity) > load factor, rehashing happens.
  • Capacity doubles, and all entries are redistributed.

QA relevance:
During load testing, rehashing can cause sudden latency spikes. We’ve validated such scenarios by profiling memory and GC behavior.

  1. Null Handling
  • HashMap allows one null key (stored at index 0).
  • Multiple null values are allowed.
  1. Time Complexity
  • Average case: O(1) for get/put
  • Worst case: O(n) (before Java 8), O(log n) (after Java 8)

From a QA perspective, understanding HashMap internals helps in:

  • Identifying performance bottlenecks
  • Validating thread-safety issues (HashMap is not synchronized)
  • Reviewing defect root causes related to memory leaks and latency

In real projects, this knowledge helps us ask the right questions during code reviews and performance testing, not just test functionality.

1. Encapsulation

Encapsulation means binding data and methods together and restricting direct access to data.

Real-time example:
In a Selenium framework, we encapsulate page elements inside Page Object Model (POM) classes.

public class LoginPage {
    private WebElement username;
    private WebElement password;

    public void login(String user, String pass) {
        username.sendKeys(user);
        password.sendKeys(pass);
    }
}

Here:

  • Test scripts cannot directly access elements
  • They interact only through methods

Benefit:
✅ Improves security
✅ Reduces script breakage when UI changes
✅ Enhances maintainability

As a QA, this helps us update locators in one place instead of fixing multiple scripts.

2. Inheritance

Inheritance allows one class to acquire properties and methods of another class.

Real-time example:
We usually create a BaseTest class:

public class BaseTest {
    protected WebDriver driver;
    public void setup() { }
}

All test classes extend it:

public class LoginTest extends BaseTest {
}

Benefit:
✅ Code reusability
✅ Centralized WebDriver, config, reporting logic
✅ Faster framework enhancements

In real projects, this avoids duplication across hundreds of test cases.

3. Abstraction

Abstraction focuses on what to do, not how to do.

Real-time example:
We use interfaces for cross-browser support.

public interface Browser {
    WebDriver launch();
}

Different implementations:

  • ChromeBrowser
  • FirefoxBrowser

Test cases don’t care how the browser launches—only that it launches.

Benefit:
✅ Loose coupling
✅ Easy browser/tool replacement
✅ Cleaner framework design

This is very useful when moving from local execution to Selenium Grid or cloud tools.

4. Polymorphism

Polymorphism means one method, multiple behaviors.

Real-time example:
Method overriding in Selenium:

WebDriver driver = new ChromeDriver();

The same driver.get() works for Chrome, Firefox, or Edge.

Benefit:
✅ Flexibility
✅ Runtime decision-making
✅ Cleaner test logic

In real automation, polymorphism helps us run the same test suite across multiple environments without changing test code.


Interview Summary

As a senior QA, I use:

  • Encapsulation → Stable page objects
  • Inheritance → Reusable base framework
  • Abstraction → Tool and browser independence
  • Polymorphism → Cross-browser execution

These concepts are critical for building enterprise‑level automation frameworks, not just for clearing interviews.

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class DBConnection {

    public static void main(String[] args) {

        Connection con = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            // 1. Load JDBC Driver
            Class.forName("com.mysql.cj.jdbc.Driver");

            // 2. Establish Connection
            con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/testdb",
                    "db_username",
                    "db_password");

            // 3. Create Statement
            stmt = con.createStatement();

            // 4. Execute Query
            rs = stmt.executeQuery(
                    "SELECT username, status FROM users WHERE status='ACTIVE'");

            // 5. Process Result
            while (rs.next()) {
                String userName = rs.getString("username");
                String status = rs.getString("status");
                System.out.println(userName + " : " + status);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6. Close Connections
            try {
                if (rs != null) rs.close();
                if (stmt != null) stmt.close();
                if (con != null) con.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }
}

Avatar for Softwaretestingo Editorial Board

I love open-source technologies and am very passionate about software development. I like to share my knowledge with others, especially on technology that's why I have given all the examples as simple as possible to understand for beginners. All the code posted on my blog is developed, compiled, and tested in my development environment. If you find any mistakes or bugs, Please drop an email to softwaretestingo.com@gmail.com, or You can join me on Linkedin.

Leave a Comment