1) Program to remove duplicates and how many times the duplicate value is repeating.
import java.util.HashMap;
import java.util.Map;
public class DuplicateRemover {
public static void main(String[] args) {
int[] numbers = {4, 5, 6, 4, 2, 4, 5, 7, 2, 2};
// Map to store each number and its count
Map<Integer, Integer> countMap = new HashMap<>();
// Count occurrences
for (int num : numbers) {
countMap.put(num, countMap.getOrDefault(num, 0) + 1);
}
System.out.println("Unique elements:");
for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
System.out.print(entry.getKey() + " ");
}
System.out.println("\n\nDuplicate elements and their counts:");
for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
if (entry.getValue() > 1) {
System.out.println(entry.getKey() + " is repeated " + (entry.getValue() - 1) + " times");
}
}
}
}
Output for the example array:
Unique elements:
4 5 6 2 7
Duplicate elements and their counts:
4 is repeated 2 times
5 is repeated 1 times
2 is repeated 2 times
2) Create more objects count how many number of instances created while the method executed?
To count how many instances of a class are created while a method is executed in Java, you can use a static counter in the class. Here's a simple example.
public class InstanceCounter {
// Static variable to count instances
private static int instanceCount = 0;
public InstanceCounter() {
instanceCount++;
}
// Getter for instance count
public static int getInstanceCount() {
return instanceCount;
}
// Reset counter if needed
public static void resetCounter() {
instanceCount = 0;
}
public static void createObjectsInMethod() {
resetCounter(); // Optional: Reset before counting
// Creating objects
InstanceCounter obj1 = new InstanceCounter();
InstanceCounter obj2 = new InstanceCounter();
InstanceCounter obj3 = new InstanceCounter();
System.out.println("Instances created in method: " + getInstanceCount());
}
public static void main(String[] args) {
createObjectsInMethod(); // Should print: 3
createObjectsInMethod(); // Should print: 3 again
}
}
Output : Instances created in method: 3
Instances created in method: 3
If you remove resetCounter(), the counter will keep increasing every time the method runs.
Let me know if you want to count instances per method in a multi threaded scenario or use AtomicInteger for thread-safety!
3)Write a spring boot program with Simple Rest controller and perform CRUD operation?
Here's a complete Spring Boot program with a simple REST controller to perform CRUD operations on a User entity. It uses:
Spring Web
Spring Data JPA
H2 in-memory database for simplicity.
Dependencies (in pom.xml for Maven)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
1. User.java - Entity
import jakarta.persistence.*;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// Constructors
public User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
// Getters & Setters
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
}
2. UserRepository.java
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
3. UserController.java - REST Controller
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserRepository userRepository;
// Create
@PostMapping
public User createUser(@RequestBody User user) {
return userRepository.save(user);
}
// Read All
@GetMapping
public List<User> getAllUsers() {
return userRepository.findAll();
}
// Read by ID
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
return userRepository.findById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
// Update
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User updatedUser) {
return userRepository.findById(id)
.map(user -> {
user.setName(updatedUser.getName());
user.setEmail(updatedUser.getEmail());
userRepository.save(user);
return ResponseEntity.ok(user);
})
.orElse(ResponseEntity.notFound().build());
}
// Delete
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
return userRepository.findById(id)
.map(user -> {
userRepository.delete(user);
return ResponseEntity.noContent().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
4. Application.java - Main Class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class CrudApplication {
public static void main(String[] args) {
SpringApplication.run(CrudApplication.class, args);
}
}
5. application.properties
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.jpa.show-sql=true
Example API Endpoints:
POST /api/users – create user
GET /api/users – list users
GET /api/users/{id} – get user by ID
PUT /api/users/{id} – update user
DELETE /api/users/{id} – delete user
4) Do you have any authentication mechanisms in your application Spring boot /microservice ?
Yes! In Spring Boot or Microservices applications, we commonly use authentication and authorization mechanisms to secure APIs. There are several options depending on your architecture and needs. Here's a quick breakdown of popular authentication mechanisms:
Common Authentication Mechanisms in Spring Boot:
1. Spring Security (with Username & Password)
Default login form
Basic in-memory authentication
Can be extended with JDBC or JPA
2. JWT (JSON Web Tokens)
Stateless authentication (perfect for microservices)
Secure APIs by passing JWT in the Authorization header
No session stored on server
3. OAuth2 / OpenID Connect
Used for social login (Google, Facebook, GitHub).
Can integrate with Keycloak, Okta, Auth0
Great for SSO (Single Sign-On)
4. API Key Authentication
Simple token/key passed in the request headers
Lightweight but less secure for large-scale apps
5. LDAP Authentication
Enterprise-level login using corporate directory services
๐Example: JWT Authentication in Spring Boot
Users log in with username/password
Server returns a signed JWT token
Client sends JWT in Authorization: Bearer <token> header
Server validates token for each request
Would you like a working JWT Authentication example with Spring Boot REST APIs?
It would include:
User registration and login
Generating and validating JWT
Securing endpoints with roles (e.g., USER, ADMIN)
6) About tokens ?
๐ What is a Token?
A token is a small piece of data (usually a string) that acts like a digital key to access protected resources or perform secure operations.
Types of Tokens in Spring Boot / Microservices
1. JWT (JSON Web Token) – Most Popular
Self-contained token (it holds user data & permissions inside itself)
Signed using a secret or private key (HMAC or RSA)
Stateless – No need to store session on server.
Example :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiJ1c2VyMSIsInJvbGUiOiJVU0VSIiwiaWF0IjoxNjEyMzQ1Njc4fQ
.rVKVkXbGx6Sp8EF8vViPKq9F0XZekjTWZrq0n2A5Aro
Structure:
Header: Algorithm & token type
Payload: User info, roles, expiry
Signature: Verifies token integrity
2. Opaque Tokens
Random strings (not self-contained).
Requires token lookup in a database or authorization server.
Used in OAuth2 with Authorization Server (e.g., Keycloak, Okta)
3. API Keys
Simple token (e.g., 12345-abcde)
Sent in header or query params
Less secure (no expiration, no encryption), but simple for internal APIs
๐ How Token Authentication Works (Typical Flow)
Login (POST /login)
User sends credentials
Server validates and returns a JWT
Access Protected APIs
Client sends Authorization: Bearer <JWT>
Server verifies the token and allows access if valid.
Token Expiration :-
JWTs usually expire (e.g., 15 mins, 1 hour)
You can implement refresh tokens to get new access tokens
๐ Advantages of Token-Based Auth
Stateless (no sessions on server)
Scalable (great for microservices & distributed systems)
Secure (if used correctly)
Easy to share between services (with appropriate scopes/claims)
7) Tell us about Grafana?
Grafana is an open-source analytics and monitoring platform. It allows you to:
Visualize time-series data (like metrics, logs, and traces)
Build beautiful and dynamic dashboards
Set up real-time alerting.
Connect to various data sources like Prometheus, InfluxDB, Loki, Elasticsearch, MySQL, and more
It’s commonly used for:
Infrastructure monitoring
Application monitoring
DevOps and SRE dashboards
Business analytics.
๐ Key Features of Grafana
1. Dashboards
Fully customizable panels: graphs, heatmaps, gauges, tables, etc.
Real-time refresh with flexible time ranges
Variables for dynamic dashboards
2. Data Sources
Grafana doesn’t store data—it connects to sources like:
Prometheus (metrics)
Loki (logs)
Elasticsearch (searchable logs)
Graphite, InfluxDB, MySQL, PostgreSQL, etc.
3. Alerts
Set conditions on metrics (e.g., CPU > 90%)
Alerts via Slack, email, Microsoft Teams, PagerDuty, etc.
4. User Management
Role-based access
Supports SSO, LDAP, OAuth
5. Plugins
Community and enterprise plugins for new panels, data sources, and apps.
๐ How Grafana Works (Simplified Flow)
You install and run Grafana (locally or in the cloud).
Connect it to a data source like Prometheus.
Build dashboards to visualize metrics (like CPU usage, request latency).
Set alerts to notify when something goes wrong.
Monitor in real time!
๐ง Example Use Case in Microservices
Let’s say you have a Spring Boot app with Prometheus metrics enabled:
Prometheus scrapes /actuator/prometheus
Grafana reads data from Prometheus.
You create a dashboard to visualize:
Number of requests
Error rate
Job execution time
You configure alerts if:
Error rate > 10%
Job failure count > 0
๐ Grafana Cloud vs Self-Hosted
Self-Hosted: You run it on your servers/VMs/Kubernetes
Grafana Cloud: Hosted by Grafana Labs with easy integrations
Want to see it in action?
I can help you:
Set up Grafana locally or in Docker
Connect it to Prometheus + Spring Boot
Build a dashboard to monitor app health & performance.
Add alerts for batch job failures or high latency.
8)employee object, doesn't want duplicate objects, How will you remove ?
If you want to avoid duplicate Employee objects in Java, the key is to:
Override equals() and hashCode() in your Employee class
Use a Set, like HashSet, which doesn’t allow duplicates
import java.util.Objects;
public class Employee {
private int id;
private String name;
// Constructor
public Employee(int id, String name) {
this.id = id;
this.name = name;
}
// Getters (optional setters)
public int getId() { return id; }
public String getName() { return name; }
// equals() and hashCode() for removing duplicates
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Employee)) return false;
Employee employee = (Employee) o;
return id == employee.id && Objects.equals(name, employee.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
// toString() for easy printing
@Override
public String toString() {
return "Employee{id=" + id + ", name='" + name + "'}";
}
}
import java.util.*;
public class EmployeeApp {
public static void main(String[] args) {
List<Employee> employeeList = new ArrayList<>();
employeeList.add(new Employee(1, "John"));
employeeList.add(new Employee(2, "Jane"));
employeeList.add(new Employee(1, "John")); // duplicate
employeeList.add(new Employee(3, "Alice"));
employeeList.add(new Employee(2, "Jane")); // duplicate
// Use Set to remove duplicates
Set<Employee> uniqueEmployees = new HashSet<>(employeeList);
System.out.println("Unique Employees:");
for (Employee e : uniqueEmployees) {
System.out.println(e);
}
}
}
Use Set (HashSet, LinkedHashSet, or TreeSet)
Implement equals() and hashCode() correctly
This works for removing duplicates from any collection of custom objects.
SQL > SELECT DISTINCT id, name
FROM employee;
WITH ranked_employees AS (
SELECT id, name,
ROW_NUMBER() OVER (PARTITION BY id, name ORDER BY id) as rn
FROM employee
)
DELETE FROM employee
WHERE (id, name) IN (
SELECT id, name
FROM ranked_employees
WHERE rn > 1
);
9) How will the threads work in SpringBoot ?
Spring Boot doesn’t create threads by default unless you explicitly configure or use something that internally spawns threads (like @Async, scheduled tasks, or web requests). Let's cover the most common ways threads work in a Spring Boot application:
Web Requests (Servlet Threads)
When a request hits your Spring Boot REST controller, the web server (like Tomcat) creates a thread to handle it.
These threads are managed by a thread pool.
Default max threads in embedded Tomcat is usually 200.
You can configure this in application.properties:
server.tomcat.threads.max=300
server.tomcat.threads.min-spare=10
2. @Async – Asynchronous Execution
You can run methods in separate threads using @Async:
@SpringBootApplication
@EnableAsync
public class MyApp { ... }
import org.springframework.scheduling.annotation.Async;
@Service
public class NotificationService {
@Async
public void sendEmail(String email) {
// This runs in a separate thread
System.out.println("Sending email to " + email);
}
}
3. Scheduled Tasks (@Scheduled)
You can schedule jobs to run in background threads:
@Component
public class ReportScheduler {
@Scheduled(fixedRate = 5000) // Every 5 seconds
public void generateReport() {
System.out.println("Report generated on thread: " + Thread.currentThread().getName());
}
}
you need to enable with :
@EnableScheduling
4. Custom ThreadPoolTaskExecutor
If you want control over your thread pool (core size, max size, queue, etc.), you can define your own:
@Configuration
@EnableAsync
public class AsyncConfig {
@Bean(name = "customExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(50);
executor.setThreadNamePrefix("MyAppThread-");
executor.initialize();
return executor;
}
}
And use it like:
@Async("customExecutor")
public void doBackgroundTask() {
// runs in your custom thread
}
5. Multithreading in Spring Batch
If you're using Spring Batch (like job processing), you can configure it to:
Process steps in parallel
Partition data and run each partition in a separate thread.
Feature Threading? Controlled By
Web Requests Yes (Tomcat) Tomcat thread pool
@Async Yes Spring's Executor
@Scheduled Yes TaskScheduler
Spring Batch Yes (if enabled) ThreadPoolTaskExecutor.
10) Create class, Create string, remove the duplicates and print remaining words in java?
Here's a simple Java class that:
Takes a string
Splits it into words
Removes duplicate words
Prints the remaining unique words.
import java.util.*;
public class RemoveDuplicateWords {
public static void main(String[] args) {
String input = "java spring boot java microservices spring boot";
// Split the string into words
String[] words = input.split("\\s+");
// Use LinkedHashSet to maintain insertion order and remove duplicates
Set<String> uniqueWords = new LinkedHashSet<>(Arrays.asList(words));
// Print the remaining words
System.out.println("Unique words:");
for (String word : uniqueWords) {
System.out.println(word);
}
}
}
Output : Unique words:
java
spring
boot
microservices
HashSet removes duplicates but doesn’t maintain order. LinkedHashSet removes duplicates and keeps the original order.
11) Write program, n number objects, instantiate the class, the file name should be printed in the console?
Instantiates a class N number of times.
Tracks the number of objects created.
Prints the name of the .java file to the console.
public class MyClass {
private static int instanceCount = 0;
public MyClass() {
instanceCount++;
System.out.println("Object " + instanceCount + " created.");
}
public static void main(String[] args) {
int n = 5; // Number of objects to create
for (int i = 0; i < n; i++) {
new MyClass();
}
// Print the file name
System.out.println("Class defined in: MyClass.java");
}
}
Sample OUTPUT : (for n = 5):
Object 1 created.
Object 2 created.
Object 3 created.
Object 4 created.
Object 5 created.
Class defined in: MyClass.java
12) Write a program to design a string which first,last,second, second last character and so on ?
input : ABCEDF
output: AFBDCE
Sure! You want to write a Java program that reorders characters in a string such that it takes:
First character
Last character
Second character
Second-last character
and so on...
public class ZigZagString {
public static void main(String[] args) {
String input = "ABCEDF";
String result = rearrangeString(input);
System.out.println("Output: " + result);
}
public static String rearrangeString(String input) {
StringBuilder output = new StringBuilder();
int i = 0;
int j = input.length() - 1;
while (i <= j) {
if (i == j) {
output.append(input.charAt(i)); // middle character (for odd length)
} else {
output.append(input.charAt(i)); // from start
output.append(input.charAt(j)); // from end
}
i++;
j--;
}
return output.toString();
}
}
15) Have you ever used try with resources ?
Yes, definitely! try-with-resources is a super useful feature in Java that helps you automatically close resources like files, database connections, sockets, etc., after you're done using them — without writing an explicit finally block.
What is try-with-resources?
Introduced in Java 7, it ensures that any resource (that implements AutoCloseable) is automatically closed after the try block, even if an exception occurs.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
String filePath = "example.txt";
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The BufferedReader is declared inside the try() statement.
Once the block finishes (normally or due to an exception), reader.close() is automatically called.
No need for a finally block.
Resources That Work with try-with-resources
Any class that implements the AutoCloseable interface:
BufferedReader, BufferedWriter
FileInputStream, FileOutputStream
Scanner, PrintWriter
Connection, Statement, ResultSet (JDBC)
Custom classes that implement AutoCloseable.
class MyResource implements AutoCloseable {
public void doSomething() {
System.out.println("Doing something with MyResource...");
}
@Override
public void close() {
System.out.println("Closing MyResource...");
}
}
public class TryWithResourcesDemo {
public static void main(String[] args) {
try (MyResource res = new MyResource()) {
res.doSomething();
}
}
}
OUTPUT : Doing something with MyResource...
Closing MyResource..
16) If you want add duplicates in set, How will you add ?
In Java, a Set does not allow duplicates, as it only stores unique elements. However, if you want to allow duplicates or track the count of elements, you can use a Map or List.
Using Set Normal Behavior
import java.util.HashSet;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> set = new HashSet<>();
set.add(1);
set.add(2);
set.add(2); // Duplicate, will not be added
set.add(3);
System.out.println(set); // Output: [1, 2, 3]
}
}
2. Allowing Duplicates with List:
If you want to allow duplicates, use a List (like ArrayList), which can store duplicates:
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(2); // Duplicate, will be added
list.add(3);
System.out.println(list); // Output: [1, 2, 2, 3]
}
}
3. Allowing Duplicates Using Map (Counting Occurrences):
If you want to track the count of duplicates (i.e., how many times an element has been added), you can use a Map, like HashMap or LinkedHashMap, where the key is the element, and the value is the count of occurrences:
import java.util.HashMap;
import java.util.Map;
public class Main {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap<>();
map.put(1, map.getOrDefault(1, 0) + 1);
map.put(2, map.getOrDefault(2, 0) + 1);
map.put(2, map.getOrDefault(2, 0) + 1); // Increment count for duplicate
map.put(3, map.getOrDefault(3, 0) + 1);
System.out.println(map); // Output: {1=1, 2=2, 3=1}
}
}
In summary, a Set in Java doesn't allow duplicates, but you can use a List or a Map if you need to track duplicates or allow them.
17) Have you ever used Java Streams, Asked scenario based question ?
Yes, Java Streams are an incredibly powerful feature that can simplify many tasks, especially when dealing with collections. They allow you to process sequences of elements in a functional style, often leading to cleaner, more readable code.
If you're asking about scenario-based questions, there are many common use cases where Java Streams are applied. Here are a few examples of such scenarios:
1. Filtering and Transforming a List of Objects:
Imagine you have a list of employees and you need to filter those who are older than 30, and then transform their names to uppercase.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Employee> employees = Arrays.asList(
new Employee("Alice", 25),
new Employee("Bob", 35),
new Employee("Charlie", 40)
);
List<String> names = employees.stream()
.filter(emp -> emp.getAge() > 30) // Filter employees older than 30
.map(emp -> emp.getName().toUpperCase()) // Convert names to uppercase
.collect(Collectors.toList()); // Collect result in a list
System.out.println(names); // Output: [BOB, CHARLIE]
}
}
class Employee {
private String name;
private int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
2. Summing Values in a List:
If you have a list of integers and you want to find the sum of all the even numbers:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int sum = numbers.stream()
.filter(n -> n % 2 == 0) // Filter even numbers
.mapToInt(Integer::intValue) // Convert to int (because map() maps to Integer)
.sum(); // Sum up the values
System.out.println(sum); // Output: 30 (2 + 4 + 6 + 8 + 10)
}
}
3. Grouping Data Based on a Property:
If you have a list of products and want to group them by category:
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Product> products = Arrays.asList(
new Product("Laptop", "Electronics"),
new Product("Shirt", "Clothing"),
new Product("Smartphone", "Electronics"),
new Product("Jeans", "Clothing")
);
Map<String, List<Product>> groupedProducts = products.stream()
.collect(Collectors.groupingBy(Product::getCategory)); // Group by category
groupedProducts.forEach((category, productList) -> {
System.out.println(category + ": " + productList.size());
});
}
}
class Product {
private String name;
private String category;
public Product(String name, String category) {
this.name = name;
this.category = category;
}
public String getCategory() {
return category;
}
}
4. Finding the Maximum/Minimum Value:
You can use max() and min() to find the highest or lowest value in a collection.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6);
Optional<Integer> maxNumber = numbers.stream()
.max(Integer::compareTo); // Find max
maxNumber.ifPresent(System.out::println); // Output: 9
}
}
5. Flattening Nested Collections:
You can use flatMap to flatten nested collections (like lists of lists).
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<List<Integer>> nestedList = Arrays.asList(
Arrays.asList(1, 2, 3),
Arrays.asList(4, 5),
Arrays.asList(6, 7)
);
List<Integer> flatList = nestedList.stream()
.flatMap(Collection::stream) // Flatten the list of lists
.collect(Collectors.toList()); // Collect the result in a flat list
System.out.println(flatList); // Output: [1, 2, 3, 4, 5, 6, 7]
}
}
6. Reduce to a Single Value:
You can use reduce to combine elements into a single result, such as multiplying all numbers in a list.
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int product = numbers.stream()
.reduce(1, (a, b) -> a * b); // Multiply all values
System.out.println(product); // Output: 120 (1 * 2 * 3 * 4 * 5)
}
}
Common Java Stream-Related Scenario-Based Questions:
How would you filter out all strings from a list that are shorter than 5 characters?
How can you sort a list of employees by their salary in descending order?
What is the best way to compute the average age from a list of employees using Streams?
How would you implement parallel processing using Streams for large datasets?
Can you group products by their category and then count how many products are in each category?
How can you merge two lists into one, removing duplicates, using Java Streams?
18) If you have a list of department and in each department has list of employees, you have to collect all the employees whose age is <45 in SQL ?
Tables:
Department (id, name)
Employee (id, name, age, department_id)
You can write the SQL query as follows:
SQL> SELECT e.id, e.name, e.age, e.department_id FROM Employee e
JOIN Department d ON e.department_id = d.id WHERE e.age < 45;
Explanation:
SELECT e.id, e.name, e.age, e.department_id: Select the relevant columns for the employees you want.
FROM Employee e: Specify the Employee table as the main table.
JOIN Department d ON e.department_id = d.id: Join the Employee table with the Department table on the department_id field.
WHERE e.age < 45: Filter employees whose age is less than 45.
This query will return a list of employees whose age is less than 45, across all departments.
If You Also Want to Group by Department:
If you want to collect employees grouped by their department, and each department should only include employees under 45, you can write:
SQL > SELECT d.name AS department_name, e.id, e.name, e.age FROM Department d
JOIN Employee e ON e.department_id = d.id WHERE e.age < 45 ORDER BY d.name, e.age;
This will list all the employees under 45, grouped by their department and ordered by department name and employee age.
19) What the versioning you used in Hibernate ?
Versioning in Hibernate refers to the mechanism that allows Hibernate to manage and track changes made to entities in a database, particularly to ensure that concurrent updates to the same data can be safely handled. It helps in preventing lost updates and ensures data integrity in concurrent environments, where multiple users or processes might be updating the same records.
Hibernate Versioning Mechanism
In Hibernate, versioning is typically implemented using a version column or field in the entity class. This version field is used to track changes to an entity. When an entity is updated, Hibernate checks the value of the version field to determine whether the entity has been modified by another transaction since it was last fetched.
Here are the key aspects of versioning in Hibernate:
1. Optimistic Locking (Default versioning mechanism)
This is the most common form of versioning used in Hibernate. It assumes that multiple transactions can complete without interfering with each other. If a conflict is detected, an exception is thrown.
Version Field: A version field (usually an integer or timestamp) is added to your entity class. Hibernate automatically increments this version field whenever an entity is updated.
Concurrency Control: When Hibernate tries to update an entity, it will check if the version field of the entity in the database matches the version field of the entity being updated. If they do not match (indicating that another transaction has modified the entity), Hibernate will throw an exception (OptimisticLockException).
Example of Optimistic Locking in Hibernate:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
@Version // This annotation marks the version field for optimistic locking
private int version;
// Getters and setters
}
In this example:
@Version is used to mark the version field in the Employee class as the version control field.
Each time an update is performed on an Employee entity, the version value is automatically incremented by Hibernate.
If two transactions try to update the same Employee simultaneously, the second one will fail with an OptimisticLockException if it detects the version mismatch.
2. Pessimistic Locking (Alternative versioning mechanism)
In pessimistic locking, the database is locked when a transaction starts to ensure that no other transaction can access the same data until the transaction is completed.
This form of locking is more aggressive and can cause performance bottlenecks because it prevents other users from accessing the data while a transaction is in progress.
It is used in scenarios where data conflicts are more likely, and locking is necessary to ensure that updates are not overwritten.
In Hibernate, pessimistic locking can be done using the LockMode feature with methods like lock() in Session:
Session session = sessionFactory.openSession();
Employee employee = session.get(Employee.class, 1L, LockMode.PESSIMISTIC_WRITE);
In this case:
LockMode.PESSIMISTIC_WRITE will lock the row for updates and prevent other transactions from modifying it.
3. Versioning with Timestamp
Another form of versioning is based on timestamps rather than integers. The version field can be a Timestamp, and Hibernate will use the timestamp value to determine when the entity was last modified.
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private int age;
@Version
@Temporal(TemporalType.TIMESTAMP)
private Date lastUpdated;
// Getters and setters
}
In this case, lastUpdated will be a Timestamp, and Hibernate will update it every time the entity is modified.
4. Versioning Annotations and Methods
@Version: Marks a field as the version field for optimistic locking.
@Temporal(TemporalType.TIMESTAMP): Specifies that the version field is based on time.
LockMode: Used for controlling pessimistic locks.
Why Use Versioning?
Concurrency Control: Versioning helps manage concurrent updates to the same record, preventing data inconsistency.
Data Integrity: Ensures that updates made by multiple users or systems do not override each other or lead to inconsistent states.
Optimistic Locking: Allows for better scalability in many situations because it only checks for conflicts when committing the transaction, reducing the need for locks and improving performance.
Example of Optimistic Locking Handling in Code:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Employee emp = session.get(Employee.class, employeeId);
emp.setName("New Name");
try {
session.update(emp);
tx.commit();
} catch (OptimisticLockException e) {
tx.rollback();
System.out.println("Conflict detected, transaction rolled back.");
}
Hibernate Versioning Support
Hibernate 5.x: Improved support for versioning through annotations and integration with JPA.
Hibernate 6.x: Refines optimistic locking and versioning support, and also allows the use of @Version with custom version strategies like Long or Date.
In summary, versioning in Hibernate ensures safe concurrent data manipulation in multi-user environments. It uses fields annotated with @Version to track changes to entities and help manage concurrent access using optimistic or pessimistic locking strategies.
20) Can you please explain composite in hibernate?
In Hibernate, a composite refers to an entity's composite key or composite identifier, which is a primary key composed of multiple fields (or properties) rather than a single column. This is useful when you need a primary key that is made up of more than one column to uniquely identify an entity.
1. Composite Primary Key
A composite primary key in Hibernate is a primary key consisting of multiple attributes (fields). In such cases, you have two main approaches to define composite keys:
a) Using @IdClass (for composite key class)
You can create a separate class to represent the composite key and use it with the @IdClass annotation.
b) Using @EmbeddedId (for embeddable composite key)
You can create an embeddable class with the @Embeddable annotation and use it with @EmbeddedId in the entity.
Approach 1: Using @IdClass
This approach uses a separate class to represent the composite key. The fields of this class will correspond to the components of the composite key in the entity.
Steps to Use @IdClass:
Create a Composite Key Class: This class will implement Serializable and represent the composite key.
Use @IdClass in the Entity Class: You will use the @IdClass annotation on the entity class to specify the composite key class.
Example:
1. Composite Key Class (Id Class):
import java.io.Serializable;
public class EmployeeDepartmentId implements Serializable {
private Long employeeId;
private Long departmentId;
// Default constructor, getters, setters, equals() and hashCode() methods
public EmployeeDepartmentId() {}
public EmployeeDepartmentId(Long employeeId, Long departmentId) {
this.employeeId = employeeId;
this.departmentId = departmentId;
}
// Getters and Setters
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmployeeDepartmentId that = (EmployeeDepartmentId) o;
return employeeId.equals(that.employeeId) && departmentId.equals(that.departmentId);
}
@Override
public int hashCode() {
return 31 * employeeId.hashCode() + departmentId.hashCode();
}
}
2. Entity Class Using @IdClass:
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
@Entity
@IdClass(EmployeeDepartmentId.class) // Specify the composite key class
public class EmployeeDepartment {
@Id
private Long employeeId;
@Id
private Long departmentId;
private String role;
// Getters and setters
}
In this example:
EmployeeDepartmentId is the composite key class.
EmployeeDepartment uses the @IdClass annotation to specify that the primary key is a combination of employeeId and departmentId.
Notes:
The composite key class (EmployeeDepartmentId) must implement Serializable and override equals() and hashCode() methods to ensure correct behavior in collections and databases.
The @Id annotation is used to mark the fields that make up the composite key.
Approach 2: Using @EmbeddedId
The @EmbeddedId annotation is another way to handle composite keys in Hibernate. In this case, the composite key class is embedded inside the entity and is used directly without the need for a separate class.
Steps to Use @EmbeddedId:
Create an @Embeddable Class: The composite key is defined as an embeddable class using the @Embeddable annotation.
Use @EmbeddedId in the Entity Class: The composite key is embedded into the entity using @EmbeddedId.
Example:
1. Composite Key Class (Embeddable Class):
import java.io.Serializable;
import javax.persistence.Embeddable;
@Embeddable
public class EmployeeDepartmentId implements Serializable {
private Long employeeId;
private Long departmentId;
// Default constructor, getters, setters, equals() and hashCode() methods.
public EmployeeDepartmentId() {}
public EmployeeDepartmentId(Long employeeId, Long departmentId) {
this.employeeId = employeeId;
this.departmentId = departmentId;
}
// Getters and Setters
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
EmployeeDepartmentId that = (EmployeeDepartmentId) o;
return employeeId.equals(that.employeeId) && departmentId.equals(that.departmentId);
}
@Override
public int hashCode() {
return 31 * employeeId.hashCode() + departmentId.hashCode();
}
}
2. Entity Class Using @EmbeddedId:
import javax.persistence.Entity;
import javax.persistence.EmbeddedId;
@Entity
public class EmployeeDepartment {
@EmbeddedId // Embedding the composite key directly
private EmployeeDepartmentId id;
private String role;
// Getters and setters
}
In this example:
EmployeeDepartmentId is the composite key class, which is @Embeddable and used directly in the entity.
EmployeeDepartment uses the @EmbeddedId annotation to embed the composite key.
Comparison of @IdClass and @EmbeddedId
Feature @IdClass @EmbeddedId
Key Class A separate class to represent the composite key. The composite key is part of the entity itself.
Field Declaration Each key component is declared as @Id in the entity. The entire composite key is declared as @EmbeddedId.
Object Structure More flexible, as you can use any class as the key. Tightly coupled with the entity, as it's embedded directly.
Serialization Requires Serializable implementation for the key class. Requires Serializable for the embeddable key class.
Use Case Suitable for legacy systems or when using existing POJOs for the key. Ideal when the composite key is part of the entity's identity.
2. Composite Key with Relationships
In the case of composite keys, if there are relationships between entities (like One-to-Many or Many-to-One), you can still map the composite key with the @ManyToOne or @OneToMany annotations.
Example of a Many-to-One relationship with a composite key:
@Entity
public class EmployeeDepartment {
@EmbeddedId
private EmployeeDepartmentId id;
@ManyToOne
@JoinColumn(name = "employeeId", insertable = false, updatable = false)
private Employee employee;
@ManyToOne
@JoinColumn(name = "departmentId", insertable = false, updatable = false)
private Department department;
// Other fields and methods
}
In this example, EmployeeDepartment has a composite key (EmployeeDepartmentId), and both Employee and Department entities are related to it.
Summary:
Composite Primary Key: You can create a composite key in Hibernate using either @IdClass or @EmbeddedId.
@IdClass: Defines a separate key class to represent the composite key.
@EmbeddedId: Defines the composite key as an embeddable class inside the entity.
Both methods allow you to handle entities with complex primary keys composed of multiple fields.
21) SQL :- Write a Query , find out duplicates from a table.
To find duplicates from a table in SQL, you typically want to identify rows where one or more columns have the same values. The most common way to do this is by using the GROUP BY clause in combination with the HAVING clause to filter out groups that have more than one occurrence.
Basic Query to Find Duplicates:
Suppose you have a table called employees with the following columns:
id (unique identifier)
name (employee name)
email (employee email)
department_id (department of the employee)
To find duplicates based on, for example, the email column (i.e., find employees with the same email address), you can use the following query:
SQL > SELECT email, COUNT(*) AS duplicate_count FROM employees
GROUP BY email HAVING COUNT(*) > 1;
Explanation:
SELECT email: This selects the column (email) that you want to check for duplicates.
COUNT(*) AS duplicate_count: This counts the number of occurrences of each value in the email column.
FROM employees: Specifies the table from which to retrieve the data.
GROUP BY email: Groups the result by email, so that we can count how many times each email appears in the table.
HAVING COUNT(*) > 1: Filters the groups to include only those where the count of rows with the same email is greater than 1, meaning they are duplicates.
Find All Columns for Duplicate Rows
If you want to see the full details of the duplicate rows (not just the duplicated column), you can use a JOIN to select all rows that have a duplicate.
SQL> SELECT e.* FROM employees e JOIN ( SELECT email FROM employees GROUP BY email
HAVING COUNT(*) > 1) dup ON e.email = dup.email;
Explanation:
The subquery (dup) selects all email values that appear more than once.
The main query (SELECT e.*) fetches all the columns from the employees table where the email matches any of the emails in the subquery.
This query will return all rows from the employees table where the email is duplicated.
Find Duplicates Based on Multiple Columns
If you want to check for duplicates based on multiple columns, you can extend the GROUP BY clause:
SELECT name, email, COUNT(*) AS duplicate_count
FROM employees
GROUP BY name, email
HAVING COUNT(*) > 1;
This query will find rows where both name and email are duplicated..
22)What is JDBC Connection ?
JDBC (Java Database Connectivity) is a Java API that allows Java applications to interact with databases. It provides a standard interface for connecting to relational databases, executing SQL queries, and processing the results. JDBC enables Java developers to easily integrate database operations into their applications.
Key Components of JDBC:
JDBC Drivers: These are the interfaces between the Java application and the database. Different databases (like MySQL, Oracle, PostgreSQL, etc.) require different JDBC drivers.
Connection: A Connection object in JDBC represents a session with the database. It’s used to establish communication between the Java application and the database.
Statement: The Statement object is used to execute SQL queries against the database.
ResultSet: A ResultSet object holds the data retrieved from the database after executing a query.
Exception Handling: JDBC throws SQLException for any database-related errors, which you need to catch and handle in your code.
Basic Steps to Establish a JDBC Connection:
Load the JDBC Driver: The first step is to load the appropriate JDBC driver for your database.
Establish a Connection: You need to create a connection to the database by providing the database URL, username, and password.
Create a Statement: Once the connection is established, a Statement object is created to execute SQL queries.
Execute the Query: The SQL query is executed using methods like executeQuery() for SELECT queries or executeUpdate() for INSERT/UPDATE/DELETE queries.
Process the Result: The results returned by the query are processed using a ResultSet.
Close the Connection: Finally, the database connection is closed to release the resources.
Example of a Simple JDBC Connection:
Here is an example of how to set up a JDBC connection to a MySQL database, query data, and close the connection:
Step-by-Step Example:
Add MySQL JDBC Driver to Your Project: If you’re using Maven, you can add the MySQL driver dependency in your pom.xml:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version> <!-- Use the appropriate version -->
</dependency>
JDBC Connection Code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCExample {
public static void main(String[] args) {
// Step 1: Declare the JDBC variables
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// Step 2: Load the JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver");
// Step 3: Establish the connection
String url = "jdbc:mysql://localhost:3306/your_database"; // Replace with your DB URL
String username = "your_username"; // Replace with your DB username
String password = "your_password"; // Replace with your DB password
connection = DriverManager.getConnection(url, username, password);
// Step 4: Create a statement
statement = connection.createStatement();
// Step 5: Execute a query
String sql = "SELECT * FROM employees"; // Replace with your SQL query
resultSet = statement.executeQuery(sql);
// Step 6: Process the result
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
String email = resultSet.getString("email");
System.out.println("ID: " + id + ", Name: " + name + ", Email: " + email);
}
} catch (ClassNotFoundException | SQLException e) {
// Handle exceptions
e.printStackTrace();
} finally {
// Step 7: Close resources
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Explanation:
DriverManager: This is used to establish a connection to the database. The DriverManager.getConnection() method takes the database URL, username, and password.
Connection: Represents an open connection to the database.
Statement: Used to execute SQL queries. In this case, createStatement() is used to create a statement object.
ResultSet: The executeQuery() method returns a ResultSet, which holds the data retrieved from the database.
Exception Handling: SQLException is thrown when there is a database-related error. ClassNotFoundException is thrown if the JDBC driver class is not found.
Close Resources: After the operations are complete, it’s important to close the ResultSet, Statement, and Connection to free up resources.
Types of JDBC Drivers: There are four types of JDBC drivers:
Type-1 Driver (JDBC-ODBC Bridge): This driver uses ODBC to connect to the database. It is rarely used nowadays.
Type-2 Driver (Native-API Driver): This driver uses native database client libraries.
Type-3 Driver (Network Protocol Driver): It communicates with the database through a middleware server.
Type-4 Driver (Thin Driver): This is the most commonly used driver. It directly communicates with the database using the database's native protocol. Examples include MySQL’s Connector/J or PostgreSQL’s JDBC driver.
Key JDBC Methods:
getConnection(): Establishes a connection to the database.
createStatement(): Creates a statement for sending SQL queries to the database.
executeQuery(): Executes a SELECT query and returns a ResultSet.
executeUpdate(): Executes an INSERT, UPDATE, or DELETE query and returns the number of affected rows.
close(): Closes the database connection and related resources.
Conclusion:
JDBC provides a fundamental framework for interacting with relational databases in Java applications. It allows you to execute SQL queries, retrieve data, and handle database connections programmatically. By using JDBC, Java developers can manage data in a database and perform various operations such as querying, inserting, updating, and deleting records.
21)API that was used for data base connection ?
The API used for database connection in Java is JDBC (Java Database Connectivity). It provides a standard interface for connecting to databases and executing SQL queries from Java applications. JDBC is a part of the Java Standard API, and it allows Java applications to communicate with relational databases in a platform-independent way.
Key JDBC API Components:
DriverManager: This class manages the list of database drivers and establishes connections to the database.
Connection: This interface represents an open connection to a specific database. It provides methods for creating Statement, PreparedStatement, and CallableStatement objects, as well as for managing transactions.
Statement: This interface is used to execute SQL queries against the database. It provides methods like executeQuery(), executeUpdate(), and execute().
PreparedStatement: This interface is a subclass of Statement and is used to execute precompiled SQL queries with input parameters, which helps in preventing SQL injection attacks and improving performance for repeated queries.
CallableStatement: This interface is used to execute stored procedures in the database.
ResultSet: This interface represents the result of a query (for SELECT queries). It provides methods for retrieving the data returned by the query.
SQLException: This class is used to handle database-related exceptions in JDBC operations.
How JDBC Works:
JDBC Drivers: When you want to connect to a specific database (like MySQL, Oracle, PostgreSQL, etc.), you need the corresponding JDBC driver. These drivers translate the JDBC calls into database-specific calls.
Establish Connection: The DriverManager class manages the database drivers and establishes a connection to the database using a URL, username, and password.
Execute Queries: Once the connection is established, you can create a Statement, PreparedStatement, or CallableStatement to execute SQL queries.
Process the Results: The results of a query are returned in a ResultSet object, which you can iterate over to process the data.
Close the Connection: After performing the database operations, it’s important to close the Connection, Statement, and ResultSet to release the resources.
Example of Using JDBC to Connect to a Database:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCExample {
public static void main(String[] args) {
// Database URL, username, and password
String url = "jdbc:mysql://localhost:3306/mydatabase"; // Example for MySQL
String username = "root"; // Your DB username
String password = "password"; // Your DB password
// Initialize JDBC objects
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 1. Load the JDBC driver
Class.forName("com.mysql.cj.jdbc.Driver"); // For MySQL
// 2. Establish the connection
connection = DriverManager.getConnection(url, username, password);
// 3. Create a statement object
statement = connection.createStatement();
// 4. Execute a query
String sql = "SELECT id, name FROM employees";
resultSet = statement.executeQuery(sql);
// 5. Process the result set
while (resultSet.next()) {
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("Employee ID: " + id + ", Name: " + name);
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
// 6. Close resources
try {
if (resultSet != null) resultSet.close();
if (statement != null) statement.close();
if (connection != null) connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
Summary of Key JDBC Classes/Interfaces:
DriverManager: Manages JDBC drivers and establishes database connections.
Connection: Represents an open connection to a database.
Statement: Used to execute SQL queries.
PreparedStatement: Extends Statement and allows parameterized queries.
CallableStatement: Used for executing stored procedures.
ResultSet: Represents the result set of a query (used to fetch data).
SQLException: Exception thrown for SQL-related errors.
22) Core Concepts of Information Security:
The CIA Triad is a fundamental model in the information security domain that focuses on the three main objectives:
Confidentiality:
Ensures that sensitive information is only accessible to those who have the necessary permissions.
Example: Encrypting passwords, using access controls, and secure communication protocols (like HTTPS) to prevent unauthorized users from accessing sensitive data.
Integrity:
Ensures that data is accurate, consistent, and unaltered from its original state during storage or transmission.
Example: Hashing, checksums, and digital signatures are used to verify the integrity of data. If data is tampered with, it can be detected.
Availability:
Ensures that systems, applications, and data are accessible when needed, even in the event of failures or attacks.
Example: Redundant systems, disaster recovery plans, and backup systems ensure that services remain available even after a failure or attack (e.g., DDoS).
Types of Security Threats:
Cyberattacks:
Malware: Software designed to damage or gain unauthorized access to a system (e.g., viruses, trojans, ransomware).
Phishing: Fraudulent attempts to obtain sensitive information (e.g., login credentials, credit card numbers) by pretending to be a trustworthy entity.
Denial-of-Service (DoS) and Distributed Denial-of-Service (DDoS): Attacks that overwhelm a system or network with traffic, making it unavailable to users.
SQL Injection: Malicious code inserted into SQL queries to manipulate the database.
Man-in-the-Middle (MitM): Intercepting and altering communication between two parties without their knowledge.
Human Factors:
Insider Threats: Employees or individuals who have authorized access to systems but misuse it to steal, leak, or damage data.
Social Engineering: Manipulating people into disclosing confidential information (e.g., tricking someone into giving away a password or clicking on a malicious link).
Physical Threats:
Theft or Loss of Devices: Physical access to devices (laptops, hard drives) can lead to the theft of sensitive data.
Natural Disasters: Fires, floods, and other natural disasters can destroy physical infrastructure, including data centers and backup systems.
Key Security Measures:Encryption:
The process of converting data into a code to prevent unauthorized access. Encryption ensures the confidentiality of data during transmission and storage.
Examples: AES (Advanced Encryption Standard), RSA, SSL/TLS for secure communications, and file encryption.
Authentication and Authorization:
Authentication: Verifying the identity of a user or system. Common methods include usernames/passwords, multi-factor authentication (MFA), biometrics, and tokens.
Authorization: Defining and enforcing the permissions or access rights a user or system has once they are authenticated.
Role-Based Access Control (RBAC): A method of restricting access to systems based on the roles of users within an organization.
Firewalls: Security systems that monitor and control incoming and outgoing network traffic based on predetermined security rules.
They are typically deployed between internal networks and the internet to prevent unauthorized access.
Intrusion Detection and Prevention Systems (IDPS):
Systems designed to detect and prevent malicious activities or violations of policies within a network or system.
IDS (Intrusion Detection Systems) identify potential threats or attacks, while IPS (Intrusion Prevention Systems) take action to block the detected threats.
Secure Software Development:
Ensuring that applications are built with security in mind by following practices like:
Code Reviews: Regularly reviewing code for potential security vulnerabilities.
Input Validation: Validating all user inputs to prevent SQL injection, cross-site scripting (XSS), and other attacks.
Secure Coding Practices: Writing code that adheres to security standards, such as the OWASP Top 10.
Security Patches and Updates:
Regularly updating software, operating systems, and applications to patch known vulnerabilities.
Attackers often exploit unpatched vulnerabilities to gain unauthorized access.
Backup and Disaster Recovery:
Maintaining regular backups of critical data and having a recovery plan in place to ensure data can be restored in the event of a breach, hardware failure, or disaster.
Endpoint Security:
Protecting devices like laptops, smartphones, and servers from cyber threats by using antivirus software, firewalls, and encryption tools.
Security Monitoring and Logging:
Continuously monitoring networks, systems, and applications for signs of potential security incidents.
Logging system activity can help detect suspicious behavior and assist in post-incident investigations.
Common Security Protocols:
SSL/TLS (Secure Sockets Layer / Transport Layer Security):
Protocols used to secure communications over a computer network by encrypting data between web browsers and servers. This is the technology behind HTTPS.
VPN (Virtual Private Network):
A secure connection between a device and a network over the internet, allowing users to access resources remotely with encryption.
SSH (Secure Shell):
A protocol used to securely access and manage remote systems over a network.
OAuth/OpenID Connect:
Authorization protocols used for allowing secure third-party applications to access user data without exposing credentials (commonly used for social logins).
Kerberos:
A network authentication protocol that uses symmetric key cryptography to authenticate users and services securely over a non-secure network.
Best Practices for Enhancing Security:
Use Strong Passwords: Enforce the use of strong, unique passwords. Implement multi-factor authentication (MFA) wherever possible.
Keep Software Updated: Regularly update operating systems, applications, and databases to patch known vulnerabilities.
Network Segmentation: Divide your network into segments to limit the access of potential attackers. For example, separate public-facing and internal networks.
Regular Security Audits: Conduct vulnerability assessments, penetration testing, and security audits to identify and address weaknesses.
User Education and Awareness: Train employees and users about security best practices, phishing, social engineering, and other potential threats.
Data Encryption: Always encrypt sensitive data, both in transit and at rest.
Limit Access: Implement the principle of least privilege, meaning users should have the minimum level of access required to perform their tasks.
Incident Response Plan: Have a well-defined plan in place to respond to security breaches or incidents, including identification, containment, eradication, and recovery processes.
Conclusion:
Security is a broad and evolving field that spans a variety of techniques, protocols, and strategies to protect information, systems, and networks from threats. It is a critical concern for individuals, businesses, and governments alike, and it requires constant vigilance, monitoring, and proactive measures to safeguard against an ever-growing list of security threats. Effective security combines technology, processes, and people to mitigate risks and protect against unauthorized access, theft, and attacks.
22) Identify the issue in this Java program.
public class Example {
public static void main(String[] args) {
int[] arr = new int[5];
for (int i = 0; i <= arr.length; i++) {
arr[i] = i * 2;
}
}
}
Here's the issue: arr.length is 5, so the loop runs from i = 0 up to and including 5.
But the valid indices for arr are only 0, 1, 2, 3, 4.
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5
Solution :Change the loop condition from i <= arr.length to i < arr.length.
public class Example {
public static void main(String[] args) {
int[] arr = new int[5];
for (int i = 0; i < arr.length; i++) {
arr[i] = i * 2;
}
}
}
23) Create method and method have 2 parameters, add both parameters should be return?
public class Calculator {
// Method to add two numbers
public int add(int a, int b) {
return a + b;
}
// Example usage
public static void main(String[] args) {
Calculator calc = new Calculator();
int result = calc.add(5, 7);
System.out.println("Sum: " + result); // Output: Sum: 12
}
}
int a and int b are the two parameters.return a + b; returns the sum.
main method demonstrates how to use the add method.
24) Difference between Boolean and boolean?
boolean (primitive type) : Type: Primitive data type. Default value: false. Cannot be null.
Faster and more memory-efficient.
Used when you don’t need the extra features of an object.
boolean flag = true;
Boolean (wrapper class):- Type: Object (wrapper class for boolean) , Can be null.
Has methods like Boolean.parseBoolean(), Boolean.valueOf(), etc.
Needed when working with collections like ArrayList<Boolean>, or when an object is required (e.g., for generics, in some frameworks, or databases).
Boolean flag = Boolean.TRUE;
Boolean obj = true; // Autoboxing: boolean → Boolean
boolean val = obj; // Unboxing: Boolean → boolean
Because Boolean can be null, this can throw a NullPointerException:
Boolean obj = null;
if (obj) { // ❌ NullPointerException
System.out.println("true");
}
26) Write a method to throw an exception when 2 parameters are same?
public class ParameterChecker {
// Method to check if two integers are the same
public void checkParameters(int a, int b) throws IllegalArgumentException {
if (a == b) {
throw new IllegalArgumentException("Parameters should not be the same!");
}
System.out.println("Parameters are different: " + a + " and " + b);
}
// Example usage
public static void main(String[] args) {
ParameterChecker checker = new ParameterChecker();
try {
checker.checkParameters(5, 5); // This will throw an exception
} catch (IllegalArgumentException e) {
System.out.println("Caught exception: " + e.getMessage());
}
}
}
27) Create a method and main class, and by using thread you have to invoke the method?
// Class containing the method to be invoked by thread
public class MyTask implements Runnable {
// Method to be invoked using a thread
public void printMessage() {
System.out.println("Hello from the thread! - " + Thread.currentThread().getName());
}
// Override run() to call the method
@Override
public void run() {
printMessage();
}
// Main method
public static void main(String[] args) {
// Create an object of MyTask
MyTask task = new MyTask();
// Create a thread with the task
Thread thread = new Thread(task);
// Start the thread
thread.start();
System.out.println("Main thread finished - " + Thread.currentThread().getName());
}
}
MyTask implements Runnable → so we can pass it to a Thread.
Inside run(), we call the custom method printMessage().
In main, we create and start the thread.
28) Create one more thread and try print the thread name for both threads ?
We create two threads using the same Runnable class (MyTask).
Each thread will print its own name using Thread.currentThread().getName().
public class MyTask implements Runnable {
// Method to print the thread name
public void printMessage() {
System.out.println("Hello from: " + Thread.currentThread().getName());
}
// run() method that gets called when thread starts
@Override
public void run() {
printMessage();
}
// Main method
public static void main(String[] args) {
// Create the task
MyTask task = new MyTask();
// Create two threads with names
Thread thread1 = new Thread(task, "Worker-1");
Thread thread2 = new Thread(task, "Worker-2");
// Start both threads
thread1.start();
thread2.start();
// Main thread name
System.out.println("Main thread: " + Thread.currentThread().getName());
}
}
Main thread: main
Hello from: Worker-1
Hello from: Worker-2
29) How does synchronized ensures that it will print only one thread ?
The synchronized keyword ensures that only one thread can access a block of code or method at a time for a given object.
So if multiple threads try to execute a synchronized method or block on the same object, only one will be allowed in at a time — the others have to wait their turn.
Program :
public class MyTask implements Runnable {
public void printMessage() {
System.out.println("Hello from: " + Thread.currentThread().getName());
}
@Override
public void run() {
printMessage();
}
public static void main(String[] args) {
MyTask task = new MyTask();
Thread t1 = new Thread(task, "Thread-1");
Thread t2 = new Thread(task, "Thread-2");
t1.start();
t2.start();
}
}
//Example with Synchronized
public class MyTask implements Runnable {
// Synchronized method: only one thread can run this at a time per object
public synchronized void printMessage() {
System.out.println("Started by: " + Thread.currentThread().getName());
// Simulate some processing
try {
Thread.sleep(1000); // Sleep for 1 second
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Finished by: " + Thread.currentThread().getName());
}
@Override
public void run() {
printMessage();
}
public static void main(String[] args) {
MyTask task = new MyTask();
Thread t1 = new Thread(task, "Thread-1");
Thread t2 = new Thread(task, "Thread-2");
t1.start();
t2.start();
}
}
OUTPUT :
Started by: Thread-1
Finished by: Thread-1
Started by: Thread-2
Finished by: Thread-2
30) Create a Spring Boot Project and create one API to print the range of prime numbers from the given input.?
Sure! Here's a simple Spring Boot project setup with:
A REST API: /prime?start=10&end=50
It returns all prime numbers in the given range [start, end]
spring-prime-api/
├── src/
│ └── main/
│ └── java/
│ └── com.example.prime/
│ ├── PrimeApplication.java
│ ├── controller/PrimeController.java
│ └── service/PrimeService.java
└── pom.xml
2. pom.xml (Maven)
<project xmlns="http://maven.apache.org/POM/4.0.0" ...>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>spring-prime-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-prime-api</name>
<description>Spring Boot Prime Number API</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<!-- Spring Boot Starter Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Optional: For testing -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Spring Boot Maven Plugin -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
✅ 3. PrimeApplication.java
package com.example.prime;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class PrimeApplication {
public static void main(String[] args) {
SpringApplication.run(PrimeApplication.class, args);
}
}
✅ 4. PrimeController.java
package com.example.prime.controller;
import com.example.prime.service.PrimeService;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/prime")
public class PrimeController {
private final PrimeService primeService;
public PrimeController(PrimeService primeService) {
this.primeService = primeService;
}
@GetMapping
public List<Integer> getPrimeNumbers(@RequestParam int start, @RequestParam int end) {
return primeService.findPrimesInRange(start, end);
}
}
✅ 5. PrimeService.java
package com.example.prime.service;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class PrimeService {
public List<Integer> findPrimesInRange(int start, int end) {
List<Integer> primes = new ArrayList<>();
for (int i = Math.max(2, start); i <= end; i++) {
if (isPrime(i)) {
primes.add(i);
}
}
return primes;
}
private boolean isPrime(int number) {
if (number <= 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;
for (int i = 3; i <= Math.sqrt(number); i += 2) {
if (number % i == 0) return false;
}
return true;
}
}
✅ Sample Request:
URL:
GET http://localhost:8080/prime?start=10&end=30
Response: [11, 13, 17, 19, 23, 29]
31) Create a method with 2 parameters, perform division and write a simple test for the program?
Defines a method to divide two numbers.
Handles division by zero safely.
Includes a JUnit test to verify the logic.
Program
package com.example.calculator;
public class Calculator {
// Method to divide two numbers
public double divide(int a, int b) {
if (b == 0) {
throw new ArithmeticException("Cannot divide by zero");
}
return (double) a / b;
}
}
Test Class: CalculatorTest.java
We'll use JUnit 5 here.
package com.example.calculator;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class CalculatorTest {
@Test
void testDivision() {
Calculator calculator = new Calculator();
double result = calculator.divide(10, 2);
assertEquals(5.0, result);
}
@Test
void testDivisionByZero() {
Calculator calculator = new Calculator();
assertThrows(ArithmeticException.class, () -> calculator.divide(10, 0));
}
}
✅ Maven Dependency for JUnit 5
If you’re using Maven, make sure your pom.xml includes this:
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
✅ Run the Test
If you're using IDEA, Eclipse, or running via Maven:
mvn test
32)Rest End points and how they handle transactions in Restful ?
Great question! Let’s walk through REST endpoints and how transactions are handled in a RESTful web service — especially in the context of Spring Boot.
In RESTful services, endpoints are usually based on HTTP verbs:
HTTP Method Purpose Typical Action Example Endpoint
GET Read data Fetch a resource /users/1
POST Create data Create a new resource /users
PUT Update data Replace an existing resource /users/1
PATCH Partial update Update part of a resource /users/1
DELETE Delete data Delete a resource /users/1
Handling Transactions in RESTful APIs
✅ What is a Transaction?
A transaction is a unit of work that must be completed entirely or not at all. It ensures data integrity, especially across multiple database operations.
๐ง How to Handle Transactions in Spring REST APIs
Spring provides the @Transactional annotation for managing transactions.
✅ Example: Transactional REST API in Spring Boot
Let’s say you’re transferring money between two accounts. You want both the debit and credit operations to succeed — or neither.
๐งฑ 1. REST Controller
@RestController
@RequestMapping("/api/transfer")
public class TransferController {
private final BankService bankService;
public TransferController(BankService bankService) {
this.bankService = bankService;
}
@PostMapping
public ResponseEntity<String> transferMoney(@RequestParam Long fromId,
@RequestParam Long toId,
@RequestParam double amount) {
bankService.transfer(fromId, toId, amount);
return ResponseEntity.ok("Transfer successful!");
}
}
๐ง 2. Service Layer with @Transactional
@Service
public class BankService {
private final AccountRepository accountRepo;
public BankService(AccountRepository accountRepo) {
this.accountRepo = accountRepo;
}
@Transactional
public void transfer(Long fromId, Long toId, double amount) {
Account from = accountRepo.findById(fromId).orElseThrow();
Account to = accountRepo.findById(toId).orElseThrow();
if (from.getBalance() < amount) {
throw new IllegalArgumentException("Insufficient balance");
}
from.setBalance(from.getBalance() - amount);
to.setBalance(to.getBalance() + amount);
accountRepo.save(from);
accountRepo.save(to);
}
}
✅ Why Use @Transactional?
Ensures that both balance updates happen together.
If any exception occurs (e.g., insufficient balance), everything rolls back — no partial changes.
๐ Extra Tips:
Use @Transactional(readOnly = true) for read-only methods to optimize performance.
You can apply @Transactional at method or class level.
๐งช Want to test this?
Use tools like:
Postman / curl to call the API
JUnit with @SpringBootTest for integration testing
35) Create a class App with method check() that returns Boolean. Hardcode return false.
Write a (failing) test that asserts if check() returns true java and junit aswell
Here's how you can create the App class with the check() method that returns false, and then write a failing JUnit test that asserts if check() returns true.
App.java (the class with the check() method):
public class App {
public boolean check() {
return false; // hardcoded to return false
}
}
AppTest.java (JUnit test class):
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
public class AppTest {
@Test
public void testCheckReturnsTrue() {
App app = new App();
assertTrue(app.check(), "Expected check() to return true, but it returned false");
}
}
Explanation:
App.java: The class has a check() method that always returns false.
AppTest.java: This is a JUnit 5 test class with a single test method testCheckReturnsTrue() that wrongly expects check() to return true. Since the check() method always returns false, this test will fail.
Make sure you have JUnit 5 in your project dependencies for this to work. The test will fail because the assertion is expecting true, while check() returns false.
No comments:
Post a Comment