1. 객체 지향 프로그래밍이란?
요약
현실 세계를 모델링하여 객체 단위로 설계하고, 유연하고 변경에 강한 구조를 만드는 프로그래밍 패러다임입니다.
상세 설명
- 객체는 상태와 행동을 가지며, 메시지를 주고받고 협력합니다.
- 주요 특징은 추상화, 캡슐화, 상속, 다형성입니다.
- 특히 "역할(인터페이스)과 구현(클래스)을 분리"하여 유연한 변경과 테스트가 가능합니다.
예시
- Car라는 인터페이스를 만들고 Sonata, Tesla가 이를 구현하면
클라이언트는 Car만 알고 다양한 구현체로 변경할 수 있음.
2. 객체 지향의 4대 특징은 무엇인가요?
요약
추상화, 캡슐화, 상속, 다형성입니다.
상세 설명
- 추상화: 공통적인 특성을 뽑아내어 클래스로 정의
- 캡슐화: 데이터와 메서드를 하나로 묶고 외부에 내부를 숨김
- 상속: 기존 클래스의 기능을 재사용하고 확장
- 다형성: 하나의 메시지에 다양한 동작 (인터페이스 기반 설계)
예시
- 인터페이스 MemberRepository를 만들고 다양한 구현체 (Memory, JDBC)로 구현
- 서비스는 구현체가 아니라 인터페이스에만 의존함 → 변경에 유리
3. SOLID 원칙이란?
요약
객체 지향 설계를 잘하기 위한 5가지 핵심 원칙입니다.
상세 설명
SRP | 클래스는 단일 책임만 가져야 함 |
OCP | 기존 코드를 변경하지 않고 확장 가능해야 함 |
LSP | 자식 클래스는 부모를 대체 가능해야 함 |
ISP | 클라이언트는 사용하지 않는 메서드에 의존하지 않아야 함 |
DIP | 고수준 모듈이 저수준 모듈에 의존하지 않도록 추상화에 의존해야 함 |
예시
- MemberService가 MemoryMemberRepository에 직접 의존하면 DIP 위반
- MemberRepository 인터페이스를 사용하고 구현체는 외부에서 주입하면 OCP + DIP 만족
4. 스프링의 DI는 무엇이고 왜 중요한가요?
요약
DI(Dependency Injection)는 객체 간 의존 관계를 외부에서 주입받는 방식으로, 유연한 설계를 가능하게 합니다.
상세 설명
- 객체 생성과 연결 책임을 개발자 코드 밖으로 분리
- 역할(인터페이스)과 구현체(구체 클래스)를 분리하고 유연하게 연결
- 테스트, 확장, 유지보수에 유리
public interface MemberRepository {}
public class MemoryMemberRepository implements MemberRepository {}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository(); // 구현체 선택은 설정에서
}
5. 스프링이 어떻게 SOLID를 구현할 수 있게 도와주나요?
요약
스프링은 DI를 통해 DIP/OCP 원칙을 실현하고, Bean 분리로 SRP도 지킬 수 있도록 돕습니다.
상세 설명
- OCP: 구현체를 바꿔도 클라이언트 코드 변경 없음
- DIP: 고수준 서비스가 인터페이스에만 의존
- SRP: 컨트롤러, 서비스, 레포지토리 등으로 역할 분리
public class OrderService {
private final OrderRepository repository;
public OrderService(OrderRepository repository) {
this.repository = repository;
}
}
6. 인터페이스 기반 개발이 왜 중요한가요?
요약
역할과 구현을 분리하면 변경에 유연하고 테스트가 쉬워집니다.
상세 설명
- 객체는 ‘무엇을 한다’(역할)는 관점으로 바라보는 것이 중요
- 구현체는 변경될 수 있지만 인터페이스는 시스템의 약속
- 인터페이스 우선 설계는 기능 확장과 대체에 유리
예시
- 개발 초기 DB를 결정하지 않고 MemberRepository 인터페이스만 설계
- 나중에 JdbcRepository, JpaRepository 등으로 구현 선택 가능
7. 스프링은 객체 지향 설계를 어떻게 돕나요?
요약
스프링은 객체 지향 원칙을 코드로 실현하는 프레임워크입니다.
상세 설명
- 객체 간 의존성은 스프링 컨테이너가 주입
- 구현체는 외부 설정으로 선택 가능 → DIP/OCP 실현
- Bean 분리를 통해 SRP 보장
- 단위 테스트가 쉬움 (Mock 주입)
8. Spring Boot에서 DI는 어떻게 설정하나요?
요약
Spring Boot는 컴포넌트 스캔과 자동 설정으로 DI를 자동화합니다.
상세 설명
- @Component, @Service, @Repository, @Controller 등으로 Bean 등록
- @Autowired 또는 생성자 주입으로 의존성 자동 주입
- @Configuration + @Bean 방식으로 수동 설정도 가능
- Spring Boot는 @SpringBootApplication 내부에 컴포넌트 스캔 범위를 자동 설정
@Service
public class OrderService {
private final OrderRepository repository;
public OrderService(OrderRepository repository) {
this.repository = repository;
}
}
9. Spring에서 AOP는 어떤 역할을 하나요?
요약
AOP는 공통 기능(로깅, 보안, 트랜잭션 등)을 핵심 로직과 분리해 모듈화하는 기술입니다.
상세 설명
- 관심사 분리(Separation of Concerns)의 대표 사례
- 반복적인 코드(예: 로깅, 권한 검사)를 Aspect로 분리
- 핵심 로직은 순수하게 유지 → 유지보수성 향상
- 프록시 기반으로 동작하며, DI와 함께 작동
@Aspect
@Component
public class LogAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("호출 전: " + joinPoint.getSignature());
}
}
10. Bean의 생명주기와 Scope 차이는 무엇인가요?
요약
Bean은 컨테이너에 의해 생성부터 소멸까지 관리되며, Scope는 Bean의 생성 범위를 결정합니다.
상세 설명
- Bean 생명주기: 생성 → 의존성 주입 → 초기화 → 사용 → 소멸
- Scope는 Bean이 몇 번, 어떻게 생성되는지를 결정
- singleton: 애플리케이션당 1개
- prototype: 요청 시마다 새로 생성
- request, session 등 웹 환경에서 사용
@Bean
@Scope("prototype")
public UserService userService() {
return new UserService();
}
11. DI와 IoC의 차이점은?
요약
IoC는 제어의 주도권을 개발자가 아닌 프레임워크가 가지는 개념이며, DI는 IoC의 한 구현 방식입니다.
상세 설명
- IoC (Inversion of Control): 객체 생성/연결의 제어권이 역전됨 (프레임워크가 담당)
- DI (Dependency Injection): IoC를 구현하는 방식 중 하나로, 의존 객체를 외부에서 주입
예시
- IoC 컨테이너는 객체를 생성하고
DI는 생성된 객체를 주입하는 방식
12. 의존성 주입 방법 3가지와 각각의 특징은?
요약
생성자 주입, 필드 주입, setter 주입이 있으며 생성자 주입이 가장 권장됩니다.
상세 설명
생성자 주입 | 불변성 보장, 의존성 누락 방지 가능, 테스트 용이 → 가장 추천 |
필드 주입 | 코드가 간결하나 테스트 어려움, 리플렉션 기반 |
Setter 주입 | 선택적 의존성에 유용, 수정 가능성 존재 |
// 생성자 주입
public MemberService(MemberRepository repository) {
this.repository = repository;
}
13. Spring에서 테스트하기 쉬운 구조란?
요약
인터페이스 기반의 DI 구조는 구현체를 쉽게 Mocking하거나 교체 가능하게 하여 테스트를 쉽게 합니다.
상세 설명
- 구현체가 아닌 인터페이스에 의존 → 테스트 대상만 격리 가능
- JUnit + Mockito 사용 시 유리
- 테스트 더블(Mock, Stub 등)로 대체 가능
@Test
void testOrderService() {
OrderRepository mockRepo = new InMemoryOrderRepository();
OrderService service = new OrderService(mockRepo);
...
}
14. Spring Bean vs 일반 객체의 차이는?
요약
Spring Bean은 스프링 컨테이너가 관리하는 객체로, 생명주기, 의존성 주입, AOP 등 기능을 사용할 수 있습니다.
상세 설명
- 일반 객체는 개발자가 직접 생성하고 관리
- Spring Bean은 DI, AOP, 트랜잭션, 이벤트 등 부가 기능 제공
- Bean은 컨테이너가 싱글톤으로 관리하거나 Scope에 따라 생성
15. 의존 역전 원칙(DIP)을 어기면 생기는 문제는?
요약
구체 클래스에 의존하면 구현 변경 시 고수준 모듈도 함께 변경되어야 하므로 유지보수성이 떨어집니다.
상세 설명
- 예: OrderService가 MemoryOrderRepository에 직접 의존 → 구현체 교체 시 OrderService도 수정 필요
- 인터페이스를 만들고 구현체는 외부 설정에서 주입해야 유연하게 변경 가능
16. 스프링 컨테이너는 어떤 역할을 하나요?
요약
객체의 생성, 생명주기 관리, 의존 관계 주입(DI), AOP 적용 등을 담당하는 핵심 컴포넌트입니다.
상세 설명
- Bean 정의를 읽고 객체를 생성
- 필요한 의존성을 주입
- 요청 시 객체를 찾아 반환
- AOP 적용 등 부가 기능 수행
- 객체 지향 프로그래밍이란?
→ 현실 세계를 객체로 추상화하여, 유연하고 확장 가능한 구조를 만드는 프로그래밍 패러다임입니다. - 객체 지향의 4대 특징은?
→ 추상화, 캡슐화, 상속, 다형성을 통해 구조화된 코드와 유연한 변경을 가능하게 합니다. - SOLID 원칙이란?
→ 객체 지향 설계를 잘하기 위한 5가지 원칙으로, 변경에 유연하고 유지보수가 쉬운 구조를 만듭니다. - Spring의 DI는 무엇이고 왜 중요한가요?
→ 객체 간 의존성을 외부에서 주입함으로써 역할과 구현을 분리하고 유연한 구조를 만듭니다. - Spring이 어떻게 SOLID를 구현할 수 있게 도와주나요?
→ DI와 Bean 분리를 통해 DIP와 OCP, SRP를 자연스럽게 실현할 수 있게 해줍니다. - 인터페이스 기반 개발이 왜 중요한가요?
→ 구현과의 결합을 줄여 변경과 테스트에 유리한 구조를 만들 수 있기 때문입니다. - 스프링은 객체 지향 설계를 어떻게 돕나요?
→ 스프링은 DI 컨테이너를 통해 객체 생성과 의존성 연결을 자동화하여 설계 원칙을 실현합니다. - Spring Boot에서 DI는 어떻게 설정하나요?
→ 컴포넌트 스캔과 자동 설정을 통해 의존성 주입이 간단하게 이루어집니다. - Spring에서 AOP는 어떤 역할을 하나요?
→ 공통 관심사를 핵심 로직에서 분리해 코드 중복을 제거하고 유지보수성을 높입니다. - Bean의 생명주기와 Scope 차이는 무엇인가요?
→ 생명주기는 생성부터 소멸까지의 흐름이고, Scope는 Bean이 생성되는 범위를 결정합니다. - DI와 IoC의 차이점은?
→ IoC는 제어의 주체가 프레임워크로 바뀌는 개념이고, DI는 이를 구현하는 구체적인 방식입니다. - 의존성 주입 방법 3가지와 각각의 특징은?
→ 생성자 주입, 필드 주입, setter 주입이 있고, 생성자 주입이 가장 명확하고 안정적입니다. - Spring에서 테스트하기 쉬운 구조란?
→ 인터페이스 기반의 DI 구조는 테스트 대상을 분리하고 Mock 주입을 가능하게 해줍니다. - Spring Bean vs 일반 객체의 차이는?
→ Bean은 컨테이너가 관리하며 DI, AOP, 생명주기 등 다양한 기능을 지원합니다. - 의존 역전 원칙(DIP)을 어기면 생기는 문제는?
→ 구현체에 직접 의존하면 변경 시 클라이언트 코드까지 수정해야 해 유지보수가 어렵습니다. - 스프링 컨테이너는 어떤 역할을 하나요?
→ 객체 생성, 의존성 주입, 생명주기 관리, AOP 적용 등 전반적인 객체 관리를 담당합니다.
'기술면접' 카테고리의 다른 글
[기술면접] 스프링 MVC 1편 전체 예상 질문 (2) | 2025.08.18 |
---|