Unit6 - Subjective Questions
CSE310 • Practice Questions with Detailed Answers
What are Generics in Java? Explain how to create a collection using generics with a code example.
Generics in Java allow types (classes and interfaces) to be parameters when defining classes, interfaces, and methods. It provides stronger type checks at compile time and eliminates the need for explicit type casting.
Benefits:
- Type Safety: It ensures that you only insert the specific type of objects into a collection.
- Elimination of Casting: No need to cast the object while retrieving it from the collection.
Creating a Generic Collection:
To create a collection using generics, specify the type of object inside angle brackets < >.
java
import java.util.ArrayList;
public class GenericExample {
public static void main(String[] args) {
// Creating a generic ArrayList that only accepts Strings
ArrayList<String> list = new ArrayList<String>();
list.add("Java");
list.add("Generics");
// list.add(10); // This would cause a compile-time error
for(String s : list) {
System.out.println(s);
}
}
}
Explain the implementation of the ArrayList class. Discuss its performance in terms of access and manipulation time complexity.
ArrayList Implementation:
ArrayList is a resizable-array implementation of the List interface. Internally, it uses a dynamic array to store the elements. It allows duplicate elements and ensures the insertion order.
Key Characteristics:
- Dynamic Resizing: When the array becomes full, a new array (usually 50% larger) is created, and elements are copied over.
- Not Synchronized: It is not thread-safe by default.
Performance (Time Complexity):
- Access (get): Random access is very fast because it works on an index basis. The time complexity is .
- Insertion (add):
- Adding at the end is amortized .
- Adding at a specific index is because elements must be shifted.
- Deletion (remove): Deleting an element is because subsequent elements must be shifted left to fill the gap.
Therefore, ArrayList is best suited for scenarios where read operations outnumber write operations.
Differentiate between the Comparable and Comparator interfaces in Java with respect to the TreeSet implementation.
Both interfaces are used to sort collection objects, which is essential for a TreeSet as it stores elements in sorted order.
| Feature | Comparable | Comparator |
|---|---|---|
| Package | java.lang |
java.util |
| Sorting Logic | Defines the natural ordering of objects. | Defines custom ordering logic distinct from the natural order. |
| Method | public int compareTo(T o) |
public int compare(T o1, T o2) |
| Implementation | The class itself implements the interface (modifies the class). | A separate class implements this interface (does not modify the original class). |
| Usage in TreeSet | Used if the constructor is new TreeSet() (elements must implement Comparable). |
Used if the constructor is new TreeSet(Comparator c). |
| Flexibility | Single sorting sequence. | Multiple sorting sequences can be created (e.g., sort by ID, then sort by Name). |
Write a Java program to implement a TreeSet that stores Student objects (id, name) and sorts them by name using the Comparator interface.
java
import java.util.*;
class Student {
int id;
String name;
public Student(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return id + ": " + name;
}
}
// Custom Comparator to sort by Name
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student s1, Student s2) {
return s1.name.compareTo(s2.name);
}
}
public class TreeSetExample {
public static void main(String[] args) {
// Pass the Comparator instance to the TreeSet constructor
TreeSet<Student> set = new TreeSet<>(new NameComparator());
set.add(new Student(101, "Alice"));
set.add(new Student(103, "Charlie"));
set.add(new Student(102, "Bob"));
System.out.println("Students sorted by Name:");
for (Student s : set) {
System.out.println(s);
}
}
}
Output:
Students sorted by Name:
101: Alice
102: Bob
103: Charlie
Explain the internal working of a HashMap in Java. How are collisions handled?
Internal Working of HashMap:
HashMap works on the principle of hashing. It uses an internal array of nodes (buckets), where each node is an entry containing: Key, Value, Hash, and Next pointer.
-
put(K, V):
- It calculates the hash of the Key using the
hashCode()method. - It calculates the index using
index = hash & (n-1). - It places the object in that bucket.
- It calculates the hash of the Key using the
-
get(K):
- It calculates the hash of the Key.
- It goes to the specific index and compares keys using
equals()to retrieve the value.
Handling Collisions:
A collision occurs when two different keys generate the same hash code/index.
- Chaining (Before Java 8):
HashMapuses a LinkedList to store multiple entries in the same bucket. The new entry is appended to the list. - Balanced Trees (Java 8+): If the number of items in a bucket exceeds a threshold (TREEIFY_THRESHOLD = 8), the LinkedList is converted into a Red-Black Tree. This improves the worst-case search time from to .
What is a Deque? Explain the implementation of ArrayDeque with its advantages over LinkedList.
Deque (Double Ended Queue):
A Deque is a linear collection that supports element insertion and removal at both ends. It can function as both a Queue (FIFO) and a Stack (LIFO).
ArrayDeque Implementation:
ArrayDeque is a resizable-array implementation of the Deque interface. It has no capacity restrictions and grows as necessary to support usage.
Advantages over LinkedList:
- Memory Efficiency:
LinkedListrequires extra memory for node objects and pointers (prev/next addresses) for every element.ArrayDequeuses a simple object array, resulting in lower memory overhead. - Performance:
ArrayDequeis generally faster thanLinkedListfor queue and stack operations because it benefits from better cache locality (elements are stored contiguously in memory). - No Nulls:
ArrayDequedoes not permitnullelements, whereasLinkedListdoes.
Usage:
java
Deque<String> stack = new ArrayDeque<>();
stack.push("A");
stack.pop();
Explain the JDBC Architecture with the help of a diagrammatic representation description.
JDBC (Java Database Connectivity) provides a standard API for Java applications to interact with various relational databases. The architecture consists of two main layers:
-
JDBC API (Application Layer):
- Used by the Java application to communicate with the JDBC Manager.
- Includes interfaces like
Connection,Statement,ResultSet, andDriver. - Package:
java.sqlandjavax.sql.
-
JDBC Driver Manager:
- Acts as a bridge between the user application and the database drivers.
- It manages a list of database drivers and establishes a connection using the appropriate driver.
-
JDBC Driver API (Driver Layer):
- Implemented by third-party database vendors (e.g., Oracle, MySQL).
- It handles the communication with the specific database server.
Flow:
Java App JDBC API DriverManager JDBC Driver Database.
This architecture ensures that the Java application remains independent of the specific database being used.
List and explain the four types of JDBC Drivers.
There are four types of JDBC drivers defined by Oracle:
-
Type 1: JDBC-ODBC Bridge Driver:
- Translates JDBC calls into ODBC calls. Relies on the client machine having an ODBC driver installed.
- Disadvantage: Platform dependent and slow.
-
Type 2: Native-API Driver (Partially Java):
- Converts JDBC calls into client-side API calls of the database (e.g., Oracle OCI). Requires native binary code on the client.
- Disadvantage: Installation of client libraries required on every machine.
-
Type 3: Network Protocol Driver (Middleware):
- Pure Java driver that converts JDBC calls into a middleware protocol. The middleware server then translates this to the DBMS protocol.
- Advantage: No client-side installation needed; flexible.
-
Type 4: Thin Driver (Pure Java):
- Converts JDBC calls directly into the vendor-specific database protocol.
- It is implemented entirely in Java.
- Advantage: Highest performance, platform-independent, and no client-side software required. It is the most commonly used driver today.
Why is the Type-4 JDBC driver considered the most efficient for web applications?
Type-4 (Thin Driver) Efficiency:
- Pure Java: It is written entirely in Java, making it platform-independent. The driver can be downloaded dynamically (e.g., via Maven or JAR inclusion).
- Direct Communication: It communicates directly with the database server using the database's native protocol (via sockets). It does not require any intermediate layers like ODBC or middleware servers, reducing latency.
- No Client Installation: Unlike Type 1 and Type 2 drivers, it does not require native libraries or client-side software (like Oracle Client) to be installed on the machine running the application.
- Performance: Because there is no translation to ODBC or intermediate formats, the conversion overhead is minimal, resulting in better performance for typical web applications.
Outline the standard steps required to connect a Java application to a Database using JDBC.
The standard steps to perform database operations in Java are:
- Import Packages: Import
java.sql.*. - Load and Register the Driver: Use
Class.forName()to load the driver class.- Example:
Class.forName("com.mysql.cj.jdbc.Driver");
- Example:
- Establish Connection: Use
DriverManager.getConnection()with the URL, username, and password.- Example:
Connection con = DriverManager.getConnection(url, user, pass);
- Example:
- Create Statement: Create a
StatementorPreparedStatementobject from the connection.- Example:
Statement stmt = con.createStatement();
- Example:
- Execute Query: Execute the SQL query using methods like
executeQuery()(for SELECT) orexecuteUpdate()(for INSERT/UPDATE/DELETE). - Process Results: If fetching data, iterate through the
ResultSet. - Close Connection: Explicitly close the
ResultSet,Statement, andConnectionto release resources.
Distinguish between Statement and PreparedStatement in JDBC. Which one protects against SQL Injection?
Differences:
-
Compilation:
- Statement: The SQL query is compiled by the database every time it is executed. Useful for static queries.
- PreparedStatement: The SQL query is pre-compiled by the database. Only the parameters change. It is faster for queries executed multiple times.
-
Parameters:
- Statement: Does not support input parameters at runtime; values must be concatenated into the string.
- PreparedStatement: Supports positional parameters defined by
?placeholders.
-
Security (SQL Injection):
- Statement: Vulnerable to SQL Injection because user input is concatenated directly into the query string.
- PreparedStatement: Protects against SQL Injection. It treats user input as data, not as executable code, by escaping special characters automatically.
Write a JDBC code snippet to perform a CRUD Insert operation using PreparedStatement.
java
import java.sql.*;
public class InsertExample {
public static void main(String[] args) {
String url = "jdbc:mysql://localhost:3306/school";
String user = "root";
String pass = "password";
String sql = "INSERT INTO students (name, age, grade) VALUES (?, ?, ?)";
try (Connection con = DriverManager.getConnection(url, user, pass);
PreparedStatement pstmt = con.prepareStatement(sql)) {
// Setting values for the placeholders
pstmt.setString(1, "John Doe");
pstmt.setInt(2, 20);
pstmt.setString(3, "A");
// Executing the update
int rowsAffected = pstmt.executeUpdate();
if (rowsAffected > 0) {
System.out.println("A new student was inserted successfully!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Explain the ResultSet interface. What are the differences between executeQuery, executeUpdate, and execute methods?
ResultSet:
The ResultSet interface represents the result set of a database query. It acts as an iterator to allow the program to move through the data rows generated by the query.
Comparison of Execute Methods:
-
executeQuery(String sql):- Usage: Used for SELECT statements.
- Returns: A
ResultSetobject containing the data retrieved.
-
executeUpdate(String sql):- Usage: Used for INSERT, UPDATE, DELETE, or DDL statements (like CREATE TABLE).
- Returns: An
intvalue representing the number of rows affected (or 0 for DDL statements).
-
execute(String sql):- Usage: Used when the type of SQL statement is unknown (can be anything).
- Returns: A
boolean. Returnstrueif the first result is aResultSet, andfalseif it is an update count. - You must subsequently call
getResultSet()orgetUpdateCount()to retrieve the actual result.
Write a Java program to retrieve and display data (Select operation) from a database table named Employees.
java
import java.sql.*;
public class SelectExample {
public static void main(String[] args) {
// Database credentials
String url = "jdbc:mysql://localhost:3306/company";
String user = "admin";
String pass = "1234";
String query = "SELECT id, name, salary FROM Employees";
try (Connection con = DriverManager.getConnection(url, user, pass);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
System.out.println("ID\tName\t\tSalary");
System.out.println("---------------------------------");
// Iterating through the ResultSet
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
double salary = rs.getDouble("salary");
System.out.println(id + "\t" + name + "\t" + salary);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
What is meant by connecting to 'Non-conventional Databases'? Explain how Java connects to NoSQL databases like MongoDB.
Non-conventional Databases:
This refers to connecting Java applications to databases that do not follow the traditional Relational (SQL) model. These are typically NoSQL databases designed for high scalability, unstructured data, and distributed systems (e.g., MongoDB, Cassandra, Redis).
Connecting to NoSQL (MongoDB example):
Unlike JDBC which provides a unified API for SQL databases, NoSQL databases often require specific drivers provided by the vendor, as there is no single standard like SQL.
Process for MongoDB:
- Add Dependency: Include the MongoDB Java Driver JAR (or Maven dependency).
- Create Client: Use
MongoClientto establish a connection. - Access Database/Collection: Select the database and the collection (equivalent to a table).
- Create Document: Data is represented as
Documentobjects (JSON-like BSON format). - Insert/Find: Use methods like
insertOne()orfind().
Example Snippet:
java
MongoClient mongoClient = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = mongoClient.getDatabase("mydb");
MongoCollection<Document> collection = database.getCollection("test");
Differentiate between Array and ArrayList in Java.
| Feature | Array | ArrayList |
|---|---|---|
| Size | Fixed size. Once created, it cannot be changed. | Dynamic size. It grows and shrinks automatically. |
| Performance | Faster (direct memory access). | Slower (overhead of resizing and object wrappers). |
| Data Types | Can store primitives (int, char) and Objects. | Can only store Objects. Primitives are stored via Autoboxing. |
| Generics | Does not support Generics. | Supports Generics for type safety. |
| Methods | Uses length property. No built-in methods for add/remove. |
Uses size() method. Provides add(), remove(), contains(), etc. |
| Syntax | int[] arr = new int[5]; |
ArrayList<Integer> list = new ArrayList<>(); |
Explain the different ways to iterate over a HashMap.
Since HashMap is not a Collection (it implements the Map interface), it cannot be iterated directly. We must iterate over its views.
-
Iterating over Keys (
keySet()):- Returns a Set of keys. You can iterate this set and use
get(key)to retrieve values.
java
for (String key : map.keySet()) { ... }
- Returns a Set of keys. You can iterate this set and use
-
Iterating over Entries (
entrySet()):- Most Efficient. Returns a Set of
Map.Entryobjects. Gives access to both key and value simultaneously.
java
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
- Most Efficient. Returns a Set of
-
Iterating over Values (
values()):- Returns a Collection of values. Useful if keys are not needed.
java
for (String val : map.values()) { ... }
- Returns a Collection of values. Useful if keys are not needed.
-
Using
forEach(Java 8+):- Uses a BiConsumer functional interface.
java
map.forEach((k, v) -> System.out.println(k + ":" + v));
- Uses a BiConsumer functional interface.
Explain the concept of Transaction Management in JDBC with the commit and rollback methods.
Transaction Management:
A transaction is a group of operations that are treated as a single unit of work. They must satisfy ACID properties (Atomicity, Consistency, Isolation, Durability).
By default, JDBC is in Auto-Commit mode (every SQL statement is committed immediately).
Handling Transactions:
To manage transactions manually (e.g., to ensure money is deducted from Account A and added to Account B simultaneously):
-
Disable Auto-Commit:
con.setAutoCommit(false); -
Perform Operations: execute multiple SQL updates.
-
Commit: If all operations are successful, save changes permanently.
con.commit(); -
Rollback: If any exception occurs during the operations, revert all changes to the state before the transaction started.
con.rollback();
This ensures data integrity.
What is ListIterator? How is it different from Iterator?
ListIterator:
ListIterator is an interface in the Java Collection framework that extends Iterator. It is used to traverse elements in a List implementation (like ArrayList, LinkedList).
Differences:
| Feature | Iterator | ListIterator |
|---|---|---|
| Direction | Forward only (next()). |
Bi-directional (next() and previous()). |
| Applicability | Can be used with List, Set, and Queue. | Can only be used with List implementations. |
| Modification | Can only remove elements (remove()). |
Can remove, set (update), and add elements during iteration. |
| Index Access | Cannot obtain current index. | Can get current index using nextIndex() or previousIndex(). |
What are the core interfaces of the Java Collections Framework? Briefly describe the hierarchy.
The core of the framework is based on the Iterable interface.
Hierarchy Overview:
-
Collection Interface (extends
Iterable): The root interface for most collections.- List: Ordered collection, allows duplicates. (Impl:
ArrayList,LinkedList,Vector). - Set: Unordered collection, no duplicates. (Impl:
HashSet,LinkedHashSet).- SortedSet: Sorted version of Set. (Impl:
TreeSet).
- SortedSet: Sorted version of Set. (Impl:
- Queue: Holds elements for processing (FIFO). (Impl:
PriorityQueue).- Deque: Double-ended queue. (Impl:
ArrayDeque).
- Deque: Double-ended queue. (Impl:
- List: Ordered collection, allows duplicates. (Impl:
-
Map Interface: (Note: Does not extend Collection). Stores Key-Value pairs.
- Impl:
HashMap,LinkedHashMap. - SortedMap: Keys are sorted. (Impl:
TreeMap).
- Impl:
The separation allows different data structures (Trees, Hash Tables, Arrays) to be manipulated through a standard set of methods.