JavaRush /Java Blog /Random-KO /Java 개발자 인터뷰의 질문과 답변을 분석합니다. 4부

Java 개발자 인터뷰의 질문과 답변을 분석합니다. 4부

Random-KO 그룹에 게시되었습니다
안녕하세요 여러분, 오늘 저는 Java 개발자를 위한 250개 이상의 인터뷰 질문을 계속 분석하고 있습니다 . Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 1분석의 이전 부분: 첫 번째 , 두 번째 , 세 번째 . 그럼 계속합시다.

29. 생성자에서 return을 사용할 수 있나요?

가능하지만 return 오른쪽에 반환 값이 없습니다 . 즉, return을 사용할 수 있습니다. 추가 코드 실행을 긴급하게 완료(중단)하고 객체 초기화를 완료하기 위해 생성자에서 계산하는 동안 보조 구성으로 사용됩니다. 예를 들어 Cat 클래스가 있고 Cat이 집이 없는 경우 - isHomeless = true 인 경우 초기화를 완료하고 다른 필드를 채우지 않아야 합니다(결국 고양이가 집이 없기 때문에 해당 필드는 우리에게 알려지지 않습니다).
public Cat(int age, String name, boolean isHomeless) {
   if (isHomeless){
       this.isHomeless = isHomeless;
       return;
   }
   this.isHomeless = isHomeless;
   this.age = age;
   this.name = name;
}
그러나 특정 값의 경우 생성자는 다음과 같은 이유로 return을 사용하여 값을 반환할 수 없습니다.
  • 생성자를 선언할 때 반환 유형과 유사한 것은 아무것도 없습니다.
  • 일반적으로 생성자는 인스턴스화 중에 암시적으로 호출됩니다.
  • 생성자는 메소드가 아닙니다. 생성자는 인스턴스 변수를 초기화하는 것이 유일한 목적인 별도의 메커니즘이며 new 연산자는 객체 생성을 담당합니다 .
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 2

30. 생성자에서 예외를 발생시키는 것이 가능합니까?

생성자는 메소드와 정확히 동일한 방식으로 예외를 처리합니다. 메소드가 메소드 헤더에 <ExceptionType>을 작성하여 예외를 발생 시킬 수 있게 하면 생성자를 통해 이를 수행할 수 있으며 상속자 생성자를 상속하고 정의할 때 예외 유형을 확장할 수 있습니다. 예를 들어 IOException -> Exception(그 반대는 아님)입니다. 생성자에 의해 예외가 발생하는 예로 Cat 클래스를 살펴보겠습니다 . 이를 생성할 때 콘솔에서 이름과 나이를 입력한다고 가정해 보겠습니다.
public Cat() throws IOException {
   BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
   this.name = reader.readLine();
   this.age = Integer.parseInt(reader.readLine());
}
reader.readLine()은 IOException을 발생 시키므로 헤더에 이를 발생 가능한 예외로 지정합니다.

31. 클래스 헤더는 어떤 요소로 구성됩니까? 예시 작성

클래스 헤더를 구성하는 요소에 관해 작은 다이어그램을 살펴보겠습니다.
  • 필수 구성요소는 괄호 안에 표시됩니다. <>
  • 선택사항 - {}에서
{클래스 액세스 수정자}{클래스 정적성}{클래스 최종성}{클래스 추상화} <클래스 이름>{부모 클래스의 상속} {인터페이스 구현} 따라서 우리가 가진 것은 다음과 같습니다: {class access modifier} - public 한정자 와 누락된 액세스 한정자, 즉 default 만 class에 사용할 수 있습니다 . {class static} - static 은 이 클래스가 정적이며 내부 클래스(다른 클래스 내부의 클래스)에만 적용 가능함을 나타내는 수정자입니다. {class finality} - 우리가 기억하는 것처럼 이것은 클래스가 상속 불가능하게 되는 최종 수정자입니다(상자의 예 - String ). {클래스 추상화} - 수정자 - abstract 는 이 클래스에 구현되지 않은 메서드가 있을 수 있음을 나타냅니다. 이 수정자는 final 수정자와 충돌합니다 . 즉, 추상 수정자는 주어진 클래스가 상속되고 추상 부분이 구현될 것임을 암시하므로 둘 중 하나만 클래스 헤더에 있을 수 있습니다. 그리고 final은 이것이 클래스의 최종(최종) 버전이며 상속될 수 없음을 나타냅니다. 실제로 두 수정자를 동시에 사용하는 것은 터무니없는 일이며 컴파일러에서는 이를 허용하지 않습니다. <class> 는 클래스 선언을 나타내는 필수 키워드입니다. <클래스 이름>은 특정 Java 클래스의 식별자인 간단한 클래스 이름입니다. 정규화된 클래스 이름은 정규화된 패키지 이름 + 로 구성됩니다. + 간단한 클래스 이름. {부모 클래스의 상속} - 확장 키워드를 사용하여 부모 클래스(있는 경우)를 지정합니다 . 예를 들어 ..는 ParentClass를 확장합니다 . {인터페이스 구현} - Implements 키워드를 사용하여 이 클래스가 구현하는 인터페이스(있는 경우)를 지정합니다 . 예를 들면 다음과 같습니다. ...는 FirstInterface, SecondInterface를 구현합니다 . 클래스 헤더의 예로 Cat 에서 상속되고 WildAnimal 인터페이스 를 구현하는 Lion 클래스의 헤더를 생각해 보세요 .
public final class Lion extends Cat implements WildAnimal
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 3

32. 메소드 헤더는 어떤 요소로 구성됩니까? 예시 작성

다시 한 번, 메소드 헤더를 구성하는 요소를 볼 때 다음과 같은 작은 다이어그램을 고려하십시오.
  • 필수 구성 요소는 괄호 안에 <>
  • 선택사항 - {}에서
{access modifier}{method static}{method abstraction}{method finality}{synchronization modifier} {native modifier}<return value><method name> <(> {method 인수} <)>{thrown 예외} {access modifier } — public , protected , default , private 메소드에 모든 액세스 한정자를 사용할 수 있습니다 . {method static} - static 은 이 메소드가 정적임을 나타내는 수정자입니다. 즉, 객체가 아닌 클래스에 연결되어 있습니다. {메소드 추상화}는 추상 수정 자 로서 메소드의 구현(본문)이 없음을 나타냅니다. 올바른 작동을 위해서는 메소드가 제공되는 클래스에 대한 추상 수정자도 필요합니다. 클래스 헤더에서와 같이 이 수정자는 final 수정자와 충돌 하지만, 이에 더해 static 수정자와도 충돌합니다 . 추상 메서드는 하위 항목의 메서드 재정의를 의미하며 정적 메서드는 재정의되지 않습니다. {메서드의 최종성} - 최종 - 이 메서드를 재정의할 수 없음을 나타내는 수정자입니다. {동기화 수정자} - 동기화됨 - 이 메소드가 다른 스레드에서 동시에 액세스하지 못하도록 보호됨을 의미하는 수정자입니다. 메서드가 정적이 아닌 경우 개체의 this 뮤텍스에서 닫힙니다. 메서드가 정적이면 현재 클래스의 뮤텍스에서 닫힙니다. {네이티브 한정자} - 네이티브 - 이 한정자는 메서드가 다른 프로그래밍 언어로 작성되었음을 나타냅니다. <반환 값>은 메서드가 반환해야 하는 값의 유형입니다. 아무것도 반환하지 않아야 하는 경우 void 입니다 . <메서드 이름> 은 메소드의 이름이자 시스템의 식별자입니다. {메소드 인수}는 메소드가 취하는 인수(매개변수)입니다. 해당 기능을 구현하는 데 필요합니다. {throwable 예외} - throwsExceptionType - 이 메서드가 throw할 수 있는 확인된 예외 목록입니다. 메소드 헤더의 예로 다음을 제공하겠습니다.
public static void main(String[] args) throws IOException

33. 기본 생성자가 기본 객체에 정의되어 있지 않은 경우(다른 생성자가 정의되어 있는 경우) 자손 객체에 기본 생성자를 생성합니다.

질문 자체를 완전히 이해하지는 못하지만, 예를 들어 부모에 사용자 정의 생성자가 있다는 뜻일 수도 있습니다.
public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
따라서 조상 클래스에서 부모 생성자를 채우(호출) 생성자를 정의해야 합니다.
public  class Lion extends Cat {

   public Lion(int age, String name) {
       super(age, name);
   }
}
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 4

34. this 키워드는 언제 사용되나요?

Java에서 이는 두 가지 다른 의미를 갖습니다. 1. this.age = 9 와 같이 현재 개체에 대한 참조로 사용됩니다 . 즉, this는 호출된 개체와 this를 사용하는 코드가 참조하는 개체를 나타냅니다 . 주요 기능은 코드 가독성을 높이고 모호성을 방지하는 것입니다. 예를 들어, 내부 클래스 필드의 이름과 메서드 인수가 동일한 경우:
public void setName(String name) {
   this.name = name;
}
즉, this.name은 객체 이름 의 필드 이고 메소드 인수입니다. this 참조는 정적 메소드에서 사용할 수 없습니다. 2. this (value) 와 같이 메서드 호출 형식으로 생성자에서 사용할 수 있습니다 . 이 경우에는 동일한 클래스의 다른 생성자를 호출하게 됩니다. 즉, 객체를 생성할 때 두 개의 생성자를 동시에 호출할 수 있습니다.
public Cat(int age, String name) {
   this(name);
   this.age = age;
}

public Cat(String name) {
   this.name = name;
}
Cat 객체 가 생성 되고 첫 번째 생성자가 호출되면 객체의 두 필드가 모두 호출되고 성공적으로 초기화됩니다. 몇 가지 뉘앙스가 있습니다.
  1. this()는 생성자에서만 작동합니다.
  2. 다른 생성자에 대한 참조는 생성자 블록(본문)의 첫 번째 줄에 있어야 합니다. 따라서 특정 클래스의 둘 이상의 생성자를 하나의 생성자에서 호출할 수 없습니다.
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 5이 기사에는 더 많은 예가 나와 있습니다 .

35. 이니셜라이저란 무엇입니까?

내가 아는 한, 이 질문에서 우리는 일반 및 통계 초기화 블록에 대해 이야기하고 있습니다. 먼저 초기화가 무엇인지 기억해 봅시다. 초기화는 생성, 활성화, 작업 준비, 매개변수 결정입니다. 프로그램이나 구성 요소를 사용할 준비가 된 상태로 만듭니다. 기억하는 것처럼 객체 생성 중에 클래스 변수는 선언 시 직접 초기화될 수 있습니다.
class Cat {
   private int age = 9;
   private  String name = "Tom";
또는 생성자를 통해 외부적으로 설정합니다.
class Cat {
   private int age;
   private  String name;

   public Cat(int age, String name) {
       this.age = age;
       this.name = name;
   }
하지만 또 다른 방법이 있습니다. 초기화 블록을 통해 내부 개체 변수를 설정하는 것입니다. 이 블록은 이름(메서드 또는 생성자 등) 없이 클래스 내부에 중괄호 { } 처럼 보입니다.
class Cat {
   private int age;
   private  String name;

   {
       age = 10;
       name = "Tom";
   }
즉, 초기화 블록은 객체가 생성될 때 로드되는 코드 조각입니다. 일반적으로 이러한 블록은 클래스를 로드할 때 필요한 일부 복잡한 계산을 수행하는 데 사용됩니다. 이러한 계산 결과는 변수 값으로 지정될 수 있습니다. 또한 일반 초기화 블록 외에도 동일해 보이지만 중괄호 앞에 static 키워드가 있는 정적 블록도 ​​있습니다 .
class Cat {
   private static int age;
   private static String name;

   static{
       age = 10;
       name = "Tom";
   }
이 블록은 이전 블록과 완전히 동일합니다. 그러나 각 객체가 초기화될 때 일반 객체가 트리거되면 정적 객체는 클래스가 로드될 때 한 번만 트리거됩니다. 이러한 블록에서는 일반적으로 정적 클래스 변수의 후속 초기화를 위해 일부 복잡한 계산도 수행됩니다. 정적 메서드와 마찬가지로 정적 블록에도 동일한 제한 사항이 적용됩니다. 즉, 비정적 데이터와 현재 개체에 대한 참조( this ) 를 사용할 수 없습니다 . Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 6다음으로, 초기화 블록이 트리거되는 순간을 더 잘 이해하기 위해 클래스의 초기화 순서(상위 클래스와 함께)를 볼 수 있습니다.

36. public class Child extends Parent 클래스를 상속받으려면 객체의 초기화 순서를 작성하세요.

Child 클래스가 로드되면 초기화 순서는 다음과 같습니다.
  1. Parent 클래스 의 정적 필드입니다 .
  2. Parent 클래스 에 대한 정적 초기화 블록입니다 .
  3. Child 클래스 의 정적 필드입니다 .
  4. Child 클래스 에 대한 정적 초기화 블록입니다 .
  5. Parent 클래스 의 비정적 필드입니다 .
  6. Parent 클래스 에 대한 정적 초기화 블록이 아닙니다 .
  7. Parent 클래스 의 생성자입니다 .
  8. Child 클래스 의 비정적 필드입니다 .
  9. Child 클래스 에 대한 정적 초기화 블록이 아닙니다 .
  10. Child 클래스 의 생성자 .
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 7다음은 실제로 초기화 순서를 설명하는 짧은 기사 입니다 .

37. 클래스(객체) 간의 어떤 관계를 알고 있나요?

Java에는 클래스 사이에 두 가지 유형의 관계가 있습니다.
  • IS-A 관계
OOP의 IS-A 원칙은 클래스 상속 또는 인터페이스 구현을 기반으로 합니다. 예를 들어 Lion 클래스가 Cat 에서 상속받는 경우 Lion is Cat 라고 합니다 .
Lion IS-A Cat
(그러나 모든 CatLion 은 아닙니다 .) 인터페이스의 상황은 정확히 동일합니다. Lion 클래스가 WildAnimal 인터페이스를 구현하는 경우 에도 관계에 있습니다.
Lion IS-A WildAnimal
  • HAS-A 관계
이러한 유형의 관계는 "연관"이라고도 하는 다른 클래스의 클래스 사용을 기반으로 합니다. 연관은 다른 클래스(또는 서로)를 참조하는 하나의 클래스입니다. 예를 들어 Car 클래스는 Passenger 클래스를 참조할 수 있으며 다음과 같은 관계가 됩니다.
Car HAS-A Passenger
반대의 경우도 마찬가지입니다. Passenger가 Car 에 대한 참조를 갖고 있는 경우 다음과 같은 관계가 됩니다.
Passenger HAS-A Car

38. 객체 간의 어떤 연관 연결을 알고 있습니까?

집합과 구성은 연합의 특별한 경우에 지나지 않습니다. 집계는 한 개체가 다른 개체의 일부인 관계입니다. 예를 들어, 승객이 자동차 안에 있을 수 있습니다. 또한 승객이 여러 명일 수도 있고 전혀 없을 수도 있습니다(Tesla에 대해 이야기하는 경우 운전자가 필요하지 않습니다). 예를 들어:
public class Car {
   private List passengers = new ArrayList<>();

 void setPassenger(Passenger passenger) {
     passengers.add(passenger);
 }

   void move() {
       for (Passenger passenger : passengers) {
           System.out.println("Перевозка пассажира - " + passenger.toString());
       }
       passengers.clear();
   }
}
즉, 우리는 승객 수(또는 승객이 있는지 여부)에 대해 신경 쓰지 않습니다. Car 클래스의 기능은 이에 의존하지 않습니다. 또한 집계는 한 개체가 다른 개체에서 사용될 때 첫 번째 개체가 다른 개체에서 사용될 수 있음을 의미합니다. 예를 들어, 같은 학생이 뜨개질 클럽과 락커 음악 그룹의 회원이면서 동시에 영어 학습자 그룹에 다닐 수 있습니다. 아시다시피 집계는 클래스 간의 보다 느슨한 연관 관계입니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 8구성은 개체가 다른 개체의 일부일 뿐만 아니라 다른 개체의 작업이 첫 번째 개체에 크게 의존하는 경우 훨씬 더 엄격한 관계입니다. 예를 들어, 자동차 엔진. 자동차 없이도 엔진은 존재할 수 있지만 자동차 밖에서는 쓸모가 없습니다. 글쎄요, 자동차는 엔진 없이는 작동할 수 없습니다.
public class Car {
   private Engine engine;

   public Car(Engine engine) {
       this.engine = engine;
   }

   void startMoving() {
       engine.start();
           ...
   }
구성은 또한 객체가 다른 객체에 의해 사용될 때 첫 번째 객체가 다른 누구에게도 속할 수 없음을 의미합니다. 우리의 예로 돌아가면 엔진은 한 대의 자동차에만 속할 수 있지만 동시에 두 대 이상의 자동차에 속할 수는 없습니다. 오늘은 아마 여기서 멈출 것 같아요.Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 4 - 9
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION