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

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

Random-KO 그룹에 게시되었습니다
안녕하세요! 어떤 일에 능숙해지려면 몇 시간이 걸리나요? 나는 종종 다음과 같은 말을 들었습니다. “어떤 일이든 마스터하려면 10,000시간을 투자해야 합니다.” 무서운 숫자죠? Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 1그런데 이것이 사실인지 궁금합니다. 그리고 나는 프로그래밍 기술을 익히는 데 이미 얼마나 많은 시간을 투자했는지 끊임없이 파악하려고 노력하고 있습니다. 그리고 그 소중한 1만 시간을 넘어 마스터가 되면 이런 차이를 느낄 수 있을까요? 아니면 이미 오래 전에 깨닫지도 못한 채 그것들을 넘어섰던 걸까요? 어떤 식으로든 프로그래머가 되기 위해 그렇게 많은 시간을 투자할 필요는 없습니다. 가장 중요한 것은 현명하게 사용하는 것입니다. 귀하의 주요 목표는 인터뷰에 합격하는 것입니다. 그리고 신입사원 면접에서는 이론을 먼저 물어보는데, 거기에 강해야 해요. 사실 면접을 준비할 때 당신의 임무는 자바 개발자의 기본 이론에서 부족한 부분을 모두 찾아내고 이를 지식으로 메우는 것입니다. 그리고 오늘 저는 가장 인기 있는 질문을 계속 분석하기 위해 여기에 왔기 때문에 이 문제에 대해 도움을 드리겠습니다. 그럼 계속하자!

89. ArrayList는 LinkedList와 어떻게 다릅니까?

HashMap 내부 구조에 대한 질문과 함께 가장 많이 묻는 질문 중 하나입니다 . 그것 없이는 단 한 번의 인터뷰도 완료되지 않으므로 이에 대한 대답은 "이빨에서 튀어 나와야"합니다. 명백한 것 외에도 - 다른 이름 - 내부 구조가 다릅니다. 이전에는 ArrayListLinkedList 의 내부 구조를 모두 조사했으므로 구현에 대해 자세히 설명하지 않겠습니다. ArrayList는 내부 배열을 기반으로 구현되며 공식에 따라 필요에 따라 증가된다는 점을 상기시켜 드리겠습니다 .
<размерТекущегоМассива> * 3 / 2  + 1
동시에 LinkedList는 내부 이중 연결 목록을 기반으로 구현됩니다. 즉, 각 요소에는 목록의 시작/끝 값을 제외하고 이전 및 다음 요소에 대한 링크가 있습니다. 사람들은 " ArrayList 또는 LinkedList 중 어느 것이 더 낫습니까?"라는 형식으로 이 질문을 하기를 좋아합니다 . 결국, 그 중 하나를 답으로 지적하면 그것은 틀린 답이 될 것입니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 2대신, 인덱스 액세스 또는 목록 중간에 삽입 등 어떤 특정 상황에 대해 이야기하고 있는지 명확히 해야 합니다. 답변에 따라 귀하의 선택을 설명할 수 있습니다. 나는 이전에 ArrayListLinkedList가 어떤 상황에서 어떻게 작동하는지 설명했습니다. 비교를 위해 동일한 페이지에 배치하여 이를 요약해 보겠습니다. 요소 추가(추가)
  1. Добавление нового element без указания индекса How местоположения будет происходить автоматически в конец обоих списков. В LinkedList новый элемент станет новым хвостом (происходит только перезаписывание пары ссылок — алгоритмическая сложность O(1)).

    В ArrayList будет добавлен новый элемент в последнюю пустую ячейку массива — O(1).

  2. Добавление element по индексу How правило подразумевает вставку примерно в середину списка. В LinkedList сперва будет вестись поиск нужного места с помощью перебора элементов с “хвоста” и “головы” — O(n/2), а после — вставка значения путем переопределения ссылок элементов, между которыми вставляется новый — O(1). Суммарная алгоритмическая сложность данного действия будет O(n/2).

    ArrayList в данной ситуации по индексу находит элемент — O(1), и все элементы справа (включая элемент, который уже хранится по данному индексу) двигаются на одну единицу вправо (при этом возможно понадобится создание нового списка и копирование элементов в него) — O(n/2). Суммарная сложность — O(n/2).

  3. Добавление element в начало списка в LinkedList будет ситуация схожая с добавлением в конец: новый элемент станет новой “головой” — O(1), в то же время когда ArrayList-у нужно будет двигать все элементы вправо — O(n).

결론: LinkedList 에서 알고리즘 복잡성의 범위는 O(1) 에서 O(n/2) 입니다 . 즉, 삽입이 목록의 끝이나 시작에 가까울수록 속도가 빨라집니다. 동시에 ArrayList 의 경우 범위는 O(1) 에서 O(n)입니다 . 삽입이 목록 끝에 가까울수록 속도가 빨라집니다. 요소 설정(세트) 이 작업은 목록의 지정된 위치에 요소를 쓰고, 이전 요소가 있는 경우 덮어씁니다. LinkedList 에서 이 작업은 추가와 유사합니다. 여기서 가장 큰 어려움은 요소를 찾는 것입니다. 한 쌍의 링크를 다시 작성하면 요소를 다시 작성할 수 있으므로 여기서도 알고리즘 복잡도는 목록의 끝이나 시작에서 위치까지의 거리에 따라 O(1) 에서 O(n/2) 까지 다양합니다. 이때 이 인덱스 작업을 위해 필요한 셀이 ArrayList 에서 발견되고 새 요소가 여기에 기록됩니다. 이 작업과 마찬가지로 인덱스 검색의 알고리즘 복잡성은 O(1) 입니다 . 인덱스로 요소 가져오기(get) LinkedList 에서 요소 가져오기는 끝이나 시작으로부터의 거리에 따라 다른 작업을 검색하는 것과 동일한 원칙에 따라 발생합니다. O(1) 에서 O(n/2) 까지 . ArrayList 에서 앞서 말했듯이 인덱스로 배열의 요소를 찾는 것은 O(1) 복잡도를 갖습니다 . 인덱스로 요소 제거(제거) LinkedList 의 경우 작동 원리는 여기서도 작동합니다. 먼저 요소를 찾은 다음 링크를 덮어씁니다. 요소의 이웃이 서로 참조하기 시작하여 이 요소에 대한 참조가 손실됩니다. 이후 가비지 수집기에 의해 삭제됩니다. 즉, 알고리즘 복잡성은 O(1) 에서 O(n/2) 까지 여전히 동일합니다 . ArrayList 의 경우 이 작업은 새 요소를 추가하는 작업(추가)과 더 유사합니다. 먼저 필요한 요소( O(1)) 를 찾은 다음 제거하고 오른쪽에 있던 모든 요소를 ​​한 단위 왼쪽으로 이동하여 결과 간격을 좁힙니다. 삭제 작업은 O(1) 에서 O(n) 까지 추가 작업과 동일한 알고리즘 복잡성을 갖습니다 . 삭제가 목록의 끝에 가까울수록 알고리즘의 복잡성이 줄어듭니다. 사실 이것들은 모두 주요 작업이었습니다. 상기시켜 드리겠습니다. 이 두 목록을 비교할 때 우리가 말하는 특정 상황이 무엇인지 명확히 해야 하며, 그런 다음 제시된 질문에 명확하게 대답할 수 있습니다.

90. ArrayList는 HashSet과 어떻게 다릅니까?

ArrayListLinkedList를 작업 측면에서 비교할 수 있다면(더 나은 경우) 완전히 다른 컬렉션이기 때문에 ArrayListHashSet을 비교하는 것은 그리 쉽지 않습니다 . 하나의 달콤한 요리를 다른 요리와 비교할 수 있지만 고기 요리로 해결됩니다. 너무 다릅니다. 그러나 나는 그들 사이에 몇 가지 차이점을 제시하려고 노력할 것입니다.
  • ArrayList는 List 인터페이스를 구현 하고 HashSet은 Set 인터페이스를 구현합니다 .

  • ArrayList 에서는 요소 인덱스를 통해 액세스가 가능합니다. 가져오기 작업 의 알고리즘 복잡도는 O(1) 이고 HashSet 에서는 필수 요소를 무차별 대입 방식으로만 얻을 수 있으며 이는 O(1) 에서 O(n) 까지 입니다. ;

  • ArrayList는 중복 요소를 허용합니다. HashSet 에서는 모든 요소가 고유합니다. 컬렉션에 이미 아날로그가 존재하는 HashSet 에 요소를 추가하면 작동하지 않습니다(중복은 해시코드를 사용하여 확인되므로 이 컬렉션의 이름이 됩니다).

  • ArrayList 는 내부 배열을 사용하여 구현되고 HashSet은 내부 HashMap을 사용하여 구현됩니다 .

  • ArrayList는 요소의 삽입 순서를 유지하는 반면, HashSet은 순서가 지정되지 않은 집합이며 요소의 순서를 유지하지 않습니다.

  • ArrayList는 빈 값(null)을 개수 제한 없이 허용하며 HashSet 에는 하나의 null 값만 삽입할 수 있습니다 (결국 요소의 고유성).

91. Java에는 왜 그렇게 다양한 동적 배열 구현이 있습니까?

Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 3글쎄, 이것은 철학적인 질문에 가깝습니다. 그렇다면 왜 그들은 그렇게 다양한 신기술을 생각해 내는 걸까요? 편안함을 위해. 실제로 동적 배열 구현이 많은 경우에도 마찬가지입니다. 그 어느 것도 최고나 이상이라고 할 수 없습니다. 각각은 특정 상황에서 이점을 갖습니다. 그리고 우리의 임무는 올바른 상황에서 가장 적합한 것을 사용할 수 있도록 차이점과 강점/약점을 아는 것입니다.

92. Java에는 왜 이렇게 다양한 키-값 저장소 구현이 있습니까?

여기서 상황은 동적 배열 구현과 동일합니다. 가장 좋은 사람은 없습니다. 각각의 장점과 단점이 있습니다. 그리고 물론 우리는 우리의 강점을 최대한 활용해야 합니다. 예: 많은 다중 스레드 기술을 포함하는 동시 패키지에는 자체 Concurrent 컬렉션이 있습니다. 동일한 ConcurrentHashMap은 일반 HashMap 에 비해 데이터를 다루는 멀티스레드 작업의 안전성 측면에서 장점이 있지만 , 멀티스레드가 아닌 환경에서는 속도가 떨어집니다. 글쎄, 어떤 상황에서도 가장 강력하지 않은 구현은 점차 사용이 중단됩니다. 예: Hashtable은 원래 스레드로부터 안전한 HashMap 으로 의도되었지만 ConcurrentHashMap은 다중 스레드 환경에서 이를 능가했으며 Hashtable은 결국 잊혀져 더 이상 사용되지 않습니다.

93. 요소 모음을 정렬하는 방법은 무엇입니까?

가장 먼저 말해야 할 것은 컬렉션 요소 클래스는 Comparable 인터페이스 와 해당 CompareTo 메서드를 구현해야 한다는 것입니다 . 또는 비교기 메서드를 사용하여 Comaprator를 구현하는 클래스가 필요합니다 . 이 게시물 에서 이에 대한 자세한 내용을 읽을 수 있습니다 . 두 방법 모두 주어진 유형의 객체를 비교하는 방법을 지정합니다. 정렬할 때 요소를 비교할 수 있는 원리를 이해해야 하기 때문에 이는 매우 중요합니다. 이를 수행하는 주요 방법은 정렬하려는 클래스에서 직접 구현된 Comparable 을 구현하는 것입니다. 동시에 비교기 의 사용은 덜 일반적입니다. Comparable 구현이 없는 일부 라이브러리의 클래스를 사용하고 있지만 어떻게든 정렬해야 한다고 가정해 보겠습니다. 이 클래스의 코드를 변경할 수 없으면(확장 제외) Comparator 구현을 작성할 수 있습니다 . 여기서는 이 클래스의 개체를 비교하려는 원칙을 나타냅니다. 그리고 또 하나의 예입니다. 동일한 유형의 객체를 정렬하는 데 서로 다른 원칙이 필요하므로 다양한 상황에서 사용하는 여러 비교기를 작성한다고 가정해 보겠습니다. 일반적으로 많은 클래스가 이미 Comparable 인터페이스 (동일한 String) 를 구현하고 있습니다 . 사실, 그것들을 사용할 때 어떻게 비교해야 할지 걱정할 필요가 없습니다. 그냥 가져다가 사용하면 됩니다. 첫 번째 이자 가장 확실한 방법 은 요소 클래스 비교기에 따라 이미 정렬된 순서로 요소를 저장하는 TreeSet 또는 TreeMap 과 같은 컬렉션을 사용하는 것입니다 . TreeMap은 키를 정렬하지만 값은 정렬하지 않는다는 점을 기억하세요 . Comparable 대신 Comparator 구현을 사용하는 경우 생성 시 해당 개체를 컬렉션 생성자에 전달해야 합니다.
TreeSet treeSet = new TreeSet(customComparator);
하지만 다른 유형의 컬렉션이 있다면 어떨까요? 어떻게 정렬하나요? 이 경우 Collections 유틸리티 클래스의 두 번째 메소드 인 sort() 메소드가 적합합니다 . 이는 정적이므로 클래스 이름과 필수 목록이 전달되는 메서드만 있으면 됩니다. 예를 들어:
Collections.sort(someList);
Comparable 을 사용하지 않고 Comparator 구현을 사용하는 경우 이를 두 번째 매개변수로 전달해야 합니다.
Collections.sort(someList, customComparator);
결과적으로 전달된 목록 요소의 내부 순서가 변경됩니다. 요소 비교기에 따라 정렬됩니다. 전송된 요소 목록은 변경 가능해야 합니다. 그렇지 않으면 메서드가 작동하지 않고 UnsupportedOperationException이 발생합니다 . 세 번째 방법 으로 , Comparable 구현이 사용되는 경우 컬렉션의 요소를 정렬하는 Stream 정렬 작업을 사용할 수 있습니다 .
someList = someList.stream().sorted().collect(Collectors.toList());
비교기 인 경우 :
someList = someList.stream().sorted(customComparator).collect(Collectors.toList());
이 문서 에서 Stream 에 대한 자세한 내용을 읽을 수 있습니다 . 네 번째 방법은 버블 정렬 이나 병합 정렬 과 같은 정렬을 수동으로 구현하는 것입니다 .

ClassObject. 같음 및 해시코드

94. Java의 클래스 객체에 대해 간략하게 설명해주세요.

분석의 두 번째 부분에서 우리는 이미 Object 클래스의 메소드에 대해 이야기했으며 Object 클래스는 Java의 모든 클래스의 조상이라는 점을 상기시켜 드리겠습니다 . 여기에는 11개의 메서드가 있으며 그에 따라 모든 클래스에서 상속됩니다. 11가지 방법 모두에 대한 정보는 토론의 두 번째 부분에서Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 4 찾을 수 있습니다 .

95. Java에서 Equals와 HashCode는 무엇에 사용됩니까?

hashCode() 는 모든 클래스에 상속되는 Object 클래스 의 메서드입니다 . 그 임무는 특정 객체를 나타내는 숫자를 생성하는 것입니다. 이 방법을 사용하는 예로는 쌍이 저장될 내부 배열(버킷)의 셀을 결정하는 로컬 해시코드를 추가로 결정하기 위해 키 객체의 HashMap 에서 사용하는 것입니다. 분석 9부에서 HashMap 의 작업에 대해 자세히 설명했으므로 이에 대해 너무 많이 다루지는 않겠습니다. 또한 일반적으로 이 메서드는 객체의 ID를 결정하는 주요 도구 중 하나로 equals() 메서드에서 사용됩니다. equals() 는 객체를 비교하고 동일한지 여부를 결정하는 작업을 수행하는 Object 클래스 의 메서드입니다 . 이 방법은 객체를 비교해야 하는 모든 곳에서 사용됩니다. ==를 사용한 일반적인 비교는 객체에 적합하지 않기 때문입니다. 해당 링크만 비교합니다. Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 5

96. Java에서 Equals와 HashCode 간의 계약에 대해 알려주십시오.

가장 먼저 말씀드리고 싶은 것은 equals()hashCode() 메서드가 올바르게 작동하려면 올바르게 재정의되어야 한다는 것입니다. 그 후에는 다음 규칙을 따라야 합니다.
  • 같음을 통한 비교가 true를 반환 하는 동일한 객체는 동일한 해시 코드 가져야 합니다 .
  • 동일한 해시 코드를 가진 객체가 항상 동일하지는 않을 수 있습니다.
이 시점에서 분석의 다음 부분까지 일시 중지하겠습니다!Java 개발자 인터뷰의 질문과 답변을 분석합니다.  파트 10 - 6
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION