Java 언어는 컴파일과 인터프리트 과정을 거치게 되는데, 각 과정을 상세히 설명하라
개발자가 작성한 소스코드를 자바 컴파일러인 Javac를 통해 바이트코드인
.class 또는 .jar(.class의 묶음)로 변환하는 과정이 자바의 컴파일이다.
그리고 이 바이트 코드를 JVM으로 기계어인 Binary Code로 변환하는 과정에서 interpret 과정을 거친다.
각 플랫폼, 실행환경에서 맞는 기계어로 변환한다.
컴파일 에러와 런타임 에러에 대해 상세하게 비교 설명하시오
컴파일 에러란 컴파일 과정 상에서 일어나는 에러이며,
Checked Exception을 처리하지 않을 경우 발생하는 에러이다.
소스코드를 통해 byte code를 생성할 때 인지되는 문법 오류와 같은 예시나
혹은 IOException이나 SQLException을 처리하지 않을 경우 발생하는 것이 컴파일 에러이다.
런타임 에러란 byte code를 JVM을 통해 구동할 때 내부 로직상에서 발생해 나오는 에러이다.
Unchecked Exception을 예상하지 못하고 처리하지 않을 경우 발생하는 에러이다.
NPE를 통해 발생하는 exception등 runtime exception을 처리하지 않아 발생하는 예시가 대표적이다.
JDK 와 JRE 각각은 무엇인지 상세하게 설명하시오
JRE는 JVM과 기타 라이브러리를 합친 자바 런타임 환경을 말한다.
JDK는 자바를 위한 SDK(Software Development Kit)이다.
JRE에 컴파일 환경인 javac를 포함한 개발에 필요한 도구를 추가한 것이 JDK이다.
도커 이미지를 만들때 JDK 와 JRE 는 어떤 상황에서 사용하게 되는가?
도커 이미지를 만들 때, JDK와 JRE는 기본적으로 jvm을 통한 application 실행 환경이 제공된다.
다만 java 소스 코드 빌드와 실행까지 한다면 jdk가 필요하다.
Gradle, Maven, Ant 같은것을 무엇이라 부르며, 왜 필요한가?
java에서 사용하는 빌드 프로세스 도구이자 패키지 매니저이다.
컴파일, 테스트, 패키징 후 JAR or WAR 산출, 배포 및 배포 전 최적화 과정을 도와준다.
Intellij 에서 프로젝트를 위한 JDK 버전과 Gradle 을 위한 JDK 버전, 이렇게 두개로 나눠 존재하는 이유?
개발자들의 프로젝트 실행환경을 위한 Java버전과 패키징 후 빌드를 위한 Java버전이 다르기 때문에 그렇다.
Lombok 은 무엇이며, 어떻게 동작되는것인가?
Lombok은 개발의 편의를 위해 미리 정해둔 메서드나 동작들을 추가해주는 어노테이션이다.
해당 어노테이션을 추가할 경우, 컴파일 과정에서 lexer -> paser 후 생성된 AST에 정해둔 메서드를 추가한 뒤 컴파일 하는 방식으로 진행된다.
Enabled Annotation Processing 옵션은 무엇을 의미하는가?
Lombok은 과거 사용시 컴파일 과정에서 Annotation Processer를 사용해야만
AST에 메서드를 추가해서 사용되게 했으므로 이를 사용하기 위해서는 Enabled Annotation Processing 옵션을 추가해줘야만 사용가능했다.
그렇지만 현재는 IDE에 기본적으로 해당기능이 on으로 설정되어있기에 굳이 해당 옵션이 사용되는지를 확인하지
않아도 사용이 가능하다.
Java 에서는 Exception 처리를 어떻게 하는가
Try -> Throw -> Catch의 방식으로 진행한다.
Exception이 발생하는 부분에서 exception이 throw 될 것이므로
Exception이 나올 부분에서 Try를 하고, 나올 것으로 예상되는 Exception을 Catch한 뒤
해당하는 exception에 대한 예외처리를 하는 직접 처리 방식과
다른 exception으로 throw해서 다른 메서드에서 처리하도록 이관하는 방식이 있다.
Checked Exception 과 Unchecked Exception 차이에 대해 상세 설명하고, 대표적 예외 한개씩 말하라
Checked Exception은 컴파일 과정 상에서 발생할 것으로 예상되는 exception으로
주로 프로그램의 외부에서 발생한다.
대표적인 예로 존재하지 않는 파일을 읽으려고 할 때 사용되는 FileNotFoundException (IOException의 하위 클래스)이 있다.
Unchecked Exception은 런타임 과정 상에서 발생할 것으로 예상되는 exception으로
주로 코드의 내부 로직 상의 오류에서 발생한다.
대표적인 예로 NullPointerException이 있다.
Exception 의 스택트레이스 표기를 위해 e.printStackTrace 대신 무엇을 사용하는게 좋은가?
즉 @Slf4j를 사용해 throwable 객체를 두 번째 파라미터로 넘겨서 사용한다.
SLF4J 는 무엇이며, 왜 사용하는가?
Simple Loggin Facade for Jave로,
여러 Logging Framework에 대한 Facade를 제공한다.
Loggin Framework의 변경이 있더라도 문제없이 로깅을 수행한다.
추가로 Throwable 객체를 두번째 파라미터로 넘기면 stackTrace를 로깅해준다.
Java 에서 Exception 을 다중화하여 다양한 상황들에서 처리하기 위해 어떻게 코딩해야하는가?
Exception이 나올 수 있는 try context에서
예상 가능한 모든 Exception에 대해 catch를 하는게 첫 번째,
RuntimeException에 대해 catch를 해서 처리를 하고
마지막으로 Exception에 대해 catch를 해서 처리하는 방식으로 다중화하여 진행한다.
JVM 구성의 3가지 요소를 간단하게 얘기하시오
Class Loader (로더) : 실행을 위한 Bytecode(.class)를 가져와서 로드
Runtime Data Area (메모리) : 메모리에 얹는다.
Execution Engine (엔진) : 구동(Bytecode를 기계어로 바꾼 후 구동한다)
Class Loader 는 무엇이며, 왜 사용되는가?
Class Loader는 javac를 통해 컴파일된 바이트코드를 Runtime Data Area에 적재하는 역할을 한다.
필요한 바이트 코드만을 runtime data area에 적재하는 동적로딩을 지원한다.
꼬리 질문 : static을 사용해 싱글턴 변수, 메서드를 생성할 때 JVM 상에서 주의해야 할 점은 무엇인가?
static이란 클래스 로더 내에서 단 하나만 존재하는 유일무이한 클래스의 변수, 메서드이고
singleton이란 클래스 로더 내에서 단 하나만 존재하는 유일무이한 객체의 변수이다.
그런데 클래스 로더 자체가 JVM내에 하나만 존재하는 것은 아니다.
그렇기 때문에 다중 스레드 환경에서 싱글턴 인스턴스가 동시에 생성되려 race condition 이 발생한다.
이를 막고 동기화를 하기 위해 blocking을 필요로 하는데, synchronized-volatile 방식 (DCL)
Lazy Holder의 방식, 그리고 Integer를 활용할 경우 atomicInteger를 활용하는 방식이 있다.
Runtime Data Area 메모리 내 Stack, Heap, Method/Class/Static 3가지 영역에 대해 상세 설명하라
개별 스레드마다 형성되는 stack 영역이 있고,
모든 스레드가 공유하는 영역인 Heap영역과 Method(Class or Static)영역이 있다.
꼬리 질문 : 각각의 Stack, Heap, Method(Class or Static)영역은 각각 어떤 목적을 위해 사용되는가?
- Stack 영역 : 메서드가 호출될 때마다 메소드 콜스택이 스택 프레임이라는 스택 메모리에 쌓이고, 메서드 수행이 끝나면 프레임 별로 삭제한다. 지역변수, 파라미터, 리턴 값
- Heap 영역 : 객체를 저장하고 garbage collection의 대상이 된다.
- Method(Class or Static) 영역 : 전역변수, Static 변수, Final Class, Class의 필드와 메서드 정보 등
꼬리 질문 : Garbage Collection 이란 무엇이며, 어느 영역에서 사용되는가?
Java는 OOP이기 때문에, 프로그램이 실행될 때 마다 수많은 객체가 형성된다.
이 생성된 객체를 JVM이 자체 알고리즘을 통해 삭제한다.
생성된 객체를 관리하는 영역은 Heap영역이기 때문에 Heap 영역에서 사용된다.
GC를 효율적으로 동작시키기 위해 Heap영역을 크게 2개(young(new), old(tenured) generation) + @(Permanent generation => 현재 metaspace)로 GC의 단계를 전자는 Minor, 후자는 Major GC를 통해 관리
꼬리 질문 : PC Register 는 무엇이며 어디에 사용되는가?
PC Register는 Runtime Data Area에서 Thread영역에 스레드 생성시 마다 생성되는 영역이다.
다음 프로그램의 실행을 위한 Program Counter를 위해 사용되는 영역이다.
꼬리 질문 : Native Method Stack 란 무엇인가? 어디에 사용되는가?
Runtime Data Area 내의 Thread 영역에 존재한다.
JNI를 통해 호출되는 C/C++ 등의 코드를 수행하기 위한 스택이다.
자바 이외의 언어 수행을 위한 개별 스택이다. 네이티브 메소드의 매개벽수, 지역변수 등을 바이트 코드로 저장한다.
Young Generation 과 Old Generation 의 차이를 설명하라
Young Generation : 모든 객체가 처음에 생성되는 공간이자 Old generation에 비해 상대적으로 작은공간
그만큼 GC에 적은 시간이 걸린다.
Eden, Survivor 0, Survivor 1으로 단계가 나눠지고, 뒤로 갈수록 오랫동안 살아 남은 객체들
Old Generation : 길게 살아남은 객체들이 존재하는 공간, GC에 많은 시간이 걸린다.
Minor GC 와 Major GC 는 어떤 차이가 있는지 상세 설명하라
Minor GC : 사용되지 않은 객체 제거 및 이관을 진행 (짧은 주기, 짧은 시간 진행)
Young generation에서만 일어남.
Young Generation이 eden -> surv 0 -> surv 1일 때 남아있는 것을 이관함.
Major GC : 사용되지 않은 객체를 제거한다. -> (긴 주기, 긴 시간 진행)
Young + Old generation 에서 일어남.
+ GC tuning을 통해서 주기의 조절이 가능하다.
3가지 Java 의 변수(정적 변수, 인스턴스 변수, 지역 변수)별로 JVM 메모리 영역에 어떻게 적재되는가?
JVM의 Runtime Data Area에 각각 다음과 같이 적재된다.
static 변수 : (method/static 영역) 클래스 내 필드/메서드와 정적 필드/메서드
인스턴스 변수 : (Heap 영역) new 키워드로 인스턴스 생성 시 생성자로 적재함.
지역 변수 : (stack 영역) 메서드 호출 시 필요한 파라미터, 내부 변수
JVM 구성 중 Execution Engine 의 역할은 무엇인가?
- Runtime Data Area 에 적재된 것을 실행
- build 된 bytecode(.class파일 등)을 각각의 머신에 맞게 기계어로 변환하여 실행하는 인터프리터의 역할
- JIT 컴파일러 : 실행이 잦은 bytecode를 기계어로 미리 컴파일해놓는 것이다.
- Runtime Data Area에 적재된 것을 정리 : Garbage Collection
'질문과 답변 > Java, Spring' 카테고리의 다른 글
Spring, Spring Boot (4) (1) | 2024.11.06 |
---|---|
Spring, Spring Boot (3) (0) | 2024.11.02 |
Spring, Spring Boot (2) (0) | 2024.10.31 |
Spring, Spring Boot (1) (1) | 2024.10.25 |