[기술 면접] Java

JVM의 구조와 Java 실행 방식

  • Java Virtual Machine은 Class Loader를 통해 Java 응용 프로그램을 읽고 Java API와 함께 실행합니다.

  • 메모리 관리(가비지 수집)를 수행하는 스택 기반 가상 머신입니다.

JVM 구조

  • 클래스로더
    • 클래스를 JVM에 로드하고 링크를 통해 노출하는 모듈입니다.

  • 엔진
    • 통역사
      • 바이트코드 실행의 역할
    • JIT 컴파일러
      • JIT 컴파일러는 인터프리터 효율성을 높이기 위한 컴파일러로서 인터프리터가 반복 코드를 감지하면 반복 코드를 네이티브 코드로 변환합니다.

      • 그런 다음 인터프리터는 컴파일된 코드를 네이티브 코드로 직접 사용합니다.

    • 가비지 컬렉터
      • 힙에서 사용하지 않는 개체를 제거하는 작업을 수행합니다.

    • 런타임 데이터 영역
      • 프로그램 실행 시 사용되는 다양한 영역
      • PC 등록
        • 스레드가 시작될 때 생성되며 현재 실행 중인 JVM 명령의 주소를 갖습니다.

      • 스택 영역
        • 지역 변수와 매개 변수가 생성되고 실제 객체가 힙에 할당되고 참조만 스택에 저장되는 영역입니다.

      • 메소드 영역
        • 클래스 멤버 변수, 메서드 정보, 타입 정보, 상수 풀, 정적, 최종 등이 생성됩니다.

        • 상수 풀에는 모든 기호 참조가 포함됩니다.

    • JNI(자바 네이티브 인터페이스)
      • Java 애플리케이션에서 C, C++ 또는 어셈블리 언어로 작성된 함수를 사용하는 방법을 제공합니다.

      • Native 키워드로 메서드 호출
      • 대표적인 메소드가 Thread의 currentThread()이다.

    • 네이티브 메서드 라이브러리
      • C, C++로 작성된 라이브러리

자바 실행 방법

  • Java 컴파일러(javac)는 Java 소스 코드(.java)를 읽고 이를 바이트코드(.class)로 변환합니다.

  • 클래스 파일은 클래스 로더를 통해 JVM에 로드됩니다.

  • 로드된 클래스 파일은 실행 엔진에 의해 해석됩니다.

  • 해석된 바이트코드는 런타임 데이터 영역에 배치되고 실제 실행이 수행됩니다.

가비지 컬렉터

  • 힙 영역에서 사용하지 않는 객체 제거
  • 이 언어는 개발자가 메모리를 직접 해제하는 것을 허용하지 않기 때문에 필요합니다.

작동 방식

  • 간단한 직렬 GC 방법으로 설명
  • 고급 GC에는 이 문서에서 다루지 않는 G1 GC 및 ZGC가 포함됩니다.

가비지 컬렉션

  • 마이너 GC와 메이저 GC로 나뉜다.

  • 젊은 영역에서 작은 GC가 발생하고 오래된 영역에서 큰 GC가 발생한다고 정의됩니다.

  • GC가 실행 중이면 GC를 실행 중인 스레드를 제외한 모든 스레드가 중지됩니다.

    이것은 세상을 멈추라고 합니다.

  • **작은 GC** 에덴룸 만실 시 시작
  • 참조가 Eden 영역에 남아 있는 개체를 표시하고 Survivor 영역에 복사합니다.

  • 그리고 에덴 지역 클리어
  • 같은 방법으로 서바이벌 공간도 가득 차면 다른 서바이버 공간으로 복사하여 비웁니다.

  • 재생은 살아남은 개체를 이전 영역으로 이동합니다.

  • **메이저 GC** 이전 섹션에서 발생하며 위와 달리 삭제할 개체를 표시합니다.

  • 그리고 삭제
  • 메모리는 조각난 상태이기 때문에 한 곳에 모으는 것을 압축(compaction)이라고 합니다.

  • 따라서 Mark Sweep Compact 알고리즘이라고도 합니다.

가비지 수집이 중요한 이유

GC를 수행할 때 시스템에서 중지되어 의도하지 않은 오류가 발생할 수 있습니다.

따라서 이를 위해 힙 공간을 조정하는 GC 튜닝이 가능하며 JVM 메모리를 임의로 조정해서는 절대 안 된다.

컬렉션 프레임

  • 데이터 구조를 기반으로 데이터를 효율적으로 관리할 수 있는 라이브러리
  • List와 Set은 Collection 인터페이스를 상속받지만 Map 인터페이스는 구조적 차이로 인해 별도로 정의된다.

일반

  • Java의 유형 안전을 담당합니다.

  • 컴파일 시 타입을 확인하는 기능으로, 컴파일 시 객체의 타입을 확인하기 때문에 객체의 타입 안전성을 높이고 타입 변환에 따른 오버헤드를 줄인다.

메모

  • 클래스에 특별한 의미를 부여하거나 기능을 주입하기 위해 주석과 같이 코드에 추가할 수 있는 인터페이스 기반 구문입니다.

  • 메타 주석
    • @Retention – 주석 보존 범위(소스, 클래스, 런타임)를 지정합니다.

    • @Inherit – 하위 클래스로 전달할지 여부를 지정하고 하위 클래스로 상속
    • @Target – 사용할 위치 지정(유형, 파일링, 메서드, 매개변수, 생성자, 지역 변수, 주석 유형)

오버로드 및 덮어쓰기

초과 적재

  • 즉, 같은 클래스에서 같은 메서드 이름을 구현할 수 있지만 매개변수의 종류와 개수는 다르게 구현할 수 있음**컴파일 타임 다형성** 너무

덮어쓰기

  • 부모 클래스의 메서드가 재정의됨을 의미합니다.

    **런타임 다형성** 너무
  • @Override를 사용하는 이유
    • 컴파일 타임 재정의 보안을 제공하므로 가능할 때마다 사용하십시오.

인터페이스 및 추상 클래스

상호 작용

  • 구현 개체가 동일한 동작을 갖도록 하는 데 사용됩니다.

  • 다중 상속이 가능하며 인터페이스를 구현하는 집합 간에 관계가 없을 수 있습니다.

추상 클래스

  • 객체의 추상적인 상위 개념으로 공통의 개념을 표현할 때 사용한다.

  • 단순 상속만 가능하며 상속 집합 간에는 연결이 있습니다.

클래스 및 객체

수업

  • 객체를 정의하는 프레임워크 또는 청사진

물체

  • 식별 가능한 물체 또는 사물
  • 고유한 식별자, 특징적인 동작 및 변경 가능한 상태를 가지며 인스턴스를 공통적으로 참조합니다.

정적

  • 클래스 멤버라고 하며, 클래스 로더가 클래스를 로드하여 메소드 메모리 영역에 로드하면 클래스에서 관리합니다.

  • static 키워드로 생성된 정적 요소는 PermGen & MetaSpace에 저장되며, 저장된 메모리는 모든 객체가 공유하며 요소는 어디에서나 참조할 수 있습니다.

  • 그러나 GC의 관리 영역 밖에 있으며 프로그램이 종료될 때까지 메모리가 할당된 상태로 유지되므로 Static을 자주 사용하면 시스템 성능에 영향을 미칠 수 있습니다.

액세스 수정자

  • 개인, 기본, 보호, 공개가 있습니다.

  • 이는 외부로 노출될 데이터를 선택적으로 제공하는 역할을 하며, 캡슐화와 소통하는 측면이 있다.

  • private – 클래스 내에서만 접근 가능
  • default – 이 패키지에서만 사용 가능
  • protected – 상속 클래스에서만 액세스 가능
  • public – 전체 영역에 액세스 가능

페스트

  • SRP(단일 책임 원칙)
    • 클래스는 하나의 책임만 가져야 합니다.

  • OCP(개폐 원칙)
    • 확장에는 개방적이어야 하지만 수정에는 폐쇄적이어야 합니다.

      다형성을 사용하세요.
  • LSP(리스코프 대체 원리)
    • 프로그램 정확성을 손상시키지 않고 개체를 하위 유형의 인스턴스로 변환할 수 있어야 한다는 원칙입니다.

      상위 유형을 상속하고 재정의해도 프로그램이 중단되지 않아야 합니다.

  • ISP(인터페이스 분리 원리)
    • 클라이언트는 사용하지 않는 방법에 의존해서는 안 됩니다.

    • 특정 클라이언트에 대한 여러 인터페이스가 하나의 일반 인터페이스보다 낫습니다.

    • 즉, 큰 인터페이스보다 작고 구체적인 인터페이스로 나누는 것이 좋습니다.

  • DIP(종속 역전 원리)
    • 초록은 자신보다 더 구체적인 것에 의존해서는 안 되며 변경될 수 있는 것에 의존해서는 안 됩니다.

    • 즉, 구현 클래스에 특별히 의존하지 말고 인터페이스에 의존해야 합니다.

정체성과 정의

  • 같음과 ==의 차이점
  • equals는 객체의 메모리 주소를 비교합니다.

  • == 개체가 같은지 비교합니다.