Essential Java Interview Questions
Essential Java Interview Questions
The Runnable interface in Java defines a single void run() method, which does not return any value and cannot throw checked exceptions, making it suitable for tasks where no result is needed or exceptions are internally managed. Callable, on the other hand, is a generic interface that defines a call() method returning a value of type V and can throw exceptions. This makes Callable better suited for concurrent tasks requiring results or exception handling, as it works well with futures and executor services .
Java 8 Streams provide a high-level abstraction for processing sequences of elements, allowing for more readable and efficient code execution through functional programming techniques. Some key operations include map, filter, reduce, and collect, which allow transformation, filtering, aggregation, and collection of elements. Streams can be processed in parallel, enhancing performance on multi-core systems by efficiently utilizing available processors without the complexity inherent in manual thread handling .
The @Transactional annotation in Spring indicates the demarcation of transaction boundaries for method execution. It provides declarative transaction management, allowing methods to execute within a transactional context without manual programming of transactional code. This enables automatic handling of transaction propagation, isolation, and rollback rules, thereby simplifying database transaction management and ensuring data integrity. The annotation supports attribute customization to fine-tune transaction behavior according to business requirements .
ArrayList is preferred when you need fast random access to elements, as it is backed by an array, providing O(1) time complexity for get operations. It is efficient for iterating over elements but less so for adding/removing elements from the middle, due to potential resizing and copying of the array. Conversely, LinkedList is more suited for scenarios where you perform numerous insertions or deletions from the middle of the list, as it provides constant-time additions/deletions but slower index-based access due to its node-based structure .
HashMap is not thread-safe because it does not employ synchronization for its methods, allowing potential data corruption when accessed concurrently by multiple threads. This is particularly dangerous during resizing or rehashing operations. To address thread safety, you can use Collections.synchronizedMap() to wrap the Map, or use ConcurrentHashMap, which offers a more concurrent-friendly solution by dividing the map into segments and synchronizing only the specific segment undergoing modifications .
INNER JOIN in SQL returns only the rows that have matching values in both tables involved in the join, effectively filtering out rows without matches from either side. It is used when you want results strictly from intersections or matches of the dataset. OUTER JOIN, which includes LEFT, RIGHT, and FULL OUTER JOIN, returns all rows from either or both tables, depending on the type, including non-matching rows, making it appropriate for scenarios needing a comprehensive dataset, with nulls in place of unmatched rows .
Java 8 introduced several key features such as Lambda Expressions, which allow concise representation of anonymous functions; the Stream API, enabling functional-style operations on collections; and the new Date and Time API that replaces the old java.util.Date. These features facilitate a more concise, functional, and expressive code style, thus improving productivity and readability in complex application development. The introduction of default methods in interfaces enhances backward compatibility by allowing methods to have implementations .
The '==' operator in Java is used for reference comparison, meaning it checks if two references point to the same object in memory. In contrast, the '.equals()' method is used for semantic or logical comparison, which means it checks if two objects are meaningfully equivalent, according to the contract defined by the class's implementation of '.equals()'. For example, two distinct String objects containing "hello" will return true for '.equals()' but false for '==' because they are not the same instance in memory .
Spring Framework provides several bean scopes: Singleton, Prototype, Request, Session, and Global-session (with addition of Custom scope). Singleton scope (default) means a single instance per Spring IoC container lifecycle; Prototype creates a new instance every time a bean is requested. Request scope produces a bean instance per HTTP request, Session creates a bean per HTTP session, and Global-session is similar to Session but for portlet-based applications. The choice of scope directly influences the bean's lifecycle and is critical depending on resource utilization and application design .
Dependency Injection (DI) in Spring is a design pattern that enables the construction and configuration of dependencies outside of a class, promoting a loose coupling and enhancing testability by allowing components to be swapped. DI helps manage dependency lifecycles, simplifies complexity, reduces boilerplate code, and improves maintainability and scalability of applications. It promotes design patterns like Inversion of Control, which enhances module decoupling and aligns with solid software engineering principles .