1. JVM이 뭔가요?
JVM(Java Virtual Machine)은 Java Runtime Environment(JRE)의 일부로서 Java 바이트코드를 실행하기 위한 런타임 환경을 제공합니다. 하드웨어 및 운영 체제의 독립성을 책임지는 Java 기술의 구성 요소로, Java의 "한 번 작성하면 어디서나 실행"이라는 핵심 기능을 가능하게 합니다. JVM은 다음과 같은 주요 작업을 수행함으로써 작동합니다:
- 코드 로드: 컴파일된 바이트코드를 메모리에 로드
- 코드 검증: 로드된 Java 바이트코드의 정확성을 보장
- 코드 실행: JVM은 기반 하드웨어에 따라 바이트코드를 기계 언어로 해석하여 실행
2. JDK, JRE 및 JVM의 차이점을 설명해 보세요?
- JVM(Java Virtual Machine): 앞서 언급한 바와 같이, Java 프로그램이 실행되는 런타임에 해당
- JRE(Java Runtime Environment): JVM과 Java 프로그램이 실행되는데 필요한 표준 라이브러리 및 리소스를 포함
- JDK(Java Development Kit): Java 애플리케이션을 개발하기 위한 전체 도구 모음입니다. 이는 JRE, 컴파일러, 디버거, 문서화 도구를 포함
3. 자바의 주요 특징은 무엇입니까?
- 객체 지향: Java에서는 모든 것이 객체로, 소프트웨어 개발 및 유지 보수를 단순화
- 플랫폼 독립적: Java 코드는 JVM이 설치된 모든 기계에서 실행할 수 있으며, 별도의 세팅이 필요 없다.
- 강타입: Java는 강타입 언어로, 변수를 사용하기 전에 반드시 정의해야 하며, 이는 보안과 가독성을 향상시켜 줍니다.
- 멀티스레드: Java는 멀티스레드 프로그래밍을 지원하여, CPU 사용률을 최대화하기 위해 프로그램의 두 부분 이상을 동시에 실행 가능
- 가비지 컬렉션: Java는 새 객체를 생성할 때 메모리 할당 및 해제를 관리
4. Java의 "WORA(Write Once, Run Anywhere)"이란?
Java의 WORA는 Java 애플리케이션을 어떤 장치에서든 작성하여 바이트코드(플랫폼 독립적 코드)로 컴파일하고
JVM이 설치된 어떤 장치에서든 실행할 수 있다는 것을 의미하는데 이 기능은 하드웨어와 운영 체제의 세부 사항을 추상화하는 JVM 더덕분에 가능하다
5. 자바에서는 예외를 어떻게 처리합니까?
Java에서는 try, catch, finally, throw 키워드를 사용하여 예외를 처리합니다.
- try: 예외가 발생할 수 있는 코드를 try 블록 안에 래핑해서 에러를 탐지한다
- catch: catch 블록으로 예외 종류별로 핸들링이 가능하다
- finally: try 및 catch 블록 이후에 항상 실행되는 코드를 포함하며 예외와 상관없이 실행됨
- throw: 예외를 수동으로 발생시키는 데 throw 키워드를 사용합니다.
- throws: 메서드가 예외를 발생시킬 수 있다는 것을 메소드 정의 부에 명시해서 예외를 자신이 아닌 호출한 곳에 떠 넘길 수 있다
6. 추상 클래스와 인터페이스의 차이점은 무엇입니까?
- 추상 클래스: 일부 메소드들이 정의 부분만 제공하여 클래스들이 공통의 구조나 메소드를 공유하지만, 구현이 다를 때 사용, 다중 상속을 제공하지 않음
- 인터페이스: 메소드 구현을 제공할 수 없습니다. 구현 클래스가 제공해야 하는 메소드들이 정의 되어있음, 다중 상속을 제공
7. 자바의 싱글톤 패턴의 개념을 설명해 주시겠습니까?
싱글턴 패턴은 클래스의 인스턴스화를 하나의 "단일" 인스턴스로 제한합니다. 시스템 전체에서 정확히 하나의 객체가 필요한 경우 유용합니다. Java에서 싱글턴 패턴은 다음과 같이 구현할 수 있습니다.
- 생성자를 private 생성
- 단일 인스턴스를 private static 변수에 저장
- 필요한 경우 인스턴스를 생성하여 반환하는 public static 메소드를 제공
8. Java Collection의 종류는?
Java 컬렉션 프레임워크는 객체 그룹을 저장하고 조작하기 위한 일련의 인터페이스와 클래스를 제공합니다.
- List: 중복 요소를 포함할 수 있는 순서가 있는 컬렉션입니다. 예: ArrayList, LinkedList.
- Set: 중복 요소를 포함할 수 없는 컬렉션입니다. 예: HashSet
9. 자바에서 멀티스레딩은 어떻게 돌아가나요?
Java의 멀티스레딩은 CPU 시간의 활용도를 극대화하기 위해 여러 스레드를 동시에 실행하는 과정이고.
스레드는 가벼운 서브 프로세스로, 처리의 가장 작은 단위입니다.
멀티스레딩은 프로그램의 두 프로세스 이상을 동시 실행하여 CPU 시간을 보다 효율적으로 활용이 가능하게 해줍니다.
10. Garbage Collection이란 무엇인가요?
Java에서 가비지 컬렉션은 프로그램에 의해 더 이상 사용되지 않는 객체를 JVM이 메모리에서 자동으로 제거하는 과정입으로 실행 중인 프로그램에 충분한 메모리가 확보되도록 도와준다
가비지 컬렉터는 사용되지 않는 객체를 찾아내서 메모리를 확보하기 위해 삭제합니다.
가비지 컬렉터의 정확한 작동 방식은 구현에 따라 다르고 JVM의 다양한 버전에 따라 달라진다.
11. Java에서 reflection은 무엇이고 언제 사용하나요?
Java에서 리플렉션은 컴파일 할 떄 구체적인 클래스를 알지 못해도 런타임에 객체에 접근하여 검사하고 조작할 수 있게 해줍니다, JVM은 클래스 정보를 클래스 로더를 통해 읽어와서 해당 정보를 JVM 메모리에 저장합니다.
이렇게 저장된 클래스에 대한 정보가 마치 거울에 투영된 모습과 닮아있어, relection이라 합니다.
아래와 같이 사용됩니다.
- 클래스, 필드, 메소드 및 생성자 검사하기.
- 동적으로 코드를 생성하는 IDE(통합 개발 환경) 또는 프레임워크 개발.
- 구성 파일에 기반하여 클래스를 인스턴스화하는 컨테이너 및 프레임워크.
12. Java에서 메서드 오버로드 및 메서드 오버라이드를 설명합니다.
- 메소드 오버로딩: 같은 클래스 내에서 이름은 같지만 매개변수(타입, 개수 또는 둘 다 다름)가 다른 두 개 이상의 메소드가 있는 경우를 말하며, 이를 통해 프로그램의 가독성을 높이는 방법
- 메소드 오버라이딩: 자식 클래스에서 이미 부모 클래스에 존재하는 동일한 시그니처(이름과 매개변수)를 가진 메소드를 다시 정의하는 것을 의미, 오버라이딩을 통해 자식 클래스는 부모 클래스에 의해 이미 제공된 메소드의 특정 구현을 제공할 수 있습니다.
13. Java 패키지란 무엇이며 어떻게 사용됩니까?
Java 패키지는 관련 클래스와 인터페이스를 그룹화하는 방법입니다.
- 패키지는 다음과 같은 목적으로 사용 됩니다.
- 명명 충돌 방지.
- 기능, 사용성, 카테고리에 따라 코드 파일을 다른 디렉토리로 조직화.
- 접근 보호 제공.
- 패키지는 import 키워드를 사용하여 다른 클래스와 인터페이스로 가져올 수 있습니다.
14. 멀티스레딩과 동기화를 설명해 주세요
Java에서 동기화는 여러 스레드가 어떤 공유 리소스에 대한 접근을 제어하는 메커니즘이다.
Java는 동기화된 블록과 동기화된 메서드를 제공하여 레이스 컨디션을 처리한다.
동기화는 스레드 안전한 작업을 보장하기 위해 한 시점에 하나의 스레드만 리소스에 접근할 수 있도록 해주기에 필수적입니다.
15. Java에서 volatile 키워드의 역할은?
Java에서 volatile 키워드는 변수의 값이 다른 스레드에 의해 수정될 것임을 나타내기 위해 사용합니다.
변수를 volatile로 선언하면 그 값이 CPU 캐시가 아닌 메인 메모리에서 읽고 쓰임을 보장한다.
보통 멀티스레딩에서 한 스레드에 의한 변경 사항이 다른 스레드에게 보이도록 하기 위해 사용합니다.
16. Java로 Generics의 개념을 설명해 주세요
제네릭스를 사용하면 클래스, 인터페이스, 메서드를 정의할 때 타입(클래스 및 인터페이스)을 매개변수로 사용할 수 있다.
제네릭스의 주요 이점은 컴파일 시간에 오류를 감지할 수 있어 코드를 더 안전하고 명확하게 만들 수 있고.
메소드 인자, 반환 타입 및 또는 필드의 타입 간 종속성을 표현하기 위해 타입(클래스 및 인터페이스) 매개변수를 사용할 수 있다.
17. Java에서 lambda를 설명해 주세요
람다 표현식은 Java 8에서 도입된 기능으로, 메서드를 하나의 식으로 표현 해준다.
익명함수로 말하기도 하며 람다식을 통해 메서드를 변수처럼 사용도 가능하다.
public class LambdaExample {
public static void main(String[] args) {
// 람다식을 사용하기 위한 함수형 인터페이스(Functional Interface) 생성
MyFunctionalInterface myLambda = () -> System.out.println("Hello, Lambda!");
// 람다식 실행
myLambda.myMethod();
}
}
// 함수형 인터페이스 정의
@FunctionalInterface
interface MyFunctionalInterface {
void myMethod();
}
18. Java Stream은 무엇이며 어떻게 사용합니까?
Java 스트림은 순차적 및 병렬 집계 연산을 지원하는 요소의 시퀀스를 나타낸다.
java 8에서 도입된 스트림은 객체 컬렉션을 처리하는 함수형 접근을 지원합니다.
스트림 파이프라인은 소스(컬렉션, 배열, 생성 함수, 또는 I/O 채널일 수 있음)로 시작하여 하나 이상의 중간 연산(스트림을 다른 스트림으로 변환하는 filter, map 등)과 종단 연산(forEach, reduce, collect 등 결과나 부수 효과를 생산하는 연산)으로 구성되는데
쉽게 말해서 데이터를 추상화해서 다양한 방식으로 저장된 데이터를 읽고 쓰기 위한 방법을 제공해준다.
19. Java에서 ==와 .equals()의 차이점은 무엇입니까?
==는 참조 비교 연산자로, 두 참조가 같은 객체를 가리키는지 비교합니다.
.equals()는 Object 클래스의 메소드로, 두 객체 내의 값을 비교합니다.
.equals() 메소드는 비즈니스 로직에 따라 어떤 클래스에서든 오버라이드될 수 있다.
20. Java에서 final 키워드는?
final 키워드는 여러 컨텍스트에서 사용될 수 있다
- Final 변수: 상수입니다. 초기화된 후 그 값은 변경될 수 없다
- Final 메소드: 서브클래스에서 오버라이드될 수 없다
- Final 클래스: 클래스가 서브클래스가 되는 것을 방지한다
- final 사용은 변수의 불변성을 보장하고, 메서드의 일관된 동작을 보장하며, 고정된 클래스 계층을 유지됨
21. 메모리 누출이란 무엇이며 Java는 이를 어떻게 처리합니까?
메모리 누수는 애플리케이션이 더 이상 사용하지 않는 객체가 가비지 컬렉터(GC)에 의해 메모리에서 제거될 수 없는 상태로 남아 있을 때 발생하는데 이는 여전히 참조되고 있기 때문이다.
Java에서는 메모리 관리가 주로 GC에 의해 처리되며,
GC는 더 이상 사용되지 않는 객체를 자동으로 할당 해제된다.
그러나 정적 참조, 리스너, 캐시된 객체를 통해 메모리 누수가 여전히 발생할 수 있으며 개발자는 누수를 피하기 위해 라이프사이클 관리와 참조에 대해 주의해야 한다
22. Java에서 객체 복제를 구현하는 방법은 무엇입니까?
Java에서 객체 복제는 Cloneable 인터페이스와 Object 클래스의 clone() 메소드를 제공해준다.
객체를 복제하기 위해 클래스는 Cloneable 인터페이스를 구현하고
clone() 메서드를 public 접근으로 오버라이드해야 합니다.
clone() 메소드는 객체의 복사본을 반환한다.
public class MyObject implements Cloneable {
// properties
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
23. Java에서 transient 키워드의 목적은 무엇인가요?
Java에서 transient 키워드는 특정 필드가 직렬화되어서는 안되는 값이 있을 때 사용합니다.
예를 들어 비밀번호같이 직렬화 과정에서 빼고 싶은 데이터가 있을 때 사용
객체가 직렬화될 때, transient로 표시된 필드는 객체의 직렬화된 표현에서 제외하며 이는 보안상의 이유나 유지하거나 전송하는 것이 논리적이지 않은 필드를 제외할 때 유용하다.
24. Java 클래스를 불변으로 만들기 위해 어떻게 하나요?
Java 클래스를 불변으로 만들려면 다음 조건을 만족하면 됩니다.
- 클래스를 final로 선언하여 확장할 수 없게 함
- 모든 필드를 private 및 final로 만듦
- "setter" 메소드를 제공하지 않음
- 객체의 모든 속성을 설정하는 생성자를 제공
- 메소드가 오버라이드 될 수 없도록 함
- 클래스가 변경 가능한 객체에 대한 참조를 가지고 있는 경우, 이러한 참조를 수정할 수 없게 함
- 변경 가능한 객체를 수정하는 메소드를 제공하지 않습니다.
- 변경 가능한 객체에 대한 참조를 공유하지 않습니다.
25. String, StringBuilder, StringBuffer의 차이점은?
- String: 불변 문자 시퀀스입니다. 연결 또는 수정 작업은 새로운 String 객체를 생성
- StringBuilder: 단일 스레드 환경에서 사용하기 위한 변경 가능한 문자 시퀀스입니다. 동기화를 보장하지 않기 때문에 더 빠릅니다.
- StringBuffer: 다중 스레드 환경에서 사용하기 위한 변경 가능한 문자 시퀀스입니다. 동기화되어 있으므로 스레드 안전하지만 StringBuilder보다 느림
26. Java 메모리 모델을 설명하세요.
Java 메모리 모델(JMM)은 스레드가 메모리를 통해 어떻게 상호 작용하고 동시 실행에서 어떤 행동이 허용되는지를 명시합니다. Go에서의 Context와 유사합니다.
변수와 스레드의 작업 사이의 관계, 포함하여 읽기 및 쓰기, 다른 스레드에 대한 필드 변경의 가시성, 작업의 순서, 그리고 원자성을 정의하며. JMM은 다중 스레드 환경에서 잘 동기화된 프로그램이 올바르게 실행되도록 보장합니다.
27. Java의 어노테이션은 무엇인가요?
Java의 어노테이션은 프로그램에 대한 데이터를 제공하지만 프로그램 자체의 일부가 아닌 메타데이터의 한 형태입니다.
어노테이션은 컴파일러에 의해 읽히거나 애플리케이션에 의해 런타임에 읽힐 수 있는데
이는 컴파일러에게 정보를 전달하는 역할을 하며, 컴파일 시간 및 배포 시간 처리, 그리고 런타임에도 사용됩니다.
@Override
public String toString() {
return "Example class";
}
28. Java에서 static 키워드의 의미는 무엇인가요?
Java의 static 키워드는 특정 필드, 메소드 또는 블록이 클래스 인스턴스가 아닌 클래스에 속한다는 것을 나타내는 데 사용할 수 있다.
Static 메서드나 필드는 인스턴스 없이 클래스 이름을 통해 직접 접근이 가능합니다.
29. Java 애플리케이션에서 스레드 안전을 보장하기 위해 해야할 것은?
Java 애플리케이션에서 스레드 안전을 보장하기 위해
- 불변 객체를 사용
- 데이터가 단일 스레드에서만 접근되도록 스레드 구속 원칙을 적용
- 동기화된 블록이나 메소드를 사용하여 가변 데이터에 대한 접근을 제어
- ConcurrentHashMap과 같은 Java 컬렉션 프레임워크의 스레드 안전 클래스를 활용
- 스레드 간 변수 변경의 가시성을 보장하기 위해 volatile 키워드를 활용
30. Java의 전통적인 for 루프와 향상된 for 루프의 차이점을 설명하세요.
- 전통적인 for 루프: 초기화, 조건, 업데이트 표현식을 명시적으로 지정함, 배열이나 컬렉션을 반복할 때 더 유연하지만 코드가 김
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
- 향상된 for 루프(또한 "for-each" 루프라고 함): Java 5에서 도입되었으며, 컬렉션이나 배열을 반복할 때 구문을 단순화함, 반복자를 추상화하여 코드를 더 읽기 쉽게 만듦
for (String element : array) {
System.out.println(element);
}
향상된 for 루프는 전통적인 for 루프보다 유연성이 떨어지지만, 간단한 반복에 대해 더 깨끗한 구문을 제공이 가능하다
'Java' 카테고리의 다른 글
[Java] Generic(제네릭)이란? (0) | 2021.06.02 |
---|