Summary
Java is a robust, object-oriented programming language widely used for enterprise backend development. This cheatsheet covers essential Java concepts including fundamentals, OOP principles, collections framework, multithreading, exception handling, Java 8+ features (lambdas, streams, optionals), Spring Framework ecosystem, JPA/Hibernate for database operations, REST API development, design patterns, and best practices. Key features include platform independence (JVM), strong type system, automatic memory management, rich standard library, and comprehensive frameworks like Spring Boot for rapid application development.
Java Fundamentals
Data Types
Primitive Types:
byte(8 bits),short(16),int(32),long(64)float(32 bits),double(64)char(16 bits Unicode)boolean(true/false)
Reference Types: Objects, Arrays, Interfaces
String
String s1 = "Hello"; // String pool
String s2 = new String("Hello"); // Heap
s1 == s2; // false (different objects)
s1.equals(s2); // true (same content)
// String is immutable
StringBuilder sb = new StringBuilder(); // Mutable, not thread-safe
StringBuffer sbuf = new StringBuffer(); // Mutable, thread-safe
Arrays
int[] arr = new int[5];
int[] arr2 = {1, 2, 3, 4, 5};
int[][] matrix = new int[3][3];
Object-Oriented Programming
Four Pillars of OOP
1. Encapsulation
public class Person {
private String name; // Hidden data
public String getName() { return name; } // Controlled access
public void setName(String name) { this.name = name; }
}
2. Inheritance
public class Employee extends Person {
private double salary;
// Inherits name, getName(), setName()
}
3. Polymorphism
// Method Overloading (Compile-time)
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
// Method Overriding (Runtime)
@Override
public String toString() { return "Custom string"; }
4. Abstraction
abstract class Animal {
abstract void makeSound(); // No implementation
}
interface Flyable {
void fly(); // All methods are abstract by default
}
Access Modifiers
private: Same class onlydefault(no modifier): Same packageprotected: Same package + subclassespublic: Everywhere
Keywords
final: Cannot be changed (variable), overridden (method), extended (class)static: Belongs to class, not instanceabstract: Must be implemented by subclasssynchronized: Thread-safe accessvolatile: Variable always read from main memory
Collections Framework
List Interface
List<String> arrayList = new ArrayList<>(); // Dynamic array, O(1) access
List<String> linkedList = new LinkedList<>(); // Doubly-linked, O(1) insert/delete
List<String> vector = new Vector<>(); // Thread-safe ArrayList
Set Interface
Set<String> hashSet = new HashSet<>(); // No order, O(1) operations
Set<String> linkedHashSet = new LinkedHashSet<>(); // Insertion order
Set<String> treeSet = new TreeSet<>(); // Sorted, O(log n)
Map Interface
Map<String, Integer> hashMap = new HashMap<>(); // No order, O(1)
Map<String, Integer> linkedHashMap = new LinkedHashMap<>(); // Insertion order
Map<String, Integer> treeMap = new TreeMap<>(); // Sorted by key
Map<String, Integer> hashtable = new Hashtable<>(); // Thread-safe
Queue Interface
Queue<String> queue = new LinkedList<>();
queue.offer("item"); // Add
queue.poll(); // Remove and return
queue.peek(); // View without removing
Deque<String> deque = new ArrayDeque<>(); // Double-ended queue
PriorityQueue<Integer> pq = new PriorityQueue<>(); // Min heap by default
Important Methods
// Common operations
list.add(element);
list.remove(index);
list.get(index);
list.size();
set.add(element);
set.contains(element);
set.remove(element);
map.put(key, value);
map.get(key);
map.containsKey(key);
map.keySet();
map.values();
map.entrySet();
Multithreading & Concurrency
Creating Threads
// Method 1: Extending Thread
class MyThread extends Thread {
public void run() { /* task */ }
}
// Method 2: Implementing Runnable
class MyRunnable implements Runnable {
public void run() { /* task */ }
}
Thread t = new Thread(new MyRunnable());
// Method 3: Lambda (Java 8+)
Thread t = new Thread(() -> { /* task */ });
Thread States
- NEW: Created but not started
- RUNNABLE: Executing or ready to execute
- BLOCKED: Waiting for monitor lock
- WAITING: Waiting indefinitely
- TIMED_WAITING: Waiting for specified time
- TERMINATED: Completed execution
Synchronization
// Synchronized method
public synchronized void method() { /* thread-safe */ }
// Synchronized block
synchronized(this) { /* critical section */ }
// ReentrantLock
ReentrantLock lock = new ReentrantLock();
lock.lock();
try { /* critical section */ }
finally { lock.unlock(); }
Concurrent Collections
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
BlockingQueue<String> queue = new LinkedBlockingQueue<>();
ExecutorService
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> { /* task */ });
executor.shutdown();
// Other executors
Executors.newSingleThreadExecutor();
Executors.newCachedThreadPool();
Executors.newScheduledThreadPool(5);
Exception Handling
Hierarchy
Throwable
├── Error (Don't catch)
└── Exception
├── RuntimeException (Unchecked)
│ ├── NullPointerException
│ ├── ArrayIndexOutOfBoundsException
│ └── IllegalArgumentException
└── IOException (Checked)
└── FileNotFoundException
Try-Catch-Finally
try {
// Risky code
} catch (IOException e) {
// Handle specific exception
} catch (Exception e) {
// Handle general exception
} finally {
// Always executes (cleanup)
}
Try-with-Resources
try (FileReader fr = new FileReader("file.txt")) {
// Use resource
} catch (IOException e) {
// Handle exception
} // Auto-closes resource
Custom Exceptions
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
Java 8+ Features
Lambda Expressions
// Before Java 8
Comparator<String> comp = new Comparator<String>() {
public int compare(String s1, String s2) {
return s1.compareTo(s2);
}
};
// Java 8+
Comparator<String> comp = (s1, s2) -> s1.compareTo(s2);
Stream API
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
// Filter, map, reduce
int sum = numbers.stream()
.filter(n -> n % 2 == 0)
.map(n -> n * 2)
.reduce(0, Integer::sum);
// Collectors
List<String> filtered = list.stream()
.filter(s -> s.startsWith("A"))
.collect(Collectors.toList());
Map<Integer, List<String>> grouped = list.stream()
.collect(Collectors.groupingBy(String::length));
Optional
Optional<String> optional = Optional.ofNullable(getString());
optional.ifPresent(System.out::println);
String value = optional.orElse("default");
String value2 = optional.orElseThrow(() -> new Exception());
Functional Interfaces
// Predicate<T> - test()
Predicate<Integer> isEven = n -> n % 2 == 0;
// Function<T,R> - apply()
Function<String, Integer> strLength = String::length;
// Consumer<T> - accept()
Consumer<String> printer = System.out::println;
// Supplier<T> - get()
Supplier<Double> random = Math::random;
Default & Static Methods in Interfaces
interface MyInterface {
default void defaultMethod() { /* implementation */ }
static void staticMethod() { /* implementation */ }
}
Spring Framework
Core Concepts
- IoC (Inversion of Control): Container manages object lifecycle
- DI (Dependency Injection): Dependencies provided by container
Annotations
@Component // Generic component
@Service // Service layer
@Repository // Data access layer
@Controller // Web controller
@RestController // @Controller + @ResponseBody
@Autowired // Dependency injection
@Qualifier("beanName") // Specify which bean
@Primary // Default bean when multiple exist
@Configuration // Java config class
@Bean // Method produces a bean
@Value("${property}") // Inject property value
Spring Boot
@SpringBootApplication // @Configuration + @EnableAutoConfiguration + @ComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
REST Controller
@RestController
@RequestMapping("/api/users")
public class UserController {
@GetMapping("/{id}")
public User getUser(@PathVariable Long id) { }
@PostMapping
public User createUser(@RequestBody User user) { }
@PutMapping("/{id}")
public User updateUser(@PathVariable Long id, @RequestBody User user) { }
@DeleteMapping("/{id}")
public void deleteUser(@PathVariable Long id) { }
}
Request Mappings
@GetMapping- GET requests@PostMapping- POST requests@PutMapping- PUT requests@DeleteMapping- DELETE requests@PatchMapping- PATCH requests
Parameter Annotations
@PathVariable- URL path variables@RequestParam- Query parameters@RequestBody- Request body@RequestHeader- HTTP headers
Database & JPA
JPA Annotations
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
private List<Order> orders;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "department_id")
private Department department;
}
Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Custom queries
Optional<User> findByEmail(String email);
List<User> findByAgeGreaterThan(int age);
@Query("SELECT u FROM User u WHERE u.name = ?1")
User findByNameCustom(String name);
@Modifying
@Query("UPDATE User u SET u.active = false WHERE u.id = :id")
void deactivateUser(@Param("id") Long id);
}
Transaction Management
@Service
@Transactional
public class UserService {
@Transactional(readOnly = true)
public User getUser(Long id) { }
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void createUser(User user) { }
}
Fetch Types
EAGER: Load immediatelyLAZY: Load when accessed
Cascade Types
PERSIST: Save child when parent savedMERGE: Update child when parent updatedREMOVE: Delete child when parent deletedREFRESH: Refresh child when parent refreshedALL: All of the above
REST APIs
HTTP Methods
- GET: Retrieve data
- POST: Create new resource
- PUT: Update entire resource
- PATCH: Partial update
- DELETE: Remove resource
Status Codes
- 2xx Success: 200 OK, 201 Created, 204 No Content
- 3xx Redirection: 301 Moved Permanently, 302 Found
- 4xx Client Error: 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
- 5xx Server Error: 500 Internal Server Error, 503 Service Unavailable
REST Best Practices
// Resource naming (nouns, plural)
GET /api/users // Get all users
GET /api/users/{id} // Get specific user
POST /api/users // Create user
PUT /api/users/{id} // Update user
DELETE /api/users/{id} // Delete user
// Filtering, sorting, pagination
GET /api/users?age=25&sort=name&page=2&size=10
Global Exception Handling
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleNotFound(ResourceNotFoundException e) {
return ResponseEntity.status(HttpStatus.NOT_FOUND)
.body(new ErrorResponse(e.getMessage()));
}
}
Design Patterns
Singleton
public class Singleton {
private static volatile Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
Factory
public interface Shape { void draw(); }
public class ShapeFactory {
public Shape getShape(String type) {
switch(type) {
case "CIRCLE": return new Circle();
case "SQUARE": return new Square();
default: return null;
}
}
}
Builder
public class User {
private String name;
private int age;
private User(Builder builder) {
this.name = builder.name;
this.age = builder.age;
}
public static class Builder {
private String name;
private int age;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public User build() {
return new User(this);
}
}
}
// Usage: User user = new User.Builder().name("John").age(25).build();
Observer
public interface Observer {
void update(String message);
}
public class Subject {
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void notifyObservers(String message) {
observers.forEach(o -> o.update(message));
}
}
Best Practices
SOLID Principles
- Single Responsibility: Class should have one reason to change
- Open/Closed: Open for extension, closed for modification
- Liskov Substitution: Subtypes must be substitutable for base types
- Interface Segregation: Many specific interfaces better than one general
- Dependency Inversion: Depend on abstractions, not concretions
Code Quality
- Use meaningful variable/method names
- Keep methods small (< 20 lines)
- Avoid deep nesting (max 3 levels)
- Handle null checks appropriately
- Use enums instead of constants
- Prefer composition over inheritance
- Write unit tests (aim for 80%+ coverage)
Performance Tips
- Use StringBuilder for string concatenation in loops
- Prefer ArrayList over LinkedList for random access
- Use primitive types when possible
- Cache expensive computations
- Use lazy initialization where appropriate
- Close resources properly (try-with-resources)
- Avoid creating unnecessary objects
Security
- Never store passwords as plain text
- Validate all inputs
- Use parameterized queries (prevent SQL injection)
- Implement proper authentication/authorization
- Keep dependencies updated
- Follow OWASP guidelines
Key Concepts & Comparisons
Core Language Comparisons
| Concept | Comparison | Key Differences | Use Cases |
|---|---|---|---|
| == vs equals() | Reference vs Content | == compares memory addresses, equals() compares values |
Use equals() for content comparison |
| String vs StringBuilder | Immutable vs Mutable | String creates new objects, StringBuilder modifies existing | Use StringBuilder in loops |
| ArrayList vs LinkedList | Array vs Linked | ArrayList O(1) access, LinkedList O(1) insert/delete | ArrayList for reads, LinkedList for modifications |
| HashMap vs TreeMap | Hash vs Tree | HashMap O(1) avg, TreeMap O(log n) but sorted | HashMap for performance, TreeMap for ordering |
| HashSet vs TreeSet | Hash vs Tree | HashSet O(1) avg, TreeSet O(log n) but sorted | HashSet for performance, TreeSet for ordering |
| Checked vs Unchecked | Compile vs Runtime | Checked must be handled, Unchecked are optional | Use checked for recoverable errors |
Collection Performance Comparison
| Collection | Access | Search | Insert | Delete | Ordered | Thread-Safe |
|---|---|---|---|---|---|---|
| ArrayList | O(1) | O(n) | O(n) | O(n) | Yes | No |
| LinkedList | O(n) | O(n) | O(1) | O(1) | Yes | No |
| Vector | O(1) | O(n) | O(n) | O(n) | Yes | Yes |
| HashMap | N/A | O(1) avg | O(1) avg | O(1) avg | No | No |
| TreeMap | N/A | O(log n) | O(log n) | O(log n) | Yes | No |
| HashSet | N/A | O(1) avg | O(1) avg | O(1) avg | No | No |
| TreeSet | N/A | O(log n) | O(log n) | O(log n) | Yes | No |
| ConcurrentHashMap | N/A | O(1) avg | O(1) avg | O(1) avg | No | Yes |
Thread Safety Comparison
| Class | Thread Safe | Alternative | Use Case |
|---|---|---|---|
| ArrayList | No | Vector, Collections.synchronizedList() |
Single-threaded access |
| HashMap | No | ConcurrentHashMap, Hashtable |
Concurrent read/write operations |
| StringBuilder | No | StringBuffer |
String building in multi-threaded env |
| SimpleDateFormat | No | DateTimeFormatter (Java 8+) |
Date formatting |
Memory Management & GC
| Generation | Purpose | Collections | Algorithms |
|---|---|---|---|
| Young Generation | New objects | Minor GC | Copy, G1 Young |
| Eden Space | Object creation | Minor GC | Objects die young |
| Survivor Spaces | Objects surviving first GC | Minor GC | S0, S1 promotion |
| Old Generation | Long-lived objects | Major GC | Mark-Sweep-Compact |
| Metaspace | Class metadata | Full GC | Replaces PermGen |
Exception Handling Strategy
| Exception Type | Examples | Handling Strategy | Best Practice |
|---|---|---|---|
| Checked | IOException, SQLException |
Must catch or declare | Use for recoverable errors |
| Unchecked | NullPointerException, IllegalArgumentException |
Optional handling | Use for programming errors |
| Error | OutOfMemoryError, StackOverflowError |
Don't catch | JVM issues, let application fail |
| Custom | Business logic exceptions | Extend Exception/RuntimeException | Create meaningful exception hierarchies |
Spring Framework Concepts
| Component | Purpose | Annotation | Scope |
|---|---|---|---|
| Component | Generic spring component | @Component |
Singleton (default) |
| Service | Business logic layer | @Service |
Singleton |
| Repository | Data access layer | @Repository |
Singleton |
| Controller | Web layer | @Controller |
Singleton |
| Configuration | Java configuration | @Configuration |
Singleton |
Bean Scopes Comparison
| Scope | Description | Use Case | Lifecycle |
|---|---|---|---|
| Singleton | One instance per container | Stateless services | Application lifetime |
| Prototype | New instance each time | Stateful objects | Until garbage collected |
| Request | One per HTTP request | Web request data | HTTP request lifetime |
| Session | One per HTTP session | User session data | HTTP session lifetime |
| Application | One per ServletContext | Application-wide data | Web application lifetime |
JPA/Hibernate Concepts
| Fetch Type | Loading Strategy | Performance | Use Case |
|---|---|---|---|
| EAGER | Immediate loading | Higher memory usage | Small, frequently accessed data |
| LAZY | On-demand loading | Lower memory usage | Large collections, optional data |
| Cascade Type | Operations | Risk Level | Use Case |
|---|---|---|---|
| PERSIST | Save operations | Low | Parent-child creation |
| MERGE | Update operations | Low | Detached entity updates |
| REMOVE | Delete operations | High | Dependent entity cleanup |
| ALL | All operations | Very High | Complete lifecycle management |
REST API Best Practices
| HTTP Method | Purpose | Idempotent | Safe | Response Code |
|---|---|---|---|---|
| GET | Retrieve resource | Yes | Yes | 200 OK |
| POST | Create resource | No | No | 201 Created |
| PUT | Update/Replace resource | Yes | No | 200 OK, 204 No Content |
| PATCH | Partial update | No | No | 200 OK, 204 No Content |
| DELETE | Remove resource | Yes | No | 200 OK, 204 No Content |
Common Design Patterns
| Pattern | Type | Use Case | Implementation |
|---|---|---|---|
| Singleton | Creational | One instance needed | Double-checked locking |
| Factory | Creational | Object creation logic | Switch-based creation |
| Builder | Creational | Complex object construction | Fluent interface |
| Observer | Behavioral | Event notification | Subject-Observer relationship |
| Strategy | Behavioral | Algorithm selection | Interface-based implementations |
| Decorator | Structural | Add behavior dynamically | Wrapper pattern |
Lambda & Stream Operations
| Operation | Type | Example | Use Case |
|---|---|---|---|
| filter() | Intermediate | stream.filter(x -> x > 5) |
Conditional filtering |
| map() | Intermediate | stream.map(String::toUpperCase) |
Transform elements |
| reduce() | Terminal | stream.reduce(0, Integer::sum) |
Aggregate to single value |
| collect() | Terminal | stream.collect(Collectors.toList()) |
Collect to collection |
| forEach() | Terminal | stream.forEach(System.out::println) |
Execute action on each |
| anyMatch() | Terminal | stream.anyMatch(x -> x > 10) |
Test if any match |
Performance Optimization Tips
| Issue | Solution | Implementation | Impact |
|---|---|---|---|
| String Concatenation | Use StringBuilder | StringBuilder sb = new StringBuilder() |
Avoid O(n²) complexity |
| Autoboxing | Use primitives | int instead of Integer |
Reduce object creation |
| Large Collections | Use appropriate size | new ArrayList<>(expectedSize) |
Avoid resizing overhead |
| Database N+1 | Use JOIN FETCH | @Query("SELECT p FROM Post p JOIN FETCH p.comments") |
Reduce query count |
| Lazy Loading | Initialize in transaction | Use @Transactional or Open Session in View |
Avoid LazyInitializationException |
Security Best Practices
| Vulnerability | Prevention | Implementation | Example |
|---|---|---|---|
| SQL Injection | Parameterized queries | Use @Query with parameters |
@Query("SELECT u FROM User u WHERE u.id = :id") |
| XSS | Input validation/escaping | Use validation annotations | @NotBlank, @Email |
| CSRF | CSRF tokens | Spring Security default | Enable CSRF protection |
| Sensitive Data | Encryption/Hashing | BCrypt for passwords | BCryptPasswordEncoder |
| Authorization | Role-based access | Spring Security | @PreAuthorize("hasRole('ADMIN')") |
Common Coding Solutions
// String reversal
public String reverse(String str) {
return new StringBuilder(str).reverse().toString();
}
// Palindrome check
public boolean isPalindrome(String str) {
String cleaned = str.replaceAll("[^a-zA-Z0-9]", "").toLowerCase();
return cleaned.equals(new StringBuilder(cleaned).reverse().toString());
}
// Find duplicates in array
public Set<Integer> findDuplicates(int[] nums) {
Set<Integer> seen = new HashSet<>();
Set<Integer> duplicates = new HashSet<>();
for (int num : nums) {
if (!seen.add(num)) {
duplicates.add(num);
}
}
return duplicates;
}
// Two sum problem
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if (map.containsKey(complement)) {
return new int[]{map.get(complement), i};
}
map.put(nums[i], i);
}
return new int[0];
}
// Binary search
public int binarySearch(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
Database & ACID Properties
| Property | Description | Example | Failure Impact |
|---|---|---|---|
| Atomicity | All or nothing | Bank transfer: debit AND credit | Partial transaction completion |
| Consistency | Valid state to valid state | Foreign key constraints | Data integrity violations |
| Isolation | Concurrent transactions don't interfere | Transaction isolation levels | Dirty reads, phantom reads |
| Durability | Committed changes persist | Write to disk | Data loss on system failure |
SQL vs NoSQL Decision Matrix
| Factor | SQL (RDBMS) | NoSQL | Decision Criteria |
|---|---|---|---|
| Schema | Fixed, normalized | Flexible, denormalized | Stable vs evolving requirements |
| Scalability | Vertical (limited) | Horizontal (unlimited) | Scale requirements |
| Transactions | ACID compliant | Eventually consistent | Consistency requirements |
| Complexity | Complex queries (JOINs) | Simple operations | Query complexity |
| Use Cases | Financial, CRM | Social media, IoT | Data nature and access patterns |
Quick Reference & Best Practices
Essential Java 8+ Features
| Feature | Syntax | Example | Use Case |
|---|---|---|---|
| Lambda | (params) -> expression |
list.forEach(x -> System.out.println(x)) |
Functional programming |
| Method Reference | Class::method |
list.stream().map(String::toUpperCase) |
Cleaner lambda syntax |
| Optional | Optional<T> |
Optional.ofNullable(value).orElse(default) |
Null safety |
| Stream | stream() |
list.stream().filter().map().collect() |
Data processing pipelines |
| Default Methods | default returnType method() |
Interface evolution | Backward compatibility |
Performance & Memory Optimization
| Optimization | Problem | Solution | Impact |
|---|---|---|---|
| String Concatenation | Creating many String objects | Use StringBuilder or String.join() |
Avoid O(n²) complexity |
| Autoboxing | Unnecessary object creation | Use primitive types when possible | Reduce GC pressure |
| Collection Sizing | Dynamic resizing overhead | Initialize with expected capacity | Reduce array copying |
| Object Pooling | Expensive object creation | Reuse expensive objects | Reduce allocation overhead |
| Lazy Initialization | Unnecessary object creation | Create objects when needed | Save memory and startup time |
Thread Safety Quick Reference
| Class/Interface | Thread Safe | Alternative | Use Case |
|---|---|---|---|
ArrayList |
❌ | Vector, Collections.synchronizedList() |
List operations |
HashMap |
❌ | ConcurrentHashMap, Hashtable |
Map operations |
StringBuilder |
❌ | StringBuffer |
String building |
SimpleDateFormat |
❌ | DateTimeFormatter |
Date formatting |
Random |
⚠️ | ThreadLocalRandom |
Random number generation |
Common Annotations Reference
| Annotation | Package | Purpose | Example |
|---|---|---|---|
@Override |
java.lang | Method overriding | @Override public String toString() |
@Deprecated |
java.lang | Mark as deprecated | @Deprecated public void oldMethod() |
@SuppressWarnings |
java.lang | Suppress compiler warnings | @SuppressWarnings("unchecked") |
@FunctionalInterface |
java.lang | Mark functional interface | @FunctionalInterface interface MyInterface |
@Autowired |
Spring | Dependency injection | @Autowired private UserService userService |
@Component |
Spring | Spring component | @Component public class MyComponent |
Exception Handling Best Practices
// ✅ Good: Specific exception handling
try {
// risky operation
} catch (SQLException e) {
// handle database errors
log.error("Database error: {}", e.getMessage());
throw new ServiceException("Unable to process request", e);
} catch (IOException e) {
// handle I/O errors
log.error("I/O error: {}", e.getMessage());
throw new ServiceException("File processing failed", e);
}
// ❌ Avoid: Catching generic Exception
try {
// risky operation
} catch (Exception e) {
// Too broad, might hide bugs
}
SOLID Principles in Practice
| Principle | Violation | Solution |
|---|---|---|
| Single Responsibility | Class handles user data AND email sending | Separate User and EmailService classes |
| Open/Closed | Modifying existing code for new features | Use interfaces and polymorphism |
| Liskov Substitution | Subclass changes expected behavior | Ensure subclass can replace superclass |
| Interface Segregation | Large interface with unused methods | Create smaller, focused interfaces |
| Dependency Inversion | Depending on concrete classes | Depend on abstractions/interfaces |
Time Complexity Reference
| Data Structure | Access | Search | Insertion | Deletion |
|---|---|---|---|---|
| Array | O(1) | O(n) | O(n) | O(n) |
| ArrayList | O(1) | O(n) | O(n) amortized | O(n) |
| LinkedList | O(n) | O(n) | O(1) | O(1) |
| HashMap | N/A | O(1) avg, O(n) worst | O(1) avg, O(n) worst | O(1) avg, O(n) worst |
| TreeMap | N/A | O(log n) | O(log n) | O(log n) |
| HashSet | N/A | O(1) avg, O(n) worst | O(1) avg, O(n) worst | O(1) avg, O(n) worst |
| TreeSet | N/A | O(log n) | O(log n) | O(log n) |
JVM Memory Areas
| Area | Purpose | Contents | GC Target |
|---|---|---|---|
| Heap | Object storage | Objects, arrays | Major/Minor GC |
| Stack | Method execution | Local variables, method calls | Automatic (scope-based) |
| Method Area | Class information | Class metadata, constants | Full GC |
| PC Registers | Execution tracking | Current instruction pointer | Not applicable |
| Native Method Stack | Native calls | Native method execution | Not applicable |
Spring Boot Configuration
# Database Configuration
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=user
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
# Server Configuration
server.port=8080
server.servlet.context-path=/api
# Logging Configuration
logging.level.com.example=DEBUG
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
Common Interview Code Solutions
// Fibonacci sequence
public int fibonacci(int n) {
if (n <= 1) return n;
int a = 0, b = 1;
for (int i = 2; i <= n; i++) {
int temp = a + b;
a = b;
b = temp;
}
return b;
}
// Merge two sorted arrays
public int[] merge(int[] arr1, int[] arr2) {
int[] result = new int[arr1.length + arr2.length];
int i = 0, j = 0, k = 0;
while (i < arr1.length && j < arr2.length) {
result[k++] = arr1[i] <= arr2[j] ? arr1[i++] : arr2[j++];
}
while (i < arr1.length) result[k++] = arr1[i++];
while (j < arr2.length) result[k++] = arr2[j++];
return result;
}
// Check if string contains unique characters
public boolean hasUniqueChars(String str) {
if (str.length() > 128) return false; // ASCII assumption
boolean[] chars = new boolean[128];
for (char c : str.toCharArray()) {
if (chars[c]) return false;
chars[c] = true;
}
return true;
}
Production Best Practices
✅ Development Best Practices
- Use dependency injection for loose coupling
- Write unit tests with high coverage (>80%)
- Implement proper logging with appropriate levels
- Use configuration files for environment-specific settings
- Handle exceptions gracefully with meaningful messages
- Follow naming conventions and code style guidelines
✅ Performance Best Practices
- Use connection pooling for database connections
- Implement caching for frequently accessed data
- Use lazy loading for expensive operations
- Profile application to identify bottlenecks
- Optimize database queries and indexes
- Use appropriate data structures for the use case
✅ Security Best Practices
- Never store passwords in plain text
- Use parameterized queries to prevent SQL injection
- Validate and sanitize all user inputs
- Implement proper authentication and authorization
- Use HTTPS for all communications
- Keep dependencies updated to latest secure versions
Testing Strategy
| Test Type | Scope | Tools | Purpose |
|---|---|---|---|
| Unit Tests | Individual methods/classes | JUnit, Mockito | Test business logic |
| Integration Tests | Component interaction | TestContainers, @SpringBootTest | Test component integration |
| Contract Tests | API contracts | Pact, Spring Cloud Contract | Verify API compatibility |
| End-to-End Tests | Full application flow | Selenium, REST Assured | Test user scenarios |
Common JVM Tuning Parameters
# Memory settings
-Xms2g # Initial heap size
-Xmx4g # Maximum heap size
-XX:MetaspaceSize=256m # Initial metaspace size
# Garbage Collection
-XX:+UseG1GC # Use G1 garbage collector
-XX:MaxGCPauseMillis=100 # Target max GC pause time
# Monitoring
-XX:+PrintGCDetails # Print GC information
-XX:+HeapDumpOnOutOfMemoryError # Dump heap on OOM
Debugging & Monitoring Tools
| Tool | Purpose | Usage | Best For |
|---|---|---|---|
| JConsole | JVM monitoring | Built-in JDK tool | Basic monitoring |
| VisualVM | Profiling | Free profiler | Memory/CPU analysis |
| JProfiler | Advanced profiling | Commercial tool | Deep performance analysis |
| Micrometer | Metrics collection | Spring Boot integration | Production monitoring |
| SLF4J + Logback | Logging | Standard logging facade | Application logging |
Memory Management Tips
// ✅ Proper resource management
try (FileInputStream fis = new FileInputStream("file.txt")) {
// Use resource
} catch (IOException e) {
// Handle exception
} // Resource automatically closed
// ✅ Avoid memory leaks
// Clear collections when done
largeList.clear();
largeList = null;
// ✅ Use appropriate collection sizes
List<String> list = new ArrayList<>(expectedSize);
Map<String, String> map = new HashMap<>(expectedSize);