JavaRush /Java 博客 /Random-ZH /第 37 级。有关该级别主题的面试问题的答案
lichMax
第 40 级
Санкт-Петербург

第 37 级。有关该级别主题的面试问题的答案

已在 Random-ZH 群组中发布
你好。我再次没有找到这些问题的答案。我决定发布我自己整理的答案。 第 37 级。有关第 1 级主题的面试问题的答案以下是实际问题: 面试问题:
  1. 什么是设计模式?
  2. 你知道哪些设计模式?
  3. 给我们介绍一下单例模式吗?如何使其线程安全?
  4. 给我们介绍一下工厂模式吗?
  5. 告诉我们 AbstractFactory 模式
  6. 给我们介绍一下 Adaper 模式,它与 Wrapper 的区别?
  7. 告诉我们有关代理模式的信息
  8. 什么是迭代器?你知道哪些与迭代器相关的接口?
  9. 为什么我们需要 Arrays 类?
  10. 为什么我们需要 Collections 类?
以下是我的回答: 我的回答:
  1. 设计模式是针对程序或其部分的设计和开发过程中出现的最常见问题的成熟、成功的解决方案。

  2. Singleton,,,,,,,,,,,, Factory. Abstract Factory_ Template method_ Strategy_ Pool_ Adapter_ Proxy_ Bridge_ MVC_

  3. 当程序中只需要存在一个类的一个实例时,就可以使用该模式Singleton。它看起来像这样(延迟初始化):

    clas Singleton {
    	private Singleton instance;
    
    	private Singleton() {}
    
    	public static Singletot getInstance() {
    		if (instance == null)
    			instance = new Singleton();
    		return instance;
    	}
    }

    为了使其线程安全,您可以向该方法添加getInstance()修饰符synchronized。但这不是最好的解决方案(而是最简单的)。更好的解决方案是以getInstance这种方式编写方法(双重检查锁定):

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

  4. 模式Factory是一种生成模式。它允许您按需创建对象(例如,在某些条件下)。它看起来像这样:

    class Factory{
    	public static Object1 getObject1() {
    		return new Object1();
    	}
    
    	public static Object2 getObject2() {
    		return new Object2();
    	}
    
    	public static Object3 getObject3() {
    		return new Object3();
    	}
    }

    这种模式还有一个变体,称为FactoryMethod。根据这种模式,根据传入的输入数据(参数值),在一种方法中创建不同的对象。所有这些对象必须有一个共同的祖先(或一个共同的可实现接口)。它看起来像这样:

    class FactoryMethod {
    	public enum TypeObject {
    		TYPE1,
    		TYPE2,
    		TYPE3
    	}
    
    	public static CommonClass getObject(TypeObject type) {
    		switch(type) {
    			case TYPE1:
    				return new Object1();
    			case TYPE2:
    				return new Object2();
    			case TYPE3:
    				return new Object3();
    			default:
    				return null;
    		}
    	}
    }

    Object1Object2Object3从类继承CommonClass

  5. 模式Abstract Factory也是一种生成设计模式。根据此模式,创建一个抽象工厂,用作多个具体工厂的模板。这是一个例子:

    class Human {}
    
    class Boy extends Human {}
    class TeenBoy extends Human {}
    class Man extends Human {}
    class OldMan extends Human {}
    
    class Girl extends Human {}
    class TeenGirl extends Human {}
    class Woman extends Human {}
    class OldWoman extends Human {}
    
    interface AbstractFactory {
    	Human getPerson(int age);
    }
    
    class FactoryMale implements AbstractFactory {
    	public Human getPerson(int age) {
    		if (age < 12)
    			return new Boy();
    		if (age >= 12 && age <= 20)
    			return new TeenBoy();
    		if (age > 20 && age < 60)
    			return new Man();
    		return new OldMan();
    	}
    }
    
    сlass FactoryFemale implements AbstractFactory {
    	public Human getPerson(int age) {
    		if (age < 12)
    			return new Girl();
    		if (age >= 12 && age <= 20)
    			return new TeenGirl();
    		if (age > 20 && age < 60)
    			return new Woman();
    		return new OldWoman();
    	}
    }

  6. 模式Adapter是一种结构模式。它的实现允许在需要另一种类型的对象(通常是抽象类型)的地方使用一种类型的对象。此模式的示例实现:

    interface TotalTime {
    	int getTotalSeconds();
    }
    interface Time {
    	int getHours();
    	int getMinutes();
    	int getSeconds();
    }
    
    class TimeAdapter extends TotalTime {
    	private Time time;
    	public TimeAdapter(Time time) {
    		this.time = time;
    	}
    	public int getTotalTime() {
    		return time.getSeconds + time.getMinutes * 60 + time.getHours * 60 * 60;
    	}
    }
    
    class TotalTimeAdapter extends Time {
    	private TotalTime totalTime;
    	public TotalTimeAdapter(TotalTime totalTime) {
    		this.totalTime = totalTime;
    	}
    
    	public int getSeconds() {
    		return totalTime % 60;
    	}
    
    	public int getMinutes() {
    		return (totalTime / 60) % 60;
    	}
    
    	public int getHours() {
    		return totaltime/ (60 * 60) ;
    	}
    }
    
    class Main {
    	public static void main(String[] args) {
    		Time time = new Time() {
    			public int getSeconds() {
    				return LocalTime.now().getSecond();
    			}
    
    			public int getMinutes() {
    				return LocalTime.now().getMinute();
    			}
    
    			public int getHours() {
    				return LocalTime.now().getHour() ;
    			}
    		};
    
    		TotalTime totalTime = new TimeAdapter(time);
    		System.out.println(totalTime.getTotalSeconds());
    
    		TotalTime totalTime2 = new TotalTime() {
    			public int getTotalSeconds() {
    				LocalTime currTime = LocalTime.now();
    				return currTime.getSecond() + currTime.getMinute * 60 + currTime.getHour * 60 * 60;
    			}
    		};
    
    		Time time2 = new TotalTimeAdapter(totalTime2);
    		System.out.println(time2.getHours + ":" + time2.getMinutes() + ":" + time2.getSeconds());
    	}
    }

    При реализации паттерна Wrapper создаётся класс, который оборачивает исходный класс и реализует тот же интерфейс, который реализует исходный класс. Таким образом, это позволяет расширить функциональность исходного класса и использовать новый класс там, где ожидается использование исходного класса. Это отличается от реализации паттерна Adapter тем, что в данном случае используется один интерфейс (тот же, что есть у исходного класса). В паттерне Adapter же используется два интерфейса, и класс, который оборачивает экземпяр исходного класса, реализует совсем другой инферфейс, не интерфейс исходного класса.

  7. Паттерн Proxy — это структурный паттерн проектирования. Он нужен для того, чтобы контролировать доступ к Howому-то an objectу. Для этого пишется класс по типу "обёртка", то есть внутрь класса передаётся исходный an object, реализующий некий интерфейс, сам класс тоже реализует этот интерфейс, и в каждом методе этого класса вызывается похожий метод у исходного an object. Реализация того же интерфейса, что и у исходного an object, позволяет подменить исходный an object прокси-an objectом. Также это позволяет, не меняя исходного an object, "навешивать" на его методы Howую-то специальную дополнительную функциональность (например, логирование, проверка прав доступа, кэширование и т.д.). Пример:

    interface Bank {
    	void setUserMoney(User user, double money);
    	double getUserMoney(User user);
    }
    
    class CitiBank implements Bank { //оригинальный класс
    	public void setUserMoney(User user, double money) {
    		UserDAO.update(user,money);
    	}
    
    	public double getUserMoney(User user) {
    		UserDAO.getUserMoney(user);
    	}
    }
    
    class SecurityProxyBank implements Bank {
    	private Bank bank;
    
    	public SecurityProxyBank(Bank bank) {
    		this.bank = bank;
    	}
    
    	public void setUserMoney(User user, double money) {
    		if (!SecurityManager.authorize(user,BankAccounts.Manager)
    			throw new SecurityException("User can't change money value");
    
    		UserDAO.update(user,money);
    	}
    
    	public double getUserMoney(User user) {
    		if (!SecurityManager.authorize(user,BankAccounts.Manager)
    			throw new SecurityException("User can't get money value");
    
    		UserDAO.getUserMoney(user);
    	}

  8. Итератор — это специальный внутренний an object коллекции, который позволяет последовательно перебирать элементы этой коллекций. Этот an object должен реализовывать интерфейс Iterator<E>, либо ListIterator<E> (для списков). Также, для того, чтобы перебирать элементы коллекции, коллекция должна поддерживать интерфейс Iterable<E>. Интерфейс Iterable<E> содержит всего один метод — iterator(), который позволяет извне получить доступ к итератору коллекции.

    Интерфейс Iterator<E> содержит следующие методы:

    • boolean hasNext() — проверяет, есть ли в коллекции ещё Howой-то элемент

    • E next() — позволяет получить очередной элемент коллекции (после получения element, внутренний курсор итератора передвигается на следующий элемент коллекции)

    • void remove() — удаляет текущий элемент из коллекции

    Интерфейс же ListIterator<E> содержит такие методы:

    • boolean hasNext() — проверяет, существуют ли ещё один элемент в коллекции (следующий за текущим)

    • E next() — возвращает очередной элемент коллекции (и передвигает внутренний курсок итератора на следующий элемент)

    • int nextIndex() — возвращает индекс следующего element

    • void set(E e) — устанавливает meaning текущего element void add(E e). Добавляет элемент в конец списка.

    • boolean hasPrevious() — проверяет, существует ли Howой-то элемент в коллекции перед данным элементом

    • E previous() — возвращает текущий элемент коллекции и переводит курсор на предыдущий элемент коллекции

    • int previousIndex — возвращает индекс предыдущего element коллекции

    • void remove() — удаляет текущий элемент коллекции

    • void add(E e) — добавляет элемент e после текущего element коллекции

  9. 该类Arrays是为各种数组操作而设计的实用程序类。此类具有将数组转换为列表、搜索数组、复制数组、比较数组、获取数组哈希码、将数组表示为字符串等方法。

  10. 该类Collections是用于处理集合的实用程序类。该类具有向集合添加元素、用元素填充集合、搜索集合、复制集合、比较集合、查找集合的最大和最小元素的方法,以及获取集合的特定修改的方法已知类型(例如,您可以获得线程安全集合或具有一个元素的不可变集合)。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION