Java Exceptions and I/O APIs
Java Exceptions and I/O APIs
Exception Fundamentals
Q1: What is an exception in Java?
An exception is an event that interrupts normal program flow due to an error or unexpected condition.
Q2: What is the root class of exceptions and errors?
`Throwable`
Q3: Difference between Error and Exception?
- `Error`: serious JVM/system issues (usually not handled in app logic).
- `Exception`: conditions application code may handle.
Q4: What is checked exception?
An exception that must be handled or declared with `throws` at compile time (e.g., IOException).
Q5: What is unchecked exception?
Runtime exceptions (`RuntimeException` and subclasses) not required to be declared/handled.
Q6: Common checked exception examples?
- IOException
- SQLException
- ClassNotFoundException
Q7: Common unchecked exception examples?
- NullPointerException
- IllegalArgumentException
- IllegalStateException
- IndexOutOfBoundsException
Q8: What is exception propagation?
If a method does not handle an exception, it passes up the call stack to caller methods.
Q9: What does `throws` mean?
Method declares it may pass specific exceptions to caller.
Q10: What does `throw` mean?
Explicitly creates and throws an exception instance in code.
try-catch-finally and try-with-resources
Q11: Purpose of try-catch?
Wrap risky code and handle specific failures gracefully.
Q12: Purpose of finally?
Executes cleanup code whether exception occurs or not (except abnormal JVM termination).
Q13: Why is try-with-resources preferred for I/O?
It automatically closes resources and prevents leaks.
Q14: What can be used in try-with-resources?
Objects implementing `AutoCloseable` (e.g., streams, readers, JDBC resources).
Q15: Basic try-with-resources pattern?
try (BufferedReader br = Files.newBufferedReader(path)) { return br.readLine(); }
Q16: Can you have catch with try-with-resources?
Yes, you can combine try-with-resources with catch/finally.
Q17: What are suppressed exceptions?
Exceptions thrown during resource close are attached as suppressed when a primary exception already exists.
Designing Good Exceptions
Q18: When should I create custom exceptions?
When expressing domain-specific failure clearly improves readability and handling.
Q19: Custom checked or unchecked?
- Checked for recoverable external situations.
- Unchecked for programming/domain rule violations.
Q20: Good custom exception naming?
Use specific, meaningful names like `InsufficientFundsException`, `FileStorageException`.
Q21: What makes a good exception message?
Clear context: what failed, where, and key identifiers (without leaking secrets).
Q22: Should I catch Exception everywhere?
No; catch specific exceptions where you can meaningfully recover or translate.
Q23: What is exception wrapping?
Throwing a higher-level exception with original cause for abstraction-friendly error handling.
Q24: Why preserve cause?
Root cause debugging becomes much easier.
Logging and Exception Handling in Backend Apps
Q25: Where should exceptions be logged?
At meaningful boundaries (e.g., controller/service boundary), not repeatedly at every layer.
Q26: Why avoid duplicate logging?
Same stack trace logged multiple times creates noise and slows incident diagnosis.
Q27: What data should logs include?
Error type, message, correlation/request ID, key business context, and stack trace when needed.
Q28: Should sensitive data be logged?
No; never log passwords, tokens, secrets, or private personal data.
Q29: What is global exception handling in Spring?
Centralized mapping via `@ControllerAdvice` to consistent HTTP error responses.
Q30: Recommended REST error payload fields?
timestamp, status, error code, message, path, correlationId.
Java I/O API Basics (java.io)
Q31: What is a stream in Java I/O?
A flow of data from source to destination.
Q32: Byte stream vs character stream?
- Byte streams: binary data (`InputStream`/`OutputStream`)
- Character streams: text data (`Reader`/`Writer`)
Q33: InputStream purpose?
Read bytes from file/network/memory source.
Q34: OutputStream purpose?
Write bytes to file/network/memory target.
Q35: Reader/Writer purpose?
Read/write text with character encoding awareness.
Q36: What is buffering and why use it?
Buffering reduces system calls and improves I/O performance.
Q37: Common buffered classes?
- BufferedInputStream / BufferedOutputStream
- BufferedReader / BufferedWriter
Q38: Why specify charset for text I/O?
Prevent encoding bugs across environments (UTF-8 recommended explicitly).
Modern File I/O (NIO.2 — java.nio.file)
Q39: Why prefer NIO.2 over old File API?
Better abstractions (`Path`, `Files`), richer operations, clearer error handling.
Q40: What is Path?
Immutable representation of a filesystem path.
Q41: How to create Path?
Path p = Path.of("data", "users.txt");
Q42: Common Files utility operations?
- exists
- createDirectories
- readString/readAllLines
- writeString/write
- copy/move/delete
Q43: How to read whole file as string?
String content = Files.readString(path);
Q44: How to write string to file?
Files.writeString(path, content);
Q45: How to append text safely?
Files.writeString(path, line, StandardOpenOption.CREATE, StandardOpenOption.APPEND);
Q46: How to list directory files?
try (Stream<Path> s = Files.list(dir)) { ... }
Q47: How to walk directory tree?
Use `Files.walk(…)` or `Files.walkFileTree(…)`.
File Metadata, Copy/Move/Delete
Q48: How to check file existence?
`Files.exists(path)`
Q49: How to distinguish file vs directory?
- `Files.isRegularFile(path)`
- `Files.isDirectory(path)`
Q50: How to copy file?
Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
Q51: How to move/rename file?
Files.move(src, dst, StandardCopyOption.REPLACE_EXISTING);
Q52: How to delete file?
- `Files.delete(path)` (fails if missing)
- `Files.deleteIfExists(path)` (safe if missing)
Q53: How to get file size?
`Files.size(path)`
Q54: Why handle IOException in file operations?
Disk permissions, missing files, locks, full storage, and device/network errors are common.
Serialization and Object I/O (Core Concepts)
Q55: What is Java serialization?
Converting object state to bytes for storage/transmission and reconstructing later.
Q56: Which interfaces/classes are involved?
- `Serializable`
- `ObjectOutputStream`
- `ObjectInputStream`
Q57: Why is default Java serialization often avoided in modern systems?
Security, versioning fragility, and interoperability concerns; JSON/Protobuf are often preferred.
Practical Exception + I/O Patterns
Q58: Pattern: validate input path early
Check null/empty/illegal path before expensive file operations.
Q59: Pattern: fail fast with clear message
Throw specific exception immediately when preconditions fail.
Q60: Pattern: translate low-level exception
Convert IOException to domain-level exception at service boundary.
Q61: Pattern: close resources automatically
Always use try-with-resources for streams/readers/writers/channels.
Q62: Pattern: don’t swallow exceptions
Empty catch blocks hide failures and create hard-to-debug data issues.
Q63: Pattern: preserve root cause
throw new FileStorageException("Failed storing avatar for userId=" + userId, e);
Common Mistakes and How to Avoid Them
Q64: Mistake: catching broad Exception
Catch specific exception types whenever possible.
Q65: Mistake: using platform default charset implicitly
Always pass explicit `StandardCharsets.UTF8`.
Q66: Mistake: reading huge file fully into memory
Stream/process line-by-line for large files.
Q67: Mistake: logging and rethrowing at every layer
Log once at boundary or where context is added.
Q68: Mistake: throwing raw RuntimeException everywhere
Use meaningful exception types with actionable context.
Q69: Mistake: ignoring interrupted status
In thread code, restore interrupt (`Thread.currentThread().interrupt()`) when catching InterruptedException.
Backend/REST Context Questions
Q70: Where should validation exceptions be converted to HTTP 400?
In controller layer/global handler mapping client-input failures.
Q71: Where should unexpected server exceptions map?
HTTP 500 with safe generic message to client and detailed server logs.
Q72: How to handle file upload size violations?
Validate limits, return 413/400-style response, and log context safely.
Q73: Should clients see stack traces?
No; return sanitized errors, keep stack traces in server logs.
Q74: Why include correlation ID in error responses/logs?
Enables fast tracing across distributed systems and support tickets.
Mini Code Q&A (Easy Snippets)
Q75: Read file line-by-line (UTF-8)?
try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { // process line } }
Q76: Write lines to file?
Files.write(path, lines, StandardCharsets.UTF_8);
Q77: Create directories if missing?
Files.createDirectories(Path.of("data/uploads"));
Q78: Safe delete attempt?
boolean deleted = Files.deleteIfExists(path);
Q79: Throw custom exception on invalid argument?
if (email == null || email.isBlank()) { throw new IllegalArgumentException("email must not be blank"); }
Q80: Wrap IOException with domain exception?
try { Files.writeString(path, payload); } catch (IOException e) { throw new FileStorageException("Unable to store report", e); }
Interview Quick Round
Q81: Why checked exceptions exist?
To force explicit handling/awareness of recoverable external failures.
Q82: Why RuntimeException is still useful?
For programmer errors and invariant violations where immediate propagation is appropriate.
Q83: Most important I/O performance habit?
Use buffering and avoid unnecessary full-memory reads for large data.
Q84: Why NIO Path is better than File for modern code?
Cleaner API, better utility support, and improved composability with Files methods.
Q85: Most important exception design habit?
Be specific and preserve cause while adding useful context.
Scenario-Based Q&A
Q86: Scenario: Config file missing at startup. What to do?
Throw clear startup exception and fail fast with actionable message/path.
Q87: Scenario: Temporary network file read failure. What to do?
Catch IOException, apply retry policy if appropriate, and log attempts/context.
Q88: Scenario: Invalid CSV row in batch import. What to do?
Record row error, continue if business allows, and produce final error summary.
Q89: Scenario: Disk full during write. What to do?
Catch IOException, return controlled server error, alert operations, and prevent partial corruption.
Q90: Scenario: User requests non-existing download file. What to do?
Map to 404 with clear message; avoid exposing internal filesystem details.
Testing Exceptions and I/O
Q91: How to assert exception in JUnit 5?
assertThrows(IllegalArgumentException.class, () -> service.process(null));
Q92: How to test exception message quickly?
var ex = assertThrows(...); assertTrue(ex.getMessage().contains("email"));
Q93: How to test file I/O safely?
Use temp directories/files and clean up automatically.
Q94: Why avoid real external paths in unit tests?
They make tests environment-dependent and flaky.
Q95: What should integration tests verify for error handling?
Correct HTTP status, error schema, and stable/loggable failure behavior.