📂
Interview Prep
LLD Questions
LLD Questions
  • LLD Introduction
  • Meeting Scheduler
  • Distributed Cache System
  • Rate limiter
  • Multi-Tier Elevator System
  • MyGate System
  • Uber Sytem LLD
  • Parking Lot System
  • Online book store
  • Library Management System
  • Movie Ticket Booking System
  • Hotel Management System
  • File Storage System
    • Solution 2
  • Chat Application
  • Social Media Platform
  • Notification System
  • Airline Reservation System
  • ATM System
  • E-commerce Website
  • Food Delivery System
  • Shopping Cart System
  • URL Shortener system
  • Chess Tournament System
  • Threading therory
  • OOP questions
Powered by GitBook
On this page
  • 1. Object-Oriented Programming (OOP) Concepts
  • 2. Why public static void main(String[] args) in Java?
  • 3. Access Modifiers in Java
  • 4. static and final Keywords
  • 5. Design Principles
  • 6. Design Patterns with Examples
  • 7. Conclusion

OOP questions

Below is a comprehensive, deep-dive answer covering several theoretical topics that are commonly discussed in technical interviews. This answer is structured into multiple sections covering core OOP concepts, the significance of the public static void main(String[] args) method in Java, access modifiers, the usage of the static and final keywords (with expected behavior and scenarios), design principles, and design patterns along with examples. Each section includes an explanation, advantages and disadvantages (pros and cons), and sample code where relevant.


1. Object-Oriented Programming (OOP) Concepts

Core Concepts

  1. Abstraction

    • Definition: Hiding complex implementation details and showing only the necessary features of an object.

    • Pros:

      • Simplifies design by focusing on high-level operations.

      • Enhances reusability by separating interface from implementation.

    • Cons:

      • Over-abstraction can lead to unnecessarily complex designs.

    • Example:

      // Abstract class demonstrating abstraction
      abstract class Shape {
          abstract double calculateArea();
      }
      
      class Circle extends Shape {
          private double radius;
          public Circle(double radius) { this.radius = radius; }
          @Override
          double calculateArea() { return Math.PI * radius * radius; }
      }
  2. Encapsulation

    • Definition: Bundling the data (attributes) and methods (functions) that operate on the data within one unit (a class), and restricting access from outside.

    • Pros:

      • Protects object state from unintended interference.

      • Improves maintainability and flexibility.

    • Cons:

      • Can lead to bloated classes if overused.

    • Example:

      class BankAccount {
          private double balance;
          public BankAccount(double balance) { this.balance = balance; }
          public void deposit(double amount) { if (amount > 0) balance += amount; }
          public double getBalance() { return balance; }
      }
  3. Inheritance

    • Definition: Mechanism for creating a new class using properties and behavior of an existing class.

    • Pros:

      • Promotes code reuse.

      • Facilitates polymorphism.

    • Cons:

      • Tight coupling between parent and child classes.

      • Can lead to fragile base class problems if not designed carefully.

    • Example:

      class Animal {
          void eat() { System.out.println("Animal eats"); }
      }
      class Dog extends Animal {
          void bark() { System.out.println("Dog barks"); }
      }
  4. Polymorphism

    • Definition: Ability of different objects to be accessed through the same interface, typically via method overriding or overloading.

    • Pros:

      • Enhances flexibility and interchangeability.

      • Simplifies code maintenance.

    • Cons:

      • Can be confusing if overused or misapplied.

    • Example:

      class Animal {
          void makeSound() { System.out.println("Some sound"); }
      }
      class Cat extends Animal {
          @Override
          void makeSound() { System.out.println("Meow"); }
      }
      class Dog extends Animal {
          @Override
          void makeSound() { System.out.println("Bark"); }
      }

2. Why public static void main(String[] args) in Java?

Explanation:

  • public: The method is accessible from anywhere. The JVM must access the main method from outside the class, so it must be public.

  • static: The method can be invoked without creating an instance of the class. The JVM calls main as the entry point, so it must be static to be callable without object instantiation.

  • void: The method does not return any value. The main method is not designed to return a value to the JVM.

  • String[] args: Accepts an array of strings as command‑line arguments, enabling external configuration or input at runtime.

Pros and Cons:

Pros:

  • Simplicity: Provides a clear entry point for Java applications.

  • Flexibility: Command‑line arguments enable external control of application behavior.

Cons:

  • Fixed Signature: Developers must adhere to the exact signature, which might be confusing to beginners.

  • Static Context: Cannot access instance variables directly, requiring careful design when using object-oriented techniques.


3. Access Modifiers in Java

Types and Their Usage:

  1. public: Accessible from any class.

  2. protected: Accessible within the same package or subclasses (even if they are in different packages).

  3. default (package-private): No explicit modifier; accessible only within the same package.

  4. private: Accessible only within the class in which it is declared.

Pros and Cons:

  • public: Pros: Easy access; Cons: Can lead to tight coupling and security issues.

  • protected: Pros: Supports inheritance; Cons: May unintentionally expose internals to subclasses.

  • default: Pros: Limits access to a package; Cons: May be too restrictive if multiple packages require access.

  • private: Pros: High encapsulation; Cons: Can require additional accessor methods for testing or interfacing.

Example:

class AccessExample {
    public int publicField = 1;
    protected int protectedField = 2;
    int defaultField = 3;  // package-private
    private int privateField = 4;
    
    public void show() {
        System.out.println("Public: " + publicField);
        System.out.println("Protected: " + protectedField);
        System.out.println("Default: " + defaultField);
        System.out.println("Private: " + privateField);
    }
}

4. static and final Keywords

static

  • Definition: The static keyword indicates that a member (variable, method, or block) belongs to the class rather than to any instance.

  • Usage Scenarios:

    • Static variables for class-level shared data.

    • Static methods that do not depend on instance state (e.g., utility methods).

  • Pros:

    • Memory efficiency: Only one copy per class.

    • Easy access: Can be accessed without creating an instance.

  • Cons:

    • Global state: Can lead to tightly coupled code if overused.

    • Harder to test: Static methods are difficult to override or mock.

Example:

class MathUtil {
    public static double square(double x) {
        return x * x;
    }
}

final

  • Definition: The final keyword can be used to mark variables, methods, or classes so that they cannot be modified, overridden, or extended.

  • Usage Scenarios:

    • Final variables: Constants that should not change.

    • Final methods: Methods that cannot be overridden by subclasses.

    • Final classes: Classes that cannot be subclassed.

  • Pros:

    • Enhances safety by preventing modifications.

    • Enables compiler optimizations.

  • Cons:

    • Restricts flexibility: Overriding and subclassing are disallowed, which may reduce extensibility.

Example:

final class Constants {
    public static final double PI = 3.14159;
}

class Base {
    public final void doSomething() {
        System.out.println("Cannot be overridden");
    }
}

class Derived extends Base {
    // Trying to override doSomething() here would cause a compile-time error.
}

5. Design Principles

Key Principles:

  1. SOLID Principles:

    • Single Responsibility: Each class should have one responsibility. Pros: Simplifies maintenance and testing. Cons: May increase the number of classes.

    • Open/Closed: Classes should be open for extension but closed for modification. Pros: Facilitates adding new functionality. Cons: Requires careful design upfront.

    • Liskov Substitution: Subtypes must be substitutable for their base types. Pros: Ensures interoperability and reliable polymorphism.

    • Interface Segregation: Prefer many specific interfaces over one general-purpose interface. Pros: Reduces unwanted dependencies.

    • Dependency Inversion: Depend on abstractions, not on concretions. Pros: Promotes loose coupling.

  2. DRY (Don't Repeat Yourself): Avoid duplication to reduce maintenance overhead.

  3. KISS (Keep It Simple, Stupid): Simpler solutions are easier to understand and maintain.


6. Design Patterns with Examples

Common Design Patterns and Their Use-Cases:

  1. Singleton Pattern: Ensures a class has only one instance and provides a global point of access. Example: AuthenticationService, PaymentService.

    • Pros: Controlled access; reduced memory footprint.

    • Cons: Can hinder testing (global state) and may lead to issues in multi-threaded contexts if not implemented correctly.

  2. Factory Pattern: Centralizes object creation, allowing for flexible instantiation. Example: TransactionFactory in a payment system.

    • Pros: Encapsulates creation logic; easy to extend.

    • Cons: Adds an extra layer of abstraction.

  3. Strategy Pattern: Defines a family of algorithms, encapsulates each one, and makes them interchangeable. Example: PaymentStrategy for processing different payment methods.

    • Pros: Flexible, promotes open/closed principle.

    • Cons: Can increase the number of classes.

  4. Observer Pattern: Allows a subject to notify a set of observers about state changes. Example: OrderObserver in an order tracking system.

    • Pros: Decouples subject and observers; dynamic subscription.

    • Cons: Can lead to unexpected behavior if observers are not managed correctly.

Example for Observer Pattern:

interface OrderObserver {
    void update(Order order, String message);
}

class EmailOrderObserver implements OrderObserver {
    @Override
    public void update(Order order, String message) {
        System.out.println("Email Notification: Order " + order.getOrderId() + " - " + message);
    }
}

class OrderManager {
    private static OrderManager instance;
    private List<OrderObserver> observers = new ArrayList<>();
    
    private OrderManager() { }
    
    public static synchronized OrderManager getInstance() {
        if (instance == null) {
            instance = new OrderManager();
        }
        return instance;
    }
    
    public void registerObserver(OrderObserver observer) {
        observers.add(observer);
    }
    
    private void notifyObservers(Order order, String message) {
        for (OrderObserver observer : observers) {
            observer.update(order, message);
        }
    }
    
    public Order checkout(User user) {
        // Simulate checkout converting cart to order...
        Order order = new Order(UUID.randomUUID().toString(), user.getUserId(), new ArrayList<>(user.getCart().getItems()), user.getCart().getTotalAmount());
        user.addOrder(order);
        user.getCart().clear();
        notifyObservers(order, "Order placed successfully");
        return order;
    }
}

7. Conclusion

In summary:

  • OOP Concepts (Abstraction, Encapsulation, Inheritance, Polymorphism) form the foundation for designing modular and reusable software, each with its own trade-offs.

  • The public static void main signature in Java provides a standardized entry point, ensuring that the JVM can invoke the method without instantiating the class.

  • Access Modifiers control the visibility of classes and members, balancing encapsulation with accessibility.

  • Static and final keywords are used to define class-level members and immutable entities, respectively, with implications for memory usage and code flexibility.

  • Design Principles such as SOLID, DRY, and KISS guide developers to create robust, maintainable systems.

  • Design Patterns like Singleton, Factory, Strategy, and Observer provide proven solutions to common design problems, each with benefits and drawbacks that must be weighed based on context.

This deep-dive answer should provide a solid foundation for understanding these concepts and be a robust discussion point in any technical interview.

Sources:

PreviousThreading therory

Last updated 2 months ago

Sources: cite

Sources: cite

Sources: cite

Sources: cite

Sources: cite

Oracle Java Concurrency Tutorial: cite

Baeldung on Java Access Modifiers and Final: cite

SOLID Principles on Wikipedia: cite

Design Patterns examples: cite

https://docs.oracle.com/javase/tutorial/java/concepts/
https://www.oracle.com/technical-resources/articles/java/javamainmethod.html
https://www.baeldung.com/java-access-modifiers
https://www.baeldung.com/java-final
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
https://docs.oracle.com/javase/tutorial/essential/concurrency/
https://www.baeldung.com/java-final
https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)
https://refactoring.guru/design-patterns