신입 면접에서 자주 묻는 질문 정리 - 스프링 부트(Spring Boot)편
2025. 10. 4. 18:09

1. Spring과 Spring Boot의 차이

Spring Framework

  • Java 엔터프라이즈 애플리케이션 개발을 위한 경량 프레임워크
  • DI, AOP, MVC 등 다양한 기능 제공
  • 복잡한 XML 설정 또는 Java Config 설정 필요
  • 의존성 관리를 직접 해야 함
  • 내장 서버 없음 (별도의 WAS 필요)

Spring Boot

  • Spring 기반 애플리케이션을 빠르게 개발하기 위한 도구
  • 주요 차이점:
    • Auto Configuration으로 설정 자동화
    • starter 의존성으로 라이브러리 관리 간소화
    • 내장 서버(Tomcat, Jetty) 제공
    • XML 설정 불필요

Spring Boot의 장점 (등장 배경)

  1. 설정 간소화: 복잡한 XML 설정 제거, 자동 설정 제공
  2. 빠른 개발: starter를 통한 의존성 자동 관리
  3. 독립 실행: 내장 WAS로 jar 파일만으로 실행 가능
  4. 운영 편의성: Actuator를 통한 모니터링 기능 제공
  5. Spring 생태계 통합: Spring의 모든 기능을 그대로 사용하면서 편의성 향상

 

구분 Spring Framework Spring Boot
설정 방식 복잡한 XML 설정 또는 Java Config 필요 Auto Configuration으로 자동 설정
의존성 관리 각 라이브러리 버전을 직접 관리 starter 의존성으로 자동 관리
내장 서버 없음 (별도 WAS 필요) 내장 서버 제공 (Tomcat, Jetty, Undertow)
실행 방식 WAR 파일로 패키징 후 외부 서버 배포 JAR 파일로 독립 실행 가능
설정 파일 applicationContext.xml 등 다수 application.properties/yml 하나로 통합
개발 속도 초기 설정에 시간 소요 빠른 개발 가능 (CoC 원칙)
모니터링 별도 구성 필요 Actuator로 기본 제공

2. MVC 패턴

애플리케이션을 Model, View, Controller 세 가지 역할로 분리하는 디자인 패턴.

  • Model: 데이터와 비즈니스 로직 담당
  • View: 사용자 인터페이스(UI) 담당
  • Controller: Model과 View 사이의 상호작용 제어, 사용자 요청 처리

장점: 각 구성요소의 독립성 확보, 유지보수성과 확장성 향상

3. @Controller와 @RestController

@Controller

  • Spring MVC에서 View를 반환하는 컨트롤러
  • 메서드의 반환값이 ViewName(문자열)이 되어 ViewResolver를 통해 View를 렌더링
  • HTML 페이지를 응답할 때 사용

@RestController

  • @Controller + @ResponseBody의 조합
  • 메서드의 반환값이 HTTP Response Body에 직접 작성됨
  • JSON, XML 등의 데이터를 응답할 때 사용
  • RESTful API 개발에 적합

4. @ResponseBody

메서드의 반환값을 HTTP Response Body에 직접 작성하도록 지정하는 어노테이션.

  • ViewResolver를 거치지 않고 HTTP 메시지 컨버터를 통해 데이터를 변환
  • 객체 반환 시 주로 JSON 형태로 변환되어 클라이언트에 전달
  • @RestController에는 기본적으로 포함되어 있음

5. DI (Dependency Injection, 의존성 주입)

정의

객체가 필요로 하는 의존 객체를 외부에서 주입받는 디자인 패턴.

장점

  1. 결합도 감소: 객체 간 의존관계를 느슨하게 유지
  2. 테스트 용이성: Mock 객체 주입으로 단위 테스트 간편
  3. 코드 재사용성: 의존성을 외부에서 관리하여 재사용 용이
  4. 유지보수성: 변경 시 영향 범위 최소화

주입 방법

  • 생성자 주입 (권장): 불변성 보장, 순환 참조 방지
  • Setter 주입: 선택적 의존성에 사용
  • 필드 주입: 간편하지만 테스트 어려움

6. IoC (Inversion of Control, 제어의 역전)

객체의 생성과 생명주기 관리를 개발자가 아닌 프레임워크(IoC Container)가 담당하는 원칙.

  • 기존 방식: 개발자가 직접 객체를 생성하고 의존성 관리
  • IoC 적용: Spring Container가 객체(Bean) 생성 및 의존성 주입 담당
  • 장점: 객체 간 결합도 감소, 개발자는 비즈니스 로직에 집중 가능

7. 싱글톤 패턴

클래스의 인스턴스가 단 하나만 생성되도록 보장하는 디자인 패턴.

  • 목적: 메모리 절약, 전역적인 접근 제공
  • Spring의 Bean: 기본적으로 싱글톤 스코프로 관리됨
  • Spring의 싱글톤: Container가 관리하여 전통적 싱글톤 패턴의 단점(테스트 어려움, 결합도 증가) 해결

8. @Autowired와 Bean

Bean

  • Spring IoC Container가 관리하는 객체
  • Container에 등록되어 생명주기를 관리받음
  • 기본적으로 싱글톤으로 생성됨

@Autowired

  • Spring이 자동으로 의존성을 주입하도록 지시하는 어노테이션
  • 타입을 기준으로 Bean을 찾아 주입
  • 생성자, 필드, Setter에 사용 가능

9. Bean 등록 방법

@Component

  • 클래스 레벨에 선언하여 Component Scan 대상으로 지정
  • Spring이 자동으로 Bean으로 등록
  • @Controller, @Service, @Repository의 상위 개념

@Bean

  • 메서드 레벨에 선언 (@Configuration 클래스 내부)
  • 메서드가 반환하는 객체를 Bean으로 등록
  • 외부 라이브러리 객체를 Bean으로 등록할 때 주로 사용

10. @Component, @Service, @Repository, @Controller

@Component

  • 일반적인 Spring 관리 컴포넌트
  • 특별한 역할이 없는 Bean 등록 시 사용

@Service

  • 비즈니스 로직을 처리하는 서비스 계층 표시
  • @Component의 특수화

@Repository

  • 데이터 접근 계층(DAO) 표시
  • DB 예외를 Spring의 DataAccessException으로 변환
  • @Component의 특수화

@Controller

  • 프레젠테이션 계층(Web MVC Controller) 표시
  • 사용자 요청을 받아 처리하고 응답 반환
  • @Component의 특수화

공통점: 모두 Component Scan 대상이며 Bean으로 등록됨

11. DAO와 DTO

DAO (Data Access Object)

  • 데이터베이스 접근을 담당하는 객체
  • DB CRUD 작업을 캡슐화
  • 비즈니스 로직과 데이터 접근 로직 분리

DTO (Data Transfer Object)

  • 계층 간 데이터 전송을 위한 객체
  • 주로 getter/setter만 가지며 비즈니스 로직 포함 안 함
  • 필요한 데이터만 선택적으로 전송하여 효율성 향상

12. REST API

정의

HTTP를 기반으로 자원(Resource)을 정의하고, 자원에 대한 행위를 HTTP 메서드로 표현하는 아키텍처 스타일.

구성 요소

  • 자원 (Resource): URI로 표현 (예: /users/1)
  • 행위 (Verb): HTTP 메서드로 표현 (GET, POST, PUT, DELETE 등)
  • 표현 (Representation): JSON, XML 등의 형태로 자원의 상태 전달

13. RESTful

REST API 설계 원칙을 잘 지킨 시스템을 의미.

RESTful 조건

  1. 자원 중심 URI 설계: 동사가 아닌 명사 사용 (/getUsers ❌, /users ✅)
  2. HTTP 메서드 적절히 사용: 행위를 메서드로 표현
  3. 무상태성 (Stateless): 각 요청이 독립적
  4. 계층화 구조: 클라이언트-서버 간 계층 구조
  5. 캐시 가능: 응답 데이터를 캐싱 가능하도록 설계

14. REST API 메서드

GET

  • 자원 조회
  • 요청 시 Body 없음, 조회만 하고 서버 상태 변경 안 함

POST

  • 새로운 자원 생성
  • 요청 시 Body에 생성할 데이터 포함

PUT

  • 자원 전체 수정 (전체 업데이트)
  • 해당 자원이 없으면 생성 가능

PATCH

  • 자원 부분 수정 (일부 필드만 업데이트)

DELETE

  • 자원 삭제

HEAD

  • GET과 동일하지만 응답 Body 없이 Header만 반환

OPTIONS

  • 서버가 지원하는 메서드 확인

15. JPA와 ORM

ORM (Object-Relational Mapping)

  • 객체와 관계형 DB의 테이블을 자동으로 매핑하는 기술
  • SQL을 직접 작성하지 않고 객체 중심으로 개발 가능
  • 장점: 생산성 향상, DB 종속성 감소, 유지보수 용이
  • 단점: 복잡한 쿼리는 성능 저하 가능

JPA (Java Persistence API)

  • Java ORM 기술의 표준 명세 (인터페이스)
  • 실제 구현체로는 Hibernate, EclipseLink 등이 존재
  • 특징: 객체 중심 개발, JPQL 제공, 캐싱 기능, Lazy Loading

16. 영속성 컨텍스트

정의

Entity를 영구 저장하는 환경으로, JPA가 관리하는 Entity 객체의 집합.

동작 방식

  1. 1차 캐시: Entity 조회 시 영속성 컨텍스트에 먼저 저장되어 캐싱 효과
  2. 동일성 보장: 같은 트랜잭션 내에서 같은 Entity는 동일한 인스턴스 반환
  3. 쓰기 지연: SQL을 모아뒀다가 트랜잭션 커밋 시점에 한 번에 실행
  4. 변경 감지 (Dirty Checking): Entity 변경 시 자동으로 UPDATE SQL 생성
  5. 지연 로딩: 연관된 Entity를 실제 사용 시점에 조회

Entity 생명주기

  • 비영속 (new): 영속성 컨텍스트와 무관한 상태
  • 영속 (managed): 영속성 컨텍스트에 저장된 상태
  • 준영속 (detached): 영속성 컨텍스트에서 분리된 상태
  • 삭제 (removed): 삭제된 상태

17. N+1 문제

정의

연관 관계가 설정된 Entity를 조회할 때, 조회된 데이터 개수(N)만큼 추가로 쿼리가 발생하는 문제.

예시: User 100명을 조회하면서 각 User의 Order를 조회하는 경우

  • 1번: User 전체 조회 쿼리
  • N번: 각 User마다 Order 조회 쿼리 (100번)
  • 총 101번의 쿼리 발생

해결 방안

1. Fetch Join

  • JPQL에서 JOIN FETCH 사용
  • 연관된 Entity를 한 번의 쿼리로 함께 조회
 
 
java
@Query("SELECT u FROM User u JOIN FETCH u.orders")

2. @EntityGraph

  • 어노테이션 기반으로 Fetch Join 수행
  • attributePaths에 함께 조회할 연관 Entity 지정
 
 
java
@EntityGraph(attributePaths = {"orders"})

3. Batch Size 설정

  • @BatchSize 또는 hibernate.default_batch_fetch_size 설정
  • N개의 쿼리를 IN 절을 사용한 쿼리로 묶어서 실행
  • N+1 → 1+1로 개선

4. Fetch Mode 조정

  • @Fetch(FetchMode.SUBSELECT): 서브쿼리로 연관 데이터 조회

5. QueryDSL/Native Query 사용

  • 복잡한 경우 직접 쿼리 작성하여 최적화

권장: 대부분 Fetch Join이나 EntityGraph 사용, 상황에 따라 Batch Size 조합