JavaRush /Java Blog /Random-KO /레벨 37. 레벨 주제에 대한 인터뷰 질문에 대한 답변
lichMax
레벨 40
Санкт-Петербург

레벨 37. 레벨 주제에 대한 인터뷰 질문에 대한 답변

Random-KO 그룹에 게시되었습니다
안녕하세요. 다시 말하지만 나도 이러한 질문에 대한 답을 찾지 못했습니다. 나는 내가 직접 편집한 답변을 게시하기로 결정했습니다. 레벨 37. 레벨-1 주제에 관한 인터뷰 질문에 대한 답변실제 질문은 다음과 같습니다. 인터뷰에 대한 질문:
  1. 디자인 패턴이란 무엇입니까?
  2. 어떤 디자인 패턴을 알고 있나요?
  3. 싱글턴 패턴에 대해 알려주세요. 스레드로부터 안전하게 만드는 방법은 무엇입니까?
  4. 팩토리 패턴에 대해 알려주세요.
  5. AbstractFactory 패턴에 대해 알려주세요.
  6. Adaper 패턴에 대해 알려주십시오. Wrapper와의 차이점은 무엇입니까?
  7. 프록시 패턴에 대해 알려주세요
  8. 반복자란 무엇입니까? Iterator와 관련된 어떤 인터페이스를 알고 있나요?
  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;
    		}
    	}
    }

    Classes Object1및 class 에서 상속 Object2됩니다 .Object3CommonClass

  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구조적 디자인 패턴입니다. 일부 개체에 대한 액세스를 제어하는 ​​데 필요합니다. 이를 위해 클래스는 "래퍼"로 작성됩니다. 즉, 특정 인터페이스를 구현하는 원본 객체가 클래스 내부에 전달되고 클래스 자체도 이 인터페이스를 구현하며 이 클래스의 각 메서드에서 유사한 메서드는 다음과 같습니다. 원본 개체에 대해 호출됩니다. 원본 객체와 동일한 인터페이스를 구현하면 원본 객체를 프록시 객체로 바꿀 수 있습니다. 또한 원본 객체를 변경하지 않고도 메소드에 특별한 추가 기능(예: 로깅, 액세스 권한 확인, 캐싱 등)을 "부착"할 수 있습니다. 예:

    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. 반복자는 이 컬렉션의 요소를 순차적으로 반복할 수 있는 컬렉션의 특수 내부 개체입니다. 이 객체는 인터페이스 Iterator<E>또는 ListIterator<E>(목록의 경우)을 구현해야 합니다. 또한 컬렉션의 요소를 반복하려면 컬렉션이 Iterable<E>. 인터페이스에는 외부에서 컬렉션 반복자에 액세스할 수 있는 Iterable<E>메서드가 하나만 포함되어 있습니다 .iterator()

    인터페이스 Iterator<E>에는 다음 메서드가 포함되어 있습니다.

    • boolean hasNext()— 컬렉션에 다른 요소가 있는지 확인합니다.

    • E next()— 컬렉션의 다음 요소를 가져올 수 있습니다(요소를 받은 후 내부 반복자 커서가 컬렉션의 다음 요소로 이동합니다).

    • 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 — это утorтарный класс, предназначенный для разнообразных манипуляций с массивами. В этом классе есть методы превращения массива в список, поиска по массиву, копирования массива, сравнения массивов, получения хешcodeа массива, представление массива в виде строки и др.

  10. Класс Collections — это утorтарный класс для работы с коллекциями. В этом классе есть методы добавления элементов в коллекцию, наполнения коллекции elementми, поиска по коллекции, копировании коллекции, сравнения коллекции, нахождения максимального и минимального элементов коллекции, а также методы получения специфический модификаций коллекций известных типов (например, можно получить потокобезопасную коллекции or неизменяемую коллекцию с одним элементом).

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION