CodeGym /Java Blog /무작위의 /Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요. 11부
John Squirrels
레벨 41
San Francisco

Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요. 11부

무작위의 그룹에 게시되었습니다
안녕! 가장 빠른 배라도 항로가 없으면 파도 위를 표류할 뿐입니다. 지금 이 글을 읽고 있는 당신에게는 분명 목표가 있습니다. 가장 중요한 것은 진로를 벗어나지 않고 대신 Java 개발자가 되기 위해 올인하는 것입니다. 오늘 저는 이론상의 공백을 메우는 데 도움이 되도록 Java 개발자를 위한 질문에 대한 검토를 계속하고 싶습니다. Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 11 - 1

97. equals()를 재정의할 때 적용되는 규칙이 있나요?

equals() 메서드를 재정의하는 경우 다음 규칙을 준수해야 합니다.
  • 재귀성 — 모든 값 x 에 대해 x.equals(x)는 항상 true를 반환해야 합니다 (여기서 x != null ).

  • 대칭 — xy 값에 대해 x.equals(y)는 y.equals(x)가 true를 반환하는 경우 에만 true를 반환해야 합니다 .

  • 전이성 — x , yz 값에 대해 x.equals (y)가 true를 반환 하고 y.equals(z)true를 반환하는 경우 x.equals(z)는 true를 반환해야 합니다 .

  • 일관성 — 모든 값 xy 에 대해 x.equals(y)를 반복적으로 호출하면 두 개체를 비교하는 데 사용된 필드가 각 호출 간에 변경되지 않는 한 항상 동일한 값이 반환됩니다.

  • null 비교 — x 값에 대해 x.equals(null) 호출은 false 를 반환해야 합니다 .

98. equals()와 hashCode()를 재정의하지 않으면 어떻게 됩니까?

이 경우 hashCode()는 객체가 저장된 메모리 셀의 주소를 기반으로 생성된 숫자를 반환합니다. 즉, 원래 hashCode() 메서드가 정확히 동일한 필드를 가진 두 객체에 대해 호출되면 결과가 달라집니다(두 객체가 서로 다른 메모리 위치에 저장되기 때문입니다). 원래의 equals() 메소드는 참조를 비교합니다. 즉, 참조가 동일한 객체를 가리키는지 여부를 나타냅니다. 즉, 비교에서는 == 연산자를 사용하며 필드가 동일한 경우에도 서로 다른 개체에 대해 항상 false를 반환합니다 . true 는 동일한 객체에 대한 참조를 비교할 때만 반환됩니다. 때로는 이러한 메서드를 재정의하지 않는 것이 합리적일 때도 있습니다. 예를 들어, 특정 클래스의 모든 개체가 고유하기를 원합니다. 이러한 메서드를 재정의하면 기존의 고유 해시 코드 보장이 손상될 수 있습니다. 중요한 것은 재정의 여부에 관계없이 이러한 메서드의 미묘한 차이를 이해하고 상황에 따라 필요한 접근 방식을 사용하는 것입니다.

99. x.equals(y)가 true를 반환하는 경우에만 대칭 요구 사항이 충족되는 이유는 무엇입니까?

이 질문은 좀 이상합니다. 객체 A가 객체 B와 같으면 객체 B는 객체 A와 같습니다. B가 객체 A와 같지 않으면 어떻게 그 반대가 가능합니까? 이것은 상식입니다.

100. HashCode 충돌이란 무엇입니까? 어떻게 처리합니까?

HashCode 충돌은 서로 다른 두 객체가 동일한 HashCode 를 가질 때 발생합니다 . 그게 어떻게 가능합니까? 해시 코드는 범위가 -2147483648에서 2147483647인 정수로 매핑됩니다. 즉, 약 40억 개의 서로 다른 정수 중 하나일 수 있습니다. 이 범위는 거대하지만 무한하지는 않습니다. 이는 완전히 다른 두 개체가 동일한 해시 코드를 가질 수 있는 상황이 있음을 의미합니다. 가능성은 거의 없지만 가능합니다. 잘못 구현된 해시 함수는 작은 범위의 숫자를 반환하여 동일한 해시 코드를 더 자주 만들어 충돌 가능성을 높일 수 있습니다. 충돌을 줄이려 면 값을 균일하게 분산시키고 값이 반복될 가능성을 최소화하는 HashCode 메서드를 효과적으로 구현해야 합니다 .

101. hashCode 컨트랙트에 참여하는 요소의 값이 변경되면 어떻게 되나요?

해시 코드 계산에 포함된 요소가 변경되면 개체의 해시 코드도 변경되어야 합니다(해시 함수가 좋은 경우). 그렇기 때문에 HashMap 에서 불변 객체를 키로 사용해야 합니다 . 내부 상태(필드)는 생성 후에 변경할 수 없기 때문입니다. 그리고 해시 코드는 생성 후에 변경됩니다. 변경 가능한 객체를 키로 사용하는 경우 객체의 필드가 변경되면 해당 해시 코드가 변경되고 HashMap 에서 해당 키-값 쌍이 손실될 수 있습니다 . 결국 원래 해시 코드와 연결된 버킷에 저장되지만 객체가 변경된 후에는 다른 버킷에서 검색하게 됩니다.

102. String name 및 int age 필드가 있는 Student 클래스에 대한 equals() 및 hashCode() 메서드를 작성하세요.


public class Student {
int age;
String name;
 
 @Override
 public boolean equals(final Object o) {
   if (this == o) {
     return true;
   }
   if (o == null || this.getClass() != o.getClass()) {
     return false;
   }
 
   final Student student = (Student) o;
 
   if (this.age != student.age) {
     return false;
   }
   return this.name != null ? this.name.equals(student.name) : student.name == null;
 }
 
 @Override
 public int hashCode() {
   int result = this.age;
   result = 31 * result + (this.name != null ? this.name.hashCode() : 0);
   return result;
 }
}
같음():
  • 먼저 참조를 직접 비교합니다. 왜냐하면 참조가 동일한 개체를 가리키는 경우 계속해서 동일한지 확인하는 것이 무슨 의미가 있을까요? 우리는 그 결과가 사실 이라는 것을 이미 알고 있습니다 .

  • 매개변수가 null이거나 다른 유형이면 객체가 동일할 수 없고 결과가 false여야 하기 때문에 null을 확인하고 클래스 유형이 동일한지 여부를 확인 합니다 .

  • 매개변수를 동일한 유형으로 캐스팅합니다(결국 상위 유형의 객체라면 어떻게 될까요).

  • 기본 필드를 비교합니다( =!를 사용한 비교로 충분합니다). 동일하지 않으면 false 를 반환합니다 .

  • 기본이 아닌 필드가 null인지 확인하고 equals 메서드를 사용하는지 확인합니다( String 클래스가 메서드를 재정의하므로 비교가 올바르게 수행됩니다). 두 필드가 모두 null이거나 같음이 true를 반환하는 경우 확인을 중지하고 메서드가 true를 반환합니다 .

해시 코드() :
  • 해시 코드의 초기 값을 객체의 age 필드 값과 동일하게 설정합니다.

  • 현재 해시 코드에 31을 곱한 다음(값의 더 큰 확산을 위해) 비원시 문자열 필드의 해시 코드를 추가합니다(null이 아닌 경우).

  • 결과를 반환합니다.

  • 이런 방식으로 메서드를 재정의하면 이름int 값이 동일한 개체가 항상 동일한 해시 코드를 반환한다는 의미입니다.

103. "if (obj instanceof Student)"와 "if (getClass() == obj.getClass())" 사용의 차이점은 무엇입니까?

각 표현식이 어떤 역할을 하는지 살펴보겠습니다.
  • instanceof는 왼쪽의 객체 참조가 오른쪽 유형의 인스턴스인지 아니면 해당 하위 유형 중 하나인지 확인합니다.

  • "getClass() == ..."는 유형이 동일한지 확인합니다.

즉, getClass() 는 클래스의 특정 ID를 반환하지만, 인스턴스는 객체가 단지 하위 유형인 경우에도 true를 반환하므로 다형성을 사용할 때 더 많은 유연성을 제공할 수 있습니다. 두 접근 방식 모두 작동 방식을 정확하게 이해하고 올바른 위치에 적용한다면 유망합니다.

104. clone() 메소드에 대해 간략하게 설명해주세요.

clone () 메소드는 Object 클래스 에 속합니다 . 그 목적은 현재 객체의 복제본(사본)을 생성하고 반환하는 것입니다. 이 방법을 사용하려면 CloneableJava 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 11 - 2 마커 인터페이스를 구현해야 합니다 .

Student implements Cloneable
그리고 clone() 메서드 자체를 재정의합니다.

@Override
protected Object clone() throws CloneNotSupportedException {
 return super.clone();
}
결국 이는 Object 클래스에서 보호됩니다. 즉, Student 클래스 내에서만 표시되고 외부 클래스에서는 표시되지 않습니다.

105. 객체의 clone() 메서드와 참조 변수와 관련하여 특별히 고려해야 할 사항은 무엇입니까?

객체가 복제되면 기본 값과 객체 참조 값만 복사됩니다. 즉, 개체에 다른 개체를 참조하는 필드가 있는 경우 참조만 복제됩니다. 참조된 다른 개체는 복제되지 않습니다. 이것을 얕은 복사본이라고 합니다. 그렇다면 모든 중첩 개체가 복제되는 완전한 복사본이 필요한 경우 어떻게 해야 할까요? 이것이 단순한 참조 복사본이 아니라 힙에서 고유한 메모리 주소를 차지하는 고유한 객체의 완전한 복사본인지 어떻게 확인합니까? 실제로는 매우 간단합니다. 내부적으로 참조되는 각 클래스에 대해 clone() 메서드를 재정의하고 Cloneable 마커 인터페이스를 추가 해야 합니다 . 이렇게 하면 복제 작업은 기존 객체에 대한 참조를 복사하지 않고 대신 참조된 객체를 복사합니다. 이제 참조된 객체도 스스로 복사할 수 있기 때문입니다.

예외

106. 오류와 예외의 차이점은 무엇입니까?

오류뿐만 아니라 예외도 Throwable 의 하위 클래스입니다 . 그러나 차이점이 있습니다. 이 오류는 주로 시스템 리소스 부족으로 인해 발생하는 문제를 나타냅니다. 그리고 우리 애플리케이션에는 이러한 유형의 문제가 표시되어서는 안 됩니다. 이러한 오류의 예로는 시스템 충돌 및 메모리 부족 오류가 있습니다. 오류는 확인되지 않았기 때문에 대부분 런타임에 발생합니다. Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 11 - 3예외는 런타임 및 컴파일 타임에 발생할 수 있는 문제입니다. 이러한 문제는 일반적으로 우리가 개발자로서 작성하는 코드에서 발생합니다. 이는 이러한 예외가 더 예측 가능하고 우리에게 더 의존적이라는 것을 의미합니다. 대조적으로, 오류는 더 무작위적이고 우리와 더 독립적입니다. 대신, 애플리케이션이 실행되는 시스템의 문제에 의존합니다.

107. 확인됨, 확인되지 않음, 예외, 던지기 및 던지기의 차이점은 무엇입니까?

앞서 말했듯이 예외는 개발자가 작성한 코드에서 (일부 비정상적인 상황으로 인해) 발생하는 런타임 또는 컴파일 타임 오류입니다. Checked 란 메서드가 try-catch 메커니즘을 사용하여 항상 처리해야 하거나 호출 메서드에 다시 발생시키는 예외를 호출하는 것입니다. throws 키워드는 메서드 헤더에서 메서드가 throw할 수 있는 예외를 나타내는 데 사용됩니다 . 즉, 호출 메서드에 예외를 발생시키는 메커니즘을 제공합니다. 확인되지 않은 예외는 처리할 필요가 없습니다. 예측 가능성이 낮고 가능성도 낮은 경향이 있습니다. 즉, 원한다면 처리할 수 있습니다. 예외를 수동으로 발생시킬 때 throw를 사용합니다 . 예를 들면 다음과 같습니다.

throw new Exception();

108. 예외 계층 구조는 무엇입니까?

예외 계층 구조는 매우 광범위합니다. 여기서 적절하게 설명하기에는 너무 많습니다. 따라서 대신 주요 분기만 고려할 것입니다. Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 11 - 4 여기 계층 구조의 맨 위에는 예외 계층 구조의 일반적인 조상이며 다음으로 나누어지는 Throwable 클래스가 있습니다.
  • 오류 — 중요하고 확인되지 않은 문제입니다.
  • 예외 — 확인할 수 있는 예외입니다.
예외는 확인되지 않은 다양한 런타임 예외와 확인된 다양한 예외로 구분됩니다.

109. 확인된 예외와 확인되지 않은 예외란 무엇입니까?

내가 전에 말했듯이:
  • 확인된 예외는 어떻게든 처리해야 하는 예외입니다. 즉, try-catch 블록에서 처리하거나 위의 메서드에 던져야 합니다. 이렇게 하려면 메서드 시그니처에 메서드 인수를 나열한 후 throws <예외 유형>을 사용하여 메서드가 해당 예외를 throw할 수 있음을 나타냅니다. 이는 호출 메서드에 해당 예외 처리에 대한 책임을 져야 한다는 점을 알리는 경고와 비슷합니다.

  • 확인되지 않은 예외는 컴파일 타임에 확인되지 않고 일반적으로 예측하기 어렵기 때문에 처리할 필요가 없습니다. 확인된 예외와의 주요 차이점은 try-catch 블록을 사용하거나 다시 throw하여 예외를 처리하는 것이 필수가 아니라 선택 사항이라는 것입니다.

101. try-catch 블록을 사용하여 예외를 포착하고 처리하는 예제를 작성하세요.


try{                                                 // Start of the try-catch block
 throw new Exception();                             // Manually throw an exception
} catch (Exception e) {                              // Exceptions of this type and its subtypes will be caught
 System.out.println("Oops! Something went wrong =("); // Display the exception
}

102. 사용자 정의 예외를 포착하고 처리하는 예제를 작성하십시오.

먼저 Exception을 상속 하고 오류 메시지를 인수로 사용하는 생성자를 재정의하는 자체 예외 클래스를 작성해 보겠습니다 .

public class CustomException extends Exception {
 
 public CustomException(final String message) {
   super(message);
 }
}
다음으로 이전 질문의 예에서 했던 것처럼 수동으로 하나를 던지고 잡을 것입니다.

try{
 throw new CustomException("Oops! Something went wrong =(");
} catch (CustomException e) {
 System.out.println(e.getMessage());
}
다시 한 번, 코드를 실행하면 다음과 같은 결과가 나타납니다.
이런! 문제가 발생했습니다 =(
Java 개발자 직위에 대한 취업 면접의 질문과 답변을 살펴보세요.  파트 11 - 5자, 오늘은 여기까지입니다! 다음 부분에서 만나요!
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION