FIF's 코딩팩토리

자바 면접 단골 문제 본문

Back-End/Java(자바)

자바 면접 단골 문제

FIF 2023. 5. 22. 09:59
반응형

 

자바 개발자로 면접을 준비하시는 분들이 한번쯤 보시면 도움이 될만한 내용을 준비해봤습니다.

스스로 얼마나 자바/스프링/웹에 관해 알고있는지 확인해보세요!

 

(1) Java Foundation 에 관한 인터뷰

1. JDK와 JRE의 차이점은 무엇입니까?

JDK(Java Development Kit)는 Java 개발을 위해 필요한 도구들의 집합입니다.

컴파일러, 디버거, 개발 도구 등을 포함하고 있습니다.

JRE(Java Runtime Environment)는 Java 애플리케이션을 실행하기 위한 런타임 환경입니다.

JVM(Java Virtual Machine), 클래스 라이브러리, 실행환경 등을 포함하고 있습니다.

JDK는 JRE를 포함하고 있으므로, JDK는 개발자용으로 JRE를 포함한 모든 도구를 제공합니다.

 

2. ==와 equals의 차이점은 무엇입니까?

==는 두 객체의 참조(메모리 주소)를 비교하는 연산자입니다. 

두 객체의 참조가 동일한 경우에만 true를 반환합니다. 

equals() 메서드는 객체들 간의 내용적인 동등성을 비교하는 메서드입니다. 

즉, 두 객체의 값이 동일한 경우에 true를 반환합니다. equals() 메서드는 객체의 클래스에 따라 재정의할 수 있습니다.

 

3. Equals()는 두 개체가 동일한 hashCode()를 가지고 있는 경우 참이어야 합니다. 맞습니까?

아닙니다. 

hashCode()는 객체의 해시 코드를 반환하는 메서드이고, equals()는 객체들 간의 동등성을 비교하는 메서드입니다. 

두 객체의 hashCode() 값이 동일하다고 해서 equals()가 항상 true를 반환하는 것은 아닙니다.

그러나 두 객체가 equals()로 비교했을 때 true를 반환한다면, 두 객체의 hashCode() 값은 같아야 합니다.

equals() 메서드를 재정의할 때 hashCode() 메서드도 함께 재정의해야 일관성을 유지할 수 있습니다.

 

4. Java에서 final의 기능은 무엇입니까?

final 키워드는 다음과 같은 기능을 가지고 있습니다
변수: final 변수는 한 번 할당되면 변경할 수 없는 상수입니다.
메서드: final 메서드는 하위 클래스에서 재정의(오버라이딩)할 수 없습니다.
클래스: final 클래스는 상속될 수 없는 클래스입니다. 즉, 확장될 수 없는 클래스입니다.

 

5.Java에서 Math.round(-1.5)는 무엇을 의미합니까?

Math.round(-1.5)는 주어진 숫자를 반올림한 결과를 반환합니다. 

-1.5는 -1로 반올림되므로, 결과는 -1입니다.

 

6. 문자열은 기본 데이터 유형입니까?

문자열은 기본 데이터 유형(primitive data type)이 아닙니다. 

기본 데이터 유형은 정수, 실수, 문자, 불리언 등과 같은 간단한 데이터를 나타내는 유형입니다. 

문자열은 여러 문자로 구성된 데이터이며, Java에서는 문자열을 다루기 위해 String 클래스를 제공합니다.


7. Java에서 문자열을 조작하기 위한 클래스는 무엇입니까? 그들 사이의 차이점은 무엇입니까?

Java에서 문자열을 조작하기 위해 주로 사용되는 클래스는 String과 StringBuilder/StringBuffer입니다. 

이들 클래스는 문자열을 생성, 조작, 비교하는 데 사용됩니다.
String은 변경 불가능한(immutable) 클래스로, 문자열의 수정이 필요하지 않은 경우에 주로 사용됩니다.

String 객체를 변경하면 새로운 String 객체가 생성됩니다.
StringBuilder와 StringBuffer는 변경 가능한(mutable) 클래스로, 문자열의 동적인 수정이 필요한 경우에 사용됩니다. StringBuilder는 단일 스레드 환경에서 사용되며, StringBuffer는 멀티스레드 환경에서 사용됩니다.

StringBuffer는 동기화를 지원하여 스레드 안전성(thread-safe)을 제공합니다.

 

8.String str="i"는 String str=new String("i")와 동의어입니까?

일반적으로는 동의어입니다.

String str="i"는 문자열 리터럴을 직접 할당하는 방식으로 String 객체를 생성합니다.

String str=new String("i")는 새로운 String 객체를 명시적으로 생성하는 방식입니다.

하지만 Java에서 문자열 리터럴은 내부적으로 String 객체로 관리되므로, 두 문장은 대부분의 경우 동일한 결과를 갖습니다.

하지만 String 객체를 비교할 때는 equals() 메서드를 사용하는 것이 좋습니다.

 

9. 문자열을 반전시키는 가장 좋은 방법은 무엇입니까?

문자열을 반전시키는 가장 간단하고 효율적인 방법은 StringBuilder 또는 StringBuffer 클래스의 reverse() 메서드를 사용하는 것입니다. 

예를 들어, StringBuilder를 사용하여 문자열을 반전시키는 코드는 다음과 같습니다:

String str = "Hello";
StringBuilder reversed = new StringBuilder(str).reverse();
String result = reversed.toString();


이 코드는 "Hello" 문자열을 "olleH"로 반전시킵니다.

 

10. String 클래스의 일반적인 메서드는 무엇입니까?

String 클래스는 다양한 유용한 메서드를 제공합니다. 일부 일반적인 메서드는 다음과 같습니다:

  • length(): 문자열의 길이를 반환합니다.
  • charAt(index): 지정된 인덱스의 문자를 반환합니다.
  • substring(beginIndex, endIndex): 지정된 인덱스 범위에 해당하는 부분 문자열을 반환합니다. beginIndex는 포함되고, endIndex는 포함되지 않습니다.
  • equals(other): 다른 문자열과 현재 문자열을 비교하여 값이 같은지 확인합니다.
  • compareTo(other): 다른 문자열과 현재 문자열을 사전식으로 비교합니다.
  • toUpperCase(): 문자열을 모두 대문자로 변환한 새로운 문자열을 반환합니다.
  • toLowerCase(): 문자열을 모두 소문자로 변환한 새로운 문자열을 반환합니다.
  • contains(str): 지정된 문자열이 현재 문자열에 포함되어 있는지 여부를 확인합니다.
  • replace(oldChar, newChar): 문자열 내의 모든 oldChar를 newChar로 대체한 새로운 문자열을 반환합니다.
  • split(regex): 지정된 정규 표현식을 기준으로 문자열을 분할하여 문자열 배열로 반환합니다.
  • trim(): 문자열의 앞뒤 공백을 제거한 새로운 문자열을 반환합니다.

 

11. 추상 클래스에 추상 메서드가 있어야 합니까?

추상 클래스에는 추상 메서드가 있을 수도 있고 없을 수도 있습니다. 

추상 클래스는 일반 클래스와 달리 인스턴스를 직접 생성할 수 없는 클래스이며, 하나 이상의 추상 메서드를 포함할 수 있습니다. 

추상 메서드는 구현이 없이 선언만 되어 있는 메서드이며, 이를 상속받은 구체적인 하위 클래스에서 반드시 구현해야 합니다. 

추상 클래스는 추상 메서드 외에도 일반적인 메서드, 필드, 생성자 등을 가질 수 있습니다.

 

12. 일반 클래스와 추상 클래스의 차이점은 무엇입니까?

일반 클래스는 인스턴스를 직접 생성하여 사용할 수 있으며, 모든 메서드가 구현되어 있습니다. 

반면에 추상 클래스는 인스턴스를 직접 생성할 수 없으며, 추상 메서드를 포함할 수 있습니다. 

추상 클래스는 하위 클래스에서 추상 메서드를 구현하도록 강제하는 역할을 하며, 일반 클래스는 그런 제약이 없습니다. 

일반 클래스는 필요에 따라 상속되거나 확장될 수 있습니다.

 

13. 추상 클래스를 수정하는 데 final을 사용할 수 있습니까?

추상 클래스를 수정하는 데 final 키워드를 사용할 수 있습니다. 

final 키워드는 클래스, 메서드 또는 변수를 수정할 수 없게 만듭니다. 

추상 클래스를 final로 선언하면 해당 클래스는 더 이상 상속될 수 없게 됩니다. 그러므로 final을 사용하면 추상 클래스를 확장할 수 없습니다.
하지만 추상 클래스의 메서드들은 오버라이딩하여 구현할 수 있습니다. 

따라서 final 키워드는 추상 클래스 내의 메서드에 사용될 수 있지만, 추상 클래스 자체에는 사용될 수 없습니다. 

추상 클래스를 상속받은 하위 클래스에서는 final로 선언된 메서드를 오버라이딩할 수 없습니다.

그러나 추상 클래스를 상속받은 하위 클래스에서는 오버라이딩하지 않은 추상 메서드를 반드시 구현해야 합니다.

 

(2)컨테이너에 관한 인터뷰

1. Java 컨테이너가 정확히 무엇입니까?

Java 컨테이너는 객체들을 저장하고 관리하는 자료 구조입니다. 

컨테이너는 객체들을 효율적으로 저장하고 검색하고 조작하는 기능을 제공합니다.

 

2. 컬렉션과 컬렉션의 차이점은 무엇입니까?

컬렉션은 객체들의 그룹을 저장하기 위한 인터페이스입니다. 컬렉션은 객체들을 추가, 제거, 검색, 순회하는 기능을 제공합니다. 컨테이너는 컬렉션 인터페이스를 구현한 클래스입니다.

 

3. 목록, 집합 및 지도의 차이점은 무엇입니까?

목록(List), 집합(Set), 지도(Map)는 컬렉션 인터페이스의 세 가지 주요 구현 유형입니다.
목록(List)은 순서가 있는 객체들의 모음으로, 중복된 값을 허용합니다.
집합(Set)은 중복된 값을 허용하지 않는 객체들의 모음입니다.
지도(Map)는 키와 값의 쌍으로 이루어진 객체들의 모음입니다. 각 키는 고유해야 하며, 키를 통해 값을 조회하거나 수정할 수 있습니다.

 

4. HashMap과 Hashtable의 차이점은 무엇입니까?

HashMap과 Hashtable은 둘 다 Map 인터페이스를 구현한 클래스입니다. 그러나 두 클래스의 차이점은 다음과 같습니다:
동기화: Hashtable은 스레드에 안전한 동기화된 메서드를 제공하지만, HashMap은 동기화를 지원하지 않습니다.
Null 허용: Hashtable은 키나 값으로 null을 허용하지 않습니다. 하지만 HashMap은 null을 키나 값으로 사용할 수 있습니다.
성능: 일반적으로 HashMap은 Hashtable보다 더 높은 성능을 가지며, 동기화가 필요하지 않은 경우에는 HashMap을 사용하는 것이 권장됩니다.

 

5. HashMap과 TreeMap 중에서 어떻게 선택합니까?

HashMap과 TreeMap 중에서 선택할 때는 다음을 고려할 수 있습니다:
정렬: TreeMap은 키의 정렬을 유지합니다. HashMap은 정렬되지 않은 순서로 요소를 저장합니다.
성능: HashMap은 일반적으로 더 빠른 검색 및 삽입 속도를 제공합니다. TreeMap은 정렬된 키에 대한 작업에서 더 빠른 성능을 보여줍니다.
메모리 사용: TreeMap은 키의 정렬을 위해 추가적인 메모리를 사용합니다. HashMap은 정렬에 필요한 추가 메모리를 사용하지 않습니다.

 

6. HashMap 구현 원칙은 무엇입니까?

 HashMap은 해시 테이블을 기반으로한 자료 구조로, 키-값 쌍을 저장하고 검색하는 데 사용됩니다. 구현 원칙은 다음과 같습니다.
해시 함수를 사용하여 키를 해시 코드로 변환합니다.
해시 충돌이 발생할 경우 충돌을 해결하기 위해 체이닝 기법을 사용합니다.
내부적으로 배열과 버킷으로 구성되며, 배열은 해시 코드를 인덱스로 사용하여 버킷에 접근합니다.
동적 크기 조정 기능을 제공하여 성능과 메모리 사용을 최적화합니다.
키 객체는 hashCode()와 equals() 메서드를 구현해야 합니다.
HashMap은 Collections Framework에 포함되어 있으며, O(1)의 평균 시간 복잡도를 가지는 효율적인 자료 구조입니다. 적절한 사용과 설정이 중요합니다.

 

7. HashSet 구현 원칙은 무엇입니까?

HashSet은 Set 인터페이스를 구현한 클래스로, 중복된 값을 허용하지 않는 집합을 나타냅니다. HashSet은 해시 테이블을 사용하여 요소를 저장하며, 고유한 값만을 저장하고 순서를 보장하지 않습니다.

 

8. ArrayList와 LinkedList의 차이점은 무엇입니까?

ArrayList와 LinkedList는 List 인터페이스를 구현한 클래스입니다. 그들의 차이점은 다음과 같습니다:
내부 구조: ArrayList는 배열을 사용하여 요소를 저장하고 인덱스로 직접 접근할 수 있습니다. LinkedList는 노드의 연결 리스트로 요소를 저장하며, 인덱스 접근은 선형 탐색을 필요로 합니다.
삽입과 삭제: ArrayList는 요소의 삽입과 삭제가 느리지만, 인덱스 기반으로 작업할 때는 빠른 접근 속도를 가집니다. LinkedList는 요소의 삽입과 삭제가 빠르지만, 인덱스 접근이 느립니다.
메모리 사용: ArrayList는 각 요소를 위한 고정된 크기의 배열을 사용하므로 메모리 사용이 상대적으로 작습니다. LinkedList는 각 요소에 대해 추가 메모리를 사용하여 노드를 유지해야 하므로 메모리 사용이 더 큽니다.

 

9. 배열과 목록 간에 어떻게 변환합니까?

배열과 목록 간의 변환은 다음과 같이 할 수 있습니다:
배열을 목록으로 변환하기 위해 Arrays.asList() 메서드를 사용할 수 있습니다.
목록을 배열로 변환하기 위해 List.toArray() 메서드를 사용할 수 있습니다.

 

10. ArrayList와 Vector의 차이점은 무엇입니까?

ArrayList와 Vector는 List 인터페이스를 구현한 클래스입니다. 그들의 차이점은 다음과 같습니다:
동기화: Vector는 스레드에 안전한 동기화된 메서드를 제공하지만, ArrayList는 동기화를 지원하지 않습니다.
성능: 일반적으로 ArrayList는 더 빠른 성능을 제공합니다. Vector는 동기화 관련 오버헤드로 인해 더 느릴 수 있습니다.
크기 조정: ArrayList는 요소가 추가될 때 자동으로 크기를 조정합니다. Vector는 요소가 추가될 때 크기를 조정하기 위해 추가적인 오버헤드가 발생할 수 있습니다.

 

11. 배열과 배열 목록의 차이점은 무엇입니까?

크기의 가변성: 배열은 고정된 크기를 가지며, 생성할 때 크기를 지정하고 그 크기 이상의 요소를 추가할 수 없습니다. 반면에 배열 목록은 크기를 동적으로 조정할 수 있으며, 요소를 추가하거나 제거함에 따라 크기가 자동으로 조절됩니다.

타입의 유연성: 배열은 특정한 데이터 타입만 저장할 수 있습니다. 예를 들어, 정수형 배열은 정수 값만 저장할 수 있습니다. 반면에 배열 목록은 제네릭을 사용하여 다양한 데이터 타입의 요소를 저장할 수 있습니다. 따라서 ArrayList는 객체의 동적인 집합을 저장하는 데 더 적합합니다.

메서드와 기능: 배열은 간단한 인덱스 기반의 접근 방식을 사용하여 요소에 접근하고 수정할 수 있습니다. 배열 목록(ArrayList)은 배열과 비슷한 인덱스 기반 접근 방식을 제공하면서도 추가적인 메서드와 기능을 가지고 있습니다. 예를 들어, ArrayList는 요소를 추가하거나 제거하는 메서드, 검색 및 정렬 기능 등을 제공합니다.

메모리 할당: 배열은 연속된 메모리 블록에 요소를 저장하므로 메모리 할당이 연속적입니다. 반면에 배열 목록(ArrayList)은 내부적으로 동적으로 크기가 조정되는 배열을 사용하여 요소를 저장하므로 메모리 할당이 동적으로 이루어집니다.

성능: 배열은 크기가 고정되어 있고 인덱스 기반의 접근 방식을 사용하기 때문에 요소에 대한 접근 및 수정이 빠릅니다. 반면에 배열 목록(ArrayList)은 크기가 동적으로 조정되므로 배열의 크기를 조정하는 추가 작업이 필요하며, 이로 인해 약간의 성능 오버헤드가 발생할 수 있습니다. 그러나 대부분의 상황에서는 이러한 성능 차이가 미미하며, 유연성과 편의성 측면에서 ArrayList가 더 많은 기능을 제공합니다.


12. 대기열에서 poll()과 remove()의 차이점은 무엇입니까?

대기열에서 poll()과 remove()의 차이점은 다음과 같습니다:
poll(): 대기열에서 가장 앞에 있는 요소를 제거하고 반환합니다. 대기열이 비어있을 경우에는 null을 반환합니다.
remove(): 대기열에서 가장 앞에 있는 요소를 제거하고 반환합니다. 대기열이 비어있을 경우에는 NoSuchElementException 예외가 발생합니다.

 

13. 스레드로부터 안전한 컬렉션 클래스는 무엇입니까?

스레드로부터 안전한 컬렉션 클래스는 멀티스레드 환경에서 동기화를 통해 스레드 안전성을 보장하는 컬렉션 클래스를 말합니다. java.util.concurrent 패키지에서 제공되는 클래스들이 스레드로부터 안전한 컬렉션 클래스입니다. 몇 가지 예시로는 ConcurrentHashMap, ConcurrentLinkedQueue, CopyOnWriteArrayList 등이 있습니다.

 

14. Iterator가 정확히 무엇입니까?

Iterator는 컬렉션의 요소들에 대해 반복하면서 순차적으로 접근하기 위한 인터페이스입니다. 반복자는 컬렉션 내의 요소들을 읽을 수 있으며, 요소를 삭제할 수도 있습니다.

 

15. 반복자의 목적은 무엇입니까? 특징은 무엇입니까?

반복자의 목적은 컬렉션 내의 요소들을 순회하면서 접근하기 위함입니다. 반복자를 사용하면 컬렉션의 내부 구조에 상관없이 요소들을 일관된 방식으로 접근할 수 있습니다. 반복자는 컬렉션에 대한 안전한 순회를 제공하고, 요소를 추가, 수정, 삭제하지 않으면서 요소들에 대한 연속적인 접근을 가능하게 합니다.

 

16. Iterator와 ListIterator의 차이점은 무엇입니까?

Iterator는 컬렉션의 요소들을 단방향으로만 반복할 수 있습니다. ListIterator는 Iterator의 기능을 포함하면서 양방향으로 반복하고, 요소를 수정할 수 있는 기능도 제공합니다.
ListIterator는 List 인터페이스를 구현한 컬렉션 클래스에서만 사용할 수 있습니다. Iterator는 모든 컬렉션 클래스에서 사용할 수 있습니다.

 

(3)멀티스레딩 인터뷰

1. 병렬성(Parallelism)과 동시성(Concurrency)의 차이점은 무엇입니까?

병렬성은 여러 작업을 동시에 실행하여 전체 작업을 가속화하는 것을 의미합니다. 각 작업은 별도의 실행 단위인 스레드 또는 프로세스에 할당됩니다.
동시성은 여러 작업이 동시에 실행되는 것처럼 보이도록 스케줄링되는 것을 의미합니다. 작업은 시분할 방식으로 실행되며, 각 작업은 일부 시간 동안 실행됩니다.

 

2. 스레드와 프로세스의 차이점은 무엇입니까?

스레드는 프로세스 내에서 실행되는 실행 단위입니다. 한 프로세스는 여러 개의 스레드를 가질 수 있으며, 스레드는 공유 자원에 접근할 수 있습니다.
프로세스는 운영 체제에서 실행 중인 프로그램 인스턴스를 나타냅니다. 각 프로세스는 독립된 메모리 공간과 자원을 가지며, 다른 프로세스와는 분리되어 실행됩니다.

 

3. 데몬 스레드가 정확히 무엇입니까?

데몬 스레드는 백그라운드에서 실행되는 스레드로, 다른 모든 일반 스레드가 종료되면 자동으로 종료됩니다. 주로 보조적인 작업을 수행하며, 예를 들어 가비지 컬렉션 등을 처리하는 데 사용됩니다.

 

4. 스레드를 만드는 방법에는 몇 가지가 있습니까?

자바에서 스레드를 생성하는 방법은 두 가지가 있습니다.
Thread 클래스를 상속받아 새로운 클래스를 작성하고, run() 메서드를 오버라이딩하여 스레드의 동작을 정의합니다.
Runnable 인터페이스를 구현하는 클래스를 작성하고, 이를 Thread 클래스의 생성자에 전달하여 스레드를 생성합니다.

 

5. Runnable과 Invocable의 차이점은 무엇입니까?


Runnable은 스레드에서 실행할 수 있는 작업 단위를 나타내는 인터페이스입니다.
Runnable 인터페이스를 구현한 객체는 run() 메서드를 구현해야 합니다.
run() 메서드는 스레드가 수행할 작업을 정의하고, 해당 작업은 별도의 스레드에서 동시에 실행될 수 있습니다.
스레드를 생성하고 Runnable 객체를 전달하여 스레드가 해당 객체의 run() 메서드를 실행하도록 할 수 있습니다.

 

Invocable은 메서드를 실행할 수 있는 개념을 나타냅니다.
호출 가능은 주로 함수형 프로그래밍에서 사용되며, 메서드나 함수를 호출할 수 있는 능력을 가리킵니다.
호출 가능은 메서드 참조(Method Reference)나 람다 표현식(Lambda Expression)을 통해 표현될 수 있습니다.
호출 가능은 실행 가능한 객체와 달리 별도의 스레드에서 실행되는 것이 아니라, 현재 실행 흐름에서 동기적으로 호출되는 것을 의미합니다.
간단히 말해, 실행 가능은 별도의 스레드에서 동시에 실행되는 작업을 나타내는 반면, 호출 가능은 메서드나 함수를 동기적으로 호출하는 데 사용됩니다.

 

6. 스레드의 다른 상태는 무엇입니까?

스레드는 다음과 같은 다양한 상태를 가질 수 있습니다

  • New: 스레드가 생성되었지만 아직 시작되지 않은 상태입니다.
  • Runnable: 스레드가 실행 가능한 상태로, 실행을 위해 대기하고 있습니다.
  • Running: 스레드가 실행 중인 상태입니다.
  • Blocked: 스레드가 블록되어 다른 스레드에 의해 사용 중인 공유 자원을 기다리는 상태입니다.
  • Waiting: 스레드가 다른 스레드에 의해 통지될 때까지 대기하고 있는 상태입니다.
  • Timed Waiting: 스레드가 주어진 시간 동안 대기하고 있는 상태입니다.
  • Terminated: 스레드의 실행이 완료되었거나 종료되었음을 나타내는 상태입니다.

 

7. sleep()과 wait()의 차이점은 무엇입니까?

sleep()은 스레드를 주어진 시간 동안 일시적으로 정지시키는 메서드입니다. 스레드는 해당 시간이 경과하면 다시 실행 가능한 상태가 됩니다.
wait()은 스레드를 일시적으로 대기 상태로 만드는 메서드입니다. 다른 스레드에 의해 통지(notify)되기 전까지 대기하며, 통지가 발생하면 다시 실행 가능한 상태가 됩니다.

 

8. notify()와 notifyAll()의 차이점은 정확히 무엇입니까?

notify()는 wait() 메서드에 의해 대기 중인 스레드 중 하나를 임의로 선택하여 깨우는 역할을 합니다. 

선택된 스레드만이 실행 가능한 상태가 되고, 다른 스레드들은 여전히 대기 상태에 머무릅니다.
notifyAll()은 wait() 메서드에 의해 대기 중인 모든 스레드를 깨웁니다. 

모든 스레드들이 실행 가능한 상태가 되어 경쟁적으로 실행될 수 있습니다.

 

9. 스레드 실행()과 스레드 시작()의 차이점은 무엇입니까?

스레드 시작(Thread.start())은 스레드를 실행시키는 메서드입니다. 

이 메서드를 호출하면 새로운 스레드가 생성되고, 해당 스레드의 run() 메서드가 실행됩니다. 스레드가 병렬로 실행되며 멀티스레딩 환경을 구현할 수 있습니다.

 

10. 스레드 풀을 생성할 수 있는 방법은 몇 가지입니까?

스레드 풀을 생성하는 방법에는 크게 두 가지가 있습니다
ThreadPoolExecutor 클래스를 직접 사용하여 스레드 풀을 생성합니다. 이 클래스는 다양한 구성 옵션을 제공하며, 스레드 풀의 동작을 세밀하게 제어할 수 있습니다.
Java.util.concurrent 패키지에서 제공하는 Executor 프레임워크를 사용하여 스레드 풀을 생성합니다. ExecutorService 인터페이스를 구현하는 클래스인 ThreadPoolExecutor가 내부적으로 사용됩니다.

 

11. 스레드 풀의 다른 상태는 무엇입니까?

스레드 풀은 일반적으로 다음과 같은 상태를 가질 수 있습니다

  • Running: 스레드 풀이 실행 중인 상태입니다. 스레드들이 작업을 처리하고 있는 상태입니다.
  • Shutting Down: 스레드 풀이 종료되기 위해 점진적으로 작업을 중지하고 있는 상태입니다. 현재 실행 중인 작업은 완료되지만, 새로운 작업은 받지 않습니다.
  • Terminated: 스레드 풀이 완전히 종료되었으며, 더 이상 실행되지 않는 상태입니다.

 

12. 스레드 풀에서 submit() 및 execute() 메서드의 차이점은 무엇입니까?

submit() 메서드는 Callable 또는 Runnable 작업을 스레드 풀에 제출합니다. 작업의 결과를 Future 객체로 반환합니다.
execute() 메서드는 Runnable 작업을 스레드 풀에 제출합니다. 작업의 결과를 반환하지 않습니다.


13. Java 프로그램에서 다중 스레드 작업의 안전성을 어떻게 보장할 수 있습니까?

상호 배제(Mutual Exclusion): 공유된 자원에 대한 동시 접근을 제어하기 위해 상호 배제 메커니즘을 사용해야 합니다. 이를 위해 synchronized 키워드나 Lock 객체를 사용하여 임계 영역을 설정하고, 하나의 스레드만이 해당 영역에 접근할 수 있도록 해야 합니다.
스레드 간 통신(Thread Communication): 스레드 간의 데이터 공유 및 동기화를 위해 적절한 통신 메커니즘을 사용해야 합니다. wait(), notify(), notifyAll() 메서드를 활용하여 스레드 간의 상호 작용을 조율할 수 있습니다.
Thread-Safe 클래스 사용: 자바에서는 스레드 안전한(Thread-Safe) 클래스와 메서드를 제공합니다. 이러한 클래스들은 내부적으로 동기화를 처리하여 여러 스레드로부터 안전하게 사용될 수 있도록 합니다. 예를 들어, ConcurrentHashMap, AtomicInteger 등이 있습니다.
데이터 동기화(Synchronized Data Access): 여러 스레드에서 공유되는 데이터에 접근할 때 동기화 메커니즘을 사용하여 데이터 일관성을 유지해야 합니다. 스레드가 공유 데이터를 읽고 쓰는 동안 다른 스레드가 동시에 접근하지 못하도록 보호합니다.
스레드 안전한 컬렉션 사용: 자바에서는 스레드 안전한 컬렉션을 제공하여 동시성 문제를 해결할 수 있도록 합니다. ConcurrentHashMap, CopyOnWriteArrayList 등이 스레드 안전한 컬렉션의 예입니다.


(4) Reflection에 관한 인터뷰

1. Reflection이란 정확히 무엇인가요?

Reflection은 실행 중인 프로그램의 구조를 분석하고 조작하는 데 사용되는 자바의 기능입니다. 
Reflection은 런타임 시에 클래스의 메서드, 필드, 생성자 등의 정보를 가져오고, 이를 통해 객체를 동적으로 생성하거나, 메서드를 호출하거나, 필드에 접근하는 등의 작업을 수행할 수 있습니다. 
Reflection은 클래스 로딩, 인스턴스 생성, 메서드 호출 등의 작업을 컴파일 타임이 아닌 런타임에 처리할 수 있도록 합니다.

 

2. 자바 직렬화(java serialization)란 정확히 무엇인가요? 언제 직렬화가 필요한가요?

자바 직렬화는 객체를 바이트 스트림으로 변환하는 프로세스를 의미합니다. 
이렇게 직렬화된 객체는 파일이나 네트워크를 통해 전송하거나 저장할 수 있습니다. 직렬화를 통해 객체의 상태를 보존하고 복원할 수 있으며, 객체 그래프를 유지하면서 데이터를 전송하거나 저장하는 데 사용됩니다.
직렬화는 주로 분산 시스템, 영속성(객체 저장) 등의 경우에 필요합니다.

 

3. 동적 프록시(dynamic proxies)란 무엇인가요? 가능한 응용 분야는 무엇인가요?

동적 프록시는 런타임에 인터페이스의 구현체를 동적으로 생성하는 기술입니다.
동적 프록시를 사용하면 프록시 객체를 통해 실제 객체에 대한 호출을 중간에 가로채고 처리할 수 있습니다. 
이를 통해 객체에 대한 추가적인 로직을 삽입하거나, 호출 전후에 작업을 수행할 수 있습니다.
동적 프록시는 AOP(Aspect-Oriented Programming), 로깅, 트랜잭션 관리 등 다양한 응용 분야에서 활용될 수 있습니다.

 

4. 동적 프록시를 어떻게 사용하나요?

동적 프록시를 사용하려면 java.lang.reflect 패키지의 Proxy 클래스와 InvocationHandler 인터페이스를 사용해야 합니다. 
먼저, InvocationHandler 인터페이스를 구현한 클래스를 작성하고, invoke() 메서드를 오버라이딩하여 호출 전후에 수행할 로직을 구현합니다. 
그런 다음 Proxy.newProxyInstance() 메서드를 사용하여 동적 프록시 객체를 생성합니다. 
이 메서드에는 ClassLoader, 구현할 인터페이스 목록 및 InvocationHandler 인터페이스를 구현한 객체를 전달해야 합니다. 
이렇게 생성된 동적 프록시 객체는 원하는 인터페이스를 구현하고, 호출되는 메서드에 대해 정의한 로직을 수행할 수 있습니다. 
동적 프록시 객체를 사용하여 원본 객체에 접근하고 메서드 호출을 중간에서 가로채어 원하는 작업을 수행할 수 있습니다.


(5) 객체 복사에 관한 인터뷰

1. 객체 복제(클로닝)는 왜 사용되는가?

객체 복제는 기존 객체의 동일한 복사본을 만드는 과정으로, 원본 객체의 상태를 보존하면서 독립적인 복사본을 생성할 수 있습니다. 주요 사용 사례는 다음과 같습니다:
객체의 안전한 수정 및 변경 가능성을 보장하기 위해 원본 객체를 보호하려는 경우.
객체의 복사본을 다른 스레드에 전달하여 동시성 문제를 방지하려는 경우.
객체의 상태를 기반으로 새로운 객체를 생성하려는 경우.

 

2. 객체 복제는 어떻게 작동하나요?

Java에서 객체 복제는 Cloneable 인터페이스를 구현하고 clone() 메서드를 오버라이딩하여 수행됩니다. 기본적으로 clone() 메서드는 얕은 복사를 수행하며, 복사된 객체의 필드는 원본 객체와 같은 메모리를 참조합니다. 객체의 필드가 기본 데이터 유형이면 값이 복사되고, 참조 유형이면 참조만 복사됩니다. 따라서 원본 객체와 복사본은 같은 객체를 참조할 수 있습니다.

 

3. 깊은 복사와 얕은 복사의 차이점은 무엇인가요?

얕은 복사(Shallow Copy): 얕은 복사는 객체의 필드를 복사할 때, 필드의 참조를 그대로 복사합니다. 따라서 원본 객체와 복사본은 같은 참조를 공유하게 되어, 한 객체의 상태 변경이 다른 객체에 영향을 줄 수 있습니다.
깊은 복사(Deep Copy): 깊은 복사는 객체의 필드를 복사할 때, 필드의 새로운 인스턴스를 생성하여 복사합니다. 따라서 원본 객체와 복사본은 완전히 독립적인 객체가 되어, 한 객체의 상태 변경이 다른 객체에 영향을 주지 않습니다. 
깊은 복사는 객체 그래프를 재귀적으로 탐색하여 모든 필드를 복사하는 것을 의미합니다.


(6) Java 웹에 관한 인터뷰

1. JSP와 서블릿의 차이점은 무엇인가요?

JSP(JavaServer Pages)와 서블릿은 Java 웹 애플리케이션 개발에서 사용되는 기술입니다. 주요 차이점은 다음과 같습니다:
JSP는 HTML 코드에 Java 코드를 삽입하여 동적 웹 페이지를 생성하는 반면, 서블릿은 Java 클래스로 웹 요청을 처리하는 로직을 구현합니다.
JSP는 웹 디자인과 표현에 더 적합하며, 서블릿은 비즈니스 로직 처리에 더 적합합니다.
JSP는 서블릿으로 변환되어 실행되므로, 실제로는 서블릿 기반으로 동작합니다.

 

2. JSP 내장 객체는 어떤 것이 있고, 그들의 책임은 무엇인가요?

JSP에는 여러 내장 객체가 있습니다. 

일반적으로 사용되는 내장 객체는 다음과 같습니다:

  • request: 클라이언트의 요청 정보와 데이터를 저장하고 전달합니다.
  • response: 클라이언트로 응답을 보내는 메서드와 도구를 제공합니다.
  • session: 클라이언트와 서버 간의 세션 정보를 저장하고 유지합니다.
  • application: 웹 애플리케이션 수준의 데이터를 저장하고 전달합니다.
  • out: 출력 스트림을 제공하여 응답을 생성합니다.
  • pageContext: JSP 페이지와 관련된 컨텍스트 정보에 액세스합니다.

 

3. JSP의 네 가지 스코프는 무엇인가요?

JSP에서는 다음 네 가지 스코프를 제공합니다:

  • page: 현재 페이지 내에서만 유효한 스코프입니다.
  • request: 현재 요청 내에서만 유효한 스코프입니다.
  • session: 사용자 세션 내에서 유효한 스코프입니다.
  • application: 웹 애플리케이션 전반에 걸쳐 유효한 스코프입니다.

 

4. 세션과 쿠키의 차이점은 무엇인가요?

세션과 쿠키는 웹 애플리케이션에서 사용되는 상태 관리 기술입니다.
쿠키는 클라이언트 측에 저장되는 작은 데이터 조각이며, 클라이언트의 요청과 응답 헤더에 포함됩니다. 

주로 클라이언트 식별과 상태관리에 사용됩니다. 
쿠키는 클라이언트 측에서 관리되며 만료 날짜 및 시간을 설정할 수 있습니다.
세션은 서버 측에 상태 정보를 저장하는 데 사용되는 객체입니다. 
각 클라이언트에 대해 고유한 세션 ID가 생성되며, 이를 통해 클라이언트와 서버 간의 상태 정보를 유지합니다. 
세션은 일정 시간 동안 유지되며 서버 측에서 관리됩니다.

 


5. 세션 처리 절차는 어떻게 이루어지나요?

세션 처리 절차는 다음과 같습니다.

  • 클라이언트가 서버에 요청을 보냅니다.
  • 서버는 요청에 대해 세션 ID를 생성하고 클라이언트에게 응답으로 세션 ID를 전송합니다.
  • 클라이언트는 세션 ID를 쿠키 또는 URL 매개 변수로 저장합니다.
  • 클라이언트는 이후의 요청에서 세션 ID를 서버에 제공합니다.
  • 서버는 제공된 세션 ID를 기반으로 해당 세션을 식별하고 관련 상태 정보를 유지하거나 업데이트합니다.
  • 세션은 일정 시간 동안 유지되며 클라이언트가 세션을 종료하거나 만료되면 삭제됩니다.

 

6. 클라이언트의 쿠키가 비활성화된 경우 세션을 사용할 수 있나요?

일반적으로 클라이언트가 쿠키를 비활성화하면 세션을 사용할 수 없습니다. 세션 ID는 대부분 쿠키를 통해 클라이언트에게 전송되기 때문입니다. 그러나 세션 ID를 URL 매개 변수로 전달하여 세션을 사용하는 대체 방법을 사용할 수 있습니다. URL 재작성 및 관련 설정을 통해 세션 관리 방법을 변경할 수도 있습니다.

 

7. Spring MVC와 Struts의 차이점은 무엇인가요?

Spring MVC와 Struts는 모두 Java 웹 애플리케이션의 MVC(모델-뷰-컨트롤러) 아키텍처를 구현하는 프레임워크입니다. 주요 차이점은 다음과 같습니다:


Spring MVC는 Spring 프레임워크의 일부로 제공되며, 경량화되고 유연한 구조를 가지고 있습니다. 

 

반면에 Struts는 독립적인 프레임워크로서 더 많은 구성 요소와 기능을 내장하고 있습니다.

 

- Spring MVC는 어노테이션을 통한 구성이 가능하고, DI(Dependency Injection)와 AOP(Aspect-Oriented Programming)를 지원합니다. Struts는 XML 기반의 설정을 사용하며, DI와 AOP를 제공하지 않습니다.

 

- Spring MVC는 유연하고 확장성이 뛰어나며, 다양한 View Resolver를 지원합니다. Struts는 기본적으로 JSP를 사용하며, 타일즈(Tiles)와 같은 기능을 통해 레이아웃 관리를 제공합니다.

 

- Spring MVC는 테스트하기 쉽고 통합이 용이하며, 다양한 기술과의 연동이 간편합니다. Struts는 구성이 복잡하고 테스트하기 어렵습니다.

 

8. SQL 인젝션을 피하는 방법은 무엇인가요?SQL 인젝션은 악의적인 사용자가 입력 데이터를 조작하여 데이터베이스에 악의적인 쿼리를 주입하는 공격입니다. 

이를 피하기 위해 다음과 같은 조치를 취할 수 있습니다

  • Prepared Statement 또는 Parameterized Query를 사용하여 동적 쿼리 생성을 피합니다.
  • 입력 데이터의 유효성을 검증하고, 필요한 경우 데이터 필터링과 이스케이프 처리를 수행합니다.
  • 데이터베이스 계정에는 최소한의 권한만 부여하여 보안을 강화합니다.
  • ORM(Object-Relational Mapping) 프레임워크를 사용하여 SQL 쿼리 생성과 관리를 자동화합니다.

 

9. XSS 공격은 무엇이며, 어떻게 방지할 수 있나요?

XSS(Cross-Site Scripting) 공격은 악의적인 사용자가 웹 페이지에 스크립트 코드를 삽입하여, 이를 통해 다른 사용자의 정보를 탈취하거나 악의적인 동작을 수행하는 공격입니다. 이를 방지하기 위해 다음과 같은 접근 방법을 사용할 수 있습니다:
사용자 입력 데이터의 필터링과 이스케이프 처리를 수행하여 스크립트 실행을 방지합니다.
적절한 HTTP 헤더를 설정하여 브라우저가 스크립트 실행을 차단하도록 합니다.
보안 관련 업데이트가 적용된 웹 애플리케이션 프레임워크를 사용하고, 취약점을 주기적으로 검토하고 수정합니다.

 

10. CSRF 공격은 무엇이며, 어떻게 방지할 수 있나요?

CSRF(Cross-Site Request Forgery) 공격은 인증된 사용자의 웹 브라우저를 통해 악의적인 요청이 서버에 전송되는 공격입니다. 공격자는 희생자의 세션 정보를 이용하여 특정 동작을 실행시키거나 데이터를 조작할 수 있습니다. 이를 방지하기 위해 다음과 같은 접근 방법을 사용할 수 있습니다:
CSRF 토큰을 사용하여 각 요청마다 토큰을 생성하고 검증합니다. 이를 통해 요청의 유효성을 확인하고 인증된 사용자만 허용합니다.
중요한 동작(예: 로그아웃, 비밀번호 변경)에는 추가적인 확인 단계를 도입하여 사용자의 의도를 확인합니다.
SameSite 쿠키 속성을 설정하여 외부 도메인에서의 쿠키 사용을 제한합니다.
HTTP Referer 검증을 수행하여 요청의 출처를 확인합니다.
웹 애플리케이션 방화벽(WAF) 등의 보안 도구를 사용하여 CSRF 공격을 탐지하고 차단합니다.

 

(7) 예외 처리에 관한 인터뷰 

1. throw와 throws의 차이점은 무엇인가요?

throw는 메서드나 코드 블록 내에서 명시적으로 예외를 발생시킬 때 사용됩니다. 

이는 예외적인 상황이 발생했음을 나타내며, Throwable 클래스의 인스턴스나 해당 클래스의 하위 클래스와 함께 사용됩니다.
throws는 메서드 선언부에서 사용되며, 해당 메서드가 하나 이상의 예외를 발생시킬 수 있다는 것을 나타냅니다. 메서드에서 발생할 수 있는 예외의 종류를 지정하여, 호출하는 쪽에서 해당 예외를 처리하거나 전파할 수 있도록 합니다.

 

2. final, finally, finalize 각각의 의미와 차이점은 무엇인가요?

final은 자바에서 변수, 메서드, 클래스에 적용될 수 있는 키워드입니다. 

변수에 적용되면 변수를 재할당할 수 없음을 나타냅니다. 메서드에 적용되면 메서드를 오버라이딩할 수 없음을 나타냅니다. 클래스에 적용되면 클래스를 서브클래스화할 수 없음을 나타냅니다.
finally는 예외 처리에서 사용되는 코드 블록입니다. 선택적으로 try-catch 블록 다음에 위치하며, 예외가 발생하든 발생하지 않든 항상 실행됩니다. finally 블록 내의 코드는 예외가 발생하든 안 하든 항상 실행됩니다.
finalize는 Object 클래스에 정의된 메서드로, 가비지 컬렉터에 의해 객체가 소멸되기 전에 호출됩니다. 해당 클래스에서 재정의하여 객체가 가비지 컬렉션되기 전에 특정 정리 작업이나 리소스 해제 작업을 수행할 수 있습니다.

 

3. try-catch-finally 구문에서 어느 부분이 생략될 수 있나요?

catch 블록과 finally 블록은 개별적으로 생략될 수 있지만, 둘 중 적어도 하나는 반드시 존재해야 합니다. 
catch 블록은 예외를 처리하거나 처리하는 코드를 작성하는 데 사용되며, finally 블록은 예외가 발생하든 발생하지 않든 항상 실행되어야 하는 정리 코드를 지정하는 데 사용됩니다.

 

4. catch 블록이 생략된 경우 finally 블록은 실행됩니까?

catch 블록이 생략된 경우 finally 블록은 여전히 실행됩니다. 
catch 블록이 생략되더라도, 예외 발생 여부와 상관없이 finally 블록은 항상 실행됩니다. 
finally 블록은 예외 처리의 마지막 단계로서, 예외 발생 여부와 상관없이 반드시 실행되어야 하는 코드를 포함할 수 있습니다.

 

5. 몇 가지 일반적인 예외 클래스의 예는 무엇인가요?

Java에서는 다양한 예외 클래스가 제공됩니다.  몇 가지 일반적인 예외 클래스에는 다음과 같은 것들이 있습니다.

  • NullPointerException: 객체 참조가 null인 상태에서 메서드 또는 필드에 접근하려고 할 때 발생합니다.
  • ArrayIndexOutOfBoundsException: 배열의 인덱스 범위를 초과하여 접근하려고 할 때 발생합니다.
  • FileNotFoundException: 파일을 찾을 수 없거나 접근할 수 없을 때 발생합니다.
  • IOException: 입출력 작업 중에 예외 상황이 발생할 때 발생합니다.
  • ClassNotFoundException: 클래스를 찾을 수 없을 때 발생합니다.
  • ArithmeticException: 수치 연산에서 예외적인 상황이 발생할 때 발생합니다.

 

(8) 인터넷에 관한 인터뷰

1. HTTP 응답 코드 301과 302의 의미는 무엇이며, 그 차이는 무엇인가요?

HTTP 301은 "영구적인 이동"을 나타내며, 리소스의 URL이 영구적으로 변경되었음을 의미합니다. 클라이언트는 새로운 URL로 리소스에 접근해야 합니다.
HTTP 302는 "임시적인 이동"을 나타내며, 리소스의 URL이 일시적으로 변경되었음을 의미합니다. 클라이언트는 임시적인 URL로 리소스에 접근하고, 원래 URL을 계속 사용해야 합니다.

 

2. 포워드와 리다이렉트의 차이점은 무엇인가요?

포워드(Forward)는 서버 내에서의 요청 전달을 의미합니다. 클라이언트는 이를 인지하지 못하고, 서버에서 새로운 페이지를 반환합니다. 클라이언트는 실제로는 새로운 페이지로 이동한 것을 알지 못합니다.
리다이렉트(Redirect)는 클라이언트에게 새로운 URL로 이동하도록 알려줍니다. 클라이언트는 새로운 URL로 요청을 보내고, 서버는 해당 페이지를 반환합니다.

 

3. TCP와 UDP의 차이점은 무엇인가요?

TCP(Transmission Control Protocol)는 연결 지향적이고 신뢰성이 있는 프로토콜입니다. 데이터 전송 시 연결을 설정하고, 오류 검출과 재전송을 통해 신뢰성을 보장합니다.
UDP(User Datagram Protocol)는 비연결성이며 신뢰성이 낮은 프로토콜입니다. 데이터를 보낼 때 연결을 설정하지 않고, 오류 검출만 수행합니다.

 

4. TCP는 왜 3-way 핸드셰이크가 필요한가요?

TCP의 3-way 핸드셰이크는 연결 설정을 위해 필요합니다. 클라이언트가 서버에 연결 요청을 보내고, 서버는 요청을 수락하고 클라이언트에게 응답합니다. 
이러한 상호작용을 통해 양측이 서로를 인식하고, 신뢰성 있는 연결을 설정할 수 있습니다.

 

5. OSI 모델의 일곱 개의 계층은 무엇인가요?

  • 물리(PHY) 계층: 비트 스트림을 전송하는 역할
  • 데이터 링크(Datalink) 계층: 네트워크 장치 간의 신뢰성 있는 데이터 전송을 담당
  • 네트워크(Network) 계층: 패킷을 목적지까지 전달하는 경로 선택과 라우팅을 처리
  • 전송(Transport) 계층: 송신자와 수신자 간의 신뢰성 있는 데이터 전송을 보장
  • 세션(Session) 계층: 세션 관리 및 동기화를 담당
  • 표현(Presentation) 계층: 데이터 표현과 암호화, 압축 등의 변환을 처리
  • 응용(Application) 계층: 사용자와 응용 프로그램 간의 통신을 담당

 

6. GET과 POST 요청의 차이점은 무엇인가요?

GET 요청은 데이터를 URL의 쿼리 문자열에 첨부하여 전송합니다. 주로 데이터를 요청하는 용도로 사용되며, 보안에 취약할 수 있습니다. 데이터 길이에 제한이 있습니다.
POST 요청은 데이터를 요청의 본문에 담아서 전송합니다. 주로 데이터를 서버로 제출하는 용도로 사용되며, GET보다 보안성이 높습니다. 데이터 길이에 제한이 없습니다.

 

7. 도메인 간 구현(Cross-domain implementation)은 어떻게 동작하나요?

도메인 간 구현은 웹 애플리케이션에서 다른 도메인으로 리소스 요청을 보낼 때 발생하는 보안 상의 제한을 우회하기 위한 메커니즘입니다.
주로 AJAX 호출에서 발생하며, Cross-Origin Resource Sharing(CORS) 정책을 사용하여 서버에서 클라이언트에게 허용된 도메인과 요청을 처리하는 방식을 명시합니다.

 

(8) 스프링에 관한 MVC 인터뷰

1. 스프링(Spring)을 사용하는 이점은 무엇인가요?

스프링은 경량화되고 모듈화된 구조를 제공하여 개발과 테스트를 용이하게 합니다.
제어의 역전(IoC)과 의존성 주입(DI)을 통해 코드의 유연성과 재사용성을 높일 수 있습니다.
스프링은 AOP(Aspect-Oriented Programming)과 트랜잭션 관리 등의 공통된 작업을 지원하여 개발 생산성을 향상시킵니다.
스프링은 다양한 서비스 모듈을 제공하여 데이터 액세스, 웹 개발, 보안 등 다양한 영역에서 개발을 지원합니다.

 

2. AOP(Aspect-Oriented Programming)란 무엇인가요?

AOP는 애플리케이션에서 공통적으로 발생하는 부가적인 기능들을 모듈화하여 관리하는 프로그래밍 패러다임입니다.
AOP는 핵심 로직과 부가적인 기능을 분리하여 코드 중복을 줄이고, 관점에 따라 모듈을 재사용할 수 있습니다.
스프링은 AOP를 지원하여 로깅, 트랜잭션 관리, 보안 등과 같은 부가 기능을 애플리케이션에 적용할 수 있습니다.

 

3. IoC(Inversion of Control)란 무엇인가요?

IoC는 객체의 생성과 의존성 관리를 프레임워크에 맡기는 개발 방법입니다.
기존에는 개발자가 직접 객체를 생성하고 의존성을 설정해야 했지만, IoC 컨테이너를 통해 객체의 생명주기와 의존성 주입을 자동으로 관리할 수 있습니다.
스프링은 IoC 컨테이너를 제공하여 객체의 생성과 의존성 주입을 관리합니다.

 

4. 스프링에서 가장 일반적으로 사용되는 주입 방법은 무엇인가요?

스프링에서 가장 일반적으로 사용되는 주입 방법은 Setter 주입과 생성자 주입입니다.
Setter 주입은 의존성을 설정하는 Setter 메서드를 통해 의존 객체를 주입하는 방식입니다.
생성자 주입은 생성자를 통해 의존성을 주입하는 방식으로, 객체를 생성할 때 필요한 의존성을 외부에서 전달받습니다.
둘 모두 XML 또는 Java Config를 사용하여 스프링 빈 설정에서 주입할 의존 객체를 지정할 수 있습니다.

 

5. 스프링의 주요 모듈은 무엇인가요?

스프링 프레임워크는 다양한 모듈로 구성되어 있습니다. 

주요한 모듈로는 다음과 같은 것들이 있습니다:

  • 스프링 코어(Spring Core): IoC 컨테이너와 의존성 주입(DI)을 위한 기본 기능을 제공합니다.
  • 스프링 MVC(Spring MVC): 웹 애플리케이션 개발을 위한 모델-뷰-컨트롤러(MVC) 아키텍처를 지원합니다.
  • 스프링 데이터(Spring Data): 데이터 액세스를 간소화하기 위한 기능을 제공하며, 다양한 데이터베이스와의 통합을 지원합니다.
  • 스프링 시큐리티(Spring Security): 인증과 권한 부여를 담당하여 웹 애플리케이션의 보안을 강화합니다.
  • 스프링 부트(Spring Boot): 스프링 애플리케이션을 빠르고 간편하게 구성하고 실행하기 위한 도구입니다.
  • 스프링 클라우드(Spring Cloud): 분산 시스템과 클라우드 환경을 위한 기능과 패턴을 제공합니다.
  • 스프링 배치(Spring Batch): 대용량 작업을 처리하기 위한 배치 프로세싱 프레임워크입니다.
  • 스프링 통합(Spring Integration): 다양한 시스템과의 통합을 위한 기능을 제공합니다.
  • 스프링 웹 플럭스(Spring WebFlux): 비동기 및 반응형 웹 애플리케이션 개발을 위한 기능을 제공합니다.

 

6. 스프링 빈은 스레드 안전한가요?

스프링 빈은 기본적으로 싱글톤(Singleton) 스코프로 생성되며, 스레드 안전하지 않을 수 있습니다.
싱글톤 스코프는 여러 스레드에서 동시에 해당 빈을 사용할 때 동기화 문제가 발생할 수 있습니다.
스레드 안전한 빈을 사용하려면 프로토타입(Prototype) 스코프를 설정하거나 동기화를 적절히 처리해야 합니다.

 

7. 스프링은 어떤 빈 스코프를 지원하나요?

스프링은 다음과 같은 다양한 빈 스코프를 지원합니다:
Singleton: 기본 스코프로, 애플리케이션 전체에서 단일 인스턴스를 공유합니다.
Prototype: 요청할 때마다 새로운 인스턴스를 생성합니다.
Request: 각 HTTP 요청마다 인스턴스를 생성하고, 요청 처리가 완료되면 인스턴스를 폐기합니다.
Session: 각 사용자 세션마다 인스턴스를 생성하고, 세션이 종료되면 인스턴스를 폐기합니다.
Global Session: 포털 애플리케이션에서 사용되는 스코프로, 전역 세션마다 인스턴스를 생성하고, 세션이 종료되면 인스턴스를 폐기합니다.

 

8. Spring이 빈을 자동으로 조립하는 다양한 방법은 무엇인가요?

XML 기반 구성: 빈은 XML 구성 파일을 사용하여 정의하고 연결할 수 있습니다.
어노테이션 기반 구성: 빈은 @Component, @Service 등의 어노테이션으로 표시하고 연결할 수 있습니다.

 

9. Spring 트랜잭션을 구현하는 다양한 방법은 무엇인가요?

XML 구성: XML 파일에서 <tx:advice>와 <tx:attributes>를 사용하여 트랜잭션을 구성합니다.
어노테이션 기반: @Transactional 어노테이션을 사용하여 메서드에 트랜잭션을 적용합니다.
프로그래밍 방식: PlatformTransactionManager 인터페이스를 사용하여 트랜잭션을 명시적으로 관리합니다.

 

10. Spring 트랜잭션 격리(Isolation)이란 정확히 무엇인가요?

트랜잭션 격리는 동시에 실행되는 여러 트랜잭션 간의 상호작용을 제어하는 기능입니다.
Spring은 트랜잭션 격리 수준을 제공하여 데이터의 일관성과 동시성을 조절합니다.
예를 들어, 격리 수준에는 READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE 등이 있습니다.

 

11. Spring MVC의 실행 흐름은 어떻게 되나요?

  • 클라이언트로부터 HTTP 요청이 들어오면 DispatcherServlet이 요청을 받습니다.
  • DispatcherServlet은 HandlerMapping을 통해 요청을 처리할 Controller를 찾습니다.
  • Controller는 비즈니스 로직을 실행하고 데이터를 처리한 후, ModelAndView 객체를 반환합니다.
  • DispatcherServlet은 ViewResolver를 통해 해당하는 View를 찾고, ModelAndView를 이용하여 응답을 생성합니다.

 

12. Spring MVC의 구성 요소는 무엇인가요?

  • Controller: 클라이언트 요청을 처리하고 비즈니스 로직을 수행합니다.
  • Model: 비즈니스 데이터를 저장하고 전달합니다.
  • View: 사용자에게 결과를 표시하는 역할을 합니다.
  • DispatcherServlet: 클라이언트 요청을 처리하는 중앙 컨트롤러입니다.

 

13. @RequestMapping은 무엇을 하는 기능인가요?

@RequestMapping은 Spring MVC에서 요청과 매핑되는 핸들러 메서드를 지정하는 데 사용됩니다.
이 어노테이션은 특정 URL패턴 또는 HTTP 메서드와 매핑하여 해당 요청을 처리할 메서드를 지정할 수 있습니다.
예를 들어, @RequestMapping(value = "/users", method = RequestMethod.GET)은 "/users" 경로로의 GET 요청을 처리하는 메서드를 지정합니다.

 

14. @Autowired의 역할은 무엇인가요?

@Autowired는 Spring에서 의존성 주입(Dependency Injection)을 수행하기 위해 사용됩니다.
이 어노테이션을 필드, 생성자, 메서드에 적용하여 해당 구성 요소가 필요로 하는 다른 빈을 자동으로 주입할 수 있습니다.
Spring은 @Autowired 어노테이션이 붙은 필드나 메서드 매개변수의 타입에 해당하는 빈을 찾아 자동으로 주입합니다.
이를 통해 객체 간의 의존성을 느슨하게 결합하고 코드의 가독성과 유지 보수성을 향상시킬 수 있습니다.

반응형
Comments