3주차 Unit 1.3 — 자바의 Call by Value 한 가지

Psj·2026년 5월 18일

F-lab

목록 보기
77/237

Unit 1.3 — 자바의 Call by Value 한 가지

F-LAB JAVA · 3주차 · Phase 1 · Pass by Value의 진짜 이해
🎯 Phase 1 정점 — 면접 단골 질문 완벽 정복


📌 학습 목표

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

  • 자바는 Call by Value 와 Call by Reference 중 어느 쪽인가? (면접 단골)
  • "자바는 모든 것이 Pass by Value" 의 정확한 의미는?
  • primitive 와 객체 참조 가 같은 원리로 동작하는 이유는?
  • "객체를 reference 로 전달" 이 왜 부정확한 표현인가?
  • 자바에서 호출자 변수를 진짜로 변경하려면?
  • 흔한 8가지 오해 를 어떻게 해소하나?
  • 박승제씨의 5문장 면접 답변 은?
  • 자바 매개변수 동작의 6단계 메모리 추적 을 그릴 수 있나?
  • Phase 1 졸업 시험 통과 가능?

🎯 핵심 한 문장

"자바는 오직 Call by Value 한 가지로만 동작한다."
primitive 든 객체든 매개변수 전달 시 변수의 값을 새 메모리에 복사 한다.
객체의 경우 그 "값" 이 참조(주소) 라서 두 변수가 같은 객체를 가리키게 되지만,
변수 자체는 별개 메모리이므로 매개변수 재할당이 호출자에 반영되지 않는다.
박승제씨가 이 한 줄을 정확히 설명할 수 있다면 Phase 1 졸업이자 면접 단골 정복.

비유 — 자바의 단일 정답

패러다임비유
자바 (Call by Value 만)모든 손님에게 동일한 영수증 발급 시스템 — 예외 없음
C/C++ (두 방식 혼재)손님에 따라 영수증 또는 공동명의 통장 발급 — 헷갈림
Kotlin (Value + final 강제)영수증 + 손님이 영수증에 낙서도 못 함 — 더 안전

→ 자바는 단순함을 선택.
→ 박승제씨가 평생 매개변수 동작을 헷갈리지 않을 수 있는 이유.


🧭 9개 섹션 로드맵

1. Call by Value 의 정확한 정의 + 용어 정리
2. primitive 매개변수의 메모리 동작
3. 객체 참조 매개변수의 메모리 동작
4. 두 경우의 통합된 원리 — "값의 복사"
5. 흔한 8가지 오해 완전 해소
6. ILIC 실무 종합 시나리오
7. 박승제씨의 5문장 답변 완성
8. Phase 1 종합 — 1, 2, 3주차 학습 통합
9. Phase 1 졸업 시험 + 자기 점검

1️⃣ Call by Value 의 정확한 정의 + 용어 정리

1.1 용어 혼동 정리

먼저 박승제씨가 헷갈릴 수 있는 용어들 정리:

혼동되는 용어들:
  - Call by Value
  - Pass by Value
  - Pass by Reference
  - Call by Reference
  - Pass by Object Reference
  - Pass by Sharing
  - Call by Sharing

용어 정리:

용어의미자바?
Call by Value"값을 호출에 사용" — 일반적 표현
Pass by Value"값을 전달" — 매개변수 관점
Call by Reference"참조 자체를 호출에 사용"
Pass by Reference"참조를 전달" — 변수 별칭
Pass by Object ReferencePython 등의 표현 — 사실 Value✅ (같은 의미)
Call by Sharing학술 용어 — Value of reference

Call by Value = Pass by Value. 같은 의미.
→ 자바는 이것만. 다른 건 없음.

1.2 Call by Value 의 정의

Call by Value (Pass by Value):
  
  메서드 호출 시, 매개변수는 호출자가 넘긴 표현식의
  값(value)을 새로 생성된 변수에 저장하여 초기화한다.
  
  결과:
    1. 매개변수는 새 메모리 슬롯
    2. 호출자의 변수와 별개
    3. 매개변수 변경이 호출자에 영향 없음

1.3 자바의 단일 방식 선언

박승제씨가 면접에서 외울 단 한 문장:

"자바의 모든 매개변수 전달은 Call by Value 입니다."
  • primitive (int, long, double, ...) → Call by Value
  • 객체 참조 (Shipment, String, ...) → Call by Value
  • 배열 → Call by Value
  • 람다 → Call by Value
  • 모든 매개변수가 예외 없이 Call by Value

1.4 "Value" 가 무엇인지

primitive 의 경우:
  Value = 값 자체 (int 면 4 bytes 정수)
  
객체 참조의 경우:
  Value = 참조 (주소, 보통 8 bytes on 64-bit)
  
배열의 경우:
  Value = 배열 객체의 참조 (배열 자체가 객체)
  
람다의 경우:
  Value = 람다 객체의 참조

→ 모두 "값" 이지만 종류만 다름.
→ Call by Value 의 단일 메커니즘.

1.5 JLS (Java Language Specification) 공식

JLS §8.4.1 Formal Parameters:

  "The formal parameters of a method or constructor, 
   if any, are specified by a list of comma-separated 
   parameter specifiers. Each parameter specifier 
   consists of a type and an identifier (optionally 
   followed by brackets) that specifies the name of 
   the parameter."

JLS §15.12.4.5 Create Frame, Synchronize, Transfer Control:

  "The values of the actual argument expressions 
   initialize newly created parameter variables..."

핵심 구절:

  • "newly created parameter variables" — 새로 생성된 매개변수 변수
  • "values ... initialize" — 값으로 초기화
  • → Call by Value

자바 공식 명세가 "새 변수에 값으로 초기화" 라고 명시.
→ 박승제씨가 면접에서 자신감 있게 인용 가능.

1.6 메모리 메커니즘

박승제씨가 2주차 Unit 1.4, 2.2 에서 본 메모리 메커니즘으로:

메서드 호출 시 JVM 동작:
  1. 새 Stack Frame 생성
  2. LVA (Local Variable Array) 슬롯 할당
  3. 매개변수마다 슬롯 부여
  4. 호출자 표현식의 값을 슬롯에 복사
  5. 메서드 본체 실행
  6. 종료 시 Frame 제거

각 슬롯은 새 메모리.
호출자 변수의 메모리와 무관.

1.7 자기 점검 답변

Call by Value 와 Pass by Value 는 같은가?

:

  • 같은 의미. 표현 방식만 다름.
  • "Call" 은 호출 관점, "Pass" 는 전달 관점
  • 둘 다 "값을 사용한다" 의 뜻
  • 자바 면접에서 둘 다 사용 가능

2️⃣ primitive 매개변수의 메모리 동작

2.1 가장 기본 시나리오

public class FreightCalculator {
    public void modify(int weight) {
        weight = 999;        // 매개변수 변경 시도
    }
    
    public static void main(String[] args) {
        int myWeight = 100;
        new FreightCalculator().modify(myWeight);
        System.out.println(myWeight);   // 100 (변경 안 됨)
    }
}

2.2 5단계 메모리 추적

Step 1: int myWeight = 100;
  main 스레드의 Stack Frame:
    ┌─────────────────────┐
    │ args[]    │ ref     │
    │ myWeight  │ 100      │
    └─────────────────────┘

Step 2: modify(myWeight) 호출 직전
  값 평가:
    myWeight 의 값을 읽음: 100
    이 값을 modify 의 매개변수로 전달

Step 3: modify 진입 직후
  Stack:
    ┌─────────────────────┐
    │ main 의 Frame        │
    │   myWeight = 100     │ ← 그대로
    ├─────────────────────┤
    │ modify 의 Frame      │
    │   this = ref         │
    │   weight = 100       │ ← 새 슬롯! (복사된 값)
    └─────────────────────┘

Step 4: weight = 999 실행
  Stack:
    ┌─────────────────────┐
    │ main 의 Frame        │
    │   myWeight = 100     │ ← 변하지 않음
    ├─────────────────────┤
    │ modify 의 Frame      │
    │   this = ref         │
    │   weight = 999       │ ← modify 의 슬롯만 변경
    └─────────────────────┘

Step 5: modify 종료
  Stack:
    ┌─────────────────────┐
    │ main 의 Frame        │
    │   myWeight = 100     │ ← 100 그대로
    └─────────────────────┘
  (modify 의 Frame 전체가 사라짐)

출력:
  100

2.3 바이트코드로 검증 (2주차 Phase 3 활용)

javac FreightCalculator.java
javap -c FreightCalculator

main 메서드:

public static void main(java.lang.String[]);
    Code:
       0: bipush        100
       2: istore_1                       // myWeight 에 100 저장
       3: new           #2               // new FreightCalculator
       6: dup
       7: invokespecial #3               // <init>()
      10: iload_1                        // myWeight 의 값 푸시 (= 100)
      11: invokevirtual #4               // modify(int)
      14: getstatic     #5               // System.out
      17: iload_1                        // myWeight 푸시 (변경 안 됨!)
      18: invokevirtual #6               // println(int)
      21: return

modify 메서드:

public void modify(int);
    Code:
       0: sipush        999
       3: istore_1                       // weight 에 999 저장 (매개변수 슬롯)
       4: return

핵심:

  • main 의 myWeight 는 LVA[1]
  • modify 의 weight 도 LVA[1] (하지만 다른 Frame!)
  • modify 의 LVA[1] 에 999 저장 → main 의 LVA[1] 무관

2주차 학습이 3주차에서 빛난다.

2.4 모든 primitive 동일

void demo(int i, long l, double d, boolean b, char c) {
    // 모두 새 메모리에 값 복사
    i = 999;
    l = 999L;
    d = 999.99;
    b = !b;
    c = 'Z';
    // 호출자 무관
}

타입 무관, 모든 primitive 가 같은 방식.

2.5 자바스러운 예외 — 없음

자바는 primitive 전달에 예외 없음:

  • C 의 register 같은 특수 키워드 없음
  • 컴파일러 최적화는 있지만 의미는 동일

→ 박승제씨가 안심하고 외울 수 있는 단일 규칙.

2.6 ILIC 시나리오

@Service
public class FareCalculator {
    
    public BigDecimal calculate(int weight, BigDecimal baseRate) {
        weight = weight + 100;        // 매개변수 변경 (호출자 무관)
        return baseRate.multiply(BigDecimal.valueOf(weight));
    }
}

// 호출
int myWeight = 1000;
BigDecimal rate = new BigDecimal("0.5");
BigDecimal result = calculator.calculate(myWeight, rate);

System.out.println(myWeight);   // 1000 (변경 안 됨)

→ ILIC 메서드들은 모두 이 패턴.
→ 매개변수 변경은 호출자에게 보이지 않음.

2.7 자기 점검 답변

primitive 매개변수에 새 값을 대입해도 호출자가 영향 안 받는 이유는?

:
1. 매개변수는 새 Stack Frame 의 LVA 슬롯
2. 호출자 변수는 자기 Frame 의 LVA 슬롯
3. 두 슬롯은 완전히 다른 메모리
4. 호출 시 값(100)이 복사됨
5. 매개변수 슬롯 변경은 호출자 슬롯과 무관

→ Frame 격리가 핵심.


3️⃣ 객체 참조 매개변수의 메모리 동작

3.1 가장 헷갈리는 시나리오

public class ShipmentService {
    
    public void processShipment(Shipment shipment) {
        // Case A: 객체 내용 변경
        shipment.setStatus(ShipmentStatus.ACTIVE);
        
        // Case B: 매개변수 재할당
        shipment = new Shipment("NEW-BL");
        shipment.setStatus(ShipmentStatus.NEW);
    }
    
    public static void main(String[] args) {
        Shipment myShip = new Shipment("BL-001");
        myShip.setStatus(ShipmentStatus.DRAFT);
        
        new ShipmentService().processShipment(myShip);
        
        System.out.println(myShip.getBlNo());    // "BL-001"
        System.out.println(myShip.getStatus());  // ACTIVE
    }
}

결과 분석:

  • blNo 는 "BL-001" 그대로 (재할당 영향 X)
  • status 는 ACTIVE (객체 내용 변경 반영)

3.2 7단계 메모리 추적

Step 1: Shipment myShip = new Shipment("BL-001");
  
  main Stack Frame:                Heap:
    ┌───────────────────┐            ┌──────────────────────┐
    │ args[]    │ ref   │            │ Shipment Object #1   │
    │ myShip    │ →     │ ─────────► │  blNo: "BL-001"       │
    │           │ 0xABC │            │  status: null         │
    └───────────────────┘            └──────────────────────┘
                                       주소: 0xABC

Step 2: myShip.setStatus(DRAFT) 실행
  
  Heap:
    ┌──────────────────────┐
    │ Shipment Object #1   │
    │  blNo: "BL-001"       │
    │  status: DRAFT        │ ← 변경
    └──────────────────────┘

Step 3: processShipment(myShip) 호출 직전
  
  값 평가: myShip 의 값 = 0xABC (참조)
  이 값을 매개변수에 전달

Step 4: processShipment 진입 직후
  
  Stack:                            Heap:
    ┌───────────────────┐            ┌──────────────────────┐
    │ main Frame        │            │ Shipment Object #1   │
    │   myShip = 0xABC  │ ──────────►│  blNo: "BL-001"       │
    ├───────────────────┤    ┌──────►│  status: DRAFT        │
    │ processShipment   │    │      └──────────────────────┘
    │   Frame           │    │
    │   shipment = 0xABC│ ───┘
    └───────────────────┘
    
    핵심: myShip 과 shipment 는
          서로 다른 슬롯 (다른 메모리)이지만
          같은 객체 (0xABC) 를 가리킴

Step 5: shipment.setStatus(ACTIVE) 실행
  
  Heap:
    ┌──────────────────────┐
    │ Shipment Object #1   │
    │  blNo: "BL-001"       │
    │  status: ACTIVE       │ ← 객체 내용 변경
    └──────────────────────┘
    
    Stack:
    ┌───────────────────┐
    │ main Frame        │
    │   myShip = 0xABC  │ ← 그대로 같은 객체 가리킴
    ├───────────────────┤
    │ processShipment   │
    │   Frame           │
    │   shipment = 0xABC│ ← 그대로
    └───────────────────┘
    
    → myShip 으로 봐도 status 가 ACTIVE 임 (같은 객체)

Step 6: shipment = new Shipment("NEW-BL") 실행
  
  Heap:
    ┌──────────────────────┐
    │ Shipment Object #1   │
    │  blNo: "BL-001"       │ ← myShip 이 가리킴
    │  status: ACTIVE       │
    └──────────────────────┘
       주소: 0xABC
    
    ┌──────────────────────┐
    │ Shipment Object #2   │ ← 새 객체 생성
    │  blNo: "NEW-BL"       │
    │  status: null         │
    └──────────────────────┘
       주소: 0xDEF
    
    Stack:
    ┌───────────────────┐
    │ main Frame        │
    │   myShip = 0xABC  │ ──► Object #1
    ├───────────────────┤
    │ processShipment   │
    │   Frame           │
    │   shipment = 0xDEF│ ──► Object #2 ← shipment 의 슬롯만 변경!
    └───────────────────┘

Step 7: shipment.setStatus(NEW) 실행
  
  Heap:
    ┌──────────────────────┐
    │ Shipment Object #1   │ ← myShip
    │  blNo: "BL-001"       │
    │  status: ACTIVE       │
    └──────────────────────┘
    
    ┌──────────────────────┐
    │ Shipment Object #2   │ ← shipment
    │  blNo: "NEW-BL"       │
    │  status: NEW          │ ← Object #2 의 status 변경
    └──────────────────────┘

Step 8: processShipment 종료
  
  Stack:
    ┌───────────────────┐
    │ main Frame        │
    │   myShip = 0xABC  │ ──► Object #1
    └───────────────────┘
  (processShipment 의 shipment 변수 사라짐)
  
  Heap:
    ┌──────────────────────┐
    │ Shipment Object #1   │ ← myShip 이 가리킴 (살아있음)
    │  status: ACTIVE       │
    └──────────────────────┘
    
    ┌──────────────────────┐
    │ Shipment Object #2   │ ← 아무도 안 가리킴 (GC 대상)
    └──────────────────────┘

출력:
  System.out.println(myShip.getBlNo());    // "BL-001"  ← 재할당 영향 X
  System.out.println(myShip.getStatus());  // ACTIVE   ← 객체 내용 변경 반영

3.3 핵심 관찰

myShip 과 shipment 는:
  ✓ 같은 객체를 가리킨다 (호출 시점에)
  ✗ 같은 메모리 슬롯이 아니다
  
객체 내용 변경:
  shipment.setStatus(ACTIVE)
  → Heap 의 Object #1 변경
  → myShip 도 Object #1 가리키므로 같은 효과
  → 반영됨

매개변수 재할당:
  shipment = new Shipment()
  → shipment 슬롯이 다른 객체 가리킴
  → myShip 슬롯은 그대로
  → myShip 무관

3.4 핵심 메시지

"같은 객체를 가리킨다" ≠ "같은 변수다"

같은 객체 가리킴:
  → 객체 내용 변경 효과 공유 ✓

같은 변수:
  → 한 쪽 재할당이 다른 쪽 재할당 ✗ (자바에선 안 됨)

→ 이 구분이 자바 매개변수의 핵심.

3.5 ILIC 시나리오 — 실수하기 쉬운 패턴

@Service
public class ShipmentService {
    
    // ❌ 매개변수 재할당으로 결과 반환 시도
    public void enrich(Shipment shipment) {
        shipment = shipment.withCargoes(loadCargoes(shipment.getId()));
        // 호출자에 반영 안 됨!
    }
    
    // ✓ 객체 내용 변경 (가능하지만 권장 X)
    public void enrichInPlace(Shipment shipment) {
        shipment.setCargoes(loadCargoes(shipment.getId()));
        // 호출자에 반영됨
    }
    
    // ✓ 가장 권장: 새 객체 반환
    public Shipment enrichReturn(Shipment shipment) {
        return shipment.withCargoes(loadCargoes(shipment.getId()));
    }
}

// 호출자
Shipment original = ...;

service.enrich(original);                  // ❌ 효과 없음
System.out.println(original.getCargoes()); // 비어있음

service.enrichInPlace(original);            // △ 원본 변경 (side effect)
System.out.println(original.getCargoes()); // 채워짐

Shipment enriched = service.enrichReturn(original);  // ✓ 함수형
System.out.println(enriched.getCargoes()); // 채워짐
System.out.println(original.getCargoes()); // 그대로 (안전)

→ ILIC 코드 리뷰 시 박승제씨가 자주 봐야 할 패턴.

3.6 자기 점검 답변

"shipment 가 원본을 가리키니 객체 변경이 반영되는 게 당연하다"
그런데 왜 "Reference 전달이 아니다" 라고 하는가?

:

  • "원본을 가리킨다" 는 맞음 — Heap 의 같은 객체
  • 하지만 변수 자체는 다른 메모리 슬롯 (Stack 의 LVA)
  • Reference 전달이라면 변수 자체가 같은 메모리여야 함
  • 자바는 그게 아니라 참조의 값을 복사
  • → "참조의 복사" 이지 "Reference 전달" 이 아님
  • → Call by Value (of a reference)

4️⃣ 두 경우의 통합된 원리 — "값의 복사"

4.1 통합 시각화

primitive (int) 의 경우:
  
  값 = 정수 (예: 100)
  
  ┌─────────┐          ┌─────────┐
  │ a = 100 │  복사→   │ x = 100 │
  └─────────┘          └─────────┘
  호출자                 매개변수
  
  (x 변경 → a 무관)


객체 참조 (Shipment) 의 경우:
  
  값 = 참조 (예: 0xABC)
  
  ┌──────────┐          ┌──────────┐
  │ a = 0xABC│  복사→   │ x = 0xABC│
  └──────────┘          └──────────┘
       │                      │
       └──────────┬───────────┘
                  ▼
            ┌──────────┐
            │ Object @ │
            │   0xABC  │
            └──────────┘
            
  (x.method() → 같은 객체 → a 도 같은 효과)
  (x = newObj → x 슬롯만 변경 → a 무관)

4.2 단일 원리

자바의 매개변수 전달 단일 원리:
  
  "호출자 변수의 값을 매개변수 슬롯에 복사한다"
  
적용:
  - primitive: 값 = 숫자/boolean/char
  - 객체: 값 = 참조 (주소)
  - 배열: 값 = 배열 객체의 참조
  - 람다: 값 = 람다 객체의 참조

모든 경우 동일.

4.3 두 종류의 변경

1. 매개변수 자체의 값을 변경
   primitive: weight = 999;
   객체:      shipment = newShipment;
   
   결과:
     매개변수 슬롯만 변경
     호출자 무관 ✗

2. 매개변수가 가리키는 객체를 변경
   primitive: (없음 — primitive 는 가리키지 않음)
   객체:      shipment.setStatus(...)
   
   결과:
     Heap 의 객체 변경
     호출자도 같은 객체 가리키므로 같은 효과 ✓

4.4 primitive 에는 종류 2 가 없는 이유

primitive:
  ┌─────────┐
  │ x = 100 │  ← 값 자체가 여기 있음
  └─────────┘
  
  "가리키는 곳" 이 없음
  → 객체 변경 같은 개념 없음
  → 변경하려면 직접 변경 (= 매개변수 재할당)
  → 호출자 무관

객체 참조:
  ┌──────────┐
  │ x = 0xABC│ ← 다른 곳의 객체를 가리킴
  └──────────┘
       │
       ▼
  ┌──────────┐
  │ Object   │ ← 변경 가능
  └──────────┘
  
  두 가지 변경 방법 존재:
    1. x 자체를 다른 주소로 (= 매개변수 재할당)
    2. x 가 가리키는 객체 변경 (= 호출자에 반영)

객체 참조만이 두 가지 변경 방법을 가짐.
→ primitive 는 단순.

4.5 자바의 천재성

설계자의 선택:
  
  "primitive 든 객체든 동일한 방식 (Call by Value) 으로 통일"
  
이점:
  1. 학습 비용 ↓ (규칙 1개)
  2. 코드 예측 가능성 ↑
  3. 매개변수 재할당이 호출자에 영향 X
  4. Frame 격리 보장

→ Kotlin 은 한 단계 더 — 매개변수 자동 val 로 재할당 자체 금지.

4.6 박승제씨의 통합 이해

박승제씨가 매개변수 보면서 항상 자문할 것:
  
  "이 매개변수의 '값' 은 무엇인가?"
  
  primitive: 숫자
  객체 참조: 참조 (주소)
  
  → 이 값이 복사된다
  → 매개변수와 호출자는 변수 자체로는 무관
  → 단, 객체 참조면 같은 객체를 가리킴

이 한 가지 사고만 하면 매개변수 동작 헷갈리지 않음.

4.7 자기 점검 답변

primitive 와 객체 참조가 같은 원리인 이유는?

:

  • 둘 다 "값의 복사" 라는 단일 원리
  • 단지 "값" 의 종류가 다를 뿐:
    • primitive: 값 자체
    • 객체 참조: 참조 (주소)
  • 메모리 메커니즘 동일 (LVA 슬롯에 복사)
  • → 자바의 단일 규칙: Call by Value

5️⃣ 흔한 8가지 오해 완전 해소

5.1 오해 1 — "객체는 Reference 로 전달된다"

❌ "Java 는 primitive 는 Value, 객체는 Reference"

✓ 정답:
  - 둘 다 Call by Value
  - 객체는 "참조의 값" 이 복사됨
  - "Reference 로 전달" 이라고 하면 C++ Reference 와 혼동
  - 정확한 표현: "Pass by Value of a reference"

5.2 오해 2 — "객체 변경되니 Reference 다"

void modify(Shipment s) {
    s.setStatus(ACTIVE);
}"호출자 객체가 변경되니 Reference 전달이 맞다"

✓ 정답:
  - 객체 내용 변경은 Heap 에서 일어남
  - 매개변수와 호출자가 같은 객체를 가리킬 뿐
  - 변수 자체는 별개
  - "객체 공유""변수 공유"

5.3 오해 3 — "primitive 도 Reference 일 수 있다"

❌ "Integer 같은 Wrapper 는 객체니까 Reference 다"

✓ 정답:
  - Wrapper 도 Call by Value (참조의 값 복사)
  - 단, Wrapper 는 불변 (immutable)
  - 매개변수 재할당 (i = i + 1) 은 새 Wrapper 객체 생성
  - 호출자 무관

5.4 오해 4 — "final 매개변수면 다르다"

void modify(final Shipment s) {
    // s = new Shipment(); // ❌ 컴파일 에러
    s.setStatus(ACTIVE);   // ✓ 가능
}"final 이라 Reference 같이 동작한다"

✓ 정답:
  - final 은 단지 매개변수 재할당 금지
  - 메커니즘은 동일 (Call by Value)
  - 객체 내용 변경은 final 과 무관
  - 메모리 동작 완전 동일

5.5 오해 5 — "static 메서드는 다르다"

❌ "static 메서드의 매개변수는 다르다"

✓ 정답:
  - static 이든 instance 든 매개변수 동작 동일
  - this 매개변수 여부만 차이
  - static 메서드는 this 없음
  - 나머지 매개변수는 모두 Call by Value

5.6 오해 6 — "큰 객체는 자동으로 Reference"

❌ "자바가 메모리 절약을 위해 큰 객체는 Reference 로 전달"

✓ 정답:
  - 모든 객체는 참조의 값 복사 (8 bytes on 64-bit)
  - 객체 크기는 영향 없음
  - 큰 객체든 작은 객체든 같은 메커니즘
  - JVM 최적화는 의미적 동일성 보장

5.7 오해 7 — "synchronized 메서드는 다르다"

❌ "synchronized 시 매개변수 동작 변경"

✓ 정답:
  - synchronized 는 락만 추가
  - 매개변수 전달 동일
  - 락 안에서도 Call by Value

5.8 오해 8 — "Reflection 으로 전달하면 다르다"

Method m = ...;
m.invoke(target, arg);
❌ "Reflection 호출은 다른 메커니즘"

✓ 정답:
  - Reflection 도 동일
  - arg 의 값이 매개변수에 복사됨
  - 객체면 참조의 값
  - 일반 호출과 의미적으로 동일

5.9 8가지 오해 종합

박승제씨가 면접에서 들을 수 있는 오해성 질문들:

오해정답
객체는 Reference 전달Call by Value of reference
객체 변경되니 Reference객체 공유 ≠ 변수 공유
Wrapper 는 Reference모든 객체와 동일
final 매개변수는 다름메커니즘 동일
static 매개변수는 다름동일
큰 객체는 Reference모든 객체 동일
synchronized 는 다름동일
Reflection 은 다름동일

모든 경우가 Call by Value.
→ 자바의 단일 규칙이 8가지 오해를 모두 잠재움.

5.10 자기 점검 답변

흔한 오해를 모두 해소할 수 있는 핵심 원리 한 문장은?

:

"자바의 모든 매개변수는 Call by Value 로 동작하며, 변수의 값(primitive 면 값 자체, 객체면 참조)이 매개변수 슬롯에 복사된다."

이 한 문장이 8가지 오해를 모두 해결.


6️⃣ ILIC 실무 종합 시나리오

6.1 시나리오 1 — Service 메서드의 매개변수

@Service
public class ShipmentService {
    
    private final ShipmentRepository repository;
    
    public ShipmentService(ShipmentRepository repository) {
        this.repository = repository;
    }
    
    /**
     * 운송 정보를 갱신한다.
     * 
     * 매개변수 update 는 호출자가 만든 객체이며,
     * 이 메서드 안에서 변경하지 않는다 (불변 입력).
     */
    public Shipment update(Long id, ShipmentUpdateRequest update) {
        Shipment shipment = repository.findById(id).orElseThrow();
        
        // ✓ shipment 의 내용 변경 (Entity 이므로 OK)
        shipment.applyUpdate(update);
        
        // 저장 후 반환
        return repository.save(shipment);
    }
}

매개변수 분석:

  • id: primitive (Long boxing). 단순 값
  • update: 객체 참조. 메서드 안에서 read-only 로 사용
  • 호출자에 영향:
    • id 변경해도 호출자 무관
    • update 객체 변경하면 호출자에 보임 (피해야 함)

6.2 시나리오 2 — Controller 의 매개변수

@RestController
@RequestMapping("/api/shipments")
public class ShipmentController {
    
    private final ShipmentService service;
    
    public ShipmentController(ShipmentService service) {
        this.service = service;
    }
    
    @PostMapping
    public ResponseEntity<ShipmentResponse> create(
        @Valid @RequestBody ShipmentCreateRequest request,
        @RequestHeader("X-User-Id") Long userId
    ) {
        // request 와 userId 는 매개변수 (Call by Value)
        // 서비스에 전달
        Shipment created = service.create(request, userId);
        return ResponseEntity.ok(ShipmentResponse.from(created));
    }
}

매개변수 분석:

  • request: HTTP body 에서 deserialize 된 객체. read-only 권장
  • userId: primitive wrapper. 단순 값
  • 매개변수 변경 시도 X (불변 입력)

6.3 시나리오 3 — 정적 유틸리티 메서드

public final class FreightUtils {
    
    private FreightUtils() {}
    
    /**
     * 운임 계산.
     * 입력 매개변수는 변경하지 않으며,
     * 새 BigDecimal 객체를 반환한다.
     */
    public static BigDecimal calculateFreight(
        int weight,
        BigDecimal baseRate,
        BigDecimal fuelRate
    ) {
        BigDecimal subtotal = baseRate.multiply(BigDecimal.valueOf(weight));
        BigDecimal fuelCharge = subtotal.multiply(fuelRate);
        return subtotal.add(fuelCharge);
    }
}

함수형 스타일:

  • 매개변수 변경 X
  • 새 객체 반환
  • side effect 없음
  • 멀티스레드 안전

→ ILIC 의 모든 유틸리티 메서드 권장 패턴.

6.4 시나리오 4 — 위험한 패턴

// ❌ 위험 패턴 1: 매개변수 컬렉션 변경
public void process(List<Shipment> shipments) {
    shipments.removeIf(Shipment::isExpired);   // 원본 변경!
}

// 호출자
List<Shipment> myList = repository.findAll();
service.process(myList);
// myList 가 의도치 않게 줄어듦 → 버그
// ✓ 안전 패턴 1: 방어적 복사 또는 새 컬렉션 반환
public List<Shipment> filterActive(List<Shipment> shipments) {
    return shipments.stream()
        .filter(s -> !s.isExpired())
        .toList();
}
// ❌ 위험 패턴 2: Entity 의 컬렉션 변경
public void clearCargoes(Shipment shipment) {
    shipment.getCargoes().clear();   // shipment 의 내부 상태 변경!
}
// ✓ 안전 패턴 2: 명시적 메서드 사용
public void clearCargoes(Shipment shipment) {
    shipment.removeAllCargoes();   // 도메인 메서드
}

6.5 시나리오 5 — 매개변수 final 패턴

@Service
public class FreightCalculator {
    
    // 매개변수에 final 명시 (재할당 방지)
    public BigDecimal calculate(
        final Shipment shipment,
        final BigDecimal baseRate
    ) {
        // shipment = null;       // ❌ 컴파일 에러
        // baseRate = BigDecimal.ZERO;  // ❌ 컴파일 에러
        
        // shipment.setStatus(...);  // 가능하지만 권장 X
        
        return shipment.getWeight() != null
            ? baseRate.multiply(BigDecimal.valueOf(shipment.getWeight()))
            : BigDecimal.ZERO;
    }
}

매개변수 final 의 효과:

  • 재할당 컴파일 에러
  • 의도 명확
  • 코드 가독성 ↑

→ Kotlin 은 자동 final.

6.6 시나리오 6 — Builder 패턴 + 매개변수

@Entity
public class Shipment {
    
    private String blNo;
    private ShipmentStatus status;
    private List<Cargo> cargoes;
    
    // 함수형 with 메서드
    public Shipment withStatus(ShipmentStatus newStatus) {
        return this.toBuilder()
            .status(newStatus)
            .build();
    }
    
    public Shipment withCargoes(List<Cargo> newCargoes) {
        return this.toBuilder()
            .cargoes(List.copyOf(newCargoes))
            .build();
    }
}

// 사용
Shipment original = new Shipment("BL-001");
Shipment updated = original
    .withStatus(ShipmentStatus.ACTIVE)
    .withCargoes(loadCargoes());

// original 은 그대로 (불변)
// updated 는 새 객체

→ Lombok @With, @Builder 활용.
→ Record 클래스 (Java 16+) 도 같은 패턴.

6.7 ILIC 매개변수 설계 체크리스트

박승제씨가 ILIC 코드 리뷰 시 체크할 것:

매개변수 자체:
  ☐ final 명시?
  ☐ 재할당 시도?
  ☐ null 가능성 명확? (@Nullable, Optional)
  
매개변수 객체:
  ☐ 메서드 안에서 변경 (side effect)?
  ☐ 컬렉션을 변경하는가?
  ☐ 불변 객체로 받을 수 있나?
  ☐ Builder/With 패턴으로 새 객체 반환?
  
메서드 시그니처:
  ☐ void 인가 반환값 있나?
  ☐ 함수형 스타일 가능?
  ☐ 이름이 의도 표현? (update vs withUpdate)
  
사이드 이펙트:
  ☐ 명시적으로 표시?
  ☐ 메서드명에 mutate, modify 등 키워드?
  ☐ 문서로 부작용 명확화?

7️⃣ 박승제씨의 5문장 답변 완성

7.1 면접 단골 질문

면접관: "Java 는 Pass by Value 인가요, Pass by Reference 인가요?"

이 질문은 자바 개발자 면접에서 거의 100% 나오는 질문.

7.2 박승제씨의 5문장 답변

박승제씨의 모범 답변:

  "자바는 오직 Call by Value 로만 동작합니다.
  
   primitive 는 값이, 객체는 참조(주소)가
   매개변수 슬롯에 복사됩니다.
  
   객체의 경우 호출자와 매개변수가 같은 객체를 가리키므로
   객체 내용 변경은 호출자에도 반영되지만,
  
   매개변수에 새 객체를 재할당하면
   매개변수 슬롯만 변경되고 호출자엔 무관합니다.
  
   C++의 Reference 처럼 진짜 별칭이 아니라
   단지 참조의 값이 복사되는 것이며,
   이를 Pass by Value of a reference 또는
   Call by Sharing 이라고도 합니다."

7.3 5문장 분석

문장 1: 단일 정답 선언
  "자바는 오직 Call by Value 로만 동작합니다."
  → 명확한 결론 먼저

문장 2: primitive 와 객체의 통합 설명
  "primitive 는 값이, 객체는 참조(주소)가
   매개변수 슬롯에 복사됩니다."
  → 통일된 원리

문장 3: 객체 변경 반영의 이유
  "객체의 경우 호출자와 매개변수가 같은 객체를 가리키므로
   객체 내용 변경은 호출자에도 반영되지만,"
  → 흔한 오해 해소

문장 4: 재할당의 무관성
  "매개변수에 새 객체를 재할당하면
   매개변수 슬롯만 변경되고 호출자엔 무관합니다."
  → 핵심 증거

문장 5: 학술 용어와 비교
  "C++의 Reference 처럼 진짜 별칭이 아니라
   단지 참조의 값이 복사되는 것이며,
   이를 Pass by Value of a reference 또는
   Call by Sharing 이라고도 합니다."
  → 깊이 + 다른 언어 비교

7.4 후속 질문 대비

면접관이 추가로 물어볼 수 있는 질문들:

Q1: "그럼 객체 변경이 반영되는데 어떻게 Reference 가 아니죠?"

박승제씨 답변:

"객체 변경이 반영되는 건 호출자와 매개변수가 같은 객체를 가리키기 때문입니다.
변수 자체는 별개 메모리이며, 변수가 가리키는 곳만 같습니다.
Reference 전달이라면 변수 자체가 같아야 하므로, 매개변수에 새 객체를 재할당했을 때
호출자도 그 새 객체를 가리켜야 합니다. 자바는 그렇지 않으므로 Reference 가 아닙니다."

Q2: "그럼 C++의 Reference 와 정확히 어떻게 다른가요?"

박승제씨 답변:

"C++의 int& x 매개변수는 호출자 변수의 별칭(alias)입니다.
매개변수와 호출자 변수가 완전히 같은 메모리를 공유합니다.
따라서 매개변수에 새 값을 대입하면 호출자 변수도 같이 변경됩니다.
자바는 매개변수가 새 슬롯이라 재할당이 호출자에 무관합니다."

Q3: "Kotlin 은 어떤가요?"

박승제씨 답변:

"Kotlin 도 자바와 동일하게 Call by Value 입니다.
단, Kotlin 매개변수는 자동으로 val (불변)이라 재할당 자체가 컴파일 에러입니다.
그래서 매개변수 재할당으로 호출자가 헷갈리는 일이 원천 차단됩니다."

Q4: "그럼 자바에서 호출자 변수를 진짜 변경하려면?"

박승제씨 답변:

"직접적인 방법은 없습니다. 우회 방법으로:
첫째, 반환값을 사용해 호출자가 직접 대입하게 합니다.
둘째, 배열이나 AtomicReference 같은 가변 컨테이너에 담아 전달합니다.
셋째, 객체의 내부 상태를 변경합니다(권장하지 않음).
자바 설계자의 의도는 호출자 변수의 명시적 재할당만 허용해 코드 예측 가능성을 높이는 것입니다."

7.5 한 단계 더 — JLS 인용

박승제씨가 면접에서 깊이를 보이려면:

"JLS 8.4.1 과 15.12.4.5 에 따르면, 매개변수는 새로 생성된 변수이며 실인자의 값으로 초기화된다고 명시되어 있습니다.
'newly created parameter variables' 와 'values ... initialize' 라는 표현이 핵심이며,
이는 Call by Value 의 정의 그대로입니다."

→ JLS 인용은 인상적이지만 외우기 부담.
→ 박승제씨가 핵심만 알고 있으면 충분.

7.6 박승제씨의 자기 점검 답변

면접에서 "Java 는 Pass by Value 인가 Reference 인가?" 질문을 받으면 어떻게 답할 것인가?

: 위 5문장 답변 → 후속 질문 대비 → JLS 인용 (선택)

→ 박승제씨가 이 답변을 외워서 자신감 있게 말하면 면접관도 인정.


8️⃣ Phase 1 종합 — 1, 2, 3주차 학습 통합

8.1 1·2주차에서 다진 토대

1주차 학습:
  - JVM 메모리 구조 (Phase 4)
  - Stack/Heap/Method Area 개론
  - "자바는 Pass by Value" 첫 소개

2주차 학습:
  - Phase 1: 변수 ↔ 메모리 매핑 (1.1 ~ 1.6)
    - Stack Area 의 LVA
    - Object Header, Class Pointer
    - String Pool, Integer Cache
  
  - Phase 2: 메서드 실행 메커니즘 (2.1 ~ 2.4)
    - Method Resolution + Invocation
    - this 의 자동 전달
    - new 의 4가지 작업
  
  - Phase 3: 바이트코드 (3.1 ~ 3.4) — 정점
    - Constant Pool
    - Symbol → Direct Reference
    - 바이트코드 실전 분석
  
  - Phase 4: G1 GC (4.1 ~ 4.5)
    - 리전 모델
    - 우선순위 회수
  
  - Phase 5-7: 컬렉션, Reflection, Buffer

8.2 3주차 Phase 1 의 위치

3주차 Phase 1 — Pass by Value 진짜 이해:
  
  1.1 C 포인터 기초
    └ 1·2주차의 메모리 모델 위에서 C 비교
  
  1.2 Pass by Value vs Pass by Reference
    └ 두 패러다임의 메모리 차이
  
  1.3 자바의 Call by Value 한 가지 (이번)
    └ 자바의 단일 답 + 면접 정복

→ Phase 1 의 정점.
→ 1·2주차의 모든 메모리 학습이 여기서 응집.

8.3 학습의 연결

박승제씨가 1·2·3주차에서 배운 것들의 연결:

1주차: "자바는 Pass by Value"
   ↓
2주차: "Stack Frame, LVA 슬롯, Heap 객체"
   ↓
3주차 Phase 1: "왜? 어떻게? 다른 언어와 비교"

각 주차의 학습이 다음 주차의 토대.

8.4 Phase 1 의 핵심 요약

🎯 Phase 1 핵심:

1. 자바의 매개변수 전달은 단 하나 — Call by Value
2. primitive 와 객체 참조 모두 같은 원리 ("값의 복사")
3. 객체의 경우 같은 객체를 가리키지만 변수는 별개
4. 재할당이 호출자에 무관한 게 Call by Value 의 증거
5. C++ Reference 가 진짜 Pass by Reference, 자바는 아님
6. 흔한 8가지 오해는 단일 원리로 모두 해소

8.5 박승제씨의 향상된 능력

Phase 1 학습 후:

✓ 매개변수 전달의 메모리 동작 완벽 이해
✓ C/C++/Python/Kotlin 등 다른 언어와 비교 가능
✓ 면접 단골 질문에 5문장 답변 자신감
✓ ILIC 코드의 매개변수 패턴 식별
✓ side effect 회피하는 함수형 설계 가능
✓ 1·2주차 메모리 학습이 실용으로 연결

8.6 Phase 2 진입 준비

다음 Phase 2: 컬렉션 프레임워크 전체 지도
  
  연결:
    - 매개변수 전달 (Phase 1) 의 컬렉션 적용
    - 1주차에서 본 ArrayList vs LinkedList
    - 2주차에서 본 컬렉션 내부 구조
    - 3주차에서는 전체 5계층 + Vector/HashTable/ConcurrentHashMap
    
  새로 다룰 것:
    - Set 3형제 (Hash/Tree/Linked)
    - Queue 자료구조 (offer/poll 등)
    - Map 5형제 (Hash/Linked/Tree/HashTable/Concurrent)
    - 전체 컬렉션 지도

8.7 자기 점검 답변

Phase 1 학습으로 박승제씨가 가진 능력은?

:
1. 자바 매개변수의 단일 정답 — Call by Value
2. 다른 언어와의 비교 — C/C++/Python/Kotlin/Rust 등
3. 면접 단골 5문장 답변
4. 메모리 다이어그램으로 설명 가능
5. ILIC 코드의 매개변수 안티패턴 식별
6. 함수형 스타일 설계 능력


9️⃣ Phase 1 졸업 시험 + 자기 점검

9.1 면접 단골 질문 매핑

Q핵심 답변
자바는 Pass by Value 인가 Reference 인가?Call by Value 만
객체 변경되니 Reference 아닌가?객체 공유 ≠ 변수 공유
primitive 와 객체 매개변수 차이?값 vs 참조의 값, 메커니즘 동일
C++ Reference 와의 차이?진짜 별칭 vs 참조의 값 복사
C 포인터 전달은 Reference?아니. Pass by Value of a pointer
자바에서 진짜 reference 효과?우회 (배열, AtomicReference, 반환값)
매개변수 final 의미?재할당 금지, 메커니즘 동일
Wrapper 는 Reference?객체와 동일, 단 불변
자바 설계자가 단일 방식 선택한 이유?단순함, 예측 가능성
Kotlin 과 비교?동일 + 자동 final

9.2 자기 점검 체크리스트

기본 이해

  • Call by Value 의 정확한 정의를 안다
  • primitive 매개변수 동작을 메모리 다이어그램으로 그릴 수 있다
  • 객체 참조 매개변수 동작을 메모리 다이어그램으로 그릴 수 있다
  • 두 경우의 통합된 원리 ("값의 복사") 를 설명할 수 있다
  • C++ Reference 와의 차이를 메모리 레벨로 설명할 수 있다

흔한 오해 해소

  • "객체는 Reference 전달" 오해 해소 가능
  • "객체 변경되니 Reference" 오해 해소 가능
  • "큰 객체는 자동 Reference" 오해 해소 가능
  • 8가지 오해 모두 단일 원리로 해소 가능

실전 적용

  • ILIC 코드에서 매개변수 안티패턴 식별 가능
  • 함수형 스타일 (새 객체 반환) 적용
  • 컬렉션 매개변수 방어적 복사 검토
  • 매개변수 final 패턴 적용
  • 불변 객체 활용

면접 대비

  • 5문장 답변 외워 즉답 가능
  • 후속 질문 4가지 대비
  • JLS 인용 (선택)
  • 다른 언어 (C++/C/Python/Kotlin) 비교 가능
  • 메모리 다이어그램으로 설명 가능

9.3 🎯 Phase 1 졸업 시험

다음 질문에 즉답할 수 있다면 Phase 1 졸업:

졸업 질문 1

Java 에서 다음 코드의 출력을 예측하라.

<void modify(int a, Integer b, Shipment c, List<String> d) {
    a = 999;
    b = 999;
    c.setStatus(ACTIVE);
    c = new Shipment("X");
    d.add("E");
    d = new ArrayList<>();
}

void main() {
    int x = 1;
    Integer y = 2;
    Shipment z = new Shipment("BL").withStatus(DRAFT);
    List<String> w = new ArrayList<>(List.of("A", "B"));
    
    modify(x, y, z, w);
    
    System.out.println(x);                    // ?
    System.out.println(y);                    // ?
    System.out.println(z.getBlNo());           // ?
    System.out.println(z.getStatus());         // ?
    System.out.println(w);                     // ?
}

답:

  • x: 1 (primitive, 매개변수 재할당 무관)
  • y: 2 (Integer 불변, 재할당 무관)
  • z.getBlNo(): "BL" (매개변수 재할당 무관)
  • z.getStatus(): ACTIVE (객체 내용 변경 반영)
  • w: [A, B, E] (컬렉션 변경 반영)

졸업 질문 2

"객체를 reference 로 전달한다" 가 왜 부정확한 표현인지 메모리 다이어그램으로 설명하라.

졸업 질문 3

C++의 void f(int& x) 와 Java 의 void f(int x) 가 어떻게 다른지,
x = 100 실행 시 호출자 변수가 어떻게 되는지 메모리 레벨로 비교하라.

졸업 질문 4

자바에서 호출자 변수를 진짜로 변경하는 방법 3가지를 제시하라.

답:
1. 반환값으로 호출자가 대입: x = transform(x)
2. 가변 컨테이너에 담아 전달: int[] holder = {x}; modify(holder); x = holder[0]
3. 객체의 내부 상태를 변경: obj.setX(newX) (side effect, 권장 X)

졸업 질문 5

박승제씨의 5문장 면접 답변을 외워서 말하라.

→ 모두 답할 수 있다면 Phase 1 완주.

9.4 박승제씨의 자가 진단

다음 중 박승제씨가 완전히 익혔는지 체크:

기본:
  ☐ Call by Value 정의 1문장
  ☐ Pass by Value 와 동의어
  ☐ JVM Stack Frame 격리

primitive:
  ☐ 5단계 메모리 추적
  ☐ 호출자 무관 이유

객체:
  ☐ 7단계 메모리 추적
  ☐ 객체 공유 vs 변수 공유 구분
  ☐ 두 가지 변경의 차이

비교:
  ☐ C 포인터와 비교
  ☐ C++ Reference 와 비교
  ☐ Python/Kotlin/Rust 비교

실무:
  ☐ ILIC 코드 리뷰 가능
  ☐ 함수형 스타일 적용
  ☐ 매개변수 final 패턴

면접:
  ☐ 5문장 답변
  ☐ 후속 질문 4가지
  ☐ 졸업 시험 5문항

→ 모두 체크 가능하면 박승제씨는 Phase 1 마스터.


🎯 핵심 요약 — 3줄 정리

1. 자바의 단일 답 — Call by Value 한 가지

  • primitive: 값 자체 복사
  • 객체: 참조(주소) 가 값으로 복사
  • 모든 경우 매개변수가 새 메모리 슬롯

2. 두 가지 변경의 구분

  • 객체 내용 변경 → 같은 객체 가리키므로 반영
  • 매개변수 재할당 → 변수 슬롯만 변경, 호출자 무관
  • 이 구분이 Call by Value 의 핵심 증거

3. ILIC 실무 + 면접

  • 매개변수 final + 함수형 스타일 + 새 객체 반환
  • 5문장 답변으로 면접 단골 정복
  • 8가지 오해 모두 단일 원리로 해소

🏆 Phase 1 완주 — Pass by Value 마스터 달성

🚀 Phase 1 — Pass by Value의 진짜 이해
  ✅ Unit 1.1 C 포인터 기초
  ✅ Unit 1.2 Pass by Value vs Pass by Reference
  ✅ Unit 1.3 자바의 Call by Value 한 가지 ← 여기, Phase 1 완주

→ 박승제씨는 이제 자바 매개변수 전달의 마스터
→ 면접 단골 질문에 즉답 가능

Phase 1 후 박승제씨가 가진 능력

  • ✓ 매개변수 전달의 단일 원리 이해
  • ✓ primitive 와 객체 통합 설명
  • ✓ 메모리 다이어그램으로 시각화
  • ✓ C/C++/Python/Kotlin 등 비교
  • ✓ 흔한 8가지 오해 해소
  • ✓ ILIC 코드 안티패턴 식별
  • ✓ 함수형 스타일 설계
  • ✓ 면접 5문장 답변 완성

3주차 진행 상황

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

3주차 누적 진행

작성한 자료:
  Unit 1.1 C 포인터 기초
  Unit 1.2 Pass by Value vs Pass by Reference
  Unit 1.3 자바의 Call by Value 한 가지 ← 여기

총: 3/43 Unit 작성 (Phase 1 완주, 약 7%)

📚 다음으로...

Phase 2 — 컬렉션 프레임워크 전체 지도 (다음)

이번 Phase 에서 매개변수 전달을 마스터했다면, 다음은 컬렉션의 전체 풍경.

박승제씨가 1·2주차에서 본 것:

  • 1주차: ArrayList vs LinkedList 비교
  • 2주차: 컬렉션 내부 구조 정밀

3주차 Phase 2:

  • 전체 5계층 컬렉션 지도 완성
  • Vector, HashTable, ConcurrentHashMap 등 신규 토픽
  • Queue 자료구조 (offer/poll 메서드 페어)
  • Set 3형제 (Hash/Tree/Linked)
  • Map 5형제 (Hash/Linked/Tree/HashTable/Concurrent)

→ Phase 2 가 끝나면 자바 컬렉션의 전체 풍경 이 완성.

profile
Software Developer

0개의 댓글