📚Java 기본
1. 자바의 특징은 무엇인가요?
Java 언어의 핵심 기능을 이해합니다.
- 객체 지향:캡슐화, 상속, 다형성과 같은 기능을 지원합니다.
- 플랫폼 독립성:한 번 작성하면 어디서나 실행(WORA)
- 자동 메모리 관리:가비지 수집 메커니즘이 자동으로 메모리를 해제합니다.
- 멀티스레딩 지원:동시 프로그래밍을 용이하게 하는 내장 스레드 메커니즘
- 강력한 보안:유형 검사, 예외 처리 등의 보안 메커니즘 제공
- 동적 특성:런타임 유형 검사 및 동적 로딩
2. JDK, JRE, JVM의 차이점은 무엇입니까?
Java 런타임 환경의 3계층 구조 이해
- JVM(자바 가상 머신):크로스 플랫폼 기능을 달성하기 위해 바이트코드를 실행하는 추상 컴퓨터인 가상 머신
- JRE(자바 런타임 환경):실행에 필요한 JVM 및 클래스 라이브러리를 포함한 런타임 환경
- JDK(자바 개발 키트):JRE + 컴파일러 + 디버깅 도구 및 기타 개발 도구를 포함한 개발 도구 키트
- 포함 관계:JDK > JRE > JVM
3. 바이트코드란 무엇인가요? Java 크로스 플랫폼인 이유는 무엇입니까?
Java의 크로스 플랫폼 메커니즘의 원리를 깊이 이해합니다.
- 바이트코드 정의:Java 소스 코드 컴파일에 의해 생성된 중간 코드, 파일 확장자는 .class입니다.
- 크로스 플랫폼 원칙:Java 소스 코드 → 바이트코드 → 다양한 플랫폼에서 JVM 실행
- 장점:한 번 컴파일하면 어디서나 실행됩니다. 개발자는 다른 플랫폼에 맞게 코드를 다시 작성할 필요가 없습니다.
- 실행 프로세스:javac 컴파일러는 .java 파일을 .class 파일로 컴파일한 후 각 플랫폼의 JVM에서 해석하고 실행합니다.
4. Java의 기본 데이터 유형은 무엇입니까?
Master Java의 유형 시스템
- 정수 유형:byte(1바이트), short(2바이트), int(4바이트), long(8바이트)
- 부동 소수점 유형:float(4바이트), double(8바이트)
- 문자 유형:char(2바이트, 유니코드 지원)
- 부울 유형:부울(1바이트, 참/거짓)
- 기본값:정수 0, 부동 소수점 0.0, 부울 false, char '\u0000'
- 포장 카테고리:Integer, Long, Float, Double, Boolean 및 기타 해당 참조 유형
5. final, finally, finalize의 차이점은 무엇인가요?
유사하지만 완전히 다른 세 가지 개념을 구별합니다.
- 최종(키워드):수정된 클래스는 상속될 수 없고 수정된 메서드는 재정의될 수 없으며 수정된 변수는 재할당될 수 없습니다.
- 마지막으로 (키워드):try-catch-finally의 코드 블록은 예외 발생 여부에 관계없이 실행되며 리소스 해제에 자주 사용됩니다.
- 마무리(방법):객체가 가비지 수집되기 전에 호출되어 리소스를 정리하는 데 사용되는 Object 클래스의 메서드(사용되지 않음)
- 애플리케이션 시나리오:final은 불변성 제어에 사용되고 finally는 예외 안전에 사용되며 finalize는 try-with-resources로 대체되었습니다.
🎯 객체 지향 프로그래밍
6. 객체지향이란 무엇입니까? 네 가지 주요 특징은 무엇입니까?
OOP의 핵심 개념을 이해합니다.
- 객체 지향 정의:객체 기반 프로그래밍 아이디어, 객체의 속성과 동작 강조
- 네 가지 주요 기능:
- 개요:사물의 공통적인 특징을 추출하고 중요하지 않은 세부정보는 무시합니다.
- 패키지:내부 구현 세부 정보를 숨기고 필요한 인터페이스를 노출하며 보안을 강화합니다.
- 상속:하위 클래스는 코드 재사용을 위해 상위 클래스의 속성과 메서드를 상속합니다.
- 다형성:동일한 인터페이스의 다양한 구현, 런타임 시 동적 바인딩
7. 다형성이란 무엇입니까? 다형성을 구현하는 방법은 무엇입니까?
Java 다형성 메커니즘에 대한 심층적인 이해
- 다형성 정의:객체에는 여러 형태가 있으며 동일한 메서드 호출이 객체마다 성능이 다릅니다.
- 구현 방법:
- 컴파일 시간 다형성(오버로딩):이름은 같지만 매개변수가 다른 메서드는 컴파일 중에 호출해야 합니다.
- 런타임 다형성(재정의됨):상위 클래스 참조는 하위 클래스 객체를 가리키며 런타임은 호출되는 실제 메서드를 결정합니다.
- 런타임 다형성 조건:상속, 재작성, 상향 변환
- 장점:코드 유연성과 유지 관리성을 향상하고 인터페이스 프로그래밍을 지원합니다.
8. 인터페이스와 추상 클래스의 차이점은 무엇입니까?
두 추상 메커니즘 간의 유사점과 차이점을 비교합니다.
- 추상 클래스:추상 수정을 사용하면 추상 메소드와 구상 메소드가 있을 수 있습니다.
- 인터페이스:인터페이스 정의를 사용합니다. 기본 메소드는 공개 추상입니다(Java 8+는 기본 구현을 지원합니다).
- 상속 관계:클래스는 단일 추상 클래스만 상속할 수 있지만 여러 인터페이스를 구현할 수 있습니다.
- 액세스 수정자:추상 클래스는 비공개/보호될 수 있으며 인터페이스 멤버는 기본적으로 공개될 수 있습니다.
- 변수:추상 클래스에는 인스턴스 변수가 있고 인터페이스에는 정적 상수만 있습니다.
- 사용 시나리오:추상 클래스는 코드 및 인터페이스 정의 사양을 공유하는 데 사용됩니다.
9. 오버로드와 오버라이드란 무엇인가요?
유사하지만 다른 두 개념을 구별하세요.
- 과부하:
- 같은 클래스 내에서도 메소드 이름은 동일하지만, 매개변수의 종류/갯수/순서가 다릅니다.
- 컴파일 타임에 결정되며 정적 바인딩에 속합니다.
- 반환 값 유형은 다를 수 있습니다(그러나 반환 값만으로는 구별되지 않음).
- 재정의:
- 하위 클래스는 상위 클래스의 메서드를 다시 구현하며 메서드 서명은 정확히 동일합니다.
- 런타임 시 결정되며 동적 바인딩에 속함
- 반환 값 유형과 예외는 호환되어야 합니다.
10. 접근 한정자는 무엇입니까? 행동 범위는 무엇입니까?
Master Java의 액세스 제어 메커니즘
- 공개:공개, 모든 클래스에 접근 가능
- 보호됨:보호됨, 동일한 패키지 및 하위 클래스에서 액세스 가능
- 기본값(수정자 없음):기본적으로 동일한 패키지에 액세스할 수 있습니다.
- 비공개:비공개, 클래스 내에서만 접근 가능
- 액세스 범위 비교:공개 > 보호 > 기본값 > 비공개
- 모범 사례:접근 권한을 최소화하고 캡슐화 원칙을 따릅니다.
💾 메모리 관리 및 가비지 수집
11. 자바 메모리 구조에는 무엇이 포함되나요?
JVM 메모리 할당 이해
- 힙:모든 스레드가 공유하는 객체 인스턴스, 가비지 수집을 위한 주요 영역, 구성 가능한 크기를 저장합니다.
- 스택:각 스레드에 고유한 지역 변수 및 메서드 호출을 저장하고 자동으로 메모리를 해제합니다.
- 방법 영역:스토리지 클래스 구조 정보, 런타임 상수 풀, 정적 변수 등은 모든 스레드에서 공유됩니다.
- 프로그램 카운터:현재 스레드에 의해 실행된 바이트코드 명령어 주소를 기록합니다.
- 로컬 메서드 스택:네이티브 메소드 실행(C/C++ 코드)
12. 가비지 컬렉션이란 무엇입니까? 가비지 수집 알고리즘이란 무엇입니까?
GC 메커니즘에 대한 깊은 이해
- 가비지 컬렉션 정의:더 이상 사용되지 않는 객체가 차지하는 메모리를 자동으로 회수합니다.
- 주요 알고리즘:
- 마크 클리어:라이브 객체 표시, 쓰레기 제거, 조각 생성
- 복사 알고리즘:메모리를 두 조각으로 나누고 삭제하는 동안 살아남은 개체를 복사합니다. 조각화는 없지만 메모리 낭비가 발생합니다.
- 태그 정렬:마킹 후 압축 및 조각 모음, 조각화는 없지만 성능이 저하됨
- 세대 알고리즘:객체는 신세대와 구세대로 구분되며, 세대마다 다른 전략을 사용합니다.
- 장점:메모리 누수를 방지하기 위한 자동 메모리 관리
13. 힙과 스택의 차이점은 무엇입니까?
두 가지 중요한 메모리 영역 비교
- 저장 내용:힙 객체, 스택 기본 유형 및 참조
- 스레드:힙은 모든 스레드에 의해 공유되며 각 스레드에는 독립적인 스택이 있습니다.
- 관리:힙은 가비지 컬렉터에 의해 관리되고 스택은 자동으로 해제됩니다.
- 크기:일반적으로 힙은 더 크고 스택은 상대적으로 작습니다.
- 성능:스택 할당은 빠르고, 힙 할당은 상대적으로 느림
- 예외:힙 오버플로 OutOfMemoryError, 스택 오버플로 StackOverflowError
14. 메모리 누수란 무엇입니까? 그것을 피하는 방법?
일반적인 기억 문제 인식
- 메모리 누수 정의:프로그램에서 요청한 메모리를 해제할 수 없고 메모리를 오랫동안 점유하고 있습니다.
- 일반적인 이유:
- 수명이 긴 개체는 수명이 짧은 개체를 나타냅니다.
- 컬렉션의 개체가 제때 정리되지 않습니다.
- 리스너 또는 콜백이 등록 취소되지 않았습니다.
- 정적 컬렉션이 무한히 증가합니다.
- 피하는 방법:참조를 즉시 해제하고, 리소스 사용 시도를 사용하고, 정기적으로 메모리 사용량을 확인하세요.
15. 강한 참조, 소프트 참조, 약한 참조, 가상 참조란 무엇입니까?
Java의 네 가지 참조 유형 이해
- 강력한 인용문:일반 참조, 강한 참조가 없을 때까지 객체는 재활용되지 않습니다.
- 소프트참조:메모리가 부족할 때 재활용하여 캐싱용으로 사용합니다.
- 약한 참조:다음 GC에서 재활용되어 WeakHashMap에 사용됩니다.
- 팬텀참조:언제든지 재활용할 수 있으며 객체 재활용을 추적하기 위해 참조 큐와 함께 사용해야 합니다.
- 재활용 우선순위:가상 참조 > 약한 참조 > 소프트 참조 > 강한 참조
📦 컬렉션 프레임워크
16. Java Collections Framework의 구조는 무엇입니까?
컬렉션 프레임워크의 전반적인 개념을 숙지하세요.
- 컬렉션 인터페이스:
- 목록:ArrayList, LinkedList와 같이 순서가 지정되고 반복 가능합니다.
- 설정:HashSet, TreeSet과 같이 순서가 없고 반복되지 않습니다.
- 대기열:LinkedList, PriorityQueue와 같은 대기열
- 지도 인터페이스:
- 키-값 쌍 매핑:HashMap, TreeMap, ConcurrentHashMap
- 전체 수준:Iterable → 컬렉션/맵 → 구체적인 구현 클래스
17. ArrayList와 LinkedList의 차이점은 무엇입니까?
일반적으로 사용되는 두 가지 목록 구현 비교
- 데이터 구조:ArrayList는 배열을 기반으로 하고 LinkedList는 이중 연결 목록을 기반으로 합니다.
- 무작위 액세스:배열리스트 O(1), 링크드리스트 O(n)
- 삽입 및 삭제:배열리스트 O(n), 링크드리스트 O(1)
- 메모리 사용량:ArrayList는 연속적이며 LinkedList는 분산되어 있습니다(포인터 오버헤드).
- 스레드 안전성:둘 다 동기화되지 않았습니다. Collections.synchronizedList() 또는 CopyOnWriteArrayList를 사용할 수 있습니다.
- 선택:빈번한 쿼리에는 ArrayList를 사용하고 빈번한 삽입 및 삭제에는 LinkedList를 사용하십시오.
18. HashMap의 원리와 성능은 무엇인가요?
HashMap 작동 방식에 대한 깊은 이해
- 데이터 구조:배열 + 연결 리스트 + 레드-블랙 트리(JDK 8+)
- 작동 방식:hash(key) % table.length 충돌 시 배열 첨자, 링크 또는 트리 계산
- 로딩 인자:기본값은 0.75, 사용 용량 ≥ 용량 × 로딩 계수일 때 확장됩니다.
- 확장 메커니즘:용량이 두 배로 증가하고 요소가 다시 해시되었습니다.
- 시간 복잡도:평균 O(1), 최악 O(n) (충돌이 많은 경우)
- 스레드 안전성:동기화되지 않았습니다. 멀티스레딩을 위해 ConcurrentHashMap 또는 Collections.synchronizedMap()을 사용하세요.
19. HashSet이 중복되지 않도록 하는 방법은 무엇입니까?
Set의 중복 제거 메커니즘 이해
- 낮은 수준 구현:HashMap을 기반으로 키는 요소이고 값은 고정된 개체입니다.
- 중복 제거 메커니즘:먼저 hashCode()를 비교한 다음 equals()를 사용하여 동일성을 확인합니다.
- 프로세스 추가:해시 계산 → 존재하는지 확인 → 존재하지 않으면 추가 → 존재하면 무시
- 사용자 정의 개체:일관성을 보장하려면 equals() 및 hashCode()를 다시 작성해야 합니다.
- 성능:해시 품질에 따라 평균 O(1) 추가, 삭제 및 검색
20. 빠른 실패와 안전 장치란 무엇입니까?
컬렉션의 반복자 안전 메커니즘 이해
- 빠른 실패:
- 반복 프로세스 중에 컬렉션을 수정하면 ConcurrentModificationException이 발생합니다.
- modCount 및 ExpectModCount를 통해 감지됨
- ArrayList, HashMap 등(스레드로부터 안전하지 않음)
- 안전 장치:
- 반복은 컬렉션의 스냅샷이나 복사본을 기반으로 합니다. 원본 컬렉션을 수정해도 반복에는 영향을 주지 않습니다.
- CopyOnWriteArrayList, ConcurrentHashMap 등
- 사용 제안:반복할 때 반복자의 Remove()를 사용하거나 안전 장치 컬렉션을 사용하세요.
⚠️예외 처리
21. 자바 예외 시스템?
Java 예외 분류 이해
- Throwable(루트 클래스):
- 예외:복구 가능한 예외
- 오류:가상 머신 수준 오류, 복구할 수 없음
- 예외 카테고리:
- 확인된 예외(확인됨):IOException과 같이 포착되거나 선언되어야 합니다.
- 확인되지 않은 예외(선택되지 않음):NullPointerException, IndexOutOfBoundsException 등을 잡을 수 없습니다.
- 일반적인 예외:NPE, ClassCastException, ArrayIndexOutOfBoundsException 등
22. Try-catch-finally 실행 순서는 무엇입니까?
예외 처리의 실행 흐름을 마스터하세요.
- 정상적인 상황:시도 → 마침내 → 정상적으로 반환
- 예외:try → 예외 발생 → catch → finally → 예외가 전달되거나 반환됨
- 마지막으로 특징:catch에서 return, throw, System.exit()를 수행하는 경우에도 실행해야 합니다.
- 예외:finally의 반환은 try/catch의 반환을 재정의합니다.
- 리소스 릴리스:리소스를 자동으로 닫으려면 try-with-resources를 사용하는 것이 좋습니다.
- 모범 사례:finally에서 반환 값을 변경하지 마세요. 이렇게 하면 예외가 손실될 수 있습니다.
23. 던지기와 던지기의 차이점은 무엇인가요?
두 가지 예외 처리 키워드 구별
- 던지기:
- 수동으로 예외 인스턴스 발생, 메소드 내에서 사용해야 함
- 형식: 새로운 예외 발생("메시지")
- 던진다:
- 메소드 서명에서 발생할 수 있는 예외 선언
- 형식: public void method()가 IOException을 발생시킵니다.
- 처리 방법:throw는 throw로 선언되고 throw는 호출자가 처리합니다.
- 신청:throw는 특정 예외 처리에 사용되고, throw는 예외 전달에 사용됩니다.
24. 예외를 사용자 정의하는 방법은 무엇입니까?
프로젝트별 예외 클래스 생성
- 상속 관계:상속 예외(확인된 예외) 또는 RuntimeException(확인되지 않은 예외)
- 필요한 부품:
- 매개변수 없는 생성자를 제공하세요.
- 생성자에 메시지 제공
- 생성자에 메시지와 원인 제공
- 코드 예:공용 클래스 CustomException은 예외 { ... }를 확장합니다.
- 모범 사례:명확한 이름 지정, 명확한 문서화 및 적절한 예외 클래스의 상속
25. try-with-resources 구문의 이점은 무엇입니까?
자동 리소스 관리 이해
- 구문:try (InputStream is = ...) { ... } 자동으로 리소스 닫기
- 요구사항:리소스는 AutoCloseable 인터페이스를 구현해야 합니다.
- 장점:
- 수동 관리 없이 자동으로 close() 메소드 호출
- 억제된 경우 예외의 올바른 처리
- 코드가 더 간결해지고 리소스 누출을 방지합니다.
- 적용 가능한 시나리오:파일, 스트림, 연결, 명령문 등과 같은 리소스 클래스입니다.
🔤 문자열, StringBuilder, StringBuffer
26. 문자열은 불변이며 그 이유는 무엇입니까?
String 디자인의 깊은 고려 사항 이해
- 불변 정의:String 개체는 생성된 후에는 수정할 수 없으며 모든 수정 작업은 새 개체를 반환합니다.
- 구현 방법:값 배열은 최종 수정되며 setter 메소드가 없습니다.
- 변경할 수 없는 이유:
- 반복 생성을 방지하기 위한 문자열 버퍼 풀 최적화
- 스레드로부터 안전하며 동기화가 필요하지 않습니다.
- HashMap 키에 적합한 hashCode 캐싱 지원
- 단점:잦은 수정으로 인해 수많은 중간 개체가 생성됩니다.
27. String, StringBuilder 및 StringBuffer의 차이점은 무엇입니까?
적절한 문자열 조작 클래스를 선택하십시오.
- 문자열:불변, 스레드 안전, 성능 저하(잦은 수정)
- 스트링빌더:가변적, 스레드로부터 안전하지 않음, 탁월한 성능(단일 스레드)
- 문자열버퍼:변경 가능, 스레드 안전(동기화 메서드), 평균 성능(멀티스레딩)
- 성능 비교:StringBuilder > StringBuffer > 문자열
- 사용 제안:
- StringBuilder를 사용한 단일 스레드 문자열 연결
- 다중 스레드 문자열 연결을 위한 StringBuffer
- 수정할 필요가 없습니다. 문자열을 사용하세요.
28. 문자열 상수 풀이란 무엇입니까?
문자열 캐싱 메커니즘 이해
- 정의:JVM에서 관리하는 문자열 캐시로 문자열 리터럴을 저장합니다.
- 위치:이전에는 메서드 영역에 있었던 힙의 JDK 7+
- 생성 메커니즘:
- "abc"와 같은 리터럴은 자동으로 상수 풀에 들어갑니다.
- new String("abc") "abc"가 풀에 없으면 추가합니다.
- 인턴() 메서드:상수 풀에 문자열을 추가하거나 기존 참조를 반환합니다.
- 최적화 효과:메모리 절약 및 문자열 비교 속도 향상
29. 문자열이 같은지 비교하는 방법은 무엇입니까?
문자열을 비교하는 방법 알아보기
- == 비교:참조가 동일한지 비교하고, 내용은 비교하지 않습니다.
- 같음() 비교:문자열 내용을 비교하여 동일한지 확인합니다. 사용하는 것이 좋습니다
- equalsIgnoreCase() 비교:대소문자 비교 내용 무시
- CompareTo() 비교:사전식 비교, 정수 반환
- Objects.equals():Null 값의 안전한 비교 처리
- 모범 사례:문자열 내용을 비교하려면 ==를 사용하지 말고 equals()를 사용하세요.
30. 문자열 연결의 성능 문제는 무엇입니까?
문자열 연결 성능 최적화
- 질문:문자열 s = "a" + "b" + "c"는 여러 중간 개체와 복사본을 생성합니다.
- 이유:문자열은 변경할 수 없으며 연결될 때마다 새 객체가 생성됩니다.
- 성능 영향:루프 접합 시 O(n²) 시간 복잡도
- 최적화 계획:
- 루프 외부에서 직접 +: 컴파일러는 StringBuilder로 최적화합니다.
- StringBuilder 또는 StringBuffer를 명시적으로 사용
- String.join(), StringJoiner 등과 같은 도구를 사용합니다.
🔄 멀티스레딩 및 동시성
31. 스레드란 무엇입니까? 스레드를 만드는 방법은 무엇입니까?
스레드의 기본 개념과 생성 방법을 숙지하세요.
- 스레드 정의:프로세스 내에서 독립적인 실행 흐름, 공유 메모리이지만 독립적인 스택
- 만드는 방법:
- 스레드 상속:공용 클래스 MyThread는 Thread { public void run() {} }를 확장합니다.
- 실행 가능 구현:공용 클래스 MyRunnable은 Runnable을 구현합니다. { public void run() {} }
- 호출 가능 구현:반환 값 및 예외 지원
- 차이점:단일 상속 제한을 피하기 위해 Runnable을 권장합니다.
- 시작:thread.start()를 호출합니다. run()을 직접 호출할 수 없습니다.
32. 스레드 수명주기 및 상태는 무엇입니까?
스레드의 다양한 상태 전환 이해
- 신규:스레드가 생성되었지만 시작되지 않았습니다.
- 실행 가능:실행 가능 상태(실행 대기 중 또는 실행 중)
- 차단됨:차단된 상태, 잠금 획득 대기 중
- 대기 중:대기 상태, 다른 스레드의 알림을 기다리는 중
- TIMED_WAITING:지정된 시간 동안 기다리기
- 종료됨:스레드가 종료되었습니다.
- 상태 전환:NEW → RUNNABLE → BLOCKED/WAITING → TERMINATED
33. 동기화는 어떻게 작동하나요?
Java의 내장 잠금 메커니즘 이해
- 동기화 메커니즘:객체의 내장 잠금을 사용한 동기화
- 사용 방법:
- 동기화 방법:공개 동기화 무효 메소드() {}
- 동기화 블록:동기화됨(obj) { ... }
- 작동 방식:
- 모든 객체에는 모니터가 있습니다
- 스레드가 잠금을 획득하고 임계 섹션에 진입하여 상호 배타적 실행
- 바이트코드: monitorenter, monitorexit
- 특징:재진입, 독점, 자동 릴리스
34. 휘발성 키워드의 역할은 무엇인가요?
메모리 가시성 이해 및 명령 재정렬 비활성화
- 기능:
- 가시성:변경 사항이 다른 스레드에 즉시 표시되는지 확인
- 리플로우 금지:컴파일러 및 CPU 재정렬 최적화 방지
- 구현:메모리 장벽, 주 메모리에서 강제로 읽고 쓰기
- 제한사항:원자성은 보장되지 않으며 동기화를 대체할 수 없습니다.
- 애플리케이션 시나리오:플래그 비트, 이중 확인 싱글톤, 상태 표시
- 동기화 비교:휘발성은 더 가볍지만 기능이 제한적입니다.
35. wait(), inform() 및 informAll()의 기능과 차이점은 무엇입니까?
스레드 간 통신 메커니즘을 마스터하세요.
- 잠깐():
- 현재 스레드는 잠금을 해제하고 깨어날 때까지 기다립니다.
- 동기화된 블록 내에서 호출되어야 합니다.
- 통지():
- 대기 중인 스레드 깨우기(무작위로 선택됨)
- 잠금을 해제하지 마십시오. 잠금을 해제하기 전에 동기화 블록이 끝날 때까지 기다리십시오.
- 통지모두():
- 모든 대기 스레드 깨우기
- 사용 모드:생산자-소비자 모드, 모니터 모드
💡 면접 준비 팁
기본 사항을 심화합니다.개념을 아는 것뿐만 아니라 원리와 구현 세부 사항도 이해합니다.
더 많은 연습을 해보세요:특히 멀티스레딩 및 동시성과 관련된 코딩 실습을 통해 지식을 통합합니다.
소스 코드를 읽어보세요:Java 라이브러리 소스 코드(컬렉션, 동시성 등)를 연구하여 이해를 심화합니다.
세부사항에 주의하세요:문자열 비교, 컬렉션 수정 등과 같은 일반적인 함정과 모범 사례를 마스터하세요.
예:인터뷰 중 개념을 설명하고 표현력을 높이기 위해 구체적인 예를 사용하십시오.