Java 미드레벨 CS 기초 기술면접
새 면접Q. HashMap과 TreeMap의 내부 구조와 시간복잡도 차이를 설명하고, 각각 어떤 상황에서 사용하는 것이 적절한지 설명해주세요. 또한 HashMap에서 해시 충돌이 발생했을 때 Java 8 이후 어떻게 처리되는지도 함께 설명해주세요.
HashMap은 해시 테이블 기반으로 O(1)의 조회/삽입 성능을 제공하며, TreeMap은 Red-Black Tree 기반으로 O(log n)의 성능을 제공합니다. HashMap은 순서가 중요하지 않고 빠른 조회가 필요할 때 사용하며, TreeMap은 키의 정렬 순서가 필요하거나 범위 검색이 필요할 때 사용합니다. Java 8 이후 HashMap은 해시 충돌 시 버킷의 엔트리 개수가 8개를 초과하면 연결 리스트에서 Red-Black Tree로 변환하여 최악의 경우 O(n)에서 O(log n)으로 성능을 개선합니다. 엔트리가 6개 이하로 줄어들면 다시 연결 리스트로 전환됩니다.
- • HashMap은 해시 테이블 기반 O(1), TreeMap은 Red-Black Tree 기반 O(log n)
- • HashMap은 빠른 조회, TreeMap은 정렬/범위 검색에 적합
- • Java 8 이후 HashMap은 충돌 시 8개 초과 시 Tree 구조로 변환하여 성능 개선
HashMap의 초기 capacity와 load factor를 설정할 때 고려해야 할 사항과, rehashing이 발생하는 시점과 성능에 미치는 영향을 설명해주세요.
Q. TCP와 UDP의 차이점을 설명하고, 각 프로토콜의 헤더 크기와 3-way handshake 과정을 설명해주세요. 실무에서 HTTP/3가 UDP 기반의 QUIC 프로토콜을 사용하는 이유는 무엇인가요?
TCP는 연결 지향적이고 신뢰성 있는 전송을 보장하며 헤더 크기가 20-60바이트이고, UDP는 비연결성이고 신뢰성을 보장하지 않으며 헤더 크기가 8바이트입니다. TCP의 3-way handshake는 SYN, SYN-ACK, ACK 세 단계로 연결을 수립합니다. HTTP/3가 UDP 기반 QUIC를 사용하는 이유는 TCP의 HOL(Head-of-Line) Blocking 문제를 해결하고, 연결 수립 시간을 단축하며(0-RTT), 스트림 단위로 독립적인 전송을 가능하게 하여 패킷 손실 시에도 다른 스트림에 영향을 주지 않기 때문입니다.
- • TCP는 연결 지향/신뢰성 보장(20-60바이트), UDP는 비연결/빠른 전송(8바이트)
- • 3-way handshake: SYN → SYN-ACK → ACK
- • HTTP/3는 QUIC로 HOL Blocking 해결, 연결 수립 시간 단축, 스트림 독립성 확보
실시간 영상 스트리밍 서비스를 개발할 때 TCP와 UDP 중 어떤 프로토콜을 선택하시겠습니까? 그 이유와 함께 발생할 수 있는 문제점과 해결 방안을 설명해주세요.
Q. 데이터베이스 인덱스의 B-Tree와 B+Tree 구조의 차이점을 설명하고, 왜 대부분의 RDBMS가 B+Tree를 사용하는지 설명해주세요. 또한 인덱스를 생성했음에도 Full Table Scan이 발생하는 경우와 그 이유를 설명해주세요.
B-Tree는 모든 노드에 데이터를 저장하지만, B+Tree는 리프 노드에만 데이터를 저장하고 내부 노드는 키만 저장합니다. B+Tree는 리프 노드가 연결 리스트로 연결되어 있어 범위 검색에 유리하고, 내부 노드가 더 많은 키를 저장할 수 있어 트리의 높이가 낮아져 디스크 I/O가 감소합니다. 인덱스가 있어도 Full Table Scan이 발생하는 경우는 인덱스 컬럼에 함수나 연산을 적용했을 때, 데이터 분포상 카디널리티가 낮을 때, OR 조건 사용 시, 타입이 불일치할 때, 또는 옵티마이저가 인덱스 스캔보다 Full Scan이 더 효율적이라고 판단할 때입니다.
- • B+Tree는 리프 노드에만 데이터 저장, 리프 노드 간 연결 리스트로 범위 검색 최적화
- • 내부 노드에 더 많은 키 저장 가능하여 트리 높이 감소, 디스크 I/O 감소
- • 인덱스 무효화: 함수 적용, 낮은 카디널리티, OR 조건, 타입 불일치, 옵티마이저 판단
커버링 인덱스(Covering Index)의 개념과 장점을 설명하고, 실무에서 커버링 인덱스를 설계할 때 고려해야 할 trade-off를 설명해주세요.
Q. 프로세스와 스레드의 차이점을 메모리 구조 관점에서 설명하고, 컨텍스트 스위칭이 발생할 때 각각의 오버헤드 차이를 설명해주세요. Java 애플리케이션에서 멀티스레드 환경의 장단점도 함께 설명해주세요.
프로세스는 독립적인 메모리 공간(Code, Data, Heap, Stack)을 가지며, 스레드는 같은 프로세스 내에서 Code, Data, Heap을 공유하고 Stack만 독립적으로 가집니다. 프로세스 간 컨텍스트 스위칭은 메모리 주소 공간 전체를 교체해야 하므로 오버헤드가 크지만, 스레드 간 스위칭은 Stack과 레지스터만 교체하므로 오버헤드가 작습니다. Java 멀티스레드의 장점은 자원 공유로 인한 메모리 효율성과 빠른 응답성이며, 단점은 동기화 문제, 데드락 가능성, 디버깅의 어려움, 그리고 공유 자원 접근 시 발생하는 경쟁 조건입니다.
- • 프로세스는 독립 메모리 공간, 스레드는 Stack만 독립적이고 나머지는 공유
- • 스레드 컨텍스트 스위칭이 프로세스보다 오버헤드가 작음(메모리 주소 공간 유지)
- • 멀티스레드 장점은 자원 효율성/응답성, 단점은 동기화 문제/데드락/디버깅 어려움
Java에서 ThreadLocal을 사용하는 이유와 동작 원리를 설명하고, ThreadLocal 사용 시 메모리 누수가 발생할 수 있는 상황과 예방 방법을 설명해주세요.
Q. 정렬 알고리즘 중 QuickSort와 MergeSort의 시간복잡도와 공간복잡도를 비교 설명하고, 각각의 장단점과 어떤 상황에서 사용하는 것이 적절한지 설명해주세요. Java의 Arrays.sort()와 Collections.sort()가 내부적으로 어떤 알고리즘을 사용하는지도 함께 설명해주세요.
QuickSort는 평균 O(n log n), 최악 O(n²)의 시간복잡도를 가지며 in-place 정렬로 O(log n)의 공간복잡도를 가집니다. MergeSort는 항상 O(n log n)의 시간복잡도를 보장하지만 O(n)의 추가 공간이 필요합니다. QuickSort는 캐시 효율성이 좋고 평균적으로 빠르지만 불안정 정렬이며, MergeSort는 안정 정렬이고 최악의 경우에도 성능이 보장되지만 추가 메모리가 필요합니다. Java의 Arrays.sort()는 기본 타입에 Dual-Pivot QuickSort를, 객체 타입에 TimSort(MergeSort + InsertionSort)를 사용하며, Collections.sort()는 TimSort를 사용하여 안정성을 보장합니다.
- • QuickSort는 평균 O(n log n)/최악 O(n²), in-place 정렬, MergeSort는 항상 O(n log n), O(n) 추가 공간
- • QuickSort는 빠르지만 불안정, MergeSort는 안정 정렬이고 성능 보장
- • Arrays.sort()는 기본 타입에 Dual-Pivot QuickSort, 객체는 TimSort 사용
실무에서 대용량 데이터를 정렬해야 할 때 메모리 제약이 있는 상황이라면 어떤 정렬 알고리즘이나 접근 방식을 선택하시겠습니까? 외부 정렬(External Sort)의 개념도 함께 설명해주세요.
아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!