[Interview] 면접준비 10일차(스터디)

Kim Hyen Su·2024년 6월 4일

면접질문

목록 보기
12/27
post-thumbnail

면접질문

Java


자바의 장단점에 대해서 설명해주세요

자바의 장점은 다음과 같습니다.

  1. 플랫폼 독립성 : 자바는 Write Once, Runtime Anywhere 원칙을 따르며, 컴파일된 자바 코드는 다양한 운영체제에서 실행 가능합니다.(JVM 덕분)

  2. 객체 지향언어 : 자바는 객체 지향 프로그래밍 패러다임을 지원하여 코드의 재사용성과 유지보수성을 높입니다.

  3. 강력한 표준 라이브러리 : 자바는 방대한 표준 라이브러리를 제공하여 다양한 기능을 쉽게 구현할 수 있습니다.

  4. 높은 안정성 : 자바는 엄격한 메모리 관리, 자동 메모리 할당/해제 등의 기능을 통해 안전성이 높으며, 해당 기능은 GC를 통해서 수행됩니다.

  5. 멀티스레딩 지원 : 자바는 멀티스레딩을 기본적으로 지원하여 병렬 처리가 용이합니다.

  6. 광범위한 커뮤니티 : 자바는 오랜 기간동안 대규모 개발자 커뮤니티를 보유하고 있어 다양한 정보와 지원을 받을 수 있습니다.(Bealdung)

자바의 단점은 다음과 같습니다.

  1. 성능 이슈 : JVM에 의해서 인터프리팅되는 과정이 이뤄지므로, 네이티브 언어에 비해서 성능이 떨어집니다.

  2. 메모리 사용량 증가 : 자바는 객체 지향 특정으로 인해 메모리 사용량이 증가할 수 있습니다.

  • 객체 생성 및 메모리 할당 되며, 이로 인해 메모리 사용량이 증가합니다.
  • 가비지 콜렉션을 통해 자동으로 메모리를 관리하며, 이를 수행하는 작업또한 메모리 할당이 일어나므로 사용량이 증가됩니다.
  • 포인터 대신 참조를 사요하므로, 참조를 저장할 추가 메모리가 필요합니다.
  1. 복잡성 : 자바는 강력한 표준 라이브러리를 통해서 다양한 기능을 제공하지만, 그만큼 learning curve가 높아집니다.

  2. 개발 속도 저하 : 자바의 엄격한 타입 시스템과 컴파일 과정으로 인해서 스크립트 언어에 비해서 속도가 느려질 수 있습니다.

  3. 모바일 환경의 제한적 사용

new String() 과 ""의 차이점에 대해서 설명해주세요

new String()은 새로운 객체를 생성하고, ""는 이미 정의된 문자열 객체를 참조합니다. 따라서, ""가 메모리 효율이 높습니다.

이에 관련한 개념으로 JVM에 String pool이 있습니다.

String Pool 이란, JVM 내 메모리 공간으로 String 문자열을 관리하는 곳입니다. 이는 메모리 공간 내 중복되지 않는 문자열을 저장하고, 해당 문자열에 접근 시 동일한 참조값을 반환하여 메모리 공간을 절약하기 위한 공간입니다. 그리고 이처럼 "" 안에 들어있는 문자열을 보통 "String Literal" 이라고 합니다.또한, 이런 프로세스를 interning 이라고 하며, 이를 String Interning 이라고 합니다.

하지만, String Literal이 많아질수록 메모리에 추가되므로 OutOfMemory 오류가 발생할 수 있습니다. 이로 인해서 Java7 부터 String Pool을 Heap 메모리로 옮겨 GC에 의해서 참조되지 않는 문자열은 지워지도록 해줌으로써 메모리를 관리할 수 있게 되었습니다.

💡 String vs. StringBuffer vs. StringBuilder 차이점

GC가 일어나는 과정에 대해서 설명해주세요

GC 처리는 크게 Minor GC와 Major GC로 구분됩니다.

  1. 어떠한 새로운 객체가 들어오면 Eden Spcace에 할당합니다.

  2. Eden space가 가득차게 되면, minor garbage collection이 수행됩니다.

  3. 참조되는 객체들은 첫 번째 surivor(S0)로 이동되어지고, 비참조 객체는 Eden space가 clear 될 때 반환됩니다. 이 때, 비참조 객체는 삭제되고, 참조 객체는 aged()로 인해 나이가 듦니다.

  4. 그 다음으로 두번째 survivor(S1)로 이동되어지고, 이동 시마다 나이는 들고, 비참조 객체는 삭제됩니다.

  5. 이렇게 나이가 들어가고, 특정 나이 이상부터 old generation으로 복사되어 집니다. 이러한 데이터들이 쌓이게 되면, 결국에는 old generation에도 메모리가 꽉차게 되어 major GC가 발생하게 되는 것입니다. 해당 공간은 GC로 인해 삭제된 다음에 compact까지 수행됩니다.

GC의 여러 알고리즘에 대해 설명해주세요

JVM이 자동으로 메모리를 관리해주는 것은 좋지만, Major GC 수행 시마다 stop the world가 발생되고 이로 인해 애플리케이션이 중지되는 문제가 발생하게 됩니다. 이를 최적화하기 위해 다양한 방식의 GC 알고리즘이 개발되었습니다.

Serial GC

  • 서버의 CPU 코어가 1개일 때 사용하기 위한 단순한 방식의 GC
  • GC를 처리하는 쓰레드가 1개 이므로, 처리 시간이 가장 깁니다.
  • 이는 Minor에서 Mark-Sweep, Major에서 Mark-Sweep-Compaction을 수행합니다.
  • 보통 실무에서 사용하는 경우는 없습니다.

Parallel GC

  • Java 8부터 default로 사용되는 GC입니다.
  • Serial과 기본적인 알고리즘은 같지만, Young 영역에서 Minor GC를 멀티쓰레드 방식으로 수행합니다.
  • 기존의 Serial 방식보다 상대적으로 처리 시간이 빠릅니다.

Parallel Old GC

  • Parallel GC를 개선한 방식으로, Old 영역에서도 멀티 쓰레드로 GC를 수행합니다.
  • 새로운 가비지 컬렉션 방식인 Mark-Summary-Compact 방식을 이용합니다.

CMS GC(Concurrent Mark Sweep)

  • 어플리케이션의 쓰레드와 GC 쓰레드가 동시에 실행되어 stop the world 시간을 최대한 줄이기 위해서 고안된 GC
  • 단, GC 과정이 매우 복잡해지며, 이로 인해 CPU 사용량이 상대적으로 많습니다.
  • 또한, 메모리 파편화 문제가 발생됨으로써 Java 9 버전 시 deprecated, Java 14 버전부터 사용이 중지된 GC입니다.

G1GC(Garbage First)

  • Java 9+ 버전의 default GC로 지정되었으며, Heap 메모리가 너무 작을 경우 미사용이 권장됩니다.(최소 4GB 이상)
  • 기존의 GC 알고리즘에서는 Heap 영역을 물리적으로 고정된 Young/Old 영역으로 나누어 사용하였지만, G1GC는 아예 이러한 개념을 뒤엎는 Region 이라는 개념을 새로 도입하여 사용하였습니다.
  • Heap의 전체 영역을 Region 이라는 영역으로 체스판 같이 분할하여 상황에 따라 Eden, Survivor, Old 영역으로 동적으로 부여해줍니다.
  • 메모리가 많이 차있는 region을 인식하여 많이 차있는 region 부터 GC를 수행합니다.
  • 전체 메모리를 탐색하는 것에서 region별로 나눠 탐색하며 GC가 수행되기 때문에 효율적입니다. 또한, 기존의 GC처럼 Eden, Survivor 영역으로 옮겨가며 GC를 수행했지만, G1GC는 효율적이라고 생각되는 위치를 내부연산하여 재할당(Relocate)시켜줍니다.

Schenandoah GC

  • Java 12부터 release 된 GC입니다.
  • RedHat에서 개발한 GC로, 기존의 CMS GC가 가지고 있던 단편화 문제와, G1GC가 가지고 있는 pause 이슈를 해결한 GC입니다.

ZGC(Z Garbage Collector)

  • Java 15부터 release 된 GC입니다.
  • 대량의 메모리를 low-latency로 잘처리하기 위해 디자인 된 GC입니다.
  • G1GC 처럼 ZGC 만의 영역인 ZPage를 사용하며, Zpage의 경우 2배수로 동적으로 할당됩니다.
  • ZGC의 장점은 힙의 크기가 아무리 증가하더라도, stop the world 시간이 10ms를 초과하지 않는다는 점입니다.

지네릭스에 대해서 설명해주세요

여러 데이터군을 다루는 Collection 클래스에서, 컴파일 시 타입 체크를 위해서 사용됩니다.

이는 객체 타입을 미리 명시하여 번거로운 형변환이 발생하는 것을 줄여줍니다.

지네릭으로 선언한 클래스는 내가 원하는 타입으로 만들어 사용이 가능합니다. 지네릭스의 타입으로는 참조타입만 가능하며, 기본타입은 Wrapper 클래스를 활용해야합니다.

profile
백엔드 서버 엔지니어

0개의 댓글