JavaRush/Java блог/Random UA/Рівень 37. Відповіді на запитання до співбесіди на тему р...
lichMax
40 рівень

Рівень 37. Відповіді на запитання до співбесіди на тему рівня

Стаття з групи Random UA
учасників
Вітаю. Знову ж таки, не знайшов відповідей і на ці запитання. Вирішив викласти відповіді, які я склав для себе. Рівень 37. Відповіді на запитання до співбесіди на тему рівня - 1Ось, власне питання: Запитання до співбесіди:
  1. Що таке патерни проектування?
  2. Які патерни проектування ви знаєте?
  3. Розкажіть про патерн Singleton? Як зробити його потокобезпечним?
  4. Розкажіть про патерн Factory?
  5. Розкажіть про патерн AbstractFactory
  6. Розкажіть про патерн Adaper, його відмінності від Wrapper?
  7. Розкажіть про патерн Proxy
  8. Що таке ітератор? Які інтерфейси пов'язані з ітератором ви знаєте?
  9. Навіщо потрібний клас Arrays?
  10. Навіщо потрібний клас Collections?
А ось мої відповіді: Мої відповіді:
  1. Паттерни проектування - це усталені вдалі рішення найпоширеніших проблем, що виникають при проектуванні та розробці програм або їх частин.

  2. Singleton, Factory, Abstract Factory, , Template method, Strategy, Pool, Adapter, Proxy, Bridge.MVC

  3. Коли потрібно, щоб у програмі існував лише один екземпляр якогось класу, то застосовують патерн Singleton. Він виглядає так (lazy initialization):

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

    Щоб зробити його потокобезпечним, можна додати методу getInstance()модифікатор synchronized. Але це буде не найкращим рішенням (зате найпростішим). Краще рішення - це написати метод getInstanceтаким чином (double-checked locking):

    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;
    		}
    	}
    }

    Класи Object1, Object2і Object3успадковуються від класу 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- це структурний патерн проектування. Він потрібний для того, щоб контролювати доступ до якогось об'єкта. І тому пишеться клас на кшталт " обгортка " , тобто всередину класу передається вихідний об'єкт, реалізує якийсь інтерфейс, сам клас теж реалізує цей інтерфейс, й у кожному методі цього класу викликається схожий метод у вихідного об'єкта. Реалізація того ж інтерфейсу, що у вихідного об'єкта, дозволяє підмінити вихідний об'єкт проксі-об'єктом. Також це дозволяє, не змінюючи вихідного об'єкта, "навішувати" з його методи якусь спеціальну додаткову функціональність (наприклад, логування, перевірка прав доступу, кешування тощо.). Приклад:

    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()- Повертає індекс наступного елемента

    • void set(E e)- Встановлює значення поточного елемента void add(E e). Додає елемент до кінця списку.

    • boolean hasPrevious()— перевіряє, чи існує якийсь елемент у колекції перед цим елементом

    • E previous()— повертає поточний елемент колекції та переводить курсор на попередній елемент колекції

    • int previousIndex- Повертає індекс попереднього елемента колекції

    • void remove()- видаляє поточний елемент колекції

    • void add(E e)— додає елемент e після поточного елемента колекції

  9. Клас Arrays– це утилітарний клас, призначений для різноманітних маніпуляцій із масивами. У цьому класі є методи перетворення масиву на список, пошуку за масивом, копіювання масиву, порівняння масивів, отримання хешкода масиву, подання масиву у вигляді рядка та ін.

  10. Клас Collections– це утилітарний клас для роботи з колекціями. У цьому класі є методи додавання елементів до колекції, наповнення колекції елементами, пошуку по колекції, копіювання колекції, порівняння колекції, знаходження максимального та мінімального елементів колекції, а також методи отримання специфічних модифікацій колекцій відомих типів (наприклад, можна отримати потокобезпечну колекцію або незмінну з одним елементом).

Коментарі
  • популярні
  • нові
  • старі
Щоб залишити коментар, потрібно ввійти в систему
Для цієї сторінки немає коментарів.