- Spring Boot: Spring의 경량화된 프레임워크로, 빠른 개발 환경 제공
- 의존성 주입(Dependency Injection): 객체 간 결합도를 낮추는 설계 원칙
- AOP(Aspect-Oriented Programming): 공통 기능을 모듈화하여 코드 중복을 줄이는 방식
- JPA vs Hibernate: Java Persistence API와 Hibernate 프레임워크의 차이
- Bean의 라이프사이클: 객체의 생성, 초기화, 소멸 과정
1. Kotlin
Java(Kotlin)으로 구성된 프로젝트의 Kotlin(Java) 컨버팅 작업이 가능한지, 무엇을 염두에 두어야 하는지 이야기해주세요.
Java와 Kotlin의 차이점을 설명해주세요
Java와 Kotlin 차이
- 간결한 문법
- Java에 비해 간결한 문법 → 더 적은 코드로 동일한 작업 수행
- 가독성, 개발 생산성 향상
- Null Safety
- Java : NullPointerException, 수동으로 null 체크 (if / try-catch)
- Kotlin : Nullable Non-nullable 개념 도입, 명시적으로 nullable로 선언된 경우에만 null값을 가질 수 있음 → NPE 발생을 줄여 안정성 향상
- 상호 운용성
- Java와 100% 호환
- 비동기 처리
- Kotlin 에서 자체 제공하는 코루틴을 통해 비동기 코드를 간편하게 작성 가능
- 확장 함수
- 기존 클래스를 상속하지 않고도 새 함수로 확장 가능
- 기본 타입
- Kotlin의 기본 타입은 객체로 취급
- Checked Exception
- Kotlin은 Checked Exception을 지원하지 않으므로 예외처리에 유의
2. Legacy Spring vs Spring Boot
Legacy Spring과 최근 Spring 또는 Spring Boot의 차이점을 설명해주세요.
Legacy Spring
- XML 기반 설정
- bean 태그를 통해 의존성을 명시하고, Id, class, property 등을 수동으로 설정
- 수동 의존성 관리
- 프로젝트 설정에서 개별 라이브러리를 추가하고 버전 관리
- WAR 배포
- 대부분의 어플리케이션이 WAR 파일로 패키징되어 외부 Tomcat 같은 서버에 배포
Spring Boot
- Java config 기반 (Annotation)
- XML 설정 대신 @Configuration과 @Bean 어노테이션을 사용한 자바 기반 설정이 표준
- @ComponentScan으로 컴포넌트 자동 탐지 및 기록
- 자동 설정 (Spring Boot Starter)
- Starter 의존성을 설정하면 필요한 의존성 및 기본 설정이 자동으로 제공
- Tomcat, DispatcherServlet등 자동 설정
- Spring Boot가 테스트된 의존성 조합 관리 → 버전 충돌 문제 해소
- 내장 서버 지원
- 내장된 Tomcat, Jetty 지원
- 독립 실행 가능한 JAR 파일로 배포 가능
Spring과 Spring Boot의 차이점은 무엇인가요?
Spring은 설정과 배포 과정이 복잡하지만 Spring Boot는 Starter를 사용한 자동 설정 기능과 내장 서버를 통해 초기 설정과 배포를 간소화하여 생산성을 높일 수 있습니다.
Spring Boot Starter가 무엇이며, 어떤 역할을 하나요?
프로젝트에서 자주 사용하는 라이브러리와 설정을 모아둔 의존성 묶음입니다. 예를 들어 springboot-starter-web은 Spring MVC, 내장 Tomcat, Json 처리 라이브러리등을 포함해 웹 애플리케이션 개발을 쉽게 해줍니다.
Spring Boot에서 내장 서버를 사용하는 이유와 장점은 무엇인가요?
WAR 배포없이 JAR 파일로 애플리케이션을 실행할 수 있습니다. 외부 서버를 설정할 필요 없이 독립정인 실행이 가능하고, CI/CD 파이프라인을 간소화하여 개발 및 테스트 환경에서 빠른 실행이 가능합니다.
3. Spring DI
Spring의 의존성 주입(Dependency Injection)이란 무엇이며, 이를 사용하는 이유를 설명해 주세요.
Dependency Injection
- 객체 간의 의존 관계를 코드에서 직접 관리하는것이 아니라 Spring 컨테이너가 객체를 생성하고 의존성을 자동으로 주입해주는 디자인패턴
- 필요한 의존성을 외부에서 주입받음
사용 이유
- 결합도 감소
- 유지보수성 향상
- 객체의 의존성을 분리하여 코드 변경 최소화
- 테스트 용이성
- 테스트 시 의존성을 Mock 객체나 Stub으로 교체할 수 있어 단위테스트에 용이
- 재사용성 증가
- 다른 환경에서 같은 객체를 쉽게 재사용 가능
- 코드 명확성 증가
- 객체 생성과 의존성 관리하 분리되어 코드가 간결하고 명확해짐
구현 방법
- 생성자 주입 : 의존성을 생성자 인자로 주입하는 방식, 불변성 보장, 많은 의존성이 필요하면 복잡해짐
- Setter 주입 : setter 메서드를 통해 주입하는 방식, 이후 변경 가능, 불완전
- 필드 주입 : 필드에 직접 주입하는 방식, 코드 간결, 테스트 어려움
어노테이션(@Autowired, @Service, @Repository) 또는 XML 설정을 통해 관리
Spring에서 DI가 잘못 적용될 수 있는 경우는 어떤 상황인가요?
DI가 순환 의존성이 발생할 때 입니다. 이는 두 객체가 서로 의존할 때 발생합니다. 이러한 경우 Setter 주입을 사용하거나 @Lazy를 사용하여 해결할 수 있습니다.
DI가 테스트에 용이한 이유는 무엇인가요?
실제 의존 객체 대신 Mock 객체나 Stub 객체를 주입할 수 있습니다. 외부 시스템과의 의존성을 차단하고 독립적인 테스트가 가능합니다. 클래스 간 결합도가 낮아져 테스트가 간결하고 명확해집니다.
4. AOP
AOP(Aspect Oriented Programming)가 무엇이며, Spring에서 AOP를 어떻게 구현할 수 있는지 설명해 주세요.
AOP
- 프로그램의 핵심 로직과 공통 관심사를 분리하여 코드의 재사용성을 높이는 프로그래밍 기법
- 유지보수성과 확장성 향상
핵심 개념:
- Aspect: 공통 관심사를 모듈화한 코드. 예를 들어, 로깅, 보안, 트랜잭션 처리 등
- Join Point: Aspect가 적용될 수 있는 코드의 지점. 예를 들어, 메서드 호출 전, 후 등
- Advice: Aspect가 특정 Join Point에 적용되어 실행되는 동작
- Pointcut: 어떤 Join Point에서 Advice가 실행될지 지정하는 표현식
- Weaving: Aspect를 프로그램에 적용하는 과정
AOP(Aspect Oriented Programming)가 무엇이며, Spring에서 AOP를 어떻게 구현할 수 있는지 설명해 주세요.
AOP는 관점 지향 프로그래밍으로, 프로그램의 핵심 로직과 부가적인 로직을 구분하여 프로그래밍하는 기법입니다. Spring에서는 주로 어노테이션 기반으로 AOP를 설정할 수 있습니다. @Aspect, @Before와 같은 어노테이션을 사용해 구현할 수 있습니다.
AOP의 장점과 단점을 설명해주세요
로깅이나 트랜잭션같은 공통 기능을 핵심 비즈니스 로직에서 분리해 코드의 모듈성과 가독성을 향상할 수 있습니다. 하지만 스프링에서 AOP는 프록시 기반으로 동작하는데, 프록시 객체를 생성할 때 약간의 성능 저하가 발생할 수 있으며 디버깅이 어려워 오류 추적이 어려울 수 있다는 단점이 있습니다.
5. JPA vs Hibernate
Spring Boot에서 JPA와 Hibernate의 차이점을 설명해 주세요.
JPA
- 자바에서 orm을 처리하는 표준 API
- 자바 객체와 관계형 데이터베이스 테이블간의 매핑을 정의하는 인터페이스
Hibernate
- JPA를 구현한 대표적인 orm 프레임워크
차이점
- JPA는 표준 API이고, Hibernate는 JPA를 구현한 프레임워크
- JPA는 기본적인 ORM 기능을 제공, Hibernate는 그 위에 추가적인 기능 제공
ORM
- 객체와 관계형 데이터 베이스 간의 매핑을 자동으로 처리하는 기술
JPA와 Hibernate의 차이점은 무엇인가요?
JPA는 Java에서 객체-관계 매핑을 위한 표준 API 입니다. JPA는 객체와 관계형 데이터베이스간의 매핑 규약을 정의하지만 실제 구현체는 제공하지 않습니다. Hibernate는 JPA 구현체로, JPA를 구현한 ORM 프레임워크입니다. Hibernate는 jpa를 따르며 추가적인 기능을 제공합니다.
AOP를 사용하는 대신, 특정 기능을 일반적인 방법(예: 인터페이스 기반 설계)으로 구현할 수도 있습니다. AOP를 사용해야 하는 상황과 그렇지 않은 상황을 어떻게 구별할 수 있을까요?
AOP를 사용해야 할 상황은 **Cross-Cutting Concern(횡단 관심사)**가 애플리케이션 전반에 걸쳐 반복적으로 발생하며, 이를 중앙에서 관리하고 분리할 필요가 있을 때입니다. 예를 들어:
- AOP를 사용해야 하는 경우:
- 로깅, 트랜잭션 관리, 보안, 모니터링 등 공통된 부가 기능을 여러 모듈에서 일관되게 적용해야 할 때.
- 코드의 중복을 제거하고 유지보수를 쉽게 하기 위해.
- AOP를 사용하지 않아도 되는 경우:
- 특정 클래스나 모듈에서만 사용하는 기능(예: 한 메서드에만 적용되는 로직).
- 복잡하지 않고, 비즈니스 로직과 부가 로직이 명확히 분리되어 있을 때.
- AOP의 학습 곡선 또는 프록시 오버헤드가 불필요한 경우.
AOP는 강력한 도구지만 과도하게 사용하면 코드 흐름이 불투명해질 수 있으므로, 적용 대상이 전역적이고 반복적인 경우에만 사용하는 것이 적절합니다.