What We Are Learn:
ToggleAnswer (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:
- Node (or Entry) Each key–value pair is stored as a Node object. A Node contains:
hash– hash value of the keykey– actual keyvalue– associated valuenext– reference to the next Node (used in collision handling)
- 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
nis the array size.
This index decides which bucket the entry will go into.
- 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.
- 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.
- Null Handling
- HashMap allows one null key (stored at index 0).
- Multiple null values are allowed.
- 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();
}
}
}
}