ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 기술 면접 - JAVA (기본)
    기술 면접 2021. 4. 22. 02:13

    1. JAVA 언어 특징


    • 운영체제에 독립적
      • JVM에서 동작하기 때문에, 특정 운영체제에 종속되지 않음
      • 하지만 JVM은 운영체제마다 따로 설치해야 한다
    • 객체 지향 언어
      • 캡슐화, 상속, 다형성, 추상화
      • 객체 지향 설계 5원칙(SOLID)
    • 가비지 컬렉터를 통한 자동 메모리 관리
    • 멀티 스레드를 쉽게 구현
    • 동적 로딩을 지원
      • 애플리케이션이 실행될 때 모든 객체가 생성되는 것이 아니고, 각 객체가 필요한 시점에 클래스를 동적 로딩해서 사용

    2. JVM(Java Virtual Machine)


    image

    JVM의 구조 중 메모리 구조는 다음과 같이 구성됩니다.

    • Method Area(메소드 영역): 클래스 변수의 이름, 타입, 접근 제어자 등과 같은 클래스와 관련된 정보를 저장한다. 그 외에도 static 변수, 인터페이스 등이 저장된다.

    • Heap Area(힙 영역): new를 통해 생성된 객체와 배열의 인스턴스를 저장하는 곳이다. 가비지 컬렉터는 힙 영역을 청소하며 메모리를 확보한다.

    • Stack Area(스택 영역): 메소드가 실행되면 스택 영역에 메소드에 대한 영역이 1개 생긴다. 이 영역에 지역변수, 매개변수, 리턴값 등이 저장된다.

    • PC register(PC 레지스터): 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장한다.(CPU의 레지스터와 다르다.)

    • Native Method Stack(네이티브 메소드 스택): 자바 외의 언어(C, C++ 등)로 작성된 코드를 위한 메모리 영역이다. JNI를 통해 사용된다.

    JVM 이해하기 링크

    3. Garbage Collector


    • 더 이상 참조되지 않는 메모리를 청소해주는 JVM의 실행 엔진의 한 요소
    • Heap 영역을 탐색하며 메모리를 정리

    가비지 컬렉션 과정

    가비지 컬렉션(GC)은 메모리를 정리하는 과정. 그렇기 때문에 일반적으로 메모리의 사용을 중단한 채로 진행한다. JVM은 GC를 실행하기 위해 애플리케이션의 실행을 멈추는 stop-the-world를 먼저 실행. stop-the-world를 실행하면 GC를 실행하는 쓰레드를 제외한 모든 쓰레드가 작업을 멈춘다. 그리고 GC가 끝나면 다시 작업을 재개. GC의 작업은 Young 영역에 대한 Minor GC와 Old 영역에 대한 Major GC로 구분.

    • Young 영역: 새롭게 생성한 객체들이 위치한다. 대부분의 객체는 금방 접근 불가능한 상태가 되기 때문에, 많은 객체가 Young 영역에 생성되었다가 사라진다.
    • Old 영역: Young 영역에서 계속 사용되어 살아남은 객체가 복사되는 영역이다. Young 영역보다 크게 할당되며, 더 적은 GC가 발생한다.

    Young 영역은 또 1개의 Eden 영역과 2개의 Survivor 영역으로 구성되는데, Young 영역에 대한 GC는 다음과 같이 작동한다.

    1. 새로운 객체가 Eden 영역에 생성됨
    2. Eden 영역에 GC가 동작하고, 그 중에서 살아남은 객체가 Survivor0으로 이동함
    3. 2번의 동작이 반복되어 Survivor0이 꽉차게 됨
    4. Survivor0 영역에 GC가 동작하고, 살아남은 객체들은 Survivor1으로 이동하고 Survivor0을 비우게 됨
      (2개의 Survivor 영역 중 1개는 반드시 비어있어야 됨)
    5. 위의 동작들이 반복되어 특정 횟수만큼 살아남은 객체는 Old 영역으로 이동함

    img

    그리고 Old 영역이 가득차서 Survivor 영역에서 Old 영역으로 Promotion이 불가능할 때 Old 영역에 대한 GC(Major GC)가 실행

    3. Static vs non-Static


    Static

    • static 멤버는 클래스 당 하나만 생성된다
    • 동일한 클래스의 모든 객체들에 의해 공유된다
    • 객체 내부가 아닌 별도의 공간에 생성( 메소드 영역 )
    • 클래스를 로딩할 때 생성됨 ( 클래스 로더 초기화 )
    • 객체를 만들기 전에도 사용이 가능하고, 객체가 사라져도 사라지지 않음
    • 프로그램이 종료될 때 사라진다

    non-Static

    • 객체마다 별도로 존재한다
    • 객체 내에 각각의 공간을 유지한다
    • 객체와 같이 스택 영역에 생성
    • 객체가 생길 때 같이 생성
    • 객체를 생성해야 사용할 수 있다
    • 객체가 사라질 때 사라진다

    4. 클래스, 객체, 인스턴스


    클래스

    • 객체를 만들어 내기 위한 설계도
    • 객체의 속성과 행위를 정의한 것

    객체

    • 소프트웨어로 구현할 대상
    • 메모리에 할당된 실체화된 인스턴스를 객체라고 부른다

    인스턴스

    • 객체를 소프트웨어로 구현한 것
    • 사실 객체랑 인스턴스의 구분이 좀 모호한 느낌

    5. 변수 타입


    • 기본형과 참조형으로 나뉜다

    Primitive Type(기본형)

    • 실제 값을 저장
    • 8개 타입
    • 논리형
      • boolean
    • 문자형
      • char
    • 정수형
      • byte
      • short
      • int
      • long
    • 실수형
      • float, double

    Reference Type(참조형)

    • 어떤 값이 저장되어 있는 주소를 값으로 갖는다
    • 8개의 기본형 타입을 제외하고 전부 참조형이다

    6. 메모리 상수풀


    힙 영역의 Permanent area(고정 영역)에 생성되어 Java 프로세스의 종료까지 계속 유지되는 메모리 영역이다. 기본적으로 JVM에서 관리하며 프로그래머가 작성한 상수에 대해서 최우선적으로 찾아보고 없으면 상수풀에 추가한 이후 그 주소값을 리턴한다.

    장점 - 메모리 절약 효과

    7. 클래스 멤버 초기화 순서


    일반 멤버 변수

    기본값 초기화 → 명시적 초기화 → 인스턴스 블럭 초기화 → 생성자 초기화

    맨 앞에서 뒤로 수행되기 때문에 앞에서 초기화 된건 덮어씌어진다.

    정적변수 초기화 순서

    기본값 초기화 → 명시적 초기화 → 스태틱 블럭 초기화
    스태틱 초기화 블럭은 클래스가 메모리로 올라갈때(거의 프로그램 시작, 클래스 로딩시) 딱 한번 실행된다.


    8. 예외, 오류

    오류 ( ERROR )

    • 시스템에 비정상적인 상황이 생겼을 때 발생
    • 개발자가 미리 예측할 수 없기 때문에 처리를 신경쓰지 않아도 된다
    • Stack overflow, outofmemoryerror 등등

    예외 ( EXCEPTION )

    • 개발자가 구현한 로직에서 발생
    • 발생할 상황을 미리 예측하여 처리할 수 있음

    Checked Exception

    • 컴파일 단계에서 발생
    • 무조건 예외처리 해야된다
    • 예외 발생 트랜잭션 처리 시 롤백은 하지 않아도 됨

    Unchecked Exception

    • 런타임 단계에서 발생
    • 반드시 예외처리를 해야 되는 것은 아님
    • 예외 발생 트랜잭션 처리 시 롤백을 해야한다

    9. String, StringBuilder, StringBuffer


    String

    • 새로운 값을 할당할 때마다 새롭게 객체가 생성된다
    • 불변객체이기 때문에 값을 바꿀 수 없음
    • String + String을 할 때 각각의 객체들이 계속 생성되기 때문에 가비지컬렉션 되기 전에는 계속 힙에 메모리가 쌓이게 된다

    StringBuilder, StringBuffer

    • 메모리에 추가하는 방식으로, 클래스에 대한 객체를 직접 생성하지 않음
    • 다른 것은 똑같지만 StringBuffer는 thread-safe하다
    • 그렇기 때문에 단일 스레드 환경에서는 StringBuilder를 사용해서 더 빠르게 실행하고, 멀티 스레드에서는 thread-safe한 StringBuffer를 사용하자

    댓글

Designed by Tistory.