- JVM의 구조와 Java의 실행방식 설명
- GC가 무엇인지, 필요한 이유와 동작방식
- 컬렉션 프레임워크
- 제너릭
- 어노테이션
- 오버라이딩과 오버로딩이 무엇이며 차이점
1. JVM의 구조와 Java의 실행방식 설명
Question
JVM이란 무엇이고, 어떤 구조로 되어있나요?
JVM은 Java Virtual Machine으로 Java 프로그램이 실행되는 환경을 제공합니다. JVM은 메서드 영역, 힙 영역, 스택 영역, PC 레지스터, 네이티브 메서드 스택으로 나뉩니다.
Question
Java 프로그램이 어떻게 실행되는지 설명해보세요
Java 코드는 컴파일러에 의해 바이트코드로 변환되며, JVM은 이 바이트 코드를 실행합니다.
Question
JVM이 다른 플랫폼에 독립적인 이유는 무엇인가요?
Java 프로그램이 독립적인 바이트코드인 .class 파일로 컴파일되기 때문입니다. Java 컴파일러가 소스 코드를 컴파일할 때 생성하는 바이트코드는 특정 플랫폼에 종속되지 않고 JVM만 설치되어있으면 동일하게 실행될 수 있습니다.
2. 가비지 컬렉션이 무엇인지, 필요한 이유와 동작방식
메모리 관리 방법 중 하나로, 프로그래머가 동적으로 할당한 메모리 영역 중 더 이상 쓰이지 않는 영역을 자동으로 찾아내어 해제하는 기능
Question
GC의 실행시점은?
일반적으로 JVM이 메모리가 부족하거나 메모리 누수 위험이 감지될 때 실행됩니다.
Question
GC가 어떤 원리에 의해 동작하는지 설명해주세요
GC는 메모리 관리의 자동화를 위해 JVM 내에서 더 이상 참조되지 않거나 접근할 수 없는 객체를 탐지하고 회수하는 역할을 합니다. 기본적인 원리는 Mark and Sweep 알고리즘입니다. Mark 단계에서는 힙 메모리를 스캔하여 아직 참조중인 객체를 마킹하고, Sweep 단계에서 마킹되지 않은 객체는 더 이상 참조되지 않으므로 메모리에서 해제됩니다.
Question
Minor GC와 Major GC의 차이점
Minor GC와 Major GC는 힙 메모리에서 서로 다른 영역을 관리합니다. Minor GC는 Young Generation을 대상으로 수행됩니다. Young Generation에는 새로 생성된 객체들이 할당됩니다. Minor GC는 자주 발생하며, 시간이 짧고 효율적입니다. Major GC는 Old Generation을 대상으로 수행됩니다. Young Generation에서 살아남은 객체가 Old Generation으로 이동하며, Stop-the-World 이벤트를 일으켜 애플리케이션의 모든 스레드를 일시적으로 중단시키기 때문에 성능에 영향을 줄 수 있습니다.
Question
C언어에서의 가비지 컬렉션 처리와 Java에서의 가비지 컬렉션 처리의 차이점
C언어는 free()같은 함수를 사용해 직접 처리해야하지만 Java에서는 JVM이 자동으로 처리합니다.
3. 컬렉션 프레임워크
데이터를 효율적으로 저장하고 관리하기 위한 표준화된 클래스와 인터페이스의 집합

List
- 객체를 일렬로 늘어놓은 구조를 가지고 있으며 객체를 인덱스로 관리하기 때문에 인덱스로 객체를 검색, 삭제 할 수 있음
Set
- List는 중복을 허용하고 인덱스를 통해 객체를 관리하는 반면, Set은 중복을 허용하지 않으며 인덱스를 사용하지 않음 (순서 무관)
Map
- key-value 형태로 객체 저장
- key는 중복 저장될 수 없지만 value는 중복 저장 가능
- 저장 순서를 유지하지 않음
Question
List와 Set의 차이점은 무엇인가요?
List는 중복을 허용하며 순서가 있는 데이터 구조를 제공하고, Set은 중복을 허용하지 않으며 순서가 없습니다.
4. Generic
클래스 내부에서 사용할 데이터 타입을 외부에서 지정하는 기법, 객체별로 다른 타입의 자료가 저장될 수 있도록 함
String[] array = new String[10];
ArrayList<String> list = new ArrayList<>(10);Question
Generic을 사용하는 이유는 무엇인가요?
잘못된 타입이 들어올 수 있는 것을 컴파일 단계에서 방지할 수 있습니다. 클래스 외부에서 타입을 지정해주기 때문에 따로 타입을 체크하고 변환해줄 필요가 없어 관리가 편합니다. 비슷한 기능을 지원하는 경우 코드 재사용성이 높아집니다.
Question
컬렉션 클래스에서 제너릭을 사용하는 이유가 무엇인가요?
타입 안정성을 보장하고, 컬렉션에서 객체를 가져올 때 명시적인 형 변환이 필요하지 않아 코드가 간결하고 오류 발생 가능성을 줄일 수 있습니다. 어떤 타입의 객체가 컬렉션에 저장될지 명시적이므로 코드의 가독성이 높아집니다.
Question
Object를 사용하지 않고 Generic을 사용하는 이유는 무엇인가요?
Object를 사용하는 경우 컬렉션에서 객체를 가져올 때마다 형 변환을 해야하며 런타임 에러를 발생시킬 수 있습니다. 반면 제너릭을 사용하면 컴파일 시점에 타입을 검사하기 때문에 이러한 위험을 줄일 수 있습니다.
5. Annotation
자바 소스코드에 추가하여 사용할 수 있는 일종의 메타 데이터
Question
Annotaion이란 무엇이고, 구체적으로 어떤 것이 있는지 예시를 들어 설명해주세요
Annotation은 자바 코드에서 추가적인 정보를 제공하는 메타데이터입니다. Annotation을 사용함으로써 코드에 대한 데이터를 정의하고 실행 시간에 분석할 수 있습니다. 예를 들어 @Override는 메서드가 상위 클래스의 메서드를 오버라이드한다는 것을 나타내며 @Deprecated는 메서드나 클래스가 더 이상 사용되지 않음을 의미합니다. 스프링에서는 @Autowired를 사용하여 자동으로 의존성을 주입합니다. Annotation은 프로그램에 추가적인 정보를 제공하고, 코드의 가독성과 유지보수성을 향상시키는 역할을 합니다.
Question
Annotation을 사용할 때 컴파일 시간과 실행 시간에 어떤 방식으로 처리되나요?
컴파일 시간에 처리되는 Annotation은 코드 검증, 문서 생성 등의 목적으로 사용됩니다. 예를 들어 @Override는 메서드가 실제로 오버라이드 되었는지 확인하는데 사용됩니다. 이런 처리는 개발 단계에서 코드 오류를 줄여주고 안정성을 높여줍니다. 실행시간에 처리되는 Annotation은 프로그램 실행 중 해당 정보를 읽고 정보에 따라 동작을 변경할 수 있게 합니다. 예를 들어 스프링 프레임워크의 @Autowired는 실행 시간에 의존성 주입을 자동으로 처리합니다. 이런 처리는 개발자가 직접적으로 관리 로직을 작성하지 않아도 되어 코드의 복잡성을 줄일 수 있습니다.
@Controller, @Service, @Repository, @Component 처리 시간은?
애플리케이션 실행 시점인 런타임에 처리됨
애플리케이션이 시작될 때 스프링 컨테이너가 annotation이 붙은 클래스들을 스캔하고 이를 기반으로 bean으로 등록
6. 오버로딩과 오버라이딩
오버로딩
- 같은 이름의 메서드를 다른 매개변수 목록으로 여러번 정의하는 것
- 주로 같은 기능을 수행하지만 매개변수 유형이나 개수에 따라 다른 처리를 하고싶을 때 사용
- 반환 타입만 다르고 매개변수가 동일하다면 오버로딩이 성립되지 않음
- 컴파일 시점에 결정
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
}오버라이딩
- 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것
- 부모클래스에서 정의된 메서드를 자식 클래스에서 재구현하여 다른 동작을 하도록 변경할 수 있음
- 메서드 이름, 매개변수 목록, 반환 타입이 부모 클래스의 메서드와 동일해야 함
- 접근 제어자는 부모 클래스의 메서드보다 좁은 범위로 변경할 수 없음 (public→ private 불가)
- @Override 애너테이션을 붙여 오버라이딩이 제대로 되었는지 확인 가능
- 런타임 시점에 결정
class Parent {
public void showMessage() {
System.out.println("Hello from Parent");
}
}
class Child extends Parent {
@Override
public void showMessage() {
System.out.println("Hello from Child");
}
}Question
오버로딩과 오버라이딩의 정의를 설명해주세요
오버로딩은 같은 이름의 메서드를 매개변수나 타입을 다르게 하여 여러번 정의하는것을 의미합니다. 오버라이딩은 부모 클래스의 메서드를 자식 클래스에서 재정의하는것을 의미하며 메서드의 시그니처가 동일해야 합니다.
Question
오버라이딩시 반드시 지켜야 하는 규칙은 무엇인가요?
메서드 이름, 매개변수 목록, 반환 타입이 동일해야 합니다. 부모 클래스의 메서드보다 좁은 범위의 접근 제어자를 사용할 수 없습니다. 부모 클래스의 메서드가 던질 수 있는 예외보다 넓은 예외를 던질 수 없습니다.
Question
오버로딩이 자바의 다형성에 어떤 역할을 하나요?
오버로딩은 자바의 컴파일타입 다형성을 구현하는 방법 중 하나입니다. 같은 이름의 메서드를 여러 형태로 정의하여 매개변수의 타입이나 개수에 따라 서로 다른 메서드가 호출되도록 합니다. 이를 통해 유연성과 가독성이 향상됩니다.
Question
JIT(Just-In-Time) 컴파일러와 인터프리터의 차이점은 무엇인가요?
컴파일러는 전체 소스 코드를 보고 명령어를 수집하고 재구성하지만, 인터프리터는 소스코드의 각 행을 연속적으로 분석하며 실행합니다. JIT 컴파일러는 반복 실행 속도가 빠르지만 초기속도가 느리고, 인터프리터는 초기 실행은 빠르지만 반복 실행은 느립니다.
Question
JIT가 성능 최적화를 어떻게 돕는지 설명하세요.
핫스팟 최적화 : 자주 실행되는 코드를 네이티브 코드로 변환해 캐싱 인라이닝 : 자주 호출되는 메서드를 코드에 삽입해 호출 오버헤드 제거 루프 최적화 : 반복문을 효율적으로 변환해 성능 향상 런타임 프로파일링 : 실행 피턴을 분석해 필요한 부분만 집중 최적화
JIT는 반복적으로 실행되는 코드의 속도를 높여 런타임에서 최적화된 네이티브 코드를 생성해 성능을 극대화합니다.