3주차 Unit 2.6 — 컬렉션 전체 지도 정리

Psj·2026년 5월 19일

F-lab

목록 보기
83/240

Unit 2.6 — 컬렉션 전체 지도 정리

F-LAB JAVA · 3주차 · Phase 2 · 컬렉션 프레임워크 전체 지도
🏆 Phase 2 완주 — 자바 컬렉션 마스터 달성


📌 학습 목표

이 Unit을 끝내면 다음을 답할 수 있어야 한다.

  • 4가지 자료구조 (List/Set/Queue/Map) 와 모든 구현체 의 종합 지도?
  • 모든 컬렉션의 시간 복잡도 종합 표?
  • 시나리오별 의사결정 트리?
  • Phase 2 의 30가지 졸업 시험 통과?
  • Phase 3 (해시의 원리) 로 진입 준비?

🎯 핵심 한 문장

자바 컬렉션 = 4가지 자료구조 (List/Set/Queue/Map) × 다양한 구현체 (트레이드오프 선택).
각 인터페이스는 의미 를 정의하고, 각 구현체는 메모리/시간 트레이드오프 를 제공한다.
Phase 2 를 마스터하며 시나리오 → 자료구조 → 구현체 의 결정 능력을 얻었다.
이 한 Unit 에서 Unit 2.1 ~ 2.5 모든 학습이 응집 되고, 3주차의 컬렉션 학습이 졸업 한다.

비유 — 다 갖춘 도구 상자

시스템비유
List 4형제카탈로그 진열대 (순서 있음)
Set 3형제단일 컬렉션 (중복 X)
Queue 5형제대기 줄 (FIFO)
Map 5형제라벨 서랍 (키-값)
17개 구현체각자 다른 용도와 장단점

→ 컬렉션 마스터의 능력 = 정확한 도구 선택.


🧭 9개 섹션 로드맵

1. Phase 2 학습 여정 회고
2. 자바 컬렉션 전체 지도 (한눈에)
3. 4가지 자료구조 의미적 차이
4. 시간 복잡도 종합 표
5. 시나리오별 의사결정 트리
6. ILIC 의 90:9:1 법칙 완성
7. Legacy 컬렉션 (절대 안 씀)
8. Phase 2 졸업 시험 — 30문항
9. Phase 3 진입 + 능력 점검

2️⃣ 자바 컬렉션 전체 지도 (한눈에)

2.1 인터페이스 계층

Iterable<E>  (java.lang)
  │
  ▼
Collection<E>  (java.util)
  │
  ├── List<E>
  │     ArrayList, LinkedList, Vector(Legacy),
  │     CopyOnWriteArrayList, List.of (불변)
  │
  ├── Set<E>
  │   │   HashSet, LinkedHashSet, TreeSet,
  │   │   EnumSet, CopyOnWriteArraySet,
  │   │   ConcurrentHashMap.newKeySet()
  │   │
  │   └── SortedSet<E>
  │         └── NavigableSet<E>
  │               TreeSet
  │
  └── Queue<E>
      │   LinkedList, PriorityQueue,
      │   ConcurrentLinkedQueue
      │
      ├── Deque<E>
      │     ArrayDeque, LinkedList,
      │     ConcurrentLinkedDeque
      │
      └── BlockingQueue<E>
            ArrayBlockingQueue, LinkedBlockingQueue,
            PriorityBlockingQueue, DelayQueue,
            SynchronousQueue


Map<K, V>  (별도 계층)
  │   HashMap, LinkedHashMap, Hashtable(Legacy),
  │   EnumMap, WeakHashMap, IdentityHashMap,
  │   Properties(Legacy 자식)
  │
  ├── SortedMap<K, V>
  │     └── NavigableMap<K, V>
  │           TreeMap, ConcurrentSkipListMap
  │
  └── ConcurrentMap<K, V>
        ConcurrentHashMap, ConcurrentSkipListMap


Map 의 view (Collection 인터페이스 활용):
  - keySet() → Set<K>
  - values() → Collection<V>
  - entrySet() → Set<Map.Entry<K, V>>

2.2 자료구조별 구현체

List 4형제

인터페이스: List<E>

구현체:
1. ArrayList         — 배열 기반, 90% 정답
2. LinkedList        — 이중 연결, Deque 도 구현
3. Vector            — Java 1.0 Legacy
4. CopyOnWriteArrayList — 읽기 위주 멀티스레드

특수:
5. List.of (Java 9+) — 불변 List
6. Collections.synchronizedList — 동기화 wrapper

Set 6형제

인터페이스: Set<E>

구현체:
1. HashSet              — 해시 테이블 (90% 정답)
2. LinkedHashSet         — HashSet + 순서
3. TreeSet              — Red-Black Tree, 정렬
4. EnumSet              — Enum 전용, 비트벡터
5. CopyOnWriteArraySet   — 멀티스레드 (배열 기반)
6. ConcurrentHashMap.newKeySet() — 멀티스레드

특수:
7. Set.of (Java 9+) — 불변 Set

Queue 7형제

인터페이스: Queue<E>, Deque<E>, BlockingQueue<E>

일반 Queue:
1. ArrayDeque             — 원형 배열 (90% 정답)
2. LinkedList             — 비권장
3. PriorityQueue          — Binary Heap

멀티스레드 (락-프리):
4. ConcurrentLinkedQueue
5. ConcurrentLinkedDeque

멀티스레드 (BlockingQueue):
6. ArrayBlockingQueue
7. LinkedBlockingQueue
8. PriorityBlockingQueue
9. DelayQueue
10. SynchronousQueue

Map 9형제

인터페이스: Map<K, V>

구현체:
1. HashMap              — 해시 테이블 (90% 정답)
2. LinkedHashMap        — HashMap + 순서/LRU
3. TreeMap              — Red-Black Tree
4. Hashtable            — Java 1.0 Legacy
5. ConcurrentHashMap    — 멀티스레드 표준
6. ConcurrentSkipListMap — 멀티스레드 + 정렬
7. EnumMap              — Enum 키, 비트벡터
8. WeakHashMap          — GC 시 자동 제거
9. IdentityHashMap      — 참조 동일성

특수:
10. Map.of (Java 9+) — 불변 Map
11. Properties — Hashtable 의 자식 (legacy)
12. Collections.synchronizedMap — 동기화 wrapper

2.3 전체 카운트

만난 컬렉션:
  - 인터페이스: ~ 10개
  - 일반 구현체: ~ 25개
  - 특수 (불변, wrapper): ~ 7개
  
  총 30여 가지

→ Phase 2 가 자바 컬렉션의 거의 모든 풍경.

2.4 자기 점검 답변

자바 컬렉션의 최상위 인터페이스 2가지는?

:
1. Iterable<E> (java.lang)

  • for-each 가능
  • Collection 의 부모
  1. Map<K, V> (java.util)
    • 별도 계층
    • Collection 자식 아님

→ "Iterable + Map" 이 자바 컬렉션의 두 축.


3️⃣ 4가지 자료구조 의미적 차이

3.1 의미 종합 표

자료구조핵심 의미순서중복인덱스키-값
List"순서 있는 가변 시퀀스"✓ 삽입 순서
Set"중복 없는 모음"△ 구현체별
Queue"처리 대기 줄"✓ FIFO
Map"키-값 매핑"△ 구현체별키 ❌, 값 ✓

3.2 자료구조 결정 트리

시나리오 → 자료구조 결정:

자료구조 선택 5단계:

Step 1: 키-값 매핑인가?
  YES → Map
  NO  → Step 2

Step 2: 중복을 허용하는가?
  NO  → Set
  YES → Step 3

Step 3: FIFO 처리인가?
  YES → Queue
  NO  → Step 4

Step 4: 인덱스 접근 필요한가?
  YES → List
  NO  → Step 4 답: List (대부분)

Step 5: 추가 요구사항?
  - 정렬 필요? → Tree 계열
  - 순서 유지? → Linked 계열
  - 멀티스레드? → Concurrent 계열
  - Enum 키? → EnumSet/EnumMap
  - 불변? → of() 사용

3.3 의미적 분류로 본 사용처

List 사용처

"순서 있는 가변 시퀀스" —  ILIC 에서:

✓ DB 조회 결과 (JPA 가 ArrayList 반환)
✓ 도메인 객체의 컬렉션 필드 (Shipment 의 List<Cargo>)
✓ DTO 변환 결과
✓ 처리 순서가 있는 작업 단계
✓ 페이지네이션 결과

Set 사용처

"중복 없는 모음" — ILIC 에서:

✓ 권한 집합 (Set<Permission>)
✓ 처리된 ID 추적 (Set<Long> processedIds)
✓ 중복 제거된 노선 목록
✓ Enum 집합 (EnumSet)
✓ 이벤트 리스너 등록 (CopyOnWriteArraySet)

Queue 사용처

"처리 대기 줄" — ILIC 에서:

✓ 이벤트 큐 (비동기 처리)
✓ 작업 큐 (워커 스레드 풀)
✓ 알림 발송 큐
✓ 메시지 큐 클라이언트 (Kafka 내부)
✓ BFS 그래프 탐색 (경로 계산)

Map 사용처

"키-값 매핑" — ILIC 에서:

✓ 캐시 (Map<Long, Shipment>)
✓ 인덱싱 (List → Map 변환)
✓ 그룹핑 결과 (groupingBy)
✓ 카운팅 (counting)
✓ 설정값 매핑
✓ JSON 응답 (LinkedHashMap)
✓ 시간순 이벤트 (TreeMap)

3.4 자기 점검 답변

Map 과 List 의 결정적 차이를 한 문장으로?

:

  • Map: 키로 값을 찾는 매핑 — "이름으로 도서 찾기"
  • List: 순서대로 나열된 시퀀스 — "도서 목록 읽기"

선택:

  • 키로 빠른 조회 → Map
  • 순서대로 작업 → List

4️⃣ 시간 복잡도 종합 표

4.1 List 시간 복잡도

작업ArrayListLinkedListVectorCopyOnWriteArrayList
get(i)O(1)O(n)O(1)O(1)
add(e)O(1) amortizedO(1)O(1) synchronizedO(n) 복사
add(0, e)O(n)O(1)O(n)O(n)
add(i, e) 중간O(n)O(n)O(n)O(n)
remove(끝)O(1)O(1)O(1)O(n)
remove(0)O(n)O(1)O(n)O(n)
containsO(n)O(n)O(n)O(n)
sizeO(1)O(1)O(1)O(1)
멀티스레드unsafeunsafesafesafe (락-프리 읽기)

4.2 Set 시간 복잡도

작업HashSetTreeSetLinkedHashSetEnumSet
add(e)O(1) 평균O(log n)O(1) 평균O(1)
contains(e)O(1) 평균O(log n)O(1) 평균O(1)
remove(e)O(1) 평균O(log n)O(1) 평균O(1)
iteratorO(capacity)O(log n)O(1)O(1)
순회O(n + capacity)O(n)O(n)O(n)
first/last(없음)O(log n)(없음)(없음)

4.3 Queue 시간 복잡도

작업ArrayDequeLinkedListPriorityQueueBlockingQueue
offer(e)O(1)O(1)O(log n)O(1) ~ O(log n)
poll()O(1)O(1)O(log n)O(1) ~ O(log n)
peek()O(1)O(1)O(1)O(1)
containsO(n)O(n)O(n)O(n)
put (차단)O(1) ~ blocking
take (차단)O(1) ~ blocking

4.4 Map 시간 복잡도

작업HashMapLinkedHashMapTreeMapHashtableConcurrentHashMap
putO(1) 평균O(1) 평균O(log n)O(1) syn.O(1) 평균
getO(1) 평균O(1) 평균O(log n)O(1) syn.O(1) 평균
removeO(1) 평균O(1) 평균O(log n)O(1) syn.O(1) 평균
containsKeyO(1) 평균O(1) 평균O(log n)O(1) syn.O(1) 평균
containsValueO(n)O(n)O(n)O(n)O(n)
firstKey/lastKey(없음)(없음)O(log n)(없음)(없음)
sizeO(1)O(1)O(1)O(1)O(1) 근사
멀티스레드unsafeunsafeunsafesafesafe (lock-stripe)

4.5 최악의 경우

Java 8+ 의 트리 변환:

HashSet, HashMap:
  - 평균: O(1)
  - 최악 (모든 키 같은 버킷): O(log n) (Java 8+ 트리)
  - Java 7 까지는 O(n) (연결 리스트만)

ConcurrentHashMap 도 동일

4.6 시간 복잡도 가벼운 암기법

암기:

자료구조 → 평균 → 최악:

HashSet, HashMap:
  → O(1) → O(log n)

TreeSet, TreeMap:
  → O(log n) → O(log n)

LinkedList:
  → O(1) 양 끝, O(n) 중간

ArrayList:
  → O(1) 인덱스, O(n) 중간

ArrayDeque (Queue):
  → O(1) 양 끝

PriorityQueue:
  → O(log n) 삽입/추출, O(1) peek

4.7 자기 점검 답변

ArrayList 의 add(e) 가 O(1) amortized 인 이유와 LinkedList 의 add(e) 가 O(1) 인 이유의 차이는?

:

  • ArrayList:

    • 일반적: O(1) (배열 끝 대입)
    • 가끔: O(n) (1.5배 확장 시 복사)
    • 평균하면 amortized O(1)
  • LinkedList:

    • 항상 O(1) (마지막 노드의 next 만 갱신)
    • 확장 개념 없음 (노드 무한 추가)
    • 진짜 O(1)

→ 미묘한 차이지만 의미 다름.


5️⃣ 시나리오별 의사결정 트리

5.1 종합 의사결정 트리

시나리오 → 자료구조 → 구현체:

[Step 1: 자료구조 결정]

키로 값 찾는가?
├── YES → Map (Step 2-M)
└── NO  → 다음

중복 허용?
├── NO  → Set (Step 2-S)
└── YES → 다음

FIFO 처리?
├── YES → Queue (Step 2-Q)
└── NO  → List (Step 2-L)


[Step 2-M: Map 구현체 결정]

추가 요구사항:
├── 정렬 키 → TreeMap
├── 순서/LRU → LinkedHashMap
├── 멀티스레드 → ConcurrentHashMap
├── Enum 키 → EnumMap
├── 불변 → Map.of
└── 그 외 → HashMap (90%)


[Step 2-S: Set 구현체 결정]

추가 요구사항:
├── 정렬 → TreeSet
├── 순서 → LinkedHashSet
├── 멀티스레드 → ConcurrentHashMap.newKeySet()
├── Enum → EnumSet
├── 불변 → Set.of
└── 그 외 → HashSet (90%)


[Step 2-Q: Queue 구현체 결정]

멀티스레드?
├── NO → Step 3-Q-single
└── YES → Step 3-Q-multi

Step 3-Q-single:
  ├── 우선순위 → PriorityQueue
  ├── Stack 도 → ArrayDeque (push/pop)
  └── 일반 → ArrayDeque

Step 3-Q-multi:
  ├── 차단 필요 → LinkedBlockingQueue (또는 ArrayBlockingQueue)
  ├── 우선순위 + 차단 → PriorityBlockingQueue
  ├── 지연 → DelayQueue
  ├── 핸드오프 → SynchronousQueue
  └── 락-프리 → ConcurrentLinkedQueue


[Step 2-L: List 구현체 결정]

추가 요구사항:
├── 멀티스레드 읽기 위주 → CopyOnWriteArrayList
├── 멀티스레드 균형 → synchronizedList
├── 불변 → List.of
└── 그 외 → ArrayList (90%)

5.2 ILIC 시나리오 예시들

예시 1 — 운송장 캐시

요구사항: ID 로 빠른 조회, 멀티스레드 환경

결정:
1. 키로 찾기 → Map ✓
2. 추가 요구: 멀티스레드 → ConcurrentHashMap

코드:
private final ConcurrentMap<Long, Shipment> cache = new ConcurrentHashMap<>();

예시 2 — 최근 본 운송장 (UI)

요구사항: 최대 10개, 접근 시 끝으로 이동, 빠른 검색

결정:
1. 키로 찾기 → Map ✓
2. 추가 요구: 순서 + LRU → LinkedHashMap(accessOrder=true)

코드:
private final Map<Long, Shipment> recent = new LinkedHashMap<>(16, 0.75f, true) {
    @Override
    protected boolean removeEldestEntry(Map.Entry<Long, Shipment> eldest) {
        return size() > 10;
    }
};

예시 3 — 비동기 이벤트 처리

요구사항: 이벤트를 큐에 넣고 워커가 처리, 멀티스레드

결정:
1. FIFO → Queue ✓
2. 추가 요구: 멀티스레드 + 차단 → LinkedBlockingQueue

코드:
private final BlockingQueue<ShipmentEvent> queue = new LinkedBlockingQueue<>(1000);

예시 4 — 권한 검사

요구사항: 권한 집합, 빠른 contains, 멀티스레드 없음

결정:
1. 중복 X → Set ✓
2. 추가 요구: Enum 타입 → EnumSet

코드:
Set<Permission> permissions = EnumSet.of(Permission.READ, Permission.WRITE);

예시 5 — 시간순 이벤트

요구사항: 시간 순서로 정렬, 범위 검색

결정:
1. 키 (시간) 로 찾기 → Map ✓
2. 추가 요구: 정렬 + 범위 → TreeMap

코드:
TreeMap<LocalDateTime, Event> timeline = new TreeMap<>();
timeline.subMap(from, to);

예시 6 — DB 조회 결과

요구사항: JPA 가 반환, 순서 있는 시퀀스

결정:
1. 키-값 X → 다음
2. 중복 허용 → List ✓
3. 추가 요구 없음 → ArrayList

코드:
List<Shipment> shipments = repository.findAll();   // JPA 가 ArrayList 반환

예시 7 — 이벤트 리스너 등록

요구사항: 리스너 등록/제거, 멀티스레드 읽기 위주

결정:
1. 키-값 X → 다음
2. 중복 X → Set ✓
3. 추가 요구: 멀티스레드 + 읽기 위주 → CopyOnWriteArraySet

코드:
Set<EventListener> listeners = new CopyOnWriteArraySet<>();

5.3 자기 점검 답변

"운송장 ID 로 시간 순으로 정렬된 캐시" 를 만들려면?

:

  • 자료구조: Map (키로 조회)
  • 정렬 필요: TreeMap
  • 멀티스레드면: ConcurrentSkipListMap
  • 단일 스레드면: TreeMap
// 단일 스레드
TreeMap<Long, Shipment> cache = new TreeMap<>();

// 멀티스레드
ConcurrentSkipListMap<Long, Shipment> cache = new ConcurrentSkipListMap<>();

6️⃣ ILIC 의 90:9:1 법칙 완성

6.1 종합 90:9:1

ILIC 코드에서 컬렉션 사용 비율:

[90% — 핵심 4 가지]

ArrayList<E>
  - DB 결과
  - 도메인 컬렉션
  - DTO 변환
  - 일반 List

HashMap<K, V>
  - 캐시 (단일 스레드)
  - 인덱싱
  - 그룹핑
  - 빈도 카운트

HashSet<E>
  - 권한 집합
  - 처리된 ID 추적
  - 중복 제거

ConcurrentHashMap<K, V>
  - 캐시 (멀티스레드)
  - 빈도 카운터 (+ AtomicLong)


[9% — 특수 케이스]

LinkedHashMap (LRU 캐시, 응답 JSON 순서)
TreeMap (시간순 이벤트, 범위 검색)
EnumMap / EnumSet (Enum 키/값)
ArrayDeque (Queue, Stack)
PriorityQueue (우선순위)
LinkedBlockingQueue (작업 큐, 멀티스레드)
ConcurrentLinkedQueue (락-프리 멀티스레드 Queue)
CopyOnWriteArraySet/List (Listener 패턴)
List.of, Map.of, Set.of (불변 상수)


[1% — 드문 사용]

WeakHashMap (자동 GC 캐시)
IdentityHashMap (참조 동일성)
ConcurrentSkipListMap (멀티스레드 정렬)
DelayQueue (스케줄링)
SynchronousQueue (핸드오프)
LinkedList (드물게)


[0% — 절대 사용 X (Legacy)]

Vector
Hashtable
Stack 클래스
Properties (예외: Spring 설정)

6.2 사용 패턴

// 매일 작성하는 코드의 90%:

// 1. 캐시 패턴
private final ConcurrentMap<Long, Shipment> cache = new ConcurrentHashMap<>();
public Shipment get(Long id) {
    return cache.computeIfAbsent(id, this::load);
}

// 2. DB 조회
List<Shipment> shipments = repository.findByStatus(status);

// 3. Stream 변환
List<ShipmentResponse> responses = shipments.stream()
    .map(ShipmentResponse::from)
    .toList();

// 4. 그룹핑
Map<String, List<Shipment>> byRoute = shipments.stream()
    .collect(Collectors.groupingBy(Shipment::getRoute));

// 5. 중복 제거
Set<String> uniqueBlNos = shipments.stream()
    .map(Shipment::getBlNo)
    .collect(Collectors.toSet());

// 6. 빈도 카운트
Map<String, Long> counts = shipments.stream()
    .collect(Collectors.groupingBy(
        Shipment::getRoute,
        Collectors.counting()));

// 7. ID 인덱싱
Map<Long, Shipment> byId = shipments.stream()
    .collect(Collectors.toMap(Shipment::getId, s -> s));

// 8. 불변 상수
private static final Set<ShipmentStatus> COMPLETED_STATES = Set.of(
    ShipmentStatus.DELIVERED,
    ShipmentStatus.CANCELLED
);

→ 이 8가지 패턴이 ILIC 코드의 80%.

6.3 90:9:1 의 의미

핵심 메시지:

90% — "고민 없이" 쓸 수 있는 표준
  → ArrayList, HashMap, HashSet, ConcurrentHashMap
  → 시간을 비즈니스 로직에 투자

9% — 특별한 요구사항 만족
  → 정렬, 순서, LRU, Enum, 멀티스레드
  → 알아두면 큰 가치

1% — 드물지만 강력
  → WeakHashMap, ConcurrentSkipListMap 등
  → 면접 + 깊이

0% — 식별해서 피함
  → Legacy 코드 리팩토링

6.4 자기 점검 답변

ILIC 의 90:9:1 법칙에서 90% 의 4가지는?

:
1. ArrayList (List)
2. HashMap (Map, 단일)
3. HashSet (Set)
4. ConcurrentHashMap (Map, 멀티)

→ 매일 만나는 자료구조.


7️⃣ Legacy 컬렉션 (절대 안 씀)

7.1 Legacy 식별

ILIC 코드 리뷰 시 즉시 교체할 것들:

1. Vector
   → ArrayList (단일)
   → CopyOnWriteArrayList (멀티 읽기 위주)
   → synchronizedList (멀티 균형)

2. Hashtable
   → HashMap (단일)
   → ConcurrentHashMap (멀티)

3. Stack 클래스
   → ArrayDeque (push/pop)

4. Properties (예외)
   → Spring @Value 사용
   → application.properties
   → 직접 사용 안 함

7.2 Legacy 인 이유

공통 이유:
  - Java 1.0 시대 (1996)
  - 컬렉션 프레임워크 (Java 1.2, 1998) 이전
  - 모든 메서드 synchronized
  - API 일관성 부족
  - 더 나은 대안 존재

7.3 리팩토링 가이드

// 패턴 1: Vector → ArrayList
- Vector<E> v = new Vector<>();
+ List<E> v = new ArrayList<>();
// 또는 멀티스레드
+ List<E> v = new CopyOnWriteArrayList<>();

// 패턴 2: Hashtable → HashMap
- Hashtable<K, V> m = new Hashtable<>();
+ Map<K, V> m = new HashMap<>();
// 또는 멀티스레드
+ ConcurrentMap<K, V> m = new ConcurrentHashMap<>();

// 패턴 3: Stack → ArrayDeque
- Stack<E> stack = new Stack<>();
+ Deque<E> stack = new ArrayDeque<>();
// 메서드 동일 (push, pop, peek)

7.4 호환성 주의

// Vector 반환하는 옛 API 처리
Vector<String> legacy = oldApi.getData();

// 즉시 변환
List<String> modern = new ArrayList<>(legacy);
// 이후엔 modern 사용

7.5 자기 점검 답변

Vector 와 Hashtable 의 공통점과 차이점은?

:

  • 공통점:

    • Java 1.0 Legacy
    • 모든 메서드 synchronized
    • 단일 스레드도 비용
    • 복합 작업 안전성 부족
    • 더 나은 대안 존재
  • 차이점:

    • Vector → List 인터페이스 (요소 컬렉션)
    • Hashtable → Map 인터페이스 (키-값)
    • Vector 의 대안: ArrayList, CopyOnWriteArrayList
    • Hashtable 의 대안: HashMap, ConcurrentHashMap

8️⃣ Phase 2 졸업 시험 — 30문항

8.1 졸업 시험

다음 30문항에 즉답할 수 있다면 Phase 2 마스터.

인터페이스 계층 (5문항)

Q1. Java 컬렉션의 두 가지 최상위 인터페이스는?
A1. Iterable<E>, Map<K, V>

Q2. Map 이 Collection 의 자식이 아닌 이유 3가지는?
A2. 본질적 차이 (단일 요소 vs 키-값 쌍), 수학적 추상화 (집합 vs 함수), API 모순 회피

Q3. Iterable 의 역할은?
A3. for-each 가능, iterator() 제공

Q4. NavigableSet 과 NavigableMap 의 의미는?
A4. 정렬된 컬렉션에 추가 메서드 제공 (floor, ceiling, headMap, tailMap, subMap 등)

Q5. ConcurrentMap 인터페이스의 의미는?
A5. 멀티스레드 안전 + 원자적 메서드 (putIfAbsent, computeIfAbsent 등)

List (5문항)

Q6. ArrayList 의 1.5배 확장 정책 코드는?
A6. oldCapacity + (oldCapacity >> 1)

Q7. LinkedList 가 List + Deque 둘 다 구현하는 의미는?
A7. List 처럼 인덱스 접근, Deque 처럼 양 끝 작업, 하나의 클래스가 두 역할

Q8. Vector 안 쓰는 이유 7가지?
A8. Legacy, synchronized 비용, 복합 작업 안전성 부족, 더 나은 대안, 확장 정책 비효율, API 일관성 부족, Stack 자식의 문제

Q9. CopyOnWriteArrayList 의 메커니즘은?
A9. 쓰기 시 전체 배열 복사 + volatile 참조 교체, 읽기 락-프리

Q10. RandomAccess 인터페이스는?
A10. 마커 인터페이스, "인덱스 접근 빠름" 표시, ArrayList O, LinkedList X

Set (5문항)

Q11. HashSet 의 내부는?
A11. HashMap 의 wrapper (키 = Set 요소, 값 = PRESENT)

Q12. TreeSet 의 내부 구조는?
A12. TreeMap (Red-Black Tree) 의 wrapper

Q13. LinkedHashSet 이 어떻게 순서 유지하나?
A13. LinkedHashMap 의 wrapper, 이중 연결 리스트로 삽입 순서 보존

Q14. hashCode + equals 계약 4가지는?
A14. equals true → hashCode 같음, 반사성, 대칭성, 추이성, 일관성

Q15. EnumSet 의 이점은?
A15. 비트벡터 사용, 매우 메모리 효율, O(1) 모든 작업

Queue (5문항)

Q16. Queue 메서드 페어 (강제/안전) 6가지는?
A16. add/offer, remove/poll, element/peek

Q17. ArrayDeque 가 LinkedList 보다 빠른 이유는?
A17. 원형 배열 (연속 메모리), 캐시 효율, Node 객체 없음, 메모리 효율

Q18. PriorityQueue 의 내부 구조는?
A18. Binary Heap (배열 기반), O(log n) 삽입/제거

Q19. BlockingQueue 의 메서드 페어 4가지는?
A19. add/offer/put/offer(timeout), remove/poll/take/poll(timeout)

Q20. Stack 클래스 안 쓰고 ArrayDeque 쓰는 이유는?
A20. Stack 은 Vector 상속 Legacy, ArrayDeque 는 빠르고 push/pop 지원

Map (5문항)

Q21. HashMap 의 LoadFactor 0.75 의 의미는?
A21. 75% 차면 2배 확장, 메모리/충돌 균형점

Q22. Java 8+ HashMap 의 트리 변환 조건은?
A22. 한 버킷의 노드 > 8 → 트리 (Red-Black), 트리 < 6 → 다시 연결 리스트

Q23. LinkedHashMap 의 accessOrder=true 의 의미는?
A23. 접근 (get) 시도 노드를 끝으로 이동, LRU 캐시 구현 가능

Q24. ConcurrentHashMap 의 Java 7 vs Java 8 차이는?
A24. Java 7: Segment 16개 락, Java 8+: 노드 락 + CAS, 더 세밀한 동시성

Q25. ConcurrentHashMap 이 null 거부하는 이유는?
A25. get 결과의 모호성 (키 없음 vs null 값) 회피

종합 (4문항)

Q27. 정렬된 키 + 범위 검색이 필요할 때 자료구조는?
A27. TreeMap (NavigableMap), subMap/headMap/tailMap 사용

Q28. 이벤트 리스너 패턴에 적합한 컬렉션은?
A28. CopyOnWriteArrayList 또는 CopyOnWriteArraySet (멀티스레드 읽기 위주)

Q29. Map 의 view 3가지는?
A29. keySet(), values(), entrySet()

Q30. for-each 안에서 list.remove() 시 발생하는 예외와 해결법은?
A30. ConcurrentModificationException, Iterator.remove() 또는 removeIf 사용

8.2 채점

30 / 30 → Phase 2 마스터
25-29   → 거의 마스터, 약점 복습
20-24   → 핵심 개념 다시
< 20    → Unit 2.1 ~ 2.5 재학습

8.3 자기 점검 답변

Phase 2 졸업 시험에서 가장 어려운 영역은?

: (개인차)

  • ConcurrentHashMap 의 Java 7 → 8 진화 (Q24)
  • HashMap 의 Java 8 트리 변환 조건 (Q22)
  • 컬렉션 view 의미 (Q29)
  • equals + hashCode 계약 (Q14)

→ 이 부분을 다시 복습.


9.2 Phase 3 진입 — 해시의 원리

다음: Phase 3 — 해시(Hash)의 원리

Phase 3 의 4 Unit:
  Unit 3.1 — 해시의 탄생 배경
  Unit 3.2 — 해시 충돌 (Hash Collision)
  Unit 3.3 — 충돌 해결법 1: 체이닝 (Chaining)
  Unit 3.4 — 충돌 해결법 2: 오픈 어드레싱 (Open Addressing)

Phase 2 → Phase 3 의 연결:
  Phase 2 에서 "HashMap 은 O(1)" 사용했다면,
  Phase 3 에서 "왜 O(1)?" 의 메커니즘 깊이 파기

9.3 Phase 3 의 가치

Phase 3 마스터하면:
  
1. HashMap 의 내부를 직접 구현 가능
2. 해시 함수의 좋은 조건 제시
3. 충돌 해결법 2가지 비교
4. 면접 단골 "HashMap 구현하시오" 즉답
5. 1주차 HashMap PPT 학습이 정점 완성

9.4 자가 진단

다음 중 자신 있는지 체크:

기본 (15개):
  ☐ List/Set/Queue/Map 구분
  ☐ ArrayList vs LinkedList 비교
  ☐ HashSet 의 내부 (HashMap wrapper)
  ☐ TreeSet 의 Red-Black Tree
  ☐ LinkedHashSet 의 이중 연결
  ☐ ArrayDeque vs LinkedList
  ☐ PriorityQueue 의 Binary Heap
  ☐ BlockingQueue 의 차단 메서드
  ☐ HashMap 의 LoadFactor
  ☐ LinkedHashMap 의 accessOrder
  ☐ TreeMap 의 NavigableMap
  ☐ ConcurrentHashMap 의 락 단위
  ☐ Vector / Hashtable / Stack Legacy
  ☐ EnumSet / EnumMap 의 비트벡터
  ☐ List.of / Map.of / Set.of 불변

심화 (10개):
  ☐ hashCode + equals 계약
  ☐ Java 8+ 트리 변환 조건
  ☐ ConcurrentHashMap Java 7 vs 8
  ☐ amortized O(1) 의 의미
  ☐ RandomAccess 마커 인터페이스
  ☐ Map 의 view 3가지
  ☐ for-each + remove 함정
  ☐ Arrays.asList 함정
  ☐ subList 의 view 특성
  ☐ Iterator vs ListIterator

실전 (5개):
  ☐ 시나리오 → 자료구조 → 구현체 결정
  ☐ ILIC 90:9:1 적용
  ☐ Legacy 코드 리팩토링
  ☐ 멀티스레드 컬렉션 선택
  ☐ 큰 컬렉션 초기 크기 지정

🏆 Phase 2 완주 — 컬렉션 마스터 달성

🚀 Phase 2 — 컬렉션 프레임워크 전체 지도
  ✅ Unit 2.1 배열의 한계와 컬렉션의 등장
  ✅ Unit 2.2 Set 3형제
  ✅ Unit 2.3 List 3형제
  ✅ Unit 2.4 Queue
  ✅ Unit 2.5 Map 5형제
  ✅ Unit 2.6 컬렉션 전체 지도 정리 ← 여기, Phase 2 완주

→ 매일 코드 작성과 리뷰에 즉시 적용 가능

3주차 진행 상황

✅ Phase 1 — Pass by Value (1.1 ~ 1.3 완주)
✅ Phase 2 — 컬렉션 프레임워크 (2.1 ~ 2.6 완주)
🚀 Phase 3 — 해시의 원리 (다음)
⏭ Phase 4 — 추상화의 두 도구
⏭ Phase 5 — 제네릭과 와일드카드
⏭ Phase 6 — 객체 비교
⏭ Phase 7 — I/O 시스템 큰 그림
⏭ Phase 8 — Stream 실전
⏭ Phase 9 — I/O 강화
⏭ Phase 10 — 함수형 프로그래밍

3주차 누적 진행

작성한 학습 자료:
  Phase 1 (3개): Unit 1.1, 1.2, 1.3
  Phase 2 (6개): Unit 2.1, 2.2, 2.3, 2.4, 2.5, 2.6

총: 9/43 Unit 작성 (Phase 2 완주, 약 21%)

📚 다음으로...

Phase 3 — 해시의 원리

Phase 2 에서 "HashMap 은 O(1)" 을 사용했다면, Phase 3 는 그 이유의 깊이.

Phase 3 — 해시의 원리

Unit 3.1 — 해시의 탄생 배경
  → "순차 검색 O(n) 의 한계"
  → "수학적으로 위치 바로 찾기"
  → 해시 함수의 정의

Unit 3.2 — 해시 충돌 (Hash Collision)
  → 비둘기집 원리
  → 충돌이 불가피한 이유
  → Perfect Hashing 의 한계

Unit 3.3 — 충돌 해결법 1: 체이닝 (★ 마스터 프롬프트 깊이)
  → 자바 HashMap 의 채택
  → 연결 리스트 + 트리 (Java 8+)
  → 직접 구현

Unit 3.4 — 충돌 해결법 2: 오픈 어드레싱 (★ 마스터 프롬프트 깊이)
  → 선형 탐사, 이차 탐사, 이중 해싱
  → 메모리 효율 vs 클러스터링
  → 삭제 시의 함정

Phase 2 → Phase 3 의 연결

Phase 2:
  "HashMap 을 사용한다"
  "ConcurrentHashMap 의 락 단위"
  "Set 의 hashCode 의존"

Phase 3:
  "왜 HashMap 이 O(1) 인가?"
  "해시 함수의 좋은 조건"
  "충돌이 발생하면 어떻게 처리?"
  "체이닝 vs 오픈 어드레싱"

→ "사용" 에서 "구현" 으로.


profile
Software Developer

0개의 댓글