How exceptions are handled in applications
Exception handling is a mechanism to handle runtime errors, so the normal flow of the application can be maintained instead of crashing.
Java uses a structured approach with five main keywords:
try, catch, finally, throw, and throws.
Throwable
├── Exception
│ ├── Checked Exceptions (e.g., IOException, SQLException)
│ └── Unchecked Exceptions (RuntimeException and its subclasses)
│ ├── NullPointerException
│ ├── ArithmeticException
│ └── IllegalArgumentException
└── Error (e.g., OutOfMemoryError, StackOverflowError)
Checked exceptions: Must be either handled with try-catch or declared using throws.
Unchecked exceptions: Occur at runtime; not required to be declared or caught.
Errors: Usually not handled — they indicate serious system issues.
3. How Exceptions Are Handled in Applications
A. Using try-catch-finally
You wrap risky code in a try block and handle specific exceptions in catch blocks.
B. Using throws in Method Signatures
If a method can’t handle an exception, it can declare it and let the caller handle it.
C. Using throw to Manually Raise Exceptions
You can create and throw exceptions explicitly.
Global Exception Handlers
Frameworks use centralized exception handling via annotations like:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGeneric(Exception ex) {
return new ResponseEntity<>("Something went wrong", HttpStatus.INTERNAL_SERVER_ERROR);
}
}
Best Practices
-
Catch only what you can handle meaningfully.
-
Use custom exceptions for domain-specific errors.
-
Never swallow exceptions silently (
catch (Exception e) {}is bad). -
Log exceptions with meaningful messages.
-
Always release resources (use
finallyor try-with-resources).
Excellent question ๐ — this is a common Java interview question that tests your understanding of serialization and the transient keyword.
Let’s go step by step ๐
๐งฉ 1. What is Serialization?
Serialization in Java is the process of converting an object into a byte stream so it can be:
-
Saved to a file
-
Sent over a network
-
Stored in memory or cache
This is done using the Serializable interface.
import java.io.Serializable;
class Employee implements Serializable {
private int id;
private String name;
}
When you serialize such an object, all its non-static, non-transient fields are saved.
⚙️ 2. How to Avoid a Variable from Being Serialized
✅ Use the transient keyword
When you mark a variable as transient, Java skips it during serialization.
import java.io.Serializable;
class Employee implements Serializable {
private int id;
private String name;
private transient String password; // ๐ซ will not be serialized
public Employee(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
}
๐งช 3. Example
import java.io.*;
class Employee implements Serializable {
private static final long serialVersionUID = 1L;
int id;
String name;
transient String password;
public Employee(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
}
public class TestSerialization {
public static void main(String[] args) throws Exception {
Employee e = new Employee(1, "John", "secret123");
// Serialize
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("emp.ser"));
out.writeObject(e);
out.close();
// Deserialize
ObjectInputStream in = new ObjectInputStream(new FileInputStream("emp.ser"));
Employee emp = (Employee) in.readObject();
in.close();
System.out.println("ID: " + emp.id);
System.out.println("Name: " + emp.name);
System.out.println("Password: " + emp.password); // will print null
}
}
๐ข Output:
ID: 1
Name: John
Password: null
๐ก 4. Alternative Ways (Advanced)
In some advanced scenarios, you can customize serialization without transient, for example:
a. Override writeObject() and readObject()
You can manually control which fields to serialize.
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject(); // write normal fields
// don't write sensitive fields
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
// reinitialize transient/sensitive fields if needed
}
b. Use Externalizable
Implement Externalizable instead of Serializable, and explicitly write/read the desired fields.
class Employee implements Externalizable {
int id;
String name;
String password;
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt(id);
out.writeObject(name);
// skip password
}
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
id = in.readInt();
name = (String) in.readObject();
}
}
๐ง 5. Common Interview Follow-ups
| Question | Short Answer |
|---|---|
| What happens to a transient variable after deserialization? | It becomes null (for objects) or 0 / false for primitives. |
| Can static variables be serialized? | No — because they belong to the class, not the object. |
| Can you serialize a non-serializable object inside a serializable class? | Only if that field is marked transient, otherwise NotSerializableException will occur. |
Excellent — this is a core Spring Boot interview question ๐ก
Let’s break it down clearly and completely ๐
⚙️ What is @SpringBootApplication?
@SpringBootApplication is a convenience annotation that marks the main class of a Spring Boot application.
It tells Spring Boot to:
-
Auto-configure the application,
-
Scan for components (like
@Controller,@Service,@Repository), and -
Enable configuration support.
๐งฉ 1. Defined As a Combination of Three Annotations
Internally, @SpringBootApplication is a shorthand for:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}
Let’s see what each does ๐
๐น A. @SpringBootConfiguration
-
It’s itself a specialization of
@Configuration. -
Marks the class as a source of bean definitions.
-
You can define beans using
@Beanmethods inside it.
@SpringBootConfiguration
public class MyAppConfig {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
✅ Essentially: Tells Spring “This class can define beans.”
๐น B. @EnableAutoConfiguration
-
Tells Spring Boot to automatically configure the application based on the dependencies present in the classpath.
Example:
-
If you have
spring-boot-starter-web, it auto-configures:-
DispatcherServlet -
Embedded Tomcat
-
JSON converters, etc.
-
✅ It reads META-INF/spring.factories to find configuration classes and auto-wire them.
๐น C. @ComponentScan
-
Tells Spring where to look for beans/components.
By default, it scans the package of the class where @SpringBootApplication is declared and all subpackages.
Example:
@SpringBootApplication // scans com.example and below
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
If your components are outside that package, you can specify base packages:
@SpringBootApplication(scanBasePackages = "com.mycompany.project")
๐ง 2. How It Works in the Main Class
@SpringBootApplication
public class MySpringBootApp {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApp.class, args);
}
}
✅ What happens here:
-
Spring Boot starts.
-
Performs component scanning.
-
Applies auto-configuration.
-
Starts the embedded server (if it’s a web app).
๐งฐ 3. Equivalent Code Without It
If you didn’t use @SpringBootApplication, you’d need to write:
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.example")
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
So @SpringBootApplication is just a shortcut that makes configuration cleaner.
๐ก 4. Common Interview Follow-Ups
| Question | Short Answer |
|---|---|
What does @SpringBootApplication do internally? |
It combines @Configuration, @EnableAutoConfiguration, and @ComponentScan. |
| Can we control which packages to scan? | Yes — @SpringBootApplication(scanBasePackages = {"com.example", "org.demo"}). |
| How does auto-configuration work? | Through @EnableAutoConfiguration, which loads config classes from spring.factories. |
| What if we don’t want certain auto-configurations? | Use @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}). |
| Where should this annotation be placed? | On the main class in the root package of your project. |
✅ 5. Summary
| Purpose | Annotation | Description |
|---|---|---|
| Declare configuration class | @SpringBootConfiguration |
Allows defining beans |
| Enable auto configuration | @EnableAutoConfiguration |
Configures app based on dependencies |
| Scan for beans | @ComponentScan |
Finds @Component, @Service, etc. |
| Shortcut for all above | @SpringBootApplication |
Cleaner and simpler main entry point |
Excellent — another must-know Spring Boot interview question ๐
Let’s break down Spring Boot Actuator in simple, clear terms — with examples and interview-style insights ๐
⚙️ What is Spring Boot Actuator?
Spring Boot Actuator is a built-in feature that provides production-ready monitoring and management endpoints for your Spring Boot application — without writing extra code.
It gives you insights into your application’s:
-
Health
-
Metrics
-
Environment
-
Configuration
-
Thread dumps
-
HTTP requests, and more.
๐งฉ 1. Why Actuator Is Needed
In real-world (production) systems, you need to:
-
Know if the app is running (health checks),
-
Monitor performance (memory, CPU, request count),
-
Expose metrics to tools like Prometheus, Grafana, or New Relic,
-
Dynamically change logging levels or configurations.
➡️ Actuator makes all that easy — automatically.
⚙️ 2. How to Enable It
Just add this dependency in your pom.xml (for Maven):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Or in Gradle:
implementation 'org.springframework.boot:spring-boot-starter-actuator'
Then start your Spring Boot app — done ✅
๐งญ 3. Common Actuator Endpoints
By default, actuator endpoints are available under /actuator.
Some important ones:
| Endpoint | Description |
|---|---|
/actuator/health |
Shows application health status |
/actuator/info |
Displays custom info about the app |
/actuator/metrics |
Shows system and app metrics (CPU, memory, etc.) |
/actuator/env |
Shows environment properties |
/actuator/beans |
Shows all Spring beans |
/actuator/mappings |
Shows all URL mappings |
/actuator/threaddump |
Shows thread info |
/actuator/loggers |
View/change log levels dynamically |
Example:
http://localhost:8080/actuator/health
๐ข Response:
{
"status": "UP"
}
๐ 4. Security Configuration
By default, only /actuator/health and /actuator/info are public.
Others are restricted — you must enable them in application.properties:
management.endpoints.web.exposure.include=*
Or to enable only specific endpoints:
management.endpoints.web.exposure.include=health,info,metrics
If you use Spring Security, you can also secure actuator endpoints with roles.
๐ง 5. Customize Health and Info
Add custom info:
management.info.env.enabled=true
info.app.name=Payment Service
info.app.version=1.0.3
Endpoint:
/actuator/info
Response:
{
"app": {
"name": "Payment Service",
"version": "1.0.3"
}
}
Add custom health indicator:
@Component
public class CustomHealthIndicator implements HealthIndicator {
@Override
public Health health() {
boolean healthy = checkExternalService();
if (healthy) return Health.up().build();
return Health.down().withDetail("Error", "External service not reachable").build();
}
}
๐ 6. Integration with Monitoring Tools
Actuator can expose metrics in formats compatible with:
-
Prometheus
-
Grafana
-
Micrometer (built-in metrics system)
Just add the relevant dependency:
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
Then you get metrics at:
/actuator/prometheus
๐งฉ 7. Example Output (Metrics)
/actuator/metrics/jvm.memory.used
Response:
{
"name": "jvm.memory.used",
"measurements": [
{ "statistic": "VALUE", "value": 23456789.0 }
],
"availableTags": [
{ "tag": "area", "values": ["heap", "nonheap"] }
]
}
๐ก 8. Common Interview Follow-Ups
| Question | Answer |
|---|---|
| What is the use of Actuator? | Provides endpoints for monitoring, health checks, metrics, etc. |
| How do you expose all actuator endpoints? | management.endpoints.web.exposure.include=* |
| How to restrict access to actuator endpoints? | Use Spring Security roles or configure management port separately. |
| How to add custom health checks? | Implement HealthIndicator interface. |
| How to monitor your app with Prometheus/Grafana? | Use micrometer-registry-prometheus and /actuator/prometheus. |
✅ 9. Summary
| Feature | Description |
|---|---|
| Purpose | Monitor and manage Spring Boot apps |
| Enabled by | spring-boot-starter-actuator |
| Endpoints | /actuator/* |
| Common Uses | Health, Metrics, Info, Logging |
| Integration | Prometheus, Grafana, Micrometer |
| Customizable? | Yes (health, info, metrics) |
Excellent question ๐ — default methods are one of the most important features introduced in Java 8, and they often come up in interviews because they show your understanding of interfaces and backward compatibility.
Let’s go step by step ๐
⚙️ 1. What is a Default Method in Java?
A default method is a method with a body (implementation) inside an interface.
It’s defined using the default keyword.
✅ Syntax:
public interface MyInterface {
default void show() {
System.out.println("Default method implementation");
}
}
This means any class implementing this interface automatically inherits this method — unless it overrides it.
๐ง 2. Why Were Default Methods Introduced?
Before Java 8, interfaces could only have abstract methods — no implementations allowed.
If you added a new method to an interface, all implementing classes would break (you’d have to modify all of them).
To solve this, Java 8 introduced default methods, allowing you to:
-
Add new functionality to existing interfaces
-
Maintain backward compatibility
✅ Purpose:
To evolve interfaces without breaking existing code.
๐งฉ Example
Before Java 8:
interface Vehicle {
void start();
}
If you add a new method later:
void stop();
Every class that implements Vehicle must implement stop() — or else it breaks.
After Java 8:
You can give it a default implementation:
interface Vehicle {
void start();
default void stop() {
System.out.println("Vehicle stopped");
}
}
Now old classes still compile fine — and can override stop() if needed.
✅ Usage Example
interface Vehicle {
void start();
default void stop() {
System.out.println("Vehicle stopped");
}
}
class Car implements Vehicle {
public void start() {
System.out.println("Car started");
}
}
public class Demo {
public static void main(String[] args) {
Vehicle car = new Car();
car.start();
car.stop(); // uses default method
}
}
๐ข Output:
Car started
Vehicle stopped
⚙️ 3. Overriding Default Methods
A class can override the default method if it wants custom behavior.
class Bike implements Vehicle {
public void start() {
System.out.println("Bike started");
}
@Override
public void stop() {
System.out.println("Bike stopped safely");
}
}
⚔️ 4. What If Two Interfaces Have the Same Default Method?
If a class implements two interfaces that define the same default method, there’s a conflict — the class must override it and decide which one to use.
Example:
interface A {
default void show() { System.out.println("From A"); }
}
interface B {
default void show() { System.out.println("From B"); }
}
class C implements A, B {
@Override
public void show() {
A.super.show(); // or B.super.show()
}
}
public class Test {
public static void main(String[] args) {
new C().show(); // prints "From A"
}
}
✅ Rule:
If multiple inherited default methods conflict, you must override and explicitly resolve which one to call.
๐งฉ 5. Default Methods vs Static Methods in Interfaces
| Feature | Default Method | Static Method |
|---|---|---|
| Can have body? | ✅ Yes | ✅ Yes |
| Can be overridden? | ✅ Yes | ❌ No |
| Called using | Object reference | Interface name |
| Introduced in | Java 8 | Java 8 |
Example:
interface Utils {
static void print() { System.out.println("Static method"); }
default void log() { System.out.println("Default method"); }
}
Usage:
Utils.print(); // static
new MyClass().log(); // default
๐ก 6. Benefits of Default Methods
| Benefit | Description |
|---|---|
| ✅ Backward compatibility | You can add new methods to interfaces without breaking old implementations. |
| ✅ Code reuse | Common behavior shared across multiple classes can live in one interface. |
| ✅ Multiple inheritance of behavior | A class can implement multiple interfaces that have reusable method logic. |
๐ซ 7. Limitations
| Limitation | Description |
|---|---|
| ⚠️ Multiple inheritance conflicts | You must resolve method conflicts manually. |
⚠️ Can’t override Object methods |
e.g., you can’t define a default toString() in an interface. |
| ⚠️ Still not a replacement for abstract classes | No state (fields) or constructors allowed. |
✅ 8. Real-World Example
Default methods are widely used in Java libraries — e.g., Collections API:
List<String> list = Arrays.asList("A", "B", "C");
list.forEach(System.out::println); // forEach() is a default method
forEach() was added to Iterable in Java 8 as a default method — so all existing collections automatically got the feature.
๐งพ Summary
| Feature | Description |
|---|---|
| Keyword | default |
| Location | Inside interfaces |
| Purpose | Add method implementations without breaking existing code |
| Introduced in | Java 8 |
| Overridable? | ✅ Yes |
| Key Use | Interface evolution, shared behavior |
Cache aside :
Purchase through Bncloud : Device details - > check in cache first : if not from DB
Excellent, Mishal ๐ — here’s your 3-week senior/lead interview preparation schedule, with daily goals, exercises, and practice questions. It blends system design, Java & Spring technical review, and hands-on practice so that by the end of 3 weeks, you’ll be interview-ready for any senior backend or architect-level round.
๐️ 3-Week Senior Java Backend Interview Preparation Plan
๐งฉ Week 1 – System Design Fundamentals
| Day | Topic | Study Focus | Hands-on / Practice | Deliverable |
|---|---|---|---|---|
| 1 | Caching Concepts | Cache types (in-memory, distributed), cache eviction, cache-aside vs write-through | Implement Redis caching in a sample Spring Boot app | Diagram: Cache + DB data flow |
| 2 | Load Balancing | Load balancers, sticky sessions, reverse proxy, failover | Draw Nginx/HAProxy setup for load balancing 3 microservices | Architecture diagram |
| 3 | Sharding | Horizontal vs Vertical sharding, consistent hashing | Design DB shard strategy by region for “Inventory Service” | DB schema split plan |
| 4 | Distributed Transactions | 2PC, Saga pattern, event choreography | Design an “Order → Payment → Inventory” workflow using Saga | Sequence diagram |
| 5 | Event-driven Design | Kafka vs RabbitMQ, async processing | Implement a producer-consumer demo in Spring Boot using Kafka | Kafka microservice |
| 6 | High-level System Design | Scalability, bottlenecks, CAP theorem, eventual consistency | Revisit all concepts and summarize tradeoffs | System design notes |
| 7 | Design #1: Order Tracking System | REST API + cache + queue + DB | Draw architecture + write data flow for tracking shipments | Design doc + diagram |
⚙️ Week 2 – Complex System Design & Architecture
| Day | Topic | Study Focus | Hands-on / Practice | Deliverable |
|---|---|---|---|---|
| 8 | Design #2: Inventory Management System | Handle concurrent stock updates, optimistic/pessimistic locks | Implement API with concurrency handling | Spring Boot mini-project |
| 9 | Design #3: Payment Gateway | Idempotency, retries, security, distributed transactions | Write pseudo-code for payment retries & rollback | Design flow document |
| 10 | Design #4: Product Recommendation System | Event-driven + async updates | Design Kafka-based recommendation flow | Architecture diagram |
| 11 | Scaling Techniques | Horizontal vs vertical scaling, caching, DB replication | Identify bottlenecks in your earlier designs and fix them | Updated architecture diagrams |
| 12 | Monitoring & Observability | Logging, metrics, tracing (Zipkin, Prometheus, Grafana) | Add actuator endpoints to a microservice | Demo project |
| 13 | Practice Mock Design Round | Pick one: “E-commerce order system” or “Ride booking system” | Present 15-min explanation aloud | Self-record or review notes |
| 14 | Review & Consolidation | Summarize key design patterns + your 3–4 system designs | Create 2-page cheat sheet | System Design Summary Sheet |
๐ป Week 3 – Java, Spring, and Database Mastery
| Day | Topic | Study Focus | Hands-on / Practice | Deliverable |
|---|---|---|---|---|
| 15 | Concurrency & Multithreading | Threads, ExecutorService, Locks, ThreadLocal | Implement producer-consumer + thread-safe singleton | Java code examples |
| 16 | JVM & Garbage Collection | Memory areas, GC algorithms (G1, ZGC), tuning | Analyze heap dump of a Spring app using VisualVM | Notes on GC optimization |
| 17 | Spring Boot Internals | Bean lifecycle, dependency injection, auto-configuration | Debug app startup with custom BeanPostProcessor | Small demo project |
| 18 | Spring Security | JWT, OAuth2, filters, roles | Add JWT-based security to your REST API | Secured API example |
| 19 | REST API Design & Error Handling | Best practices, status codes, @ControllerAdvice | Implement global exception handler + versioned API | REST API project |
| 20 | Database Design & Optimization | Indexing, query plans, transactions | Optimize a few SQL queries; analyze EXPLAIN PLAN |
SQL optimization notes |
| 21 | Final Review & Mock Interview | Combine Java + Spring + System Design | Conduct a mock interview (self or peer) | Confidence checklist |
๐ง Daily Study Routine (2–3 hours suggested)
| Time | Activity |
|---|---|
| 30 min | Theory reading (concepts, notes, or video lecture) |
| 1 hr | Hands-on coding / system design sketching |
| 30 min | Review + write key takeaways in notes |
| 30 min | Practice 2–3 interview questions aloud |
๐ฌ Sample Practice Questions (Use Throughout)
System Design
-
Design an order tracking system that supports millions of users.
-
How would you scale a payment gateway that handles 10K TPS?
-
How to ensure data consistency between Order and Inventory services?
Core Java
-
Explain the difference between synchronized and ReentrantLock.
-
How does
CompletableFutureimprove async programming? -
How does G1 GC differ from Parallel GC?
Spring
-
How does Spring Boot auto-configuration work internally?
-
How would you secure microservices using JWT tokens?
-
What are @Transactional pitfalls in microservices?
Database
-
Explain deadlock detection and prevention.
-
How would you design a DB for order and payment relationships?
-
What indexing strategy would you use for frequent order lookups?
๐ฏ End Goal by Week 3
✅ You can design and explain at least 3 production-grade systems
✅ You can answer deep Java & Spring questions confidently
✅ You have working demos & architecture diagrams ready to discuss in interviews
✅ You’ve practiced mock interviews and identified weak spots
No comments:
Post a Comment