Spring 미드레벨 CS 기초 면접

Spring 미드레벨 (3~7년) CS 기초 5문항 조회수 77 · 2026-07-23 (목) 19:11:05
1 자료구조
Medium

Q. HashMap과 ConcurrentHashMap의 동작 원리를 설명하고, 멀티스레드 환경에서 ConcurrentHashMap이 synchronized를 사용한 Collections.synchronizedMap보다 성능상 유리한 이유를 락 메커니즘 관점에서 설명해주세요. 또한 Spring에서 캐시 저장소로 사용할 때 어떤 자료구조를 선택해야 하는지 설명해주세요.

A. 모범답안

HashMap은 해시 충돌 시 체이닝 방식(Java 8부터 임계값 초과 시 트리화)을 사용하며 thread-safe하지 않습니다. ConcurrentHashMap은 버킷 단위 락(segment lock)을 사용하여 여러 스레드가 동시에 다른 버킷에 접근할 수 있어 높은 동시성을 제공합니다. synchronized 방식은 전체 맵에 하나의 락을 사용하므로 모든 스레드가 순차적으로 접근해야 하지만, ConcurrentHashMap은 락 분할(lock striping)로 동시 쓰기가 가능합니다. Spring에서 멀티스레드 환경의 캐시 저장소로는 ConcurrentHashMap을 사용하며, 단일 스레드나 불변 데이터라면 일반 HashMap으로도 충분합니다.

핵심 포인트
  • • HashMap은 thread-safe하지 않으며 해시 충돌 시 체이닝/트리 구조 사용
  • • ConcurrentHashMap은 버킷 단위 락으로 동시성 제어, 여러 스레드가 다른 버킷에 동시 접근 가능
  • • synchronized 방식은 전체 락으로 성능 저하, ConcurrentHashMap은 락 분할로 높은 처리량 제공
  • • Spring 캐시 저장소는 멀티스레드 환경에서 ConcurrentHashMap 사용 권장
Follow-up 질문

ConcurrentHashMap의 size() 메서드가 정확한 값을 보장하지 못하는 이유는 무엇이며, 이것이 실무에서 어떤 영향을 미칠 수 있나요?

2 네트워크
Medium

Q. HTTP/1.1과 HTTP/2의 차이점을 멀티플렉싱, 헤더 압축, 서버 푸시 관점에서 설명하고, Spring Boot 애플리케이션에서 HTTP/2를 활성화했을 때 실제로 성능 개선이 나타나는 시나리오와 그렇지 않은 시나리오를 설명해주세요.

A. 모범답안

HTTP/1.1은 하나의 TCP 연결에서 요청/응답이 순차적으로 처리되어 HOL(Head-of-Line) blocking이 발생하지만, HTTP/2는 멀티플렉싱으로 하나의 연결에서 여러 요청/응답을 동시에 처리합니다. HTTP/2는 HPACK 알고리즘으로 헤더를 압축하여 오버헤드를 줄이고, 서버 푸시로 클라이언트 요청 전에 리소스를 미리 전송할 수 있습니다. 성능 개선은 다수의 정적 리소스를 로드하는 웹 페이지나 API Gateway에서 여러 마이크로서비스를 호출할 때 두드러지지만, 단일 API 요청이나 대용량 파일 다운로드처럼 연결 수가 적은 경우에는 개선 효과가 미미합니다. Spring Boot에서는 server.http2.enabled=true로 활성화할 수 있으며 HTTPS 설정이 필수입니다.

핵심 포인트
  • • HTTP/2는 멀티플렉싱으로 하나의 연결에서 다중 요청 동시 처리, HOL blocking 해결
  • • HPACK 헤더 압축과 서버 푸시 기능으로 전송 효율성 향상
  • • 다수의 리소스 로드 시 성능 개선 효과 크지만 단일 요청에서는 효과 미미
  • • Spring Boot에서 HTTP/2는 HTTPS 기반으로 활성화 가능
Follow-up 질문

HTTP/3(QUIC)는 HTTP/2와 어떤 차이가 있으며, TCP 대신 UDP를 사용하는 이유는 무엇인가요?

3 데이터베이스
Hard

Q. 데이터베이스 인덱스의 B-Tree와 B+Tree 구조의 차이점을 설명하고, 대부분의 RDBMS가 B+Tree를 선택하는 이유를 범위 검색과 순차 접근 관점에서 설명해주세요. 또한 인덱스가 있음에도 Full Table Scan이 발생하는 경우를 3가지 이상 설명하고, Spring JPA 쿼리 작성 시 주의해야 할 점을 설명해주세요.

A. 모범답안

B-Tree는 모든 노드에 데이터를 저장하지만, B+Tree는 리프 노드에만 데이터를 저장하고 내부 노드는 키만 가집니다. B+Tree의 리프 노드는 연결 리스트로 연결되어 있어 범위 검색과 순차 접근이 효율적이며, 내부 노드가 더 많은 키를 저장할 수 있어 트리 높이가 낮아 디스크 I/O가 감소합니다. Full Table Scan이 발생하는 경우는: 1) 인덱스 컬럼에 함수나 연산 적용(WHERE YEAR(created_at)=2024), 2) 데이터 분포상 카디널리티가 낮아 옵티마이저가 Full Scan 선택(성별 같은 컬럼), 3) OR 조건이나 NOT 연산 사용, 4) LIKE '%keyword'처럼 와일드카드가 앞에 위치, 5) 인덱스 컬럼의 타입 불일치입니다. JPA에서는 @Query 작성 시 인덱스 컬럼을 그대로 사용하고, 엔티티 필드명과 DB 컬럼 타입을 일치시켜야 합니다.

핵심 포인트
  • • B+Tree는 리프 노드에만 데이터 저장, 연결 리스트로 범위 검색 최적화
  • • 내부 노드에 더 많은 키 저장 가능하여 트리 높이 감소, 디스크 I/O 효율적
  • • 인덱스 컬럼에 함수 적용, 낮은 카디널리티, OR/NOT 조건, 앞 와일드카드, 타입 불일치 시 Full Scan 발생
  • • JPA 쿼리에서 인덱스 컬럼을 가공하지 않고 타입 일치시켜 사용
Follow-up 질문

Covering Index가 무엇이며, Spring JPA에서 Projection을 활용하여 Covering Index의 이점을 얻는 방법을 설명해주세요.

4 운영체제
Medium

Q. 프로세스와 스레드의 차이점을 메모리 구조와 컨텍스트 스위칭 비용 관점에서 설명하고, Spring Boot 애플리케이션에서 Tomcat의 스레드 풀 설정(server.tomcat.threads.max, server.tomcat.threads.min-spare)을 튜닝할 때 고려해야 할 요소들을 설명해주세요. CPU-bound 작업과 I/O-bound 작업에 따라 적절한 스레드 풀 크기가 어떻게 달라지는지도 포함해주세요.

A. 모범답안

프로세스는 독립적인 메모리 공간(Code, Data, Heap, Stack)을 가지며 프로세스 간 컨텍스트 스위칭은 메모리 맵 교체, 캐시 무효화 등으로 비용이 큽니다. 스레드는 같은 프로세스 내에서 Code, Data, Heap을 공유하고 Stack만 독립적으로 가지며, 컨텍스트 스위칭 비용이 상대적으로 작습니다. Tomcat 스레드 풀 튜닝 시 동시 접속자 수, 평균 응답 시간, 서버 CPU 코어 수를 고려해야 합니다. CPU-bound 작업은 CPU 코어 수 +1 정도가 적절하며(과다 스레드 시 컨텍스트 스위칭 오버헤드), I/O-bound 작업은 대기 시간이 많아 더 많은 스레드(코어 수의 2~3배 이상)를 설정하여 동시성을 높일 수 있습니다. 실무에서는 부하 테스트를 통해 최적값을 찾아야 합니다.

핵심 포인트
  • • 프로세스는 독립 메모리 공간, 스레드는 Stack만 독립적이고 나머지 공유
  • • 스레드 컨텍스트 스위칭이 프로세스보다 비용 낮음
  • • CPU-bound는 CPU 코어 수 정도, I/O-bound는 더 많은 스레드로 대기 시간 활용
  • • 동시 접속자 수, 응답 시간, CPU 코어 수 고려하여 부하 테스트로 최적화
Follow-up 질문

Virtual Thread(Project Loom)가 기존 플랫폼 스레드와 어떻게 다르며, Spring Boot 3.2 이상에서 Virtual Thread를 활성화했을 때 어떤 종류의 애플리케이션에서 성능 개선을 기대할 수 있나요?

5 알고리즘
Medium

Q. 시간 복잡도 O(n log n)인 정렬 알고리즘들(Quick Sort, Merge Sort, Heap Sort)의 특징과 차이점을 공간 복잡도, 안정성(Stable), 최악의 경우 관점에서 비교 설명하고, Spring에서 대용량 데이터를 정렬해야 할 때(예: 페이징 없이 전체 데이터 정렬) 어떤 알고리즘을 선택하는 것이 적절한지 메모리 제약 상황을 포함하여 설명해주세요.

A. 모범답안

Quick Sort는 평균 O(n log n)이지만 최악의 경우 O(n²)이며, 제자리 정렬(in-place)로 공간 복잡도 O(log n), 불안정 정렬입니다. Merge Sort는 항상 O(n log n)을 보장하고 안정 정렬이지만, 추가 배열이 필요하여 공간 복잡도 O(n)입니다. Heap Sort는 항상 O(n log n)이고 제자리 정렬로 공간 복잡도 O(1)이지만 불안정 정렬이며 캐시 효율이 낮아 실제 성능은 Quick Sort보다 느립니다. Spring에서 대용량 데이터 정렬 시 메모리가 충분하면 Java의 Arrays.sort(Dual-Pivot Quick Sort + Insertion Sort)나 parallelSort를 사용하고, 메모리 제약이 있으면 DB 레벨에서 ORDER BY로 정렬하거나 External Sort(디스크 기반 Merge Sort)를 고려해야 합니다. 안정성이 필요하면 Merge Sort 계열을 선택합니다.

핵심 포인트
  • • Quick Sort는 빠르지만 최악 O(n²), 제자리 정렬, 불안정
  • • Merge Sort는 항상 O(n log n), 안정 정렬이지만 O(n) 추가 공간 필요
  • • Heap Sort는 O(n log n) 보장, O(1) 공간이지만 캐시 비효율적
  • • 대용량 데이터는 DB 정렬 우선, 메모리 제약 시 External Sort 고려
Follow-up 질문

TimSort가 무엇이며, Java의 Collections.sort()가 TimSort를 사용하는 이유와 실제 데이터에서 O(n)에 가까운 성능을 내는 경우를 설명해주세요.

댓글 0

로그인 후 댓글을 작성할 수 있습니다.

아직 댓글이 없습니다. 첫 번째 댓글을 남겨보세요!