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

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

Random-KO 그룹에 게시되었습니다
안녕, 친구! 개발자가 되려면 얼마나 걸리나요? 다양한 사람들에게 물어봤고, 다양한 답변을 들었습니다. 어떤 사람에게는 한 달이면 충분할 수 있지만, 어떤 사람에게는 1년이라도 충분하지 않을 수 있습니다. 그러나 나는 초기 능력에 관계없이 Java 개발자가 되는 것이 어렵고 험난한 길이라는 것을 확실히 알고 있습니다. 결국 중요한 것은 능력이 아니라 고집과 노력만큼 중요합니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 1따라서 오늘 우리는 Java 개발자에게 가장 인기 있는 면접 질문을 의도적으로 계속 분석합니다. 그것들을 공부하면 점차적으로 소중한 목표에 더 가까워질 것입니다. 시작하자!

17. Optional 사용의 성공 사례와 실패 사례를 제시하세요.

스트림을 통과하는 특정 일련의 값이 있고 결국 결과적으로 일부 Optional을 얻는다고 가정합니다.
Optional<String> stringOptional = Stream.of("a", "ab", "abc", "abcd")
   .filter(str -> str.length() >= 3)
   .findAny();
예상대로 우리는 이 Optional 에서 값을 얻어야 합니다 . get()을 사용하는 것은 나쁜 방법입니다.
String result = stringOptional.get();
그런데 이 메서드는 Optional 에서 값을 가져 와서 우리에게 반환 해야 합니까 ? 물론 이것은 사실이지만 의미가 있다면. 음, 스트림의 값이 다르고 결국 빈 Optional 을 받은 경우 get() 메서드를 사용하여 값을 가져오려고 하면 다음이 발생합니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 2좋지 않습니다. 이 경우 다음 구성을 사용하는 것이 좋습니다.
  1. String result = null;
    if (stringOptional.isPresent()) {
     stringOptional.get();
    }

    이 경우 요소가 Optional 에 있는지 확인하고 있습니다 . 그렇지 않은 경우 결과 문자열은 이전 값을 갖습니다.

  2. String result = stringOptional.orElse("default value");

    이 경우 빈 Optional 의 경우 결과 문자열에 제공될 일부 기본값을 지정합니다 .

  3. String result = stringOptional.orElseThrow(() -> new CustomException());

    이 경우 Optional이 비어 있으면 예외가 발생합니다 .

이는 예를 들어 Spring JPA 메서드( 선택적 값을 반환하는 findById()) 가 사용되는 경우 애플리케이션에서 편리할 수 있습니다 . 이 경우 이 메서드를 사용하여 값을 가져오려고 시도하고 값이 없으면 일부 런타임 예외를 발생시킵니다. 이 예외는 ExceptionHandler를 사용하여 컨트롤러 수준에서 처리되고 404 - NOT FOUND 상태의 HTTP 응답 으로 변환됩니다 . Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 3

18. 메인 메소드를 final로 선언하는 것이 가능한가요?

예, 물론 main() 메소드를 final 로 선언하는 것을 방해하는 것은 없습니다 . 컴파일러는 오류를 생성하지 않습니다. 그러나 final 로 선언한 모든 메소드는 재정의되지 않고 마지막 메소드가 된다는 점을 기억할 가치가 있습니다 . 하지만 누가 메인을 재정의할까요 ??? Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 4

19. 동일한 패키지/클래스를 두 번 가져올 수 있습니까? 그 결과는 무엇입니까?

그래 넌 할수있어. 결과? Intelijj IDEA가 회색으로 표시할 몇 가지 불필요한 가져오기가 있습니다. 미사용. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 5Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 6

20. 캐스팅이란 무엇입니까? ClassCastException은 언제 발생할 수 있나요?

캐스팅 또는 유형 캐스팅은 하나의 데이터 유형을 다른 데이터 유형으로 수동(암시적 캐스팅) 또는 자동(명시적 유형 캐스팅)으로 변환하는 프로세스입니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 7자동 변환은 컴파일러에 의해 수행되고 수동 변환은 개발자가 수행합니다. 프리미티브와 클래스의 타입 캐스팅은 다소 다르기 때문에 별도로 고려하겠습니다. 기본 유형 기본 유형의 자동 캐스팅 예 :
int value = 17;
double convertedValue = value;
보시다시피 여기서는 = 기호 이외의 추가 조작이 필요하지 않습니다. 기본 유형의 수동 캐스팅 예 :
double value = 17.89;
int convertedValue = (int)value;
이 경우 (int)를 사용하여 구현되는 수동 형변환을 관찰할 수 있습니다 . 그러면 쉼표 뒤의 부분이 삭제되고 ConvertValue 의 값은 - 17이 됩니다. 이 기사 에서 형변환에 대한 자세한 내용을 읽어보세요 . 자, 이제 객체로 넘어 갑시다. 참조 유형 참조 유형 의 경우 하위 클래스에서 상위 클래스로의 자동 캐스팅이 가능합니다. 이를 다형성 이라고도 합니다 . Cat 클래스 를 상속받은 Lion 클래스 가 있다고 가정해 보겠습니다 . 이 경우 자동 변환은 다음과 같습니다.
Cat cat = new Lion();
하지만 명시적 캐스트를 사용하면 모든 것이 다소 복잡해집니다. 기본 형식처럼 초과분을 잘라내는 기능이 없기 때문입니다. 그리고 다음 형식을 명시적으로 변환하면 됩니다.
Lion lion= (Lion)new Cat();
오류가 발생합니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 8실제로 원래 Cat 클래스 에 없었던 Lion 하위 클래스에 메서드를 추가한 다음 이를 호출하려고 시도할 수 있습니다. 개체 유형이 Lion 이 되기 때문입니다 . 글쎄, 여기에는 논리가 없습니다. 따라서 유형 축소는 원래 객체가 Lion 유형 이지만 나중에 상위 클래스로 캐스팅된 경우에만 가능합니다.
Lion lion = new Lion();
Cat cat = lion;
Lion newLion = (Lion)cat;
또한 신뢰성을 높이기 위해 objectOf 구문을 사용하여 객체의 범위를 좁히는 것이 좋습니다 .
if (cat instanceof Lion) {
 newLion = (Lion)new Cat();
}
이 기사에서 참조 유형 캐스트에 대해 자세히 알아보세요 .

21. 현대 프레임워크에서는 왜 확인되지 않은 예외만 주로 사용합니까?

확인된 예외를 처리하는 것은 여전히 ​​​​모든 곳에서 반복되는 스파게티 코드이지만 모든 경우에 실제로 필요한 것은 아니기 때문에 이것이 전부라고 생각합니다 . Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 9그러한 경우, 처리를 다시 개발자의 어깨로 옮기지 않도록 프레임워크 내부에서 처리를 수행하는 것이 더 쉽습니다. 예, 물론 긴급 상황이 발생할 수 있지만 이러한 동일한 확인되지 않은 예외는 try-catch 처리를 방해하거나 메서드를 통해 추가로 전달하지 않고도 보다 편리한 방법으로 처리할 수 있습니다 . 예외를 예외 핸들러 의 일부 HTTP 응답으로 변환하는 것만으로도 충분합니다 .

22. 정적 가져오기란 무엇입니까?

정적 데이터(메서드, 변수)를 사용할 때 객체 자체를 생성할 수는 없고 클래스 이름으로 생성하는데, 이 경우에도 클래스에 대한 참조가 필요합니다. 모든 것이 간단합니다. 일반 가져오기를 사용하여 추가됩니다. 그런데 마치 현재 클래스의 정적 메서드인 것처럼 클래스 이름을 쓰지 않고 정적 메서드를 사용하게 된다면 어떻게 될까요? 이는 정적 가져오기를 통해 가능합니다! 이 경우 정적 가져오기 및 해당 메서드에 대한 링크를 작성해야 합니다. 예를 들어, 코사인 값을 계산하기 위한 Math 클래스의 정적 메서드는 다음과 같습니다.
import static java.lang.Math.cos;
결과적으로 클래스 이름을 지정하지 않고도 메서드를 사용할 수 있습니다.
double result = cos(60);
정적 가져오기를 사용하여 클래스의 모든 정적 메서드를 한 번에 간단히 로드할 수도 있습니다.
import static java.lang.Math.*;
Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 10

23. hashCode()와 equals() 메소드 사이의 관계는 무엇입니까?

Oracle 에 따르면 규칙은 다음과 같습니다. 두 객체가 동일한 경우(즉, equals() 메서드가 true를 반환하는 경우 ) 두 객체는 ​​동일한 해시 코드를 가져야 합니다. 동시에, 서로 다른 두 개체가 동일한 해시 코드를 가질 수 있다는 점을 잊지 마십시오. 왜 equals()hashCode()가 항상 쌍으로 재정의되는지 이해하려면 다음 사례를 고려하십시오.
  1. 두 방법 모두 재정의됩니다.

    이 경우 내부 상태가 동일한 두 개의 서로 다른 객체는 equals() - true 를 반환 하고 hashCode() 는 둘 다 동일한 숫자를 반환합니다.

    규칙이 준수되고 있기 때문에 모든 것이 괜찮은 것으로 나타났습니다.

  2. 두 방법 모두 재정의되지 않습니다.

    이 경우, 내부 상태가 동일한 두 개의 서로 다른 객체는 == 연산자를 통해 참조로 비교되기 때문에 == 연산자를 통해 동등 할 때 false를 반환합니다 .

    hashCode() 메서드는 메모리 위치 주소의 변환된 값을 생성하므로 다른 값(아마도)을 반환합니다. 그러나 동일한 객체의 경우 이 값은 동일합니다. 이 경우에는 참조가 동일한 객체를 가리키는 경우에만 true를 반환하는 equals() 와 같습니다.

    이 경우 모든 것이 정상이며 규칙이 충족되는 것으로 나타났습니다.

  3. 재정의된 hashCode() 가 아니라 재정의된 equals( ) 입니다 .

    이 경우 내부 상태가 동일한 두 개의 서로 다른 객체에 대해 equals()는 true를 반환 하고 hashCode()는 (아마도) 다른 값을 반환합니다.

    이는 규칙 위반이므로 권장하지 않습니다.

  4. equals()는 재정의 되지 않고 hashCode() 는 재정의됩니다 .

    이 경우 내부 상태가 동일한 두 개의 서로 다른 객체에 대해 equals()는 false를 반환 하고 hashCode()는 동일한 값을 반환합니다.

    규칙 위반이 있으므로 접근 방식이 올바르지 않습니다.

보시다시피 이 규칙은 equals()hashCode()가 모두 재정의되거나 둘 다 전혀 재정의되지 않은 경우에만 실행될 수 있습니다. 이 기사에서 equals()hashCode()Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 11 에 대해 자세히 알아보세요 .

24. BufferedInputStream 및 BufferedOutputStream 클래스는 언제 사용됩니까?

InputStream은 일부 리소스에서 데이터를 바이트 단위로 읽는 데 사용되며 OutputStream은 데이터 바이트 단위로 쓰는 데 사용됩니다. 그러나 바이트 단위 작업은 매우 불편할 수 있으며 추가 처리가 필요할 수 있습니다(텍스트를 정상적으로 읽고 쓰기 위해서는). 실제로 이러한 바이트 레코드를 단순화하기 위해 BufferedOutputStream이 도입되었고 , 읽기용으로 BufferedInputStream이 도입되었습니다 . 이러한 클래스는 데이터를 축적하는 버퍼에 지나지 않으므로 바이트 단위가 아닌 전체 데이터 패킷(배열) 단위로 데이터 작업을 수행할 수 있습니다. BufferedInputStream이 생성되면 데이터를 읽는 InputStream 유형 의 인스턴스를 생성자로 가져옵니다 .
BufferedInputStream bufferedInputStream = new BufferedInputStream(System.in);
byte[] arr = new byte[100];
bufferedInputStream.read(arr);
System.in 은 콘솔에서 데이터를 읽는 InputStream 개체 입니다 . 즉, 이 BufferedInputStream 객체를 사용하면 전달된 배열에 데이터를 작성하여 InputStream 에서 데이터를 읽을 수 있습니다 . 이는 일종의 InputStream 클래스 래퍼로 밝혀졌습니다 . 이 예제 의 arr 배열은 BufferedInputStream 에서 데이터를 수신하는 배열입니다 . 그러면 기본적으로 크기가 2048바이트인 다른 배열을 사용하여 InputStream 에서 데이터를 읽습니다. BufferedOutputStream 의 경우에도 마찬가지입니다 . OutputStream 유형 의 인스턴스는 전체 배열의 데이터를 쓸 생성자에 전달되어야 합니다.
byte[] arr = "Hello world!!!".getBytes();
BufferedOutputStream bufferedInputStream = new BufferedOutputStream(System.out);
bufferedInputStream.write(arr);
bufferedInputStream.flush();
System.out은 콘솔에 데이터를 쓰는 OutputStream 개체 입니다 . 플러시() 메소드는 BufferedOutputStream 에서 OutputStream 으로 데이터를 전송하고 프로세스에서 BufferedOutputStream을 플러시합니다 . 이 방법이 없으면 아무것도 녹음되지 않습니다. 이전 예제와 유사합니다. arr은 BufferedOutputStream 에 데이터가 기록되는 배열입니다 . 거기에서 기본적으로 크기가 512바이트인 다른 배열의 OutputStream 에 기록됩니다 . 기사에서 이 두 클래스에 대해 자세히 알아보세요 .

25. java.util.Collection과 java.util.Collections 클래스의 차이점은 무엇입니까?

컬렉션은 컬렉션 계층 구조의 선두인 인터페이스입니다. 전체 개체 그룹을 생성, 포함 및 수정할 수 있는 클래스를 소개합니다. add() , Remove() , Contains() 등과 같이 이를 위해 제공되는 많은 메서드가 있습니다 . Collection 클래스 의 주요 인터페이스 :
  • Set은 순서가 지정되지 않은 고유한(반복되지 않는) 요소를 포함하는 집합을 설명하는 인터페이스입니다.

  • List 는 순서가 지정된 개체 시퀀스를 저장하는 데이터 구조를 설명하는 인터페이스입니다. 이러한 개체는 고유한 인덱스(번호)를 수신하며 이를 사용하여 가져오기, 삭제, 변경, 덮어쓰기 등 개체와 상호 작용할 수 있습니다.

  • 큐는 FIFO - First In First Out 규칙을 따르는 큐 형태로 요소를 저장하는 데이터 구조를 설명하는 인터페이스입니다 .

Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 12컬렉션 에 대해 자세히 알아보세요 . 컬렉션은 다양한 유틸리티 메서드를 제공하는 유틸리티 클래스입니다. 예를 들어:
  • addAll(Collection<? super T> collection, T...element) - T 유형의 전달된 요소를 collection 에 추가합니다 .

  • copy(List<? super T> dest, List<? extends T> src) - 목록 src 의 모든 요소를 ​​dest 의 목록으로 복사합니다 .

  • emptyList() - 빈 목록을 반환합니다.

  • max(Collection<? extends T> collection, Comparator<? super T> comp) - 지정된 비교기에 의해 지정된 순서에 따라 주어진 컬렉션의 최대 요소를 반환합니다.

  • unmodifyingList(List<?extends T> list) - 전달된 목록의 수정 불가능한 표현을 반환합니다.

그리고 Collections 에는 이렇게 다양하고 편리한 메소드가 많이 있습니다 . Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 13이러한 방법의 전체 목록은 Oracle 웹 사이트에서 찾을 수 있습니다 . 내가 그들이 편안하다고 말한 것은 아무것도 아닙니다. 결국 그들은 모두 정적입니다. 즉, 필요한 메소드를 호출하기 위해 이 클래스의 객체를 매번 생성할 필요가 없습니다. 클래스 이름을 입력하고 원하는 메서드를 호출한 후 필요한 모든 인수를 전달하기만 하면 됩니다. 요약하면 Collection은 컬렉션 프레임워크의 루트 인터페이스입니다. 컬렉션은 컬렉션 구조의 특정 유형에 속하는 객체를 보다 편리하게 처리하기 위한 도우미 클래스입니다. 오늘은 여기까지입니다. 모두 제일 좋다!Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 16 - 14
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION