- Variable Naming
- Method Naming
- Magic Numbers
- Code Formatting
- Avoiding Redundant Code
- Using StringBuilder for Concatenation in Loops
- Proper Resource Management (Avoiding Resource Leaks)
- Avoid Catching Generic Exceptions
- Use Enum Instead of Constant Strings
- Using Streams Instead of Loops for Filtering
- Avoid Using Raw Types (Generics)
- Prefer Interfaces Over Concrete Classes for Type References
- Best Practices accepted by community
- Java Naming Conventions
- Avoid Overusing Static Methods
- Use Optional to Avoid Null Checks
- Close Streams Properly
- Favor Immutable Objects
- Use @Override Annotation
- Use Logging Instead of System.out.println
- Use Meaningful Constants
- Interview Questions
int a = 10; int b = 20; int c = a + b;
int numApples = 10; int numOranges = 20; int totalFruits = numApples + numOranges;
The Good approach uses descriptive variable names that clearly convey their purpose, making the code easier to understand and maintain.
public int f(int x, int y) { return x * y; }
public int multiply(int firstNumber, int secondNumber) { return firstNumber * secondNumber; }
The Good example uses a descriptive method name (multiply) and meaningful parameter names, improving readability.
double finalAmount = 1000 * 0.08;
final double TAX_RATE = 0.08; double initialAmount = 1000; double finalAmount = initialAmount * TAX_RATE;
The Good example avoids “magic numbers” by using a constant (TAX_RATE), making the code self-explanatory and easier to modify.
public class Example {public void sayHello(){System.out.println("Hello!");}}
public class Example { public void sayHello() { System.out.println("Hello!"); } }
Proper indentation and spacing improve readability and maintainability.
if (userAge >= 18) { return true; } else { return false; }
return userAge >= 18;
The Good example simplifies the logic without unnecessary conditionals.
String result = ""; for (int i = 0; i < 10; i++) { result += i; }
StringBuilder result = new StringBuilder(); for (int i = 0; i < 10; i++) { result.append(i); }
Using StringBuilder is more efficient than repeatedly concatenating strings, as it avoids creating multiple immutable String objects.
FileReader reader = new FileReader("file.txt"); BufferedReader br = new BufferedReader(reader); System.out.println(br.readLine()); br.close(); reader.close();
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) { System.out.println(br.readLine()); } catch (IOException e) { e.printStackTrace(); }
Using Try-with-resources automatically closes resources, preventing memory leaks.
try { int result = 10 / 0; } catch (Exception e) { System.out.println("Error occurred."); }
try { int result = 10 / 0; } catch (ArithmeticException e) { System.out.println("Cannot divide by zero."); }
Use Catch specific exceptions to improve debugging and error handling.
public static final String STATUS_ACTIVE = "ACTIVE"; public static final String STATUS_INACTIVE = "INACTIVE";
public enum Status { ACTIVE, INACTIVE; }
Enums improve type safety, readability, and prevent invalid values.
List<String> names = Arrays.asList("Alice", "Bob", "Charlie"); List<String> filteredNames = new ArrayList<>(); for (String name : names) { if (name.startsWith("A")) { filteredNames.add(name); } }
List<String> filteredNames = names.stream() .filter(name -> name.startsWith("A")) .collect(Collectors.toList());
Streams are more concise and readable than traditional loops.
List list = new ArrayList(); list.add("Hello"); String s = (String) list.get(0); // Requires explicit casting
List<String> list = new ArrayList<>(); list.add("Hello"); String s = list.get(0); // No explicit casting needed
Using generics makes the code type-safe and eliminates unnecessary type casting.
ArrayList<String> names = new ArrayList<>();
List<String> names = new ArrayList<>();
Using interfaces (List instead of ArrayList) improves flexibility and allows for easier switching of implementations.
public class MathUtils { public static int add(int a, int b) { return a + b; } }
public class MathUtils { public int add(int a, int b) { return a + b; } }
Favor instance methods when they depend on object state or when you want to leverage polymorphism and mocking.
public String getUserName(User user) { if (user != null && user.getName() != null) { return user.getName(); } return "Unknown"; }
public String getUserName(User user) { return Optional.ofNullable(user) .map(User::getName) .orElse("Unknown"); }
Optional makes null-handling explicit and avoids potential NullPointerException.
FileInputStream fis = new FileInputStream("data.txt"); byte[] data = fis.readAllBytes(); fis.close();
try (FileInputStream fis = new FileInputStream("data.txt")) { byte[] data = fis.readAllBytes(); }
Always close streams in a try-with-resources block to avoid memory leaks.
public class User { private String name; public void setName(String name) { this.name = name; } }
public final class User { private final String name; public User(String name) { this.name = name; } public String getName() { return name; } }
Immutable objects are thread-safe, easier to reason about, and prevent unintended changes.
public class MyList extends ArrayList<String> { public boolean add(String s) { // No @Override return super.add(s); } }
public class MyList extends ArrayList<String> { @Override public boolean add(String s) { return super.add(s); } }
@Override helps catch errors when method signatures change.
System.out.println("Application started");
logger.info("Application started");
Logging frameworks give you levels (INFO, DEBUG, ERROR) and allow output redirection.
if (speed > 120) { /* ... */ }
private static final int SPEED_LIMIT = 120; if (speed > SPEED_LIMIT) { /* ... */ }
Constants improve readability and make code easier to update.
| Task | Standard Tools | 3rd Party Tools |
|---|---|---|
| API Documentation | Javadoc | Swagger, Postman collections |
| API Security | Spring Security, Java EE Security | Custom JWT/OAuth implementations |
| Build Tool | Maven, Gradle | Ant, Bazel |
| Database Access | JDBC, JPA, Hibernate | MyBatis, jOOQ |
| Dependency Injection | Spring Framework, Jakarta CDI | Google Guice |
| Logging | SLF4J + Logback, Java Util Logging (JUL) | Log4j |
| Testing | JUnit, TestNG, Mockito | Spock, Cucumber |
| Web Frameworks | Spring Boot, Java EE (Jakarta EE) | Play Framework, Micronaut |
| What | How | Good | Bad |
|---|---|---|---|
| Class Attributes | CamelCase, start with a lowercase letter | customerName, totalAmount |
Customer_name, TOTALAMOUNT |
| Classes | PascalCase | CustomerDetails, OrderProcessor |
customerDetails, order_processor |
| Constants | UPPER_SNAKE_CASE | MAX_RETRIES, DEFAULT_TIMEOUT |
MaxRetries, defaultTimeout |
| Enum Names | PascalCase | OrderStatus, UserType |
order_status, usertype |
| Exceptions | PascalCase with Exception suffix | InvalidInputException |
invalidinputexception |
| Interfaces | PascalCase, usually adjective-based | Runnable, Serializable |
runnable, serializable |
| Local Variables | camelCase | orderCount, userId |
Order_count, User_ID |
| Methods | camelCase | calculateTotal(), getUserId() |
Calculate_Total(), GetUserID() |
| Packages | lowercase, domain-based | com.example.service |
Com.Example.Service |
| Static Variables | camelCase | defaultConfig, appName |
DefaultConfig, APP_NAME |
| Test Classes | PascalCase with Test suffix | UserServiceTest, OrderTest |
userservicetest, ordertest |
- What are Java’s key features?
- Platform-Independent: Java runs on any OS with a JVM.
- Object-Oriented: Java supports OOP principles like inheritance and polymorphism.
- Multi-threaded: Java supports concurrent programming using threads.
- Garbage Collection: Automatic memory management via the Garbage Collector.
- What is the difference between
==and.equals()in Java?==checks if two references point to the same object in memory..equals()checks if two objects have the same value.
- What are Java’s primitive data types?
byte,short,int,long(integer types)float,double(floating-point types)char(character)boolean(true/false)
- What is the difference between an ArrayList and a LinkedList?
-
Feature ArrayList LinkedList Storage Dynamic array Doubly linked list Access Time Fast (O(1)) random access Slow (O(n)) sequential access Insert/Delete Slow (O(n)) Fast (O(1) at head/tail) Memory Usage Less (contiguous memory) More (extra pointers)
-
- What is the difference between
final,finally, andfinalize()?final: Used for constants, preventing method overriding or inheritance.finally: A block in a try-catch-finally statement that always executes.finalize(): A method called before an object is garbage collected.
- How does Java achieve memory management?
- Heap and Stack: Java uses a heap (for objects) and stack (for local variables).
- Garbage Collection: Java automatically removes unused objects.
- What is the difference between checked and unchecked exceptions?
- Checked Exception: Must be handled using try-catch or declared with throws.
- Example:
IOException,SQLException.
- Example:
- Unchecked Exception: Extends RuntimeException, doesn’t require handling.
- Example:
NullPointerException,ArrayIndexOutOfBoundsException.
- Example:
- Checked Exception: Must be handled using try-catch or declared with throws.
- What is the purpose of volatile in Java?
- The volatile keyword ensures that changes to a variable are visible to all threads immediately, preventing caching issues.
- What is the difference between synchronized and lock in Java?
synchronizedis a keyword that locks an object or method.- Lock (from
java.util.concurrent.locks) provides more flexibility, allowing try-lock and timed locking.
- What is the difference between String, StringBuilder, and StringBuffer?
-
Feature String(Immutable)StringBuilder(Mutable)StringBuffer(Thread-Safe)Thread Safety No No Yes Performance Slow Fast Slower than StringBuilder
-
- What is the Java Collections Framework?
- A set of classes and interfaces for working with data structures like lists, sets, and maps.
- List:
ArrayList,LinkedList - Set:
HashSet,TreeSet - Map:
HashMap,TreeMap
- List:
- A set of classes and interfaces for working with data structures like lists, sets, and maps.
- What is the
transientkeyword in Java?- The
transientkeyword prevents a field from being serialized.
- The
- What are Java 8 features?
- Lambda Expressions
- Streams API
- Functional Interfaces
- Optional Class