JavaRush /จาวาบล็อก /Random-TH /ระดับ 37 คำตอบสำหรับคำถามสัมภาษณ์ในหัวข้อระดับ
lichMax
ระดับ
Санкт-Петербург

ระดับ 37 คำตอบสำหรับคำถามสัมภาษณ์ในหัวข้อระดับ

เผยแพร่ในกลุ่ม
สวัสดี ฉันไม่พบคำตอบสำหรับคำถามเหล่านี้เช่นกัน ฉันตัดสินใจโพสต์คำตอบที่ฉันรวบรวมไว้เพื่อตัวเอง ระดับ 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;
    		}
    	}
    }

    คลาส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 — это структурный паттерн проектирования. Он нужен для того, чтобы контролировать доступ к 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