🎯 F-lab Java 2주차 학습 커리큘럼

2주차 자료의 모든 토픽을 "표면 → 깊이" 순서로 재배열한 학습 경로.
1주차에서 OOP·JVM·GC·컬렉션을 개론 으로 봤다면, 2주차는 동일 주제를 JVM 내부·바이트코드·메모리 매핑 수준으로 파고든다.
새로 등장하는 주제: Reflection, Iterator, 버퍼(Buffer).


📊 학습 경로 한눈에 보기

[Phase 1] 자바 변수 ↔ 메모리 영역의 매핑
   ↓
[Phase 2] JVM 메서드 실행 메커니즘
   ↓
[Phase 3] 바이트코드와 상수 풀의 세계  ◄── 여기가 2주차의 정점
   ↓
[Phase 4] GC 심화 — G1 GC 들여다보기
   ↓
[Phase 5] 컬렉션 프레임워크 내부 구조
   ↓
[Phase 6] 동적 프로그래밍 — Reflection & Iterator
   ↓
[Phase 7] 보조 개념 — Buffer

총 7 Phase × 23 Unit — 각 Unit은 30분~1시간 분량.

🔗 1주차와의 관계

1주차 (개론)2주차 (심화)
JVM 메모리 영역의 5분할Method Area의 3개 존 으로 더 쪼개기
GC의 동작 원리G1 GC 리전 모델 과 정지시간 예측
ArrayList vs LinkedList 비교배열 확장 정책·노드 구조 코드로 검증
(없음)바이트코드 읽기, Reflection, Iterator

🗓️ 권장 학습 일정 (7일 기준)

DayPhase학습 목표
1일차Phase 1변수 3종류와 메모리 영역의 매핑 정복
2일차Phase 2메서드 호출이 JVM 안에서 어떻게 일어나는지
3일차Phase 3 (전반)바이트코드 읽는 법 + 상수 풀
4일차Phase 3 (후반)심볼 참조와 new의 진실
5일차Phase 4G1 GC의 모든 것
6일차Phase 5 + 7컬렉션 내부 + Buffer
7일차Phase 6Reflection + Iterator

📚 Phase 1 — 자바 변수와 메모리 영역의 매핑

목표: "이 변수는 메모리의 어디에 저장될까?"에 즉답할 수 있게 된다.
1주차에서는 Heap/Stack/Method Area를 큰 그림으로 봤다면, 여기선 변수 종류 ↔ 영역 매핑 을 손에 익힌다.

Unit 1.1 — 자바 변수의 3종류

선수 지식: 1주차 Phase 2 (클래스/메서드)

핵심 개념

  • 지역 변수 (Local): 메서드 안에서 선언, 메서드 종료 시 사라짐
  • 인스턴스 변수 (Instance): static 없이 클래스에 선언, 객체별로 존재
  • 클래스 변수 (Class / static): static으로 선언, 클래스 단위 1개

자기 점검

  • 한 클래스에서 객체 100개를 만들면 인스턴스 변수와 클래스 변수의 개수는 각각?
  • 메서드 매개변수는 어느 종류에 속하는가?

Unit 1.2 — 변수별 저장 위치 (Stack / Heap / Method Area)

선수 지식: Unit 1.1

핵심 개념

변수 종류저장 영역생성 시점소멸 시점
지역 변수Stack메서드 호출메서드 종료
인스턴스 변수Heap (객체와 함께)new 시점GC가 객체 회수 시
클래스 변수Method Area클래스 로딩 시JVM 종료 시

자기 점검

  • Member m = new Member() 에서 m(참조)과 Member 객체 본체의 저장 위치는?
  • 클래스 변수가 모든 객체가 공유하는 이유는 어느 영역에 있기 때문인가?

Unit 1.3 — Method Area의 3개 존 (★ 2주차 핵심)

선수 지식: Unit 1.2

핵심 개념

Method Area
├─ Class Metadata Zone : 클래스명, 부모, 메서드 시그니처, 필드 선언 정보
├─ Static Zone         : static 메서드/필드의 실제 바이트코드
└─ Non-Static Zone     : 인스턴스 메서드의 실제 바이트코드
  • Class Metadata Zone: "이 클래스는 무엇이 있는가" (선언 정보만)
  • Static Zone: 실제 실행 가능한 static 메서드 바이트코드 (서로 직접 호출 가능)
  • Non-Static Zone: 인스턴스 메서드 바이트코드 (객체 통해서만 접근)

자기 점검

  • main() 이 Static Zone에 있는 이유는?
  • Static Zone의 메서드가 Non-Static Zone의 메서드를 직접 호출할 수 없는 이유는?

Unit 1.4 — Stack Area의 동작

선수 지식: Unit 1.2

핵심 개념

  • LIFO (Last In, First Out) 구조
  • 메서드 호출 시마다 스택 프레임(Stack Frame) 생성 → 지역변수, 매개변수 저장
  • PC(Program Counter) 가 현재 실행 중인 명령을 가리킴
  • 메서드 종료 → 해당 프레임 제거

자기 점검

  • 재귀 호출이 무한히 깊어지면 무엇이 발생하는가?
  • 멀티스레드에서 Stack은 공유되는가, 아니면 스레드별로 따로인가?

Unit 1.5 — Heap Area와 객체-Metadata 연결

선수 지식: Unit 1.3, Unit 1.4

핵심 개념

  • new로 만든 모든 객체는 Heap에
  • 각 객체는 Method Area의 자기 클래스 metadata를 가리킨다
  • 멤버변수가 있으면 new 시점에 Heap의 객체 안에 함께 할당
  • GC의 청소 대상

자기 점검

  • 같은 클래스의 객체 100개가 있을 때, 메서드 바이트코드는 100번 복제되는가?
  • 객체가 어떻게 자기 클래스의 메서드를 찾아 호출하는가?

Unit 1.6 — Literal Pool Area (문자열 재활용)

선수 지식: Unit 1.5

핵심 개념

  • 문자열 상수가 저장되는 재활용 메모리 공간
  • "Hello world" 같은 리터럴은 한 번만 만들고 재사용
  • 1주차에서 본 String Constant Pool과 같은 영역

자기 점검

  • String a = "abc"; String b = "abc"; 일 때 메모리에 String 객체는 몇 개 만들어지는가?
  • 이 영역의 이점은 메모리 절약 외에 또 무엇이 있는가?

📚 Phase 2 — JVM 메서드 실행 메커니즘

목표: 메서드 호출 한 줄(obj.method())이 JVM 안에서 실제로 어떤 단계를 거치는지 추적할 수 있다.

Unit 2.1 — 메서드 호출의 2단계 처리

선수 지식: Phase 1 전체

핵심 개념

메서드 호출 시 JVM의 처리 순서:
1. Class Metadata Zone에서 메서드 시그니처 확인
2. Static Zone 또는 Non-Static Zone에서 실제 바이트코드 찾아서 실행

즉, "무엇을 호출하는가""실제 코드가 어디 있는가" 가 분리되어 있다.

자기 점검

  • 메서드 시그니처와 메서드 구현 바이트코드가 분리된 이유는?
  • 이 2단계 구조가 다형성/오버라이딩과 어떤 관련이 있는가?

Unit 2.2 — Static vs 인스턴스 메서드 호출 경로

선수 지식: Unit 2.1

핵심 개념

  • Static 메서드끼리: Static Zone 내부에서 직접 접근 (Model1.hap()hap() 으로도 호출 가능)
  • Static → 인스턴스: 객체를 만들어서 Heap 통해 접근해야 함
  • 인스턴스끼리: 같은 객체 내에서 자유롭게 호출 가능

자기 점검

  • main() 안에서 인스턴스 메서드를 직접 호출할 수 없는 이유는?
  • 왜 객체를 만들어야 인스턴스 메서드를 부를 수 있는가?

Unit 2.3 — 인스턴스 메서드 호출의 전 과정 (Case Study)

선수 지식: Unit 2.2

케이스: Model2 m2 = new Model2(); int sum = m2.hap(1, 2);

호출 과정 추적
1. JVM이 바이트코드 읽기 → Class Metadata, Static Zone, Non-Static Zone에 정보 적재
2. main() 실행 시작 (Static Zone)
3. new Model2() 만나면:

  • Class Metadata Zone의 Model2 정보 사용
  • Heap에 Model2 객체 생성 (객체는 Method Area의 metadata를 가리킴)
  • Non-Static Zone의 Model2() 생성자가 Stack에 호출 → 실행 → 제거
  1. Heap 객체의 참조가 m2로 main 스택 프레임에 저장
  2. m2.hap(1, 2):
    • Heap의 Model2 객체 → Method Area의 metadata
    • Non-Static Zone의 hap() 발견 → Stack에 호출 → 실행 → 제거

자기 점검

  • 위 5단계 중 가장 비용이 큰 단계는?
  • 같은 객체의 메서드를 100번 호출하면 매번 metadata 조회를 하는가? (힌트: JIT)

Unit 2.4 — new 연산자가 실제로 하는 일

선수 지식: Unit 2.3

핵심 개념

new Model2() 한 줄이 하는 4가지:
1. Class Metadata Zone에서 Model2 클래스 정보 찾기
2. Heap에 객체 메모리 공간 확보
3. 멤버변수 초기화 (있다면)
4. 생성자(Constructor) 호출

자기 점검

  • new 없이 객체를 만들 수 있는 방법은? (힌트: Reflection, clone, deserialization)
  • 생성자가 호출되기 전에 객체는 이미 메모리에 존재하는가?

📚 Phase 3 — 바이트코드와 상수 풀의 세계 (★ 2주차의 정점)

목표: .class 파일을 직접 읽을 수 있게 된다. JVM이 클래스 정보를 어떻게 식별·관리하는지 본다.

Unit 3.1 — 바이트코드란 무엇인가

선수 지식: Phase 2 전체

핵심 개념

  • .javajavac.class (바이트코드)
  • JVM이 이해하는 어셈블리 비슷한 명령어
  • 플랫폼 독립적 (어느 OS의 JVM이든 같은 .class 실행 가능)
  • 확인 명령어: javap -c MyClass

자기 점검

  • 바이트코드는 기계어와 무엇이 다른가?
  • "Write Once, Run Anywhere"의 비밀이 바이트코드에 어떻게 담겨있는가?

Unit 3.2 — 상수 풀(Constant Pool)의 생성과 구조

선수 지식: Unit 3.1

핵심 개념

  • 자바 소스 → 컴파일 시점에 클래스 파일 내부에 상수 풀 생성
  • 저장되는 것:
    • 문자열 상수
    • 클래스 참조
    • 필드 참조
    • 메서드 참조
  • 바이트코드의 #숫자 표기는 상수 풀 인덱스

자기 점검

  • 상수 풀이 클래스 파일에 함께 저장되는 이유는?
  • 같은 문자열 리터럴이 여러 곳에 쓰이면 상수 풀에 몇 번 저장되는가?

원본 자료: JVM 밑바닥까지 파헤치기, p.67


Unit 3.3 — 심볼 참조(Symbolic Reference)

선수 지식: Unit 3.2

핵심 개념

  • 컴파일 시점엔 클래스/메서드/필드의 실제 메모리 주소를 알 수 없다
  • 그래서 이름(심볼) 으로 참조해두고, 런타임에 실제 위치로 해석(resolve)
  • 바이트코드의 #7 같은 인덱스 → 상수 풀에서 "어떤 심볼인가" 찾아냄

예시: new 명령

  • 바이트코드: 4: new #7 // class org/example/CalHap
  • #7 = 상수 풀의 7번 = org/example/CalHap 클래스 심볼
  • JVM이 런타임에 이 심볼이 가리키는 클래스가 로딩·해석·초기화 되었는지 확인

자기 점검

  • 왜 컴파일 시점에 실제 주소를 박아두지 않는가?
  • 심볼 참조 → 실제 참조 변환은 언제 일어나는가?

원본 자료: JVM 밑바닥까지 파헤치기, p.67


Unit 3.4 — 바이트코드 실전 분석

선수 지식: Unit 3.3

예시 분석

public static void main(String[] args) {
    int a=1, b=1;
    CalHap ch = new CalHap(a, b);
    ch.hap();
}

→ 바이트코드:

0: iconst_1        // a=1
1: istore_1
2: iconst_1        // b=1
3: istore_2
4: new #7          // new CalHap (#7은 상수 풀의 CalHap 클래스 참조)
7: dup             // 스택의 객체 참조 복제
8: iload_1         // a를 스택에
9: iload_2         // b를 스택에
10: invokespecial #9   // 생성자 호출
13: astore_3       // ch에 저장

자기 점검

  • dup는 왜 필요한가? (힌트: 생성자 호출 후에도 ch에 저장할 객체 참조가 필요)
  • invokespecial, invokevirtual, invokestatic의 차이는?

📚 Phase 4 — GC 심화: G1 GC 들여다보기

목표: 1주차에서 이름만 봤던 G1 GC를 리전 모델·정지시간 예측 모델 까지 이해한다.

Unit 4.1 — 참조 카운팅의 치명적 한계 (왜 JVM은 안 쓰는가)

선수 지식: 1주차 Phase 5

핵심 개념

  • 참조 카운팅: 객체마다 카운터 → 0이면 회수
  • 장점: 즉시 회수 가능
  • 치명적 단점: 순환 참조에서 누수

순환 참조 시나리오:

Root → A ⇄ B  (A와 B가 서로 참조)

Root가 참조를 끊어도 A↔B의 카운터는 0이 안 됨 → 영원히 회수 안 됨 → 메모리 누수

자기 점검

  • JVM이 참조 카운팅 대신 어떤 방식을 쓰는가? (힌트: Reachability Analysis)
  • 순환 참조 외에 참조 카운팅의 또 다른 단점은? (힌트: 카운터 갱신 비용)

원본 자료: JVM 밑바닥까지 파헤치기, p.94


Unit 4.2 — G1 GC의 등장 배경

선수 지식: Unit 4.1, 1주차 Phase 5

핵심 개념

  • 시대적 배경: 멀티프로세서 + 멀티 기가바이트 힙
  • 기존 GC의 한계: Young/Old를 통째로 회수 → 큰 힙에서 STW 시간 폭발
  • G1의 목표: 정지시간 예측 모델(Pause Prediction Model)
    • "M밀리초 안에 끝낼게" 라고 약속하고 그 안에 끝냄 (기본 200ms)

자기 점검

  • 큰 힙에서 기존 GC가 느린 근본 이유는?
  • 정지시간 예측 모델은 어떻게 시간을 통제하는가?

Unit 4.3 — G1 GC의 리전(Region) 기반 레이아웃

선수 지식: Unit 4.2

핵심 개념

기존 GC vs G1:

[기존 GC]
  ┌─ Eden ──┬─ Survivor ──┬─── Old ───┐  ← 영역 크기 고정, 위치 고정
  │         │             │           │
  └─────────┴─────────────┴───────────┘

[G1 GC]
  ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
  │E│ │S│O│ │O│E│ │ │S│O│ │E│  ← 같은 크기의 리전, 역할은 동적으로 부여
  └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘
  • 자바 힙을 동일한 크기의 여러 리전으로 분할
  • 각 리전은 필요에 따라 Eden / Survivor / Old로 동적 할당
  • 리전 크기: 1MB~32MB (2의 제곱수), -XX:G1HeapRegionSize 로 조절

자기 점검

  • 리전 단위로 쪼개면 어떤 이점이 있는가?
  • 리전 크기를 너무 작게 하면 어떤 문제가?

Unit 4.4 — 거대 리전(Humongous Region)

선수 지식: Unit 4.3

핵심 개념

  • 리전 용량의 절반보다 큰 객체 = 큰 객체 = 거대 객체
  • 큰 객체는 연속된 거대 리전(Humongous Region) 에 저장
  • 거대 리전은 주로 구세대(Old) 로 취급

자기 점검

  • 거대 객체를 별도 리전에 두는 이유는?
  • 거대 객체가 많으면 G1의 효율이 어떻게 되는가?

Unit 4.5 — G1의 우선순위 기반 회수

선수 지식: Unit 4.4

핵심 개념

G1의 회수 기준:
1. 어느 리전에 쓰레기가 가장 많은가 (회수 가능 공간 크기)
2. 회수에 드는 시간이 얼마인가 (경험값으로 예측)
3. → 정지시간 한도 내에서 회수 효과가 큰 리전부터 처리

이게 G1의 이름의 유래: Garbage First (쓰레기 많은 곳 먼저)

자기 점검

  • "정지시간이 허용하는 한도 내에서" 라는 제약이 어떻게 보장되는가?
  • 모든 리전을 다 회수하지 않아도 메모리가 부족해지지 않는 이유는?

📚 Phase 5 — 컬렉션 프레임워크 내부 구조

목표: 1주차에 ArrayList vs LinkedList를 큰 그림으로 봤다면, 여기서는 배열 확장 정책·노드 연결 구조 를 코드로 검증한다.

Unit 5.1 — List / Set / Map의 본질적 차이

선수 지식: 1주차 Phase 6

핵심 개념

자료구조순서중복키-값
List✅ 있음✅ 허용
Set❌ 없음❌ 불허
Map❌ 없음키 ❌ / 값 ✅

자기 점검

  • "순서가 있다"는 정확히 무엇을 의미하는가? (힌트: 삽입 순서 vs 정렬 순서)
  • HashSet은 어떻게 중복을 막는가? (힌트: HashMap 내부)

Unit 5.2 — ArrayList 내부 (배열 확장 정책)

선수 지식: Unit 5.1

핵심 개념

  • 기본 크기 10
  • 공간 부족 시: 1.5배 확장 → 새 배열 생성 → 기존 데이터 복사
  • 중간 삽입: 새 배열 안 만듦, 기존 요소를 한 칸씩 밀어냄
  • 중간 삽입/삭제 비용: O(n)

자기 점검

  • new ArrayList<>(1000) 처럼 초기 크기를 지정하는 게 왜 효율적인가?
  • 1.5배인 이유는? (3배·2배가 아닌)

원본 자료: 자바의신 2 + 컬렉션 내부 분석


Unit 5.3 — LinkedList 내부 (노드 연결)

선수 지식: Unit 5.2

핵심 개념

  • 연속된 메모리가 아니라 메모리 주소를 연결
  • 각 노드: [이전 노드 주소 | 데이터 | 다음 노드 주소]
  • 중간 삽입/삭제: 참조만 변경 → O(1) (단, 위치 찾기는 O(n))

자기 점검

  • 단일 연결 리스트와 이중 연결 리스트의 차이는?
  • 자바 LinkedList는 어느 쪽인가?

Unit 5.4 — 삽입/삭제 효율의 진짜 이유 (코드 검증)

선수 지식: Unit 5.2, Unit 5.3

핵심 질문:

"ArrayList도 LinkedList도 결국 O(n)인데, 왜 LinkedList가 삽입/삭제에 유리하다고 하는가?"

: 비용의 종류가 다르다.

작업ArrayListLinkedList
위치 찾기O(1) (인덱스 직접 접근)O(n) (순차 탐색)
실제 삽입/삭제O(n) 메모리 복사O(1) 참조 변경

메모리 복사는 데이터 크기에 따라 비용이 더 크게 증가한다. 데이터가 많을수록 ArrayList의 복사 비용이 폭증.

검증 코드 (직접 돌려보면서 이해)

int[] arr = new int[5];
arr[0]=0; arr[1]=1; arr[2]=2; arr[3]=3;

// 인덱스 1에 99를 삽입하려면?
// arr[4]=arr[3], arr[3]=arr[2], arr[2]=arr[1], arr[1]=99
// → 데이터를 일일이 복사해서 밀어낸다

자기 점검

  • "위치를 알고 있다" 면 LinkedList의 삽입은 정말 O(1)인가?
  • ArrayList에서도 끝에 add는 O(1)인 이유는?

📚 Phase 6 — 동적 프로그래밍 (Reflection & Iterator)

목표: 컴파일 타임 정보로 다 풀리지 않는 문제 두 가지 — 런타임에 클래스 정보 다루기, 컬렉션 통합 순회 — 의 해결책을 본다.

Unit 6.1 — 모든 Object는 metadata를 가진다

선수 지식: Phase 1 전체

핵심 개념

  • 자바의 모든 객체는 Object 를 상속 → metadata를 동반
  • 접근 가능한 정보: construction(생성자), field, method, annotation
  • 이 정보들은 Class<?> API로 접근 가능

자기 점검

  • obj.getClass() 가 반환하는 것은?
  • Member.classmember.getClass() 의 차이는?

Unit 6.2 — Reflection의 용도와 사용법

선수 지식: Unit 6.1

핵심 개념

  • 런타임에 클래스 정보를 보고 동적으로 사용
  • 주요 용도:
    • 런타임에 인스턴스 생성
    • private 필드/메서드 접근
    • 어노테이션 처리
  • 실무 사용처: Spring (DI/AOP), JPA (Entity 매핑), Jackson (JSON 직렬화)

예시 (개념)

Class<?> clazz = Class.forName("org.example.Member");
Object obj = clazz.getDeclaredConstructor().newInstance();
Method m = clazz.getMethod("hap", int.class, int.class);
m.invoke(obj, 1, 2);

자기 점검

  • Reflection의 단점은? (힌트: 성능, 컴파일 타임 안전성, 캡슐화 위반)
  • Spring이 Reflection을 어떻게 활용하는지 한 가지 예를 들어보라

Unit 6.3 — Iterator의 탄생 이유

선수 지식: 1주차 Phase 6

핵심 문제:
Iterator가 없던 시절, 컬렉션마다 순회 방식이 달랐다.

// ArrayList: 인덱스 순회
for (int i = 0; i < list.size(); i++) { list.get(i); }

// HashSet: 인덱스가 없어서 다른 방식 필요
// LinkedList: 또 다른 방식

문제점:

  • 컬렉션마다 순회 코드가 다름 → 비일관
  • 컬렉션 내부 구조를 알아야 순회 가능 → 캡슐화 위반
  • 코드 중복 증가

자기 점검

  • HashSet에 인덱스가 없는 이유는?
  • "내부 구조와 무관하게 순회"라는 요구가 어떤 디자인 패턴을 떠올리게 하는가?

Unit 6.4 — Iterator 패턴의 적용

선수 지식: Unit 6.3

핵심 개념

  • 모든 Collectioniterator() 메서드 제공
  • Iterator 인터페이스: hasNext(), next(), remove()
  • 어떤 컬렉션이든 동일한 코드로 순회 가능
Collection<String> c = new ArrayList<>();  // 또는 HashSet, LinkedList
Iterator<String> it = c.iterator();
while (it.hasNext()) {
    System.out.println(it.next());
}
  • for-each 문은 내부적으로 Iterator를 사용

자기 점검

  • for-each 와 Iterator의 관계는?
  • 순회 도중 컬렉션을 수정하면 무엇이 발생하는가? (힌트: ConcurrentModificationException)

📚 Phase 7 — 보조 개념: Buffer

목표: 1주차의 NIO에서 등장했던 Buffer를 좀 더 일반적인 개념으로 이해한다.

Unit 7.1 — 버퍼(Buffer)란 무엇인가

선수 지식: 1주차 Phase 7

핵심 개념

  • 데이터를 임시로 저장하는 메모리 공간
  • 두 시스템 간 속도 차이를 해결하는 완충지
  • 예: 빠른 CPU와 느린 디스크 사이, 빠른 네트워크와 느린 사용자 입력 사이
  • 실무 등장:
    • NIO의 ByteBuffer
    • BufferedReader / BufferedWriter (I/O 성능)
    • 영상/음성 스트리밍의 버퍼링

자기 점검

  • 버퍼가 없으면 어떤 비효율이 발생하는가?
  • 버퍼가 너무 작으면? 너무 크면?

원본 자료: JVM 밑바닥까지 파헤치기, p.69


🎓 종합 자기 점검 (2주차 졸업 시험)

JVM 메모리 (심화)

  1. 자바 변수 3종류와 각각의 저장 영역을 매핑하라
  2. Method Area의 3개 존(Class Metadata / Static / Non-Static)의 역할 차이는?
  3. main() 이 Static Zone에 있어야 하는 이유는?
  4. Heap의 객체가 자기 클래스의 메서드를 어떻게 찾아 호출하는가?
  5. Stack은 왜 스레드별로 따로 있는가?

메서드 호출 메커니즘

  1. 메서드 호출의 2단계(시그니처 확인 → 바이트코드 실행)를 그림으로 설명하라
  2. new Model2() 한 줄이 JVM에서 하는 4가지를?
  3. Static 메서드와 인스턴스 메서드의 호출 경로 차이는?

바이트코드 & 상수 풀

  1. 바이트코드의 #7 같은 표기는 무엇을 의미하는가?
  2. 상수 풀(Constant Pool)에 저장되는 것 4가지는?
  3. 심볼 참조(Symbolic Reference)란 무엇이며, 왜 필요한가?
  4. invokespecialinvokevirtual 의 차이는?

G1 GC

  1. JVM이 참조 카운팅을 안 쓰는 이유는?
  2. G1 GC의 "리전(Region)" 모델이 기존 GC와 다른 점은?
  3. 거대 리전(Humongous Region)은 언제 사용되는가?
  4. G1의 이름이 "Garbage First"인 이유는?
  5. 정지시간 예측 모델은 어떻게 시간을 통제하는가?

컬렉션 내부

  1. ArrayList가 1.5배로 확장되는 정책의 의미는?
  2. "삽입/삭제 시 LinkedList가 유리하다"는 말의 정확한 의미는?
  3. List/Set/Map의 본질적 차이는?

Reflection & Iterator

  1. Reflection으로 할 수 있는 일 3가지는?
  2. Spring/JPA/Jackson이 Reflection을 사용하는 이유는?
  3. Iterator가 없던 시절의 문제 2가지는?
  4. for-each 와 Iterator의 관계는?

Buffer

  1. 버퍼가 해결하는 문제는?

📌 학습 운영 팁

9-섹션 마스터 프롬프트로 깊이 파야 할 Unit

반드시 깊이 파기 (면접 단골 + 실무 직결):

  • Unit 1.3 — Method Area의 3개 존
  • Unit 2.3 — 인스턴스 메서드 호출의 전 과정
  • Unit 3.2 ~ 3.4 — 상수 풀과 심볼 참조 (★★★)
  • Unit 4.3 ~ 4.5 — G1 GC 리전 모델
  • Unit 6.2 — Reflection (Spring 이해의 출발점)

기본 이해로 충분:

  • Unit 1.6 — Literal Pool (1주차에서 본 개념의 재확인)
  • Unit 7.1 — Buffer (개념만 알면 됨)

Phase별 진도 체크리스트

[ ] Phase 1 — 자바 변수 ↔ 메모리 매핑 (Unit 1.1~1.6)
[ ] Phase 2 — JVM 메서드 실행 메커니즘 (Unit 2.1~2.4)
[ ] Phase 3 — 바이트코드와 상수 풀 (Unit 3.1~3.4) ★ 정점
[ ] Phase 4 — G1 GC 심화 (Unit 4.1~4.5)
[ ] Phase 5 — 컬렉션 내부 구조 (Unit 5.1~5.4)
[ ] Phase 6 — Reflection & Iterator (Unit 6.1~6.4)
[ ] Phase 7 — Buffer (Unit 7.1)
[ ] 종합 자기 점검 25문항 통과

실습 도구

  • javap -c MyClass.class: 바이트코드 읽기
  • javap -v MyClass.class: 상수 풀까지 보기
  • java -XX:+PrintGCDetails: GC 로그 확인
  • java -XX:+UseG1GC: G1 GC 강제 활성화

ILIC 실무 연결 지점

PhaseILIC 실무 연결
1~2 (JVM 메모리/실행)OOM 분석, heap dump 읽기, 스레드 덤프
3 (바이트코드/상수 풀)Spring AOP 동작 이해, 빌드 산출물 분석
4 (G1 GC)운영 서버 GC 튜닝, GC 로그 분석
5 (컬렉션 내부)DTO/Entity 컬렉션 매핑 시 자료구조 선택
6 (Reflection)Spring DI, JPA Entity, Jackson DTO 매핑 이해
6 (Iterator)Stream API의 기반 (3주차로 확장)
7 (Buffer)파일 업로드 처리, NIO 활용

1주차 → 2주차 → 3주차로 연결될 흐름

  • 1주차: OOP·JVM·GC·컬렉션·I/O 개론
  • 2주차 (지금): JVM 내부·바이트코드·G1 GC·컬렉션 내부·Reflection·Iterator
  • 3주차 예상: Stream API (Iterator의 진화), 람다와 함수형 프로그래밍, 제네릭 심화, 멀티스레딩
profile
Software Developer

0개의 댓글