2023 Top Interview Questions About Design Patterns - IQCode

Introduction to Design Patterns

Overview
Design patterns are reusable templates for solving common problems that occur in software development. They address repetitive code, reusable patterns, redundant functions, and other issues to provide customizable blueprints for solving problems. This concept was first described by Christopher Alexander and picked up by popular authors Erich Gamma, John Vlissides, Ralph Johnson, and Richard Helm, known as the Gang of Four. They published their findings in Design Patterns: Elements of Reusable Object-Oriented Software in 1994, where they teach developers to solve commonly recurring problems without spending too much time and effort on them. Due to this, the demand for software developers who know these patterns has increased.

Design Patterns Interview Questions

For Freshers

1. What are design patterns?

Answer: Design patterns are reusable templates for solving recurring problems in software development. They offer a way to standardize software development practices to save time and provide a proven blueprint for creating software solutions.

2. What are the advantages of design patterns?

Answer: Design patterns provide numerous benefits, including:

- They offer a standard blueprint for solving recurring problems in software development. - They improve software development practices. - They help to create efficient and scalable software solutions. - They make software development easy to maintain and update. - They reduce development time and effort, which saves resources.

3. What are the types of design patterns?

Answer: Design patterns can be classified into three categories:

- Creational Patterns - Structural Patterns - Behavioral Patterns

4. What are Creational Design Patterns?

Answer: Creational design patterns deal with object creation, hiding the complexity that may be involved in creating objects. They involve class instantiation and use inheritance to vary the object classes that are instantiated. Examples of creational design patterns include Factory, Abstract Factory, Singleton, Builder, and Prototype.

5. What are Structural Design Patterns?

Answer: Structural design patterns focus on relationships between objects and make it easier for these objects to work together. They help to create a structure of objects and define how these objects interact in a program. Examples of structural design patterns include Adapter, Bridge, Composite, Decorator, Facade, Flyweight, and Proxy.

6. What are Behavioral Design Patterns?

Answer: Behavioral design patterns deal with communication between objects, providing strategies for communication and coordination between them. These patterns help create patterns for objects to communicate and work together in an organized manner. Examples of behavioral design patterns include Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.

7. What is the difference between Aggregation and Composition?

Answer: Aggregation is a weak relationship that represents the "has-a" relationship. In contrast, Composition is a strong relationship that represents the "part-of" relationship. Composition refers to a relationship where the parent object contains child objects, and the child objects cannot exist without the parent object. On the other hand, Aggregation refers to a relationship where the parent object contains child objects, but the child objects can exist without the parent object.

What are the Advantages of Using Java Design Patterns?

Java design patterns provide numerous benefits, including:

1. Reusability: Design patterns can be reused in multiple projects, making it easier and faster to develop new applications.

2. Maintainability: Since design patterns promote modularity and code organization, maintaining and modifying code becomes easier and less error-prone.

3. Flexibility: Patterns provide a flexible and extensible design, making it easier to add new features or modify existing ones in the future.

4. Scalability: Design patterns can help to manage complexity and extend the functionality of a system as it grows and evolves over time.

5. Guaranteed Solution: Using established and proven design patterns ensures the solution will be reliable, efficient, and consistent with software best practices.

Overall, using design patterns can improve the quality of code, reduce development time, and increase the effectiveness and usability of an application.

Description of a Design Pattern

A design pattern is a reusable solution that solves a commonly occurring problem in software design. It provides a way to describe a solution to a problem that can be adapted to different situations. A design pattern also encapsulates and decouples the solution from the implementation, making it easy to maintain and modify the code. Good design patterns are well documented and have been thoroughly tested and proven to be effective. They help developers write more efficient and maintainable code, resulting in higher quality software applications.

Types of Design Patterns in Java

Design patterns in Java are categorized into three main types:

1. Creational Patterns - These patterns focus on the process of object creation, providing better ways for creating objects.

2. Structural Patterns - These patterns focus on object composition, providing better ways to compose objects to form larger structures.

3. Behavioral Patterns - These patterns focus on communication between objects, providing better ways of communication between objects.

Examples of different patterns under each type are as follows: - Creational patterns: Singleton, Factory, Abstract Factory, Builder, Prototype. - Structural patterns: Adapter, Bridge, Decorator, Facade, Flyweight, Proxy. - Behavioral patterns: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor.

Code:

// Example of Singleton Pattern
public class Singleton {
   private static Singleton instance = null;
   private Singleton() {
      // private constructor
   }
   public static Singleton getInstance() {
      if(instance == null) {
         instance = new Singleton();
      }
      return instance;
   }
}

In the above code, we have implemented the Singleton pattern. The constructor is made private to prevent direct instantiation of the class from outside. The getInstance() method of the class is used to get the instance of the class. The instance is created only on the first call to getInstance() and subsequent calls return the same instance.

Understanding Inversion of Control

Inversion of Control (IoC) is a design pattern in object-oriented programming where the control of the program flow is inverted. Instead of a program calling and controlling the flow of a library, IoC allows a library to call and control the flow of a program.

In simpler terms, IoC means that a higher-level module depends on a lower-level module, and the flow of control is inverted from what it would otherwise be. This allows for better decoupling and easier testing of individual components.

IoC is often implemented using dependency injection, which is the process of injecting the required dependencies (objects) into a class rather than the class creating them itself. This helps components remain loosely coupled and easier to maintain.

Overall, Inversion of Control is a powerful design pattern that helps to improve the extensibility and maintainability of software systems, making IoC a crucial concept for developers to understand.

Gang of Four (GoF) in Design Patterns

The Gang of Four refers to the four authors of the book "Design Patterns: Elements of Reusable Object-Oriented Software". The book is considered one of the foundational works on software design patterns. The Gang of Four includes Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. They were all developers and researchers who worked together at the Xerox Palo Alto Research Center in the 1990s. The book introduces 23 design patterns that are commonly used in object-oriented software design. These patterns serve as standard solutions to common software design problems, allowing developers to write more efficient, maintainable, and reusable code.

What are the SOLID Principles?

The SOLID Principles are five design principles for object-oriented programming (OOP) that help to write code that is easier to understand, maintain and extend. The five principles are:

1. Single Responsibility Principle (SRP): a class should have only one reason to change. 2. Open/Closed Principle (OCP): a class should be open for extension but closed for modification. 3. Liskov Substitution Principle (LSP): derived classes should be substitutable for their base classes. 4. Interface Segregation Principle (ISP): a client should not be forced to depend on interfaces it does not use. 5. Dependency Inversion Principle (DIP): High-level modules should not depend on low-level modules. Both should depend on abstractions, and abstractions should not depend on details.

By following these principles, developers can create code that is more flexible, scalable, and easier to maintain over time.

Understanding the Open-Closed Principle (OCP)

The Open-Closed Principle (OCP) is a principle in object-oriented programming that states that software entities such as classes, modules, functions, etc., should be open for extension but closed for modification. It means that you should be able to extend the behavior of a software entity without modifying its source code. This principle helps to reduce the risk of introducing new bugs or affecting the existing functionality of a software system. Instead, you can create new classes that inherit from the original class and add new functionality to it. By keeping the original class intact, you ensure that it is stable and reliable, and you can still benefit from any changes or improvements made to it.

Design Patterns in Java's JDK Library

Java's JDK library includes various design patterns to facilitate the development process. Some of the design patterns used in Java's JDK library are:

1. Singleton Pattern - This pattern ensures that only one instance of a class is created and provides a global point of access to that instance.

2. Factory Method Pattern - This pattern provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created.

3. Adapter Pattern - This pattern allows classes with incompatible interfaces to work together by wrapping its own interface around that of an already existing class.

4. Observer Pattern - This pattern defines a one-to-many dependency between objects, so that when one object changes state, all its dependent objects are notified and updated automatically.

5. Iterator Pattern - This pattern provides a way to access the elements of a collection without exposing its underlying representation.

6. Decorator Pattern - This pattern allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.

7. Command Pattern - This pattern encapsulates a request as an object, thereby allowing for parameterization of clients with different requests, queue or log requests, and support for undoable operations.

8. Template Method Pattern - This pattern defines the skeleton of an algorithm in a method, deferring some steps to subclasses. Subclasses can then override some of the steps but the general structure of the algorithm is preserved.

Understanding the Difference between Design Principles and Design Patterns

Design principles refer to the fundamental concepts and guidelines that designers follow while creating a product or solution. They are more like a set of broad rules that guide designers to come up with a solution that is aesthetically pleasing, easy to use, and solve users' problems.

On the other hand, design patterns are specific solutions to recurring design problems. They are more like proven solutions that designers use to solve common design problems that they face in their projects. Design patterns are usually more concrete and specific when compared to design principles.

In summary, design principles guide the overall design process, whereas design patterns are specific solutions that designers use to solve recurring design problems. Understanding and implementing both of them is crucial to creating effective and efficient designs.

Difference between Design Patterns and Algorithms

Design patterns and algorithms are two different concepts in software engineering.

  • Design patterns are solutions to common problems in software design that have been tried and tested over time. They are reusable and provide a structured approach to solving a particular design problem.
  • Algorithms, on the other hand, are step-by-step procedures used to solve a specific problem or accomplish a particular task. They are designed to optimize performance and efficiency in the execution of a task.

In summary, while design patterns are more focused on design and architecture, algorithms are more focused on efficient execution of tasks. Both are important concepts to understand and utilize in software development.

Overview of Factory Design Pattern

The Factory Design Pattern is a creational design pattern that provides an interface for creating objects in a superclass, but allows subclasses to alter the type of objects that will be created. This pattern is used when a class cannot anticipate which class or subclass of objects it must create during runtime.

In simpler terms, the Factory Design Pattern provides a way to create an object without exposing the creation logic to the client and refers to the newly created object through a common interface.

For example, let's say that we have a superclass called "Animal." The Animal class has a factory method that delegates the responsibility of creating animals to its subclasses, such as "Dog" or "Cat." This allows the client to create animals without knowing the specific class details, like what type of animal it is or how it is created.

Code:


public abstract class Animal {
   public abstract String makeSound();
}

public class Dog extends Animal {
   @Override
   public String makeSound() {
      return "Woof";
   }
}

public class Cat extends Animal {
   @Override
   public String makeSound() {
      return "Meow";
   }
}

public class AnimalFactory {
   public static Animal createAnimal(String type) {
      if ("dog".equalsIgnoreCase(type)) {
         return new Dog();
      } else if ("cat".equalsIgnoreCase(type)) {
         return new Cat();
      } else {
         return null;
      }
   }
}

In the above example, the AnimalFactory class has a createAnimal method that returns an Animal object based on the type of animal requested. The AnimalFactory class provides a common interface for clients to create animals without exposing the creation logic to them. With this design, adding a new animal to the system is as simple as creating a new subclass of the Animal class and adding it to the AnimalFactory createAnimal method.

Adapter Design Pattern

The Adapter Design Pattern is a structural design pattern that allows incompatible interfaces to collaborate. It acts as a bridge between two incompatible interfaces by translating one interface into another expected by the clients. In other words, the adapter converts the interface of a class into another interface that the client expects to interact with. This pattern is used when the client is interested in one interface, but the available interface is different.

Proxy Design Pattern

The proxy design pattern is used in software engineering to provide a surrogate or placeholder object that acts as a representative of another object. The proxy controls access to the original object, allowing you to perform additional operations before or after the request gets passed on to the original object. This pattern is useful when you need to add functionality to an existing object without modifying its code.

Bridge Design Pattern

The Bridge Design Pattern is a structural pattern in software engineering that decouples an abstraction from its implementation. It accomplishes this by creating two separate class hierarchies, one for the abstraction and the other for the implementation, and establishing a bridge between them. This allows the two hierarchies to vary independently and enables flexibility and extensibility in the code. The Bridge pattern is often used in cases where changes in one part of the code are likely to affect other parts, providing a way to manage such changes in a more controlled and modular manner.

Instances where Abstract Classes are Preferred over Interfaces in Java

In Java, there are some situations where we prefer to use abstract classes instead of interfaces. One such situation is when we want to provide some default implementation of a method or a behavior. Abstract classes can have both abstract and non-abstract methods, which can be inherited by the subclass.

Another instance is when we want to use the "template method" design pattern, which involves defining a skeleton of an algorithm in an abstract class and leaving some of the steps to be implemented by the subclass.

We may also prefer abstract classes when we need to define common functionality for a group of related classes. In such cases, we can create an abstract base class containing the common code and have the related classes extend it.

Overall, the choice between using an interface or an abstract class depends on the specific requirements of the project and the design patterns being used.

Chain of Responsibility Pattern

The Chain of Responsibility Pattern is a behavioral pattern in software design where a request is passed down a chain of objects until it is handled by one of the objects in the chain. This pattern is used when there are multiple objects that can handle the same request.

The scenario where this pattern would apply is when there is a group of objects that can perform different types of work, but the specific object that will handle the work is unknown at the start. In this case, the request will be sent to the first object in the chain, which will determine if it can handle the request. If not, it will pass the request down the chain until it finds an object that can handle it.

This pattern allows for flexibility in the system design by allowing objects to be added or removed from the chain as needed without affecting the overall functionality of the system. It also promotes decoupling between objects by reducing the direct interaction between them.

Understanding the Decorator Design Pattern

The Decorator design pattern is a structural pattern that allows the modification of an object's behavior by adding functionality to it at runtime. This pattern involves creating a decorator class that wraps the original class and provides additional functionality while still maintaining the original class methods.

The decorator pattern is ideal when you have a class that has a lot of subclasses, and you want to add new functionality to some or all of them at runtime. It also provides a flexible alternative to subclassing for extending functionality.

Here's an example:

class Beverage { getDescription() {} cost() {} }

class Coffee extends Beverage { getDescription() { return "Coffee"; }

cost() { return 2.99; } }

class MilkDecorator extends Beverage { constructor(beverage) { super(); this.beverage = beverage; }

getDescription() { return this.beverage.getDescription() + " + Milk"; }

cost() { return this.beverage.cost() + 0.5; } }

let myCoffee = new Coffee(); let myCoffeeWithMilk = new MilkDecorator(myCoffee);

console.log(myCoffee.getDescription()); // Output: "Coffee" console.log(myCoffee.cost()); // Output: 2.99

console.log(myCoffeeWithMilk.getDescription()); // Output: "Coffee + Milk" console.log(myCoffeeWithMilk.cost()); // Output: 3.49

In this example, the Beverage class is the base component, while the Coffee class is the concrete component. The MilkDecorator class is the decorator that adds milk to the coffee (extends the Beverage object with additional functionality).

When we create a new instance of Coffee and call the getDescription() and cost() methods on it, it returns the name of the beverage ("Coffee") and its cost (2.99), respectively.

When we create a new instance of MilkDecorator and pass in our Coffee object, and call the getDescription() and cost() methods on it, it returns the name of the new beverage ("Coffee + Milk") and its cost (3.49), respectively.

This shows how we can dynamically add new functionality to a class without modifying its source code using the decorator pattern.

Command Pattern: Overview and Explanation

The Command Pattern is a design pattern in object-oriented programming that involves encapsulating a request as an object, thereby allowing you to parameterize clients with different requests. It enables decoupling of the requester of a particular action from the object that performs the action, allowing for greater flexibility and easier maintenance.

In essence, the Command Pattern is a behavioral pattern that defines an object that encapsulates all information necessary to perform a given action, including the method to call, the arguments to pass, and the object that will receive the request. This object is known as a command, and it can be stored, passed around, and invoked at any point in time.

The pattern typically involves several classes: the client, the invoker, the command, and the receiver. The client creates a command object and specifies its receiver. The invoker decides when to execute the command, and the receiver performs the actual work.

Using the Command Pattern can simplify the code by breaking down complex actions into smaller, discrete commands that can be managed and invoked independently. It also allows for greater flexibility, as new commands can be added and executed without modifying existing code.

Overall, the Command Pattern is a useful tool in any programmer's toolbox, providing a powerful way to encapsulate functionality and decouple code.

Observer Design Pattern

The observer design pattern is a behavioral design pattern that defines a one-to-many dependency between objects, so that when one object changes its state, all its dependents are notified and updated automatically. This pattern is commonly used in situations where an object needs to be aware of the changes occurring in several other objects, and must react to those changes in some way. It promotes loose coupling between objects, allowing for greater flexibility and extensibility in the design of a system.H3 tag: Understanding the Builder Pattern

The Builder Pattern aims to address the issue of creating objects that contain a large number of attributes, some of which may be optional. Instead of creating a constructor with an excessive number of parameters, the Builder Pattern allows us to construct objects step-by-step, providing a clean and flexible solution. This pattern is particularly useful when dealing with objects that have several ways of being constructed, or when there is a need for multiple configurations of the same object.

Designing a System for Market Data Classes with Flexibility to Switch Vendors or Direct Exchange Feed

To design a system for providing market data classes with the flexibility to switch vendors or direct exchange feed, I would approach the problem as follows:

1. Create a base class called "MarketData" that will contain all the common properties and methods for market data.

2. Create two subclasses, "VendorMarketData" and "DirectExchangeMarketData", that will inherit from the base class.

a. The "VendorMarketData" class will contain properties for the vendor name, vendor ID, and other vendor-specific data.

b. The "DirectExchangeMarketData" class will contain properties for the exchange name, exchange ID, and other exchange-specific data.

3. Define interfaces for each vendor or exchange feed that need to be supported by the system. Each interface will contain methods for receiving market data from the respective vendor or exchange feed.

4. Implement the vendor or exchange feed interfaces in the corresponding classes. This will allow the system to handle market data from different vendors or exchange feeds in a uniform manner, by calling the same methods regardless of the source of the data.

5. Use a factory method pattern to create instances of the "MarketData" subclasses based on user configuration. This will allow the system to switch between different vendors or exchange feeds at runtime, by changing the configuration without changing the code.

By following this approach, we can provide a flexible and extensible system for handling market data that can adapt to different vendors or exchange feeds as needed.

Understanding the Null Object Pattern

The Null Object Pattern is a design pattern that avoids null references by providing a "null" object that behaves like a real object but does nothing. This pattern is used to avoid null reference exceptions and simplifies code. It is particularly useful in cases where a method may return null, as it provides a default object to return instead. By implementing this pattern, you can avoid the need for null checks and increase the robustness of your code.

Overview of the MVC Design Pattern

The MVC (Model-View-Controller) design pattern is a software architecture that separates an application into three interconnected components:

  • Model: this component represents the data and business logic of the application. It interacts with the database and performs operations on data.
  • View: this component is responsible for displaying the data to the user. It receives input from the user and sends it to the controller.
  • Controller: this component acts as the intermediary between the model and the view. It receives input from the view, interacts with the model to retrieve or update data, and then updates the view with the new data.

By separating the application into these three components, it becomes easier to manage and update each component individually without affecting the others. This separation also allows for better code reuse and modular development. The MVC design pattern is widely used in web development frameworks like Ruby on Rails, Django, and AngularJS.

Components of the Composite Entity Pattern

The Composite Entity Pattern has three main components:

  1. Composite Entity: It's the primary component of the pattern and represents the entire composite object. It contains a collection of dependent objects known as the Coarse-Grained Objects.
  2. Coarse-Grained Object: It's the secondary component of this pattern and represents the dependent objects inside the composite entity. These objects can be related to each other and can form a hierarchy as well.
  3. Dependent Object: These are the final components of the pattern that represent the individual objects contained inside of the Coarse-Grained Object. They are the leaf nodes of the hierarchy.

// Example Implementation

class CompositeEntity {
   private CoarseGrainedObject cgo = new CoarseGrainedObject();
 
   public void setData(String data1, String data2){
      cgo.setData(data1, data2);
   }
 
   public String[] getData(){
      return cgo.getData();
   }
}
 
class CoarseGrainedObject {
   private DependentObject1 do1 = new DependentObject1();
   private DependentObject2 do2 = new DependentObject2();
 
   public void setData(String data1, String data2){
      do1.setData(data1);
      do2.setData(data2);
   }
 
   public String[] getData(){
      return new String[] {do1.getData(),do2.getData()};
   }
}
 
class DependentObject1 {
   private String data;
 
   public void setData(String data){
      this.data = data; 
   } 
 
   public String getData(){
      return data;
   }
}
 
class DependentObject2 {
   private String data;
 
   public void setData(String data){
      this.data = data; 
   } 
 
   public String getData(){
      return data;
   }
}

Above code snippet shows the implementation of the Composite Entity Pattern in Java.

Advantages of Prototype Design Pattern over Object Creation using 'new' keyword

The main advantage of using Prototype Design Pattern is that it allows us to create new objects by copying/cloning existing objects. This eliminates the need to recreate objects using the 'new' keyword, thereby reducing the overhead of object creation.

Additionally, the Prototype Design Pattern allows us to easily modify and customize existing objects as needed since we can simply clone the original object and make changes to the copy without affecting the original object. This provides greater flexibility and reusability in our code.

How to Implement Thread-Safe Singleton Patterns in Java?

In Java, we can achieve thread-safe singleton patterns using various methods. One of the best and most recommended approaches is to use the double-checked locking mechanism.

The basic idea behind this approach is to check for an instance of the singleton class twice. The first check occurs without locking the object, and if the instance is null, the synchronized block is then executed to create the instance.

Here's an example of implementing thread-safe singleton pattern using double-checked locking mechanism:


public class Singleton {
   private volatile static Singleton instance;
   
   private Singleton() {}
   
   public static Singleton getInstance() {
      if (instance == null) {
         synchronized (Singleton.class) {
            if (instance == null) {
               instance = new Singleton();
            }
         }
      }
      return instance;
   }
}

In this example, the volatile keyword ensures that the instance variable is accessed concurrently, while the synchronized block guarantees that only one thread can access the instance at any given time. This approach provides a highly efficient and thread-safe implementation of the singleton pattern.

It's important to note that there are other ways to implement thread-safe singleton patterns in Java, such as using the enum type or the holder class idiom. However, the double-checked locking mechanism is the most common and widely used approach.

Singleton Instance in a Multi-Threaded Environment without Synchronized Method

In a multi-threaded environment, not having a synchronized method for returning a singleton instance may lead to different threads accessing and modifying the instance simultaneously. Hence, it may result in race conditions and ultimately lead to incorrect behavior or program crashes. Additionally, the instance may not be truly a singleton if multiple instances get created due to race conditions. Therefore, having a synchronized method is crucial to ensure only one instance of the singleton class is created and accessed in a multi-threaded environment.

Pyramid Design Program in Java


public class PyramidPattern {
   public static void main(String[] args) {
   
      int rows = 6; //Number of rows in the pyramid
      
      //Loop to print rows of pyramid
      for (int i = 0; i < rows; i++) {
      
         //Loop to print spaces before the stars
         for (int j = i; j < rows - 1; j++) {
            System.out.print(" ");
         }
         
         //Loop to print stars
         for (int j = 0; j <= i; j++) {
            System.out.print("* ");
         }
         
         System.out.println(); //Move to the next line after each row
      }
   }
}

The above program will display the pyramid pattern as shown:

             *
            * *
          * * *
        * * * *
      * * * * *
    * * * * * *

Java program to display left triangle star pattern


  public class LeftTriangle {
    public static void main(String[] args) {
        
        int rows = 5; // number of rows in the pattern
        
        // outer loop to iterate through rows
        for (int i = 0; i < rows; i++) {
            
            // inner loop to print stars for each row
            for (int j = 0; j <= i; j++) {
                System.out.print("* ");
            }
            
            // move to next line after each row is printed
            System.out.println();
        }
    }
  }

This program uses nested loops to print a left triangle star pattern on the system console. The outer loop controls the number of rows in the pattern, while the inner loop prints the stars for each row. After each row is printed, the program moves to the next line using the System.out.println() method.

Print Diamond Number Pattern using Java

Here's the Java code to print the diamond number pattern.


public class DiamondNumberPattern {
    public static void main(String[] args) {
        
        int rows = 7;

        for (int i = 1; i <= rows; i++) {
            for (int j = 1; j <= rows - i; j++) {
                System.out.print(" ");
            }
            for (int k = i; k >= 1; k--) {
                System.out.print(k);
            }
            for (int l = 2; l <= i; l++) {
                System.out.print(l);
            }
            System.out.println();
        }

        for (int i = rows-1; i >= 1; i--) {
            for (int j = 1; j <= rows - i; j++) {
                System.out.print(" ");
            }
            for (int k = i; k >= 1; k--) {
                System.out.print(k);
            }
            for (int l = 2; l <= i; l++) {
                System.out.print(l);
            }
            System.out.println();
        }
    }
}

The output of this code will be the diamond number pattern as shown below:

                1
             212
            32123
           4321234
          543212345
      65432123456
     7654321234567
   65432123456
     543212345
       4321234
         32123
           212
             1

Java Program to Print Pattern Using Odd Numbers


public class OddNumbersPattern {
   public static void main(String[] args) {
      
      int rows = 5;
      int num = 1;
      
      for (int i = 1; i <= rows; i++) {   //loops through rows 
         
         for (int j = 1; j <= i; j++) {  //loops through columns 
            System.out.print(num + " "); //prints the number
            num += 2; //incrementing the odd number
         }
         System.out.println();
      }
   }
}

This Java program takes an input string and prints a pattern using odd numbers. It uses a nested loop to iterate through both rows and columns, printing each odd number in increasing order. The program allows for the number of rows to be changed by modifying the "rows" variable at the beginning of the code.

Printing Pascal's Triangle Pattern in Java


class PascalTriangle {
    public static void printPascalTriangle(int rows) {
        int coef = 1;
        for(int i = 0; i < rows; i++) {
            for(int space = 1; space < rows-i; space++) {
                System.out.print(" ");
            }
            for(int j = 0; j <= i; j++) {
                if (j == 0 || i == 0)
                    coef = 1;
                else
                    coef = coef * (i - j + 1) / j;
                System.out.print(coef + " ");
            }
            System.out.println();
        }
    }
    
    public static void main(String[] args) {
        int rows = 5;
        printPascalTriangle(rows);
    }
}

The program above uses two loops to iterate through the rows and columns of the triangle. It uses the mathematical formula for calculating Pascal's Triangle coefficients to print each number in the triangle. The function printPascalTriangle() takes an integer parameter "rows" which determines how many rows are in the triangle to be printed. In this example, we have set the number of rows to 5 in the main() function, which can be changed as per requirement.

Technical Interview Guides

Here are guides for technical interviews, categorized from introductory to advanced levels.

View All

Best MCQ

As part of their written examination, numerous tech companies necessitate candidates to complete multiple-choice questions (MCQs) assessing their technical aptitude.

View MCQ's
Made with love
This website uses cookies to make IQCode work for you. By using this site, you agree to our cookie policy

Welcome Back!

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign in
Recover lost password
Or log in with

Create a Free Account

Sign up to unlock all of IQCode features:
  • Test your skills and track progress
  • Engage in comprehensive interactive courses
  • Commit to daily skill-enhancing challenges
  • Solve practical, real-world issues
  • Share your insights and learnings
Create an account
Sign up
Or sign up with
By signing up, you agree to the Terms and Conditions and Privacy Policy. You also agree to receive product-related marketing emails from IQCode, which you can unsubscribe from at any time.