자바 면접질문 정리

Jifrozen·2023년 2월 12일
1

기초 다지기

목록 보기
29/29
post-custom-banner

Java (완료)

  • JVM의 구조와 Java의 실행방식을 설명해주세요. 자바 가상 머신의 약자를 따서 줄여 부르는 용어로 JVM의 역할은 운영체제의 독립적으로 자바를 실행하는 것입니다. JVM의 구조
    • Class Loader : JVM 내(Runtime Data Area)로 Class 파일을 로드하고 링크

    • Execution Engine : 메모리(Runtime Data Area)에 적재된 클래스들을 기계어로 변경해 실행

    • Garbage Collector : 힙 메모리에서 참조되지 않는 개체들 제거

    • Runtime Data Area : 자바 프로그램을 실행할 때, 데이터를 저장

      Java의 실행방식

    1. 자바로 개발된 프로그램을 실행하면 JVM은 OS로부터 메모리를 할당합니다.
    2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 자바 바이트코드(.class)로 컴파일합니다.
    3. Class Loader를 통해 JVM Runtime Data Area로 로딩합니다.
    4. Runtime Data Area에 로딩 된 .class들은 Execution Engine을 통해 해석합니다.
    5. 해석된 바이트 코드는 Runtime Data Area의 각 영역에 배치되어 수행하며 이 과정에서 Execution Engine에 의해 GC의 작동과 스레드 동기화가 이루어집니다.
    • JVM Runtime data area 구조 +
      JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역입니다. 이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있습니다.
      - Method area - 클래스, 인터페이스, 메서드, 필드 등의 대한 정보를 저장 , JVM 구동 시작 시에 생성이 되며, 종료 시까지 유지되는 공통 영역이다.
      - Heap area - 인스턴스가 생성되는 공간 해당 영역이 가진 데이터는 모든 Java Stack 영역에서 참조되어, Thread 간 공유가 된다. arbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역입니다.
      - Stack area - 메서드 작업에서 필요한 메모리 공간 제공 각 Thread 별로 따로 할당되는 영역입니다. 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장합니다
      - PC Register - Java 에서 Thread 는 각자의 메소드를 실행하게 됩니다. 이때, Thread 별로 동시에 실행하는 환경이 보장되어야 하므로 최근에 실행 중인 JVM 에서는 명령어 주소값을 저장할 공간
      - Native method stack 자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역입니다.
  • GC가 무엇인지, 필요한 이유는 무엇인지, 동작방식에 대해 설명해주세요. GC는 힙 영역에서 사용하지 않는 객체들을 제거하는 작업을 총칭합니다. 이 객체를 제거하는 작업이 필요한 이유는 메모리는 한정적이기 때문에 쓰지 않는 객체들을 삭제하는 과정이 필요하다. 다른 프로그래밍 언어인 C언어 같은경우 메모리 할당과 제거를 수동으로 해줘야하지만, 자바는 자동으로 GC가 처리해준다. GC의 동작방식은 Minor GC, Major GC로 구분할 수 있습니다. Minor GC는 young 영역에서, Major GC는 old 영역에서 일어난다고 정의합니다. Minor GC는 Eden 영역이 가득 참에서 부터 시작됩니다. Eden 영역에서 참조가 남아있는 객체를 mark하고 survivor 영역으로 복사합니다. 그리고 Eden 영역을 비웁니다. Survivor 영역도 가득차면 같은 방식으로 다른 Survivor 영역에 복사하고 비웁니다. 이를 반복하다 보면 계속 해서 살아남는 객체는 old 영역으로 이동하게 됩니다. Major GC는 old 영역에서 일어납니다. 위와 반대로 삭제되어야 하는 객체를 mark합니다. 그리고 지웁(sweep)니다. 메모리는 단편화 된 상태이므로 이를 한 군데에 모아주는 것을 Compaction이라 하며 compact라고 합니다. 그래서 Mark-Sweep-Compact 알고리즘이라고 합니다. GC를 수행할 때는 GC를 수행하는 스레드 이외의 스레드는 모두 정지합니다. 이를 Stop-the-world라고 합니다. 이것이 중요한 이유는 GC 수행시 시스템이 멈추기 때문에 의도치 않은 장애의 원인이 될 수 있습니다. 따라서 이를 위해 힙 영역을 조정하는 것을 GC 튜닝이라고 하고 JVM 메모리는 절대 마음대로 조정해선 안됩니다.
    • gc의 종류 java 8과 java 9 이상이 사용하는 GC는?
      1. Parallel - 멀티스레드로 병렬처리함
      • java 8 default GC
      1. G1 - heap을 일정한 크기의 region으로 나눠서 region단위로 탐색
      • java 9+이 default GC
  • 컬렉션 프레임워크에 대해서 설명해주세요. Java Collection은 널리 알려져 있는 자료구조를 바탕으로 객체, 데이터들을 효율적으로 관리 할 수 있는 자료구조들이 있는 라이브러리를 컬렉션 프레임워크라고 합니다.
  • 제네릭에 대해서 설명해주세요. -+ 제네릭은 다양한 타입의 객체들을 다루는 메서드나 컬렉션 클래스에 컴파일 시의 타입체크를 해주는 기능 입니다. 객체의 타입을 컴파일 시에 체크하기 때문에 객체의 타입 안정성을 높이고 형변환의 번거로움을 줄여줍니다.
  • 애노테이션에 대해서 설명해주세요. 애노테이션은 인터페이스를 기반으로 한 문법으로 주석처럼 코드에 달아 클래스에 특별한 의미를 부여하거나 기능을 주입할 수 있습니다. 뒤에는 x 메타 애너테이션은 애노테이션을 선언할 때 사용하는 애노테이션입니다.
    • @Retention: 애노테이션 유지 범위를 지정합니다. (소스, 클래스, 런타임)
    • @Inherit: 애노테이션을 하위 클래스까지 전달여부를 지정합니다. 이 애노테이션이 있으면 하위 클래스까지 상속이 가능합니다.
    • @Target: 해당 애노테이션을 어디에 사용할 지 결정합니다. (타입, 필드, 메서드, 파라미터, 생성자, 로컬변수, 애노테이션 타입)
  • 오버라이딩과 오버로딩이 무엇이며 어떤 차이가 있을까요?
    • 오버로딩

      • 두 메서드가 같은 이름을 갖고 있으나 인자의 수나 자료형이 다른 경우
    • 오버라이딩
      - 하위 클래스에서 상위 클래스의 메서드와 일치하는 함수를 재정의하는 것

      추가로 @Override를 써야하는 이유는? 이 애노테이션은 컴파일 타임에 오버라이딩에 대한 안정성을 부여해주기 때문에 반드시 써주는 것이 좋습니다.

  • 인터페이스와 추상클래스의 차이점에 대해 설명해주세요. 추상클래스는 객체의 추상적인 상위 개념으로 공통된 개념을 표현할 때 사용합니다. 단일 상속만 가능합니다. 인터페이스는 구현 객체가 같은 동작을 한다는 것을 보장하기 위해 사용합니다. 다중 상속이 가능합니다.
  • 클래스는 무엇이고 객체는 무엇인가요? 클래스는 객체를 만들어 내기 위한 설계도, 틀이고 객체는 클래스에 선언된 모양 그대로 생성된 실체로 메모리에 할당되어 실제로 사용될때는 인스턴스라고도 부릅니다.
  • 정적(static)이란 무엇인가요? static은 클래스 멤버라고 하며, 클래스 로더가 클래스를 로딩해서 메소드 메모리 영역에 적재할 때 클래스별로 관리됩니다. static 키워드를 통해 생성된 정적멤버들은 모든 객체가 공유하며 어디서든지 참조할 수 있는 장점이 있습니다. 그러나, GC의 관리 영역 밖에 존재하기 때문에 프로그램 종료시까지 메모리가 할당된 채로 존재합니다. 너무 남발하게 되면 시스템 성능에 악영향을 줄 수 있습니다.
  • 자바의 원시타입들은 무엇이 있으며 각각 몇 바이트를 차지하나요? boolean(1), char(2), byte(1), short(2), int(4), long(8), float(4), double(8) 사실 JVM에 의존적이기 때문에 정확한 크기라기 보다는 대략적인 크기입니다.
  • 접근 제어자의 종류와 이에 대해 설명해주세요. private, default, protected, public이 있습니다. private은 해당 클래스 내에서만 접근 가능하고, default는 해당 패키지, protected는 상속한 클래스와 해당 패키지, public은 전체 영역에서 접근 가능합니다.
    • 접근 제어자를 사용하는 이유는? 외부에 보여주고 싶은 정보들을 선택적으로 제공하기 위함이고, 캡슐화와 통하는 면이 있습니다.
  • 객체지향프로그래밍이란? 객체 지향 프로그래밍이란 프로그램 구현에 필요한 객체를 파악하고 객체들 간의 상호작용을 통해 프로그램을 만드는 것
    • 객체지향 프로그래밍의 특징은?
      • 캡슐화
        • 정보 은닉 : 필요 없는 정보는 외부에서 접근하지 못하도록 제한
        • 높은 응집도, 낮은 결합도로 유연함과 유지보수성 증가
      • 추상화
        • 사물들의 공통적인 특징을 파악해서 하나의 개념(집합)으로 다루는 것
        • 목적과 관련이 없는 부분을 제거하여 필요한 부분만을 표현하기 위한 개념
      • 상속
        • 기존 상위클래스에 근거하여 새롭게 클래스와 행위를 정의할 수 있게 도와주는 개념
      • 다형성
        • 형태가 같은데 다른 기능을 하는 것을 의미
  • SOLID(객체지향 5대원칙)에 대해서 설명해주세요. SRP(단일책임원칙)은 한 클래스의 하나의 책임만 가져야 합니다. OCP(개방-폐쇄 원칙)은 확장에는 열려 있으나 변경에는 닫혀 있어야 합니다. LSP(리스코프 치환 원칙)은 프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야하는 원칙입니다. ISP(인터페이스 분리 원칙)은 특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫다. DIP(의존관계 역전 원칙)은 의존 관계를 맺을 때 변화하기 쉬운 것 또는 자주 변화하는 것보다는 변화하기 어려운 것, 거의 변화가 없는 것에 의존하라는 것이다. 구체적으론 구현 클래스에 의존하지 말고, 인터페이스에 의존해야 하는 원칙입니다.
  • 동일성(identity)와 동등성(equality)에 대해 설명해주세요. (equals(), ==) 동일성은 객체의 주소를 비교하는 것이고, 동등성은 객체의 같음을 비교하는 것입니다. 기본적으로 자바에서는 Object 클래스에 정의된 equals() 메소드가 동등성 비교를 합니다.
  • 원시타입과 참조타입의 차이에 대해 설명해주세요. 원시타입은 Java에서 단 8개 밖에 존재하지 않는 타입입니다. 나머지는 모두 참조타입이라고 볼 수 있습니다. 원시타입은 항상 값이 존재해야 합니다. 반면, Object 타입은 null 포인터를 가질 수 있습니다.
    • 원시타입을 객체 타입으로 만드는방법은? wrapper class 기본타입을 객체로 만들어줍니다.
  • String, StringBuilder, StringBuffer 각각의 차이에 대해 설명해주세요. String은 불변입니다. 따라서 새로운 값을 할당할 때마다 새로운 클래스에 대한 객체가 생성됩니다. StringBuilder와 StringBuffer는 이런 String의 특징때문에 사용하는 가변타입이라고 볼 수 있습니다. StringBuilder와 StringBuffer는 Thread-safe 여부의 차이가 있습니다. StringBuilder는 Thread-safe하지 않습니다. 따라서 Multi-Thread 환경에서 사용할 때는 StringBuffer를 사용합니다.
  • Checked Exception과 Unchecked Exception에 대해 설명해주세요. 스프링 트랜잭션 추상화에서 rollback 대상은 무엇일까요? Checked Exception는 RuntimeException 상속 X 컴파일 시점 확인하고 반드시 예외 처리를 해줘야합니다. Unchecked Exception RuntimeException 상속 런타임 시점 확인하고 예외처리를 명시적으로 하지 않아도 됩니다. (예외 발생시 롤백 대상임)
  • Java8에서 추가된 기능에 대해서 설명해주세요. Java8에서는
    • optional

    • stream

    • lambda

    • localDateTime

    • default 메서드

      꼬리 질문 java8에서 추가된 기능중 사용 경험 말해보기

      저의 경우는 인터페이스에 default 메서드가 가능한 부분이 가장 좋았습니다. 기존에는 인터페이스를 구현할때 공통적인 메서드를 하나하나 하위객체에 작성을 해줘야해서 중복되는 코드가 있었는데 인터페이스 default 메서드가 생기면서 인터페이스에 공통 로직을 작성하면 되어 편리하였습니다.

  • try-with-resource에 대해서 설명해주세요. try-with-resources는 자바 버전7에 도입된 문법입니다. 자바 7 버전 이전에서 하나 이상의 리소스(java.lang.AutoCloseable을 구현한 객체 혹은 java.io.Closeable를 구현한 객체)를 사용할 경우 개발자가 임의로 finally 문에서 ~~.close()를 사용하여 자원 해제를 시켜줘야 했습니다. 만약 개발자가 사용한 자원을 finally 문에서 해제시켜주지 않고 누락시켰다면 자원이 해제되지 않은 채로 프로그램이 오작동하게 되고, finally 문에서 자원을 해제 시켜주더라도 자원 해제를 위한 중복 코드가 발생하기 때문에 소스 코드의 가독성을 해치는 단점이 있었습니다. 이를 해결하기 위해 try() 안에 사용할 리소스 객체를 명시적으로 선언하여 사용하면, try 블록 안에서 로직이 정상적으로 완료되었는지, 갑작스럽게 완료되었는지 여부와 관계 없이 JVM에서 자동으로 자원을 반납해주는 기능을 하도록 도입하였습니다.
  • 강한 결합과 느슨한 결합이 무엇인지 설명해주세요. 결합도는 의존성의 정도를 나타내며 다른 모듈에 대해 얼마나 많은 정보를 알고 있는지에 대한 척도입니다. 어떤 모듈이 다른 모듈에 너무 자세한 부분(구현 세부사항)까지 알고 있을 경우에 강한 결합도를 가진다고 합니다. 어떤 모듈이 다른 모듈에 대해 필요한 정보(인터페이스로 추상화된 고수준 정책)만 알고 있다면 두 모듈은 낮은 결합도를 가진다고 합니다. 객체지향 관점에서 결합도는 객체 또는 클래스가 협력에 필요한 적절한 수준의 관계만을 유지하고 있는지를 나타냅니다. 이러한 관점에서 강한 결합도는 반드시 지양해야 하며, 개발자는 적절한 결합도를 유지할 수 있도록 고민하고 설계해야 합니다.
  • 직렬화와 역직렬화에 대해서 설명해주세요. 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트 형태로 데이터를 변환하는 기술
    • 직렬화 조건
      • 자바 기본 타입
      • Serializable 인터페이스 상속받은 객체
  • 자바의 동시성 이슈(공유자원 접근)에 대해 설명해주세요.
    • synchronized 키워드는 통해 공유 데이터에 lock을 걸어서 먼저 작업 중이던 스레드가 작업을 완전히 마칠 때까지 다른 쓰레드가 접근해도 공유 데이터가 변경되지 않도록 보호하는 기능을 제공한다.
    • synchornized 키워드는 어떤 것을 위한 wait, notify인지 명시적으로 알기 어렵기 때문에 Lock, Condition을 사용하기도 한다.(내부적으로는 synchornized로 구현되어 있다.)
    • 스레드 로컬을 사용하면 각 스레드만의 고유 공간을 만들어서 사용할 수 있다.
    • java.util.concurrent 패키지에 동기화 컬렉션과 atomic 자료형을 제공한다.(concurrentHashMap, AtomicInteger 등)
  • Mutable 객체와 Immutable 객체의 차이점에 대해 설명해주세요. Mutable 객체는 변경 가능 객체이고, Immutable 객체는 불변 객체라고 흔히들 말합니다. 대표적으로 String이 immutable 객체인데 String의 값을 변경하고자하면 기존 객체는 삭제하고 새로운 객체의 주소값을 할당받게 된다.
  • 자바에서 null을 안전하게 다루는 방법에 대해 설명해주세요. 공개 메서드가 아닌 곳에는 assert를 사용하여 null을 방어할 수 있습니다. 또한 메서드의 인자를 받을 때 Objects.requireNonNull()을 사용하여 방어할 수 있습니다. 그리고 Optional을 사용해 리턴 타입에서 null을 반환하지 않도록 방어할 수 있습니다. 마지막으로 사전 조건과 사후 조건을 명확히 하여 계약에 의한 설계를 실천해야 합니다.
  • 자바 8 vs 자바 11 default GC가 Paralle GC에서 G1GC로 변경 람다에서 로컬 변수 var이 사용 가능 자바 11은 LTS 버전이므로 장기적인 지원이 보장된 버전이다
  • 스레드 생성 방법
post-custom-banner

0개의 댓글