Today's Codekata
// 멀리 뛰기
class Solution {
public long solution(int n) {
if (n == 1) return 1;
if (n == 2) return 2;
long[] arr = new long[n + 1];
arr[1] = 1;
arr[2] = 2;
for (int i = 3; i <= n; i++) {
arr[i] = (arr[i - 1] + arr[i - 2]) % 1234567;
}
return arr[n];
}
}
이 문제는 효진이가 1칸 또는 2칸씩 점프해서 n칸에 도달하는 경우의 수를 구하는 문제이다.
효진이가 n칸에 도달하려면, n-1칸에서 1칸 점프하거나 n-2칸에서 2칸 점프하는 방법밖에 없다.
따라서 n칸까지 가는 방법의 수는 (n-1칸까지 가는 방법 수) + (n-2칸까지 가는 방법 수)가 된다.
점화식
수학에서 수열의 항들 사이의 관계를 표현하는 식이다.
쉽게 말해 앞의 항들을 이용해서 다음 항을 계산하는 규칙이라고 생각하면 된다.
F(n) = F(n-1) + F(n-2)
여기서 F(n)은 n번째 항, F(n-1)과 F(n-2)는 바로 앞의 두 항이다.
이 규칙을 반복해서 전체 수열을 만들어가는 것이다.
스프링부트 자바 기초 다시 정리해보기
실행 흐름과 Bean
Spring Boot의 기본 구조는 단순하지만 명확하다.
Controller, Service, Repository 계층이 역할을 나누어 유지보수성과 확장성을 높여준다.
이번엔 이 구조가 실제로 어떻게 실행되고 연결되는지, 그리고 그 중심에 있는 Bean이 무엇인지 되짚어본다.
Spring Boot 애플리케이션은 `@SpringBootApplication`으로 시작한다.
이 어노테이션은 세 가지를 포함한다.
`@SpringBootConfiguration`, `@EnableAutoConfiguration`, `@ComponentScan`
각각은 설정 클래스임을 알리고, 필요한 의존성을 자동 설정하며, 하위 패키지를 탐색해 컴포넌트를 자동 등록한다.
실행 시 스프링이 애플리케이션 전체를 스캔하며 필요한 컴포넌트(Controller, Service, Repository 등)를 자동으로 Bean으로 등록하고 연결한다.
이 과정을 통해 개발자는 별도의 설정 없이도 동작하는 구조를 얻는다.
Spring에서 Bean은 스프링 컨테이너가 관리하는 객체를 의미한다.
개발자가 직접 new로 생성하지 않고, 스프링이 대신 생성하고 의존 관계를 주입한다.
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
위 코드에서 `UserService`와 `UserRepository`는 모두 Bean이다.
Spring 컨테이너는 실행 시점에 이 객체들을 생성하고, `UserService`가 필요로 하는 `UserRepository`를 주입한다.
이 과정을 `ApplicationContext`가 담당하며, `ApplicationContext`는 Bean의 생명주기와 의존 관계를 관리하는 스프링의 중심 엔진이다.
요청이 들어왔을 때의 흐름은 다음과 같다.
클라이언트 → Controller : 요청 수신
Controller → Service : 비즈니스 로직 처리
Service → Repository : DB 접근
Repository → DB : 데이터 조회/저장
결과 → Controller → 클라이언트 : 응답 반환
이 단순한 흐름 안에서 DI, 트랜잭션, 예외 처리 같은 스프링의 핵심 기능이 작동한다.
다시 살펴보니 Spring Boot의 진짜 강점은 자동화보다 명확한 구조와 제어의 단순화였다.
개발자는 객체를 일일이 관리하지 않아도 되고, 스프링은 Bean을 중심으로 애플리케이션의 흐름을 책임진다.