CS 면접 준비

[백엔드 면접 질문] CS - JAVA 면접 질문 정리(1)

민돌v 2022. 5. 11. 19:49

JAVA 관련 백엔드 면접 질문-답변 정리(1)

 

JAVA란 무엇인가요, (자바의 특징, OOP)

자바는 객체지향적 프로그래밍 언어(OOP) 입니다.

객체지향적 언어 OOP란, 프로그래밍에 사용 될 데이터의 상태와 행위를 객체로 만들어, 객체간의 상호작용을 통해 비지니스 로직을 구성하는 프로그래밍 기법입니다. (OOP의 특징은 아래에서)

 

자바의 특징

자바의 특징은

  1. JVM을 이용하기 때문에 운영체제에 독립적입니다.
  2. 객체지향언어이기 때문에 캡슐화, 상속, 다형성, 추상화의 특징을 가집니다.
  3.  컴파일시 데이터 타입이 결정되는 정적 타입 언어입니다.
  4. 컴파일 언어와 인터프리터 언어 2가지 동작방식을 복합적으로 사용하는 하이브리드 언어라고 불리기도 합니다.
  5. GC를 지원합니다.

기타 등등..

 


JAVA 접근제어자

java 접근제어자에 대해서 설명해주세요~

자바 접근제어자는 클래스, 인터페이스, 멤버변수, 함수 등의 접근을 제어하는 지시어를 말합니다.

접근제어자를 사용함으로써, 외부 객체의 무분별한 접근으로부터 내부 데이터를 보호할 수 있습니다(데이터 무결성).

 

접근제어자 같은 클래스 멤버 같은 패지지 멤버 자식 클래스 멤버 그 외
Public O O O O
Protected O O O X
Default O O X X
Private O X X X

 

  • public :  모든 패키지, 모든 클래스의 접근 허용
  • protected  : 같은 패키지, 모든 클래스의 접근 허용 (단, 다른 패키지인 경우 자식 클래스의 접근 허용)
  • default : 같은 패키지 내 클래스만 접근 허용
  • private : 같은 클래스 내 접근만 허용

접근 제어자를 사용하는 이유는 다음과 같습니다.

  • 객체지향 프로그래밍이란 객체들 간의 상호작용을 코드로 표현하는 것인데요.
  • 이때 객체들간의 관계에 따라서 접근 할 수 있는 것과 아닌 것, 권한을 구분할 필요가 생깁니다.
  • 클래스 내부에 선언된 데이터의 부적절한 사용으로부터 보호하기 위해서 접근 제어자를 사용합니다.

 


JAVA final 키워드란

final이란, 변수나 메소드 또는 클래스가 '변경 불가능' 하도록 만드는 자바 키워드 입니다.

final로 선언 시, 무조건 초기화를 해야하며, 초기화 프로그램 실행 도중 값 수정이 불가능합니다.

 

final을 사용하는 이유

클래스, 메서드, 변수가 변하지 않도록 하기 위해 사용합니다.

final을 선언하면, 절대 변하지 않는 값, 상수라는 개념을 가지게 됩니다.

데이터를 ReadOnly로 만들어, 객체 내부에서 값의 변환이나 가공을 하지 않겠다고 선언하여 데이터를 지킬 때 사용됩니다.

 


인터페이스와 추상 클래스의 차이

추상 클래스는, abstract로 선언되거나 추상메서드를 하나 이상 포함한 클래스를 말합니다.

  • 클래스이기 때문에 하나만 상속이 가능합니다.
  • 추상메소드란, 선언부만 있고 구현부가 없는 메소드이벼, 하위 클래스에게 메소드의 구현을 강제하는 메소드 입니다.
  • 추상 클래스 → extends 키워드 사용, 하나만 가능

인터페이스는 구현체 없이 메서드에 대한 명세만 가지고있고 모든 메서드 추상메서드입니다.

  • 따라서 인터페이스를 상속받는 자식클래스에 모든 메서드에 대한 구현을 강제하며, 다중 상속이 가능합니다.
  • 인터페이스 → implements 키워드 사용, 여러개 가능

 


Overriding VS Overloading

오버로딩이란,

  • 오버라이딩이란, 같은 이름을 가지는 메소드를 여러개 가지는 것을 말합니다.
  • 메소드의 이름은 같지만, 매개변수의 개수, 타입 등을 다르게 함으로써, 같은 메소드의 이름을 다른 기능으로 재정의하여 사용할 수 있습니다.
  • 메소드 이름 1개로 여러 기능으로 재정의하여 사용할 수 있기 때문에 가독성이 좋아집니다.

 

오버라이딩이란,

  • 하위 클래스에서 상위 클래스의 메소드를 재정의하여 사용하는 것을 말합니다.
  • 상위 클래스의 기능을, 하위클래스에서 필요한 부분만 재 수정하여 원하는 기능으로 구현하는 것을 말합니다.
  • 오버라이딩의 이점으로, 코드 중복을 줄이고, 기능 확장에 이점이 있다고 생각합니다,

 

오버라이딩과 오버로딩 모두 하나의 이름(기능)이 여러 역할(구현)을 할 수 있도록 할 수 있게 해주어 객체지향의 다형성의 특징을 가지게 합니다.

 


JAVA Generic이란

제네릭이란, 데이터 타입(data type, 자료형)을 일반화(generalize)하는 것으로, 데이터타입을 컴파일 시 미리 지정해 두는 것을 말합니다.

제네릭은 보통 클래스나 리스트 타입을 미리 지정할 때 사용됩니다.

 

자바 제네릭스의 형식과 약어

자주 사용되는 타입 인자는 다음과 같습니다.

- <T> == Type
- <E> == Element
- <K> == Key
- <V> == Value
- <N> == Number
- <R> == Result

제네릭스는 Java에서 컬렉션을 사용하면 자주 볼 수 있습니다.
제네릭스는 꺽쇠를 사용하여 타입을 명시해 줌으로서, 컴파일 시에 객체의 타입을 체크하는 것을 말합니다.
의도하지 않은 타입의 객체가 저장되는 것을 막고 잘못된 형변환을 막을 수 있기 때문에 안정성이 높아집니다. 더불어 동작은 같지만 클래스 타입만 바뀌어야 하는 경우를 쉽게 다룰 수 있게 됩니다.

 

제네릭스를 가장 잘 사용한 예제는 바로 Collection으로 볼 수 있습니다.

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class Main {
    public static void main(String[] args) {

        List<String> list = new ArrayList();
        Collection<String> collection = list;
    }
}
 

위의 collection의 경우, String type만을 담겠다고 명시되어 있습니다.
만약에, string 타입이 아닌 타입을 넣으면, 컴파일 에러가 납니다.

public interface Collection<E> extends Iterable<E> {
    int size();
    boolean isEmpty();
    Iterator<E> iterator();
    boolean add(E e);
    <T> T[] toArray(T[] a);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
}

 

Generic 장단점

제네릭을 사용하게 되면, 컴파일 시 타입을 명시해주기 때문에 의도하지않은, 형변환을 막을 수 있고,

타입만 변경해서 코드를 수정해야할 경우 쉽게 변경할 수 있다는 장점이 있습니다.

 


Statc이란 무엇인가요

static이란, static 변수와 static 메소드, 즉 정적 멤버(=클래스 멤버)를 만들 수 있는 키워드입니다.

정적 필드와 정적 메소드는 인스턴스(객체)가 아닌, 클래스에 고정되어, 클래스 로더가 클래스를 로딩해 메모리 영역에 적재할 때, 클래스별로 관리되어 정적 메모리로 사용할 수 있습니다.

객체 멤버는 객체를 생성할 때, 힙 영역에 할당됩니다.

 

static은 언제 사용되는지

정적 멤버는, 클래스가 메모리에 올라갈 때 자동적으로 생성되기 때문에 객체 인스턴스를 따로 생성하지 않아도 호출하여 사용할 수 있습니다.

따라서 static은 유틸리티 함수를 만드는데 사용하거나, 변하지 않는 자주 사용하는 값, 설정 정보등을 정적 메모리에 올려, 객체 생성 비용을 줄일 수 있습니다.

 

static 장,단점

static의 장점은 위와 같고, 단점은, 메모리에 올라가는 것이기 때문에, 남용하며 메모리를 낭비할 수 있습니다.

 

java의 main 메서드가 static인 이유

메모리가 초기화 된 순간 객체는 하나도 존재하지 않기 때문에 객체 멤버 메서드는 바로 실행 할 수 없습니다.

따라서, 객체의 존재 여부에 관계없이 쓰기 위해 static이어야 합니다. static 멤버는 JVM 구동시 스태틱 영역에 바로 배치되기 때문입니다.

 


JVM의 동작과정 및 원리

 JVM이란, 자바 가상 머신(Java Virtual Machine)의 약자로, 컴퓨터가 자바 바이트 코드를 운영체제에 맞게 실행시키는 역할을 수행합니다.

JVM은, OS의 종류에 상관없이 자바 파일을 실행할 수 있도록 중개자 역할을 합니다. 따라서 자바는 플랫폼 독립적 특성을 가집니다.

 

JVM 동작 과정

  1. 프로그램이 실행되면 JVM은 OS로부터 필요한 메로리를 할당받습니다.
  2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환시킵니다.
  3. Class Loader를 통해 Class 파일들을 JVM으로 로딩합니다.
  4. 로딩된 class 파일들은 Execution engine을 통해 해석됩니다.
  5. 해석된 바이트코드는 Runtime Data Areas에 배치되어 실질적인 수행이 이루어집니다.

 

JVM 구조

JVM의 구조는 Class Loader, Exection engine, Runtime Data Area, Garbage Collector로 이루어져 있습니다.

 

  • Class Loader는 자바 컴파일러가 .java 파일을 컴파일하여 .class 파일(바이트 코드)이 생성되면,
    이 생성된 클래스 파일들을 엮어 Runtime Data Area 형태로 메모리에 적재하는 역할을 합니다.
  • Execution Engine는 클래스 로더를 통해 JVM 내의 Runtime Data Area에 배치된 바이트 코드들을 명령어단위로 읽어서 실행합니다. 메모리에 적재된 클래스들을 기계어로 변경해 명령어 단위로 실행하는 역할을 합니다.
  • Garbage Collector는 Heap 메모리 영역에 생성 된 객체들 중에 참조되지 않는 객체들을 탐색 후 제거하는 역할을 합니다.
  • Runtime Data Area는 JVM이 프로그램을 수행하기 위해 OS로 부터 별도로 할당 받은 메모리 공간을 말합니다.
    Runtime Data Area는 크게 5가지 영역으로 나눌 수 있습니다.
    • 모든 스레드에서 공유하는 영역
      • Method Area
        • 메소드 영역에서 자바 프로그램의 클래스 코드, 변수 코드, static, final 변수 등이 생성된다.
      • Heap Area
        • new 키워드로 생성한 객체가 저장되는 영역
        • 동적으로 생성된 객체와 배열이 저장되는 곳으로 Garbage Collection의 대상이 되는 영역이다.
      • Stack Area
        • 지역 변수, 파라미터 등이 생성되는 영역, 동적으로 객체를 생성하면 실제 객체는 Heap에 할당되고 해당 레퍼런스만 Stack에 저장된다.
        • Stack은 스레드별로 독자적으로 가진다.
        • Heap에 있는 객체가 Stack에서 참조 할 수 없는 경우 GC의 대상이 된다.
    • 각 스레드 별로 생성되는 영역
      • PC Register
        • 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있다.(CPU의 PC Register와 다르다.)
      • Native Method
        • 자바외 언어로 작성된 네이티브 코드를 위한 메모리 영역

 


 

GC(Garbage Collector)의 종류와 동작 과정, 원리

가비지 컬렉터란, 힙 메모리 관리를 위해, 참조되고 있지 않은 객체들을 메모리에서 삭제하는 역할을 합니다.

 

어떻게 사용하지 않는다고 판단하고 제거가 되나요

객체는, 힙영역에 저장되고, 스택 영역에 이를 가르키는 주소값이 저장되는데,

힙영역에서 자신을 가르키는 주소값이 없으면, 참조되고 있지 않는다고 판단합니다.

  1. GC가 동작을 하면, GC Root부터 객체를 찾고, 그 객체가 참조하는 객체를 찾아 mark 합니다.
  2. Mark되지 않은 객체는 접근할 수 없다고 판단하여 제거합니다.

 

 

GC 동작 과정

  1. 객체가 생성되면 메모리를 young 영역에 저장합니다.
  2. 객체를 최초 생성하면 Young 영역에 Eden 영역에 위치합니다.
  3. Eden 영역에서 Minor GC가 발생하면, 참조 중인 객체는 1번 Survivor 영역으로 이동합니다.
  4. 1번 Survivor 영역에서 Minor GC가 발생하면, 참조 중인 객체는 2번 Survivor 영역으로 이동하고 1번 Survivor 영역은 비게됩니다.
  5. Young 영역에서 오래 살아남은 객체는 Old영역으로 이동하게 됩니다.
  6. Old 영역에 있는 객체는 Major GC가 발생했을 때, 참조 여부에 따라 유지되거나 제거됩니다.

 

GC 알고리즘 종류

  1. Serial GC
    • 가장 단순한 방식한 GC 입니다.
    • 싱글 스레드로 동작하고, 그만큼 느립니다.
    • Mark-sweep-compact 알고리즘(mark하고, sweep(지우고)하고, compact(빈공간을 채워넣는다)
    • 적은 메모리와 CPU 코어 갯수가 적을 때 적합하다.
  2. Paraller GC
    • Java8의 default GC입니다.
    • Serial GC와 알고리즘은 같지만 GC를 처리하는 Thread가 여러개이다.
    • 메모리와 코어가 충분할 때 적합하다.
  3. Paraller Old GC
    • Paraller GC는 Young영역에서만 멀티스레드를 사용하지만,
    • 이건 Old 영역까지 멀티스레드를 사용합니다.
    • Paraller GC에서 Old GC 알고리즘을 개선한 버전이다.

 

GC의 장단점

GC를 사용할때의 장점은

  1. 메모리 누수를 막을 수 있습니다.
  2. 해제된 메모리에 접근하는 오류와, 해제된 메모리를 한번 더 해제하는 이중 해제를 막을 수 있습니다.

GC를 사용할 때의 단점은

  1. GC의 메모리 해제 타이밍을 개발자가 정화하게 알기 힘듭니다.
  2. 따라서 실시간성이 강조되는 프로그램에의 경우 GC에게 메모리를 맡기는 것을 알맞지 않을 수 있습니다.

 

정적타입 언어와 동적 타입 언어의 차이

타입(자료형)의 결정을 컴파일할 때 결정한다면 정적 타입 언어(Java, C, C++), 런타임 과정에서 결정한다면 동적 타입 언어(Python, JavaScript, Rudy)입니다.

 

정적타입, 동적타입 언어의 장단점

  • 정적 타입 언어의 경우
    컴파일 때 미리 타입을 결정하기 때문에 실행속도가 빠르고 타입 에러로 인한 문제점을 초기에 발견할 수 있어 타입의 안정성이 높습니다.
    하지만, 매번 코드 작성시 변수형을 결정해줘야 하는 번거로움이 있습니다.

 

  • 동적 타입 언어의 경우
    런타임까지 타입에 대한 결정을 끌고 갈 수 있기 때문에 유연성이 높고, 컴파일시 타입을 명시해주지 않아도 되기 때문에 빠르게 코드를 작성할 수 있습니다.
    하지만, 실행 도중에 변수에 예상치 못한 타입이 들어와 타입에러가 발생할 수 있습니다.
    동적타입 언어는 런타임 시 확인할 수 밖에 없기 때문에, 코드가 길고 복잡해질 경우 타입 에러를 찾기가 어려워 집니다.

 

스크립트 언어와 컴파일 언어 차이

  • 스크립트 언어는 Javascript, Python이 대표적인 스크립트 언어입니다.
  • 컴파일 언어는 C, C++이 있습니다.
  • 스크립트 언어와 컴파일 언어의 차이점은
    • 스크립트 언어
      • 인터프리터가 한 라인 한 라인 기계어로 번역하며 실행합니다.
      • 우리가 컴파일 에러라고 부르는 문법 오류를 사전에 방지하지 못하기 때문에 주의해야 합니다.
    • 컴파일 언어
      • 실행 전 소스코드를 컴파일하여 기계어로 변환 후 해당 파일을 실행합니다.
      • 이미 기계어로 변환된 것을 실행하므로 비교적 빠릅니다.
      • 컴파일 과정을 거쳐 기계어 코드로 번역이 되기 때문에 사전에 검증을 할 수 있고, 최적화를 해줄 수 있습니다.
  • 또한, 스크립트 언어는 운영체제를 신경 쓸 필요 없이 한 번만 작성하면 되지만, 컴파일 언어는 운영체제에 따라 다르게 작업해야 합니다.

 

자바는 컴파일 언어인가 스크립트 언어인가

  • Java는 컴파일 언어에 더 가깝다고 생각합니다. 자바 컴파일러가 기계어로 번역해주기 때문입니다.
  • 다만, Java는 조금 특수한 경우입니다.
    • 자바는 한 번의 컴파일링으로 실행 가능한 기계어가 만들어지지 않고 JVM에 의해 기계어로 번역되고 실행하는 과정을 거치기 때문에 C나 C++의 컴파일 단계에서 만들어지는 완전한 기계어보다는 속도가 느립니다. (Java는 컴파일 시에 Java Byte Code로 컴파일 되며, 이는 JVM에서 인터프리터 방식으로 동작함)
    • 그러나 최근의 JVM 구현은 JIT 컴파일러를 포함하여 일부 구간에서는 최적화를 수행하여 기계어 코드를 생성하여 바로 실행합니다.

 

JAVA 코드 컴파일 과정

1. 개발자가 자바 소스 코드를 작성하면, 자바 컴파일러가 자바 소스 파일을 컴파일 합니다.

이때 나오는 파일은 자바 바이트 코드 파일로, 아직 컴퓨터가 읽을 수 없는 자바 가상 머신이 이해할 수 있는 코드 입니다.

2. 컴파일 된 바이트 코드를 JVM의 클래스 로더에게 전달합니다.

3. 클래스 로더는 동적로딩을 통해 필요한 클래스들을 로딩 및 링크하여 JVM의 런타임 데이터 영역에 올립니다.

마지막으로 실행엔진은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행합니다.
이때, 실행엔진은 바이트 코드를 각 OS가 실행할 수 있는 기계어로 변환시킵니다.

 

바이트 코드란

바이트코드는 특정 하드웨어가 아닌 가상 머신에서 돌아가는 실행 프로그램을 위한 이진 표현법입니다.
바이트 코드의 대부분 명령어는 0개 이상의 매개변수를 갖는 1바이트 크기를 가지고 있습니다.

(= 기계어)

 

클래스 로더 동작 과정

클래스 로더의 세부 동작은 다음과 같습니다.

  1. 가장 먼저, 클래스 파일을 가져와서 JVM의 메모리에 로드합니다.
  2. 그 다음, 자바 언어 명세 및 JVM 명세에 명시된 대로 구성되어 있는지 검사합니다.
  3. 검사 후에는, 필드, 메서드, 인터페이스 등 메서드클래스가 필요로 하는 메모리를 할당합니다.
  4. 이 후, 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경합니다.
  5. 마지막으로 클래스 변수들을 적절한 값으로 초기화합니다.

 

+ 심볼릭 레퍼런스는 무엇인가요?

심볼릭 레퍼런스란 참조할 때, 클래스의 특정 메모리 주소를 참조 관계로 구성한 것이 아닌 참조하는 대상의 이름을 지칭합니다.
Class 파일이 JVM에 올라가게 되면 심볼릭 레퍼런스는 그 이름에 맞는 객체의 주소를 찾아서 연결하는 작업을 수행합니다.
그러므로, 실제 메모리 주소가 아니라 이름만을 가집니다.

 

+ 다이렉트 레퍼런스로 변경이라는 의미는?

실제 메모리 주소 값으로 변경해 주는 작업을 의미합니다.

 

동적로딩이란

동적로딩은 프로그램을 실행할 때, 필요할 때마다 동적으로 메모리를 생성하고 필요없는 메모리는 자동으로 메모리에서 소멸시키는 것을 말합니다.
일부 클래스가 변경되어도 전체 어플리케이션을 다시 컴파일 하지 않아도 되기에, 변경사항이 발생해도 비교적 적은 작업만으로도 처리할 수 있습니다.

 

실행엔진이 바이트코드를 실행하는 과정

두가지 방식을 사용하게 됩니다.

  • 인터프리터 방식은 바이트코드 프로그램은 보통 한 번에 하나의 명령어를 읽은 후 실행합니다.
    이러한 형태의 바이트코드 인터프리터는 한 줄씩 수행하기 때문에 느립니다.
  • 인터프리터 방식의 단점을 보완하기 위해 도입된 JIT 컴파일러가 나왔습니다.
    인터프리터 방식으로 실행하다가 적절한 시점에서 바이트 코드 전체를 컴파일 하여 네이티브 코드로 변경하고, 이후에는 더이상 인터프리팅 하지 않고 네이티브 코드를 직접 실행합니다.
  • JIT 컴파일러를 사용하는 JVM은 내부적으로 해당 메서드가 얼마나 자주 수행되는지 체크하고, 일정 정도를 넘었을 때, 컴파일을 수행합니다.
  • JIT 컴파일러로 인해, 자바는 네이티브 언어와 유사한 수준의 퍼포먼스를 낼 수 있게 되었습니다.

 


primitive Type VS referenc Type

primitive type는 기본 데이터 타입으로,
종류는 byte, short, char, int, float, double, boolean이 있습니다.

 

reference type은 참조 데이터 타입으로,
기본 데이터 타입을 제외하고는 모두 참조 데이터 타입입니다.

  • 참조 데이터 탑입 종류는 class, array, interface, Enumeration이 있습니다.
  • 참조 타입은 값이 저장된 곳의 주소를 저장합니다.
  • 참조 타입은 4 byte 크기의 주소값이 들어갑니다.

 

primitive type과 reference type의 차이점

  • 기본 데이터 타입은 실제 데이터 값 자체를 저장합니다.
    데이터의 크기가 작고 고정적이기 때문에 메모리의 Stack 영역에 저장됩니다.
  • 반면, array와 class와 같은 참조 데이터 타입은 객체가 메모리 상에 위치한 주소를 저장합니다.
    데이터의 크기가 동적이기 때문에 동적으로 관리하는 Heap 영역에 저장됩니다.
  • 또한, 참조 데이터 타입의 경우 더이상 참조하는 변수가 없을 때, 가비지 컬렉션에 의해 파괴 됩니다.

 

기본 데이터 타입과 참조 데이터 타입이 사용되는 경우

primitive type

  • primitive type은 null을 다루지도 못하고, generics에 담기지도 못합니다.
  • primitive type이 reference type과 비교해서 갖는 장점은 성능과 메모리에 이점이 있습니다.

왜냐하면, reference type은 스택 메모리에는 참조 값만 있고 실제 값은 힙 메모리에 존재하기 때문입니다.

따라서 reference type은 값이 필요로 할 때마다, primitive type과 비해 접근 속도가 느려지게 됩니다.

reference type

  • 데이터가 동적이지 않으면, 성능과 메모리에 장점이 있는 primitive type을 먼저 고려해보고,
  • 만약 Null을 다뤄야 하거나, Generic 타입에서 사용되어야 한다면 reference type을 사용합니다.

JAVA ThreadLocal이란

ThreadLocal이란,

  • Thread 내부에서 사용하는 지역변수입니다.

일반 변수의 수명은 특정 코드 블록 범위 내에서만 유효하지만, ThreadLocal을 이용하면 쓰레드 영역에 변수를 설정할 수 있기 때문에, 특정 쓰레드가 실행하는 모든 코드에서 그 쓰레드에 설정된 변수 값을 사용할 수 있게 됩니다.

멀티 쓰레드 환경에서 각 쓰레드마다 get(), set() 메서드를 통해 독립적으로 변수에 접근할 수 있습니다.

 

ThreadLocal의 활용은 다음과 같습니다.

  • ThreadLocal은 한 쓰레드에서 실행되는 코드가 동일한 객체를 사용할 수 있도록 해 줍니다.
    따라서, 쓰레드와 관련된 코드에서 변수를 공유할 때, 파라미터 또는 리턴 값으로 정보를 제공해주지 않아도 됩니다.
  • 대표적인 활용 예시는 Spring Security에서 사용자 인증 정보를 사용입니다.
    서버에서 클라이언트 요청들에 대해 각 쓰레드에서 처리하게 될 경우, 해당 유저의 인증 및 세션 정보나 참조 데이터를 저장하는데 ThreadLocal이 사용됩니다.

 

ThreadLocal의 내부 구조

ThreadLocal의 내부는 thread 정보를 key로 하여 값을 저장해두는 Map 구조를 가지고 있습니다.
기본적인 사용에는 getset 메서드를 이용합니다.

 

쓰레드 로컬 사용 시 주의 사항

ThreadLocal은 Thead의 정보를 key로 하여 Map의 형식으로 데이터를 저장한 후 사용할 수 있는 자료구조를 가지고 있습니다.
따라서 만약 ThreadPool을 사용하여 thread를 재활용한다면
동일한 이전에 세팅했던 ThreadLocal의 정보가 남아있어 원치않는 동작을 할 수 있습니다. 따라서 ThreadPool을 사용하는 경우에는 반드시 모두 사용 후 THreadLocal의 값을 remove 메서드를 사용하여 값을 제거해주는것이 필요합니다.


 

JAVA SE와 JAVA EE 어플리케이션의 차이

JAVA SE는 자바 표준 에디션이고, JAVA EE는 JAVA SE의 API에 추가로 JSP, Servelt 등의 추가 API를 탑재한 것입니다.