매운코딩 :: 매운코딩
300x250

Spring AI ChatClient 사용법과 오류 해결

Spring AI에서 ChatClient를 org.springframework.ai.chat.client.ChatClient 못찾는 오류 해결법을 작성해본다.

기본 사용법부터 실전 예제, 그리고 그 유명한 클래스패스 오류까지 차근차근 풀어보자.

ChatClient 기본 개념과 생성

ChatClient는 Spring AI에서 AI 모델과 대화할 때 쓰는 fluent API다. ChatModel 위에 쌓여 있어서 Prompt를 메시지 단위로 쉽게 조립하고, 동기/스트리밍 둘 다 지원한다.

가장 간단한 생성법은 Spring Boot 자동 구성 쓰는 거. Controller에서 ChatClient.Builder를 주입받아서 build하면 된다.

@RestController
class MyController {
    private final ChatClient chatClient;

    public MyController(ChatClient.Builder chatClientBuilder) {
        this.chatClient = chatClientBuilder.build();
    }

    @GetMapping("/ai")
    String generate(@RequestParam String message) {
        return this.chatClient.prompt()
                .user(message)
                .call()
                .content();
    }
}

여기서 .prompt().user(message).call().content() 흐름이 핵심이다. user()로 사용자 메시지 넣고 call() 치면 AI 응답이 String으로 나온다. 

시스템 메시지와 파라미터 넣기

실무에선 시스템 프롬프트 없으면 안 된다. 기본 시스템 메시지 설정하거나 동적으로 param 넣을 수 있다.

@Bean
ChatClient chatClient(ChatClient.Builder builder) {
    return builder
            .defaultSystem("너는 {voice}처럼 말하는 챗봇이야.")
            .build();
}

Controller에서 쓰려면:

@GetMapping("/ai/chat")
Map<String, String> chat(@RequestParam String message, @RequestParam String voice) {
    return Map.of("response",
            chatClient.prompt()
                    .system(sp -> sp.param("voice", voice))
                    .user(message)
                    .call()
                    .content());
}

.system()에 람다로 param 주입하는 게 포인트. 공식 문서에 따르면 이렇게 하면 템플릿처럼 동작한다. voice가 "친근하게"면 그에 맞춰 응답 나온다.

스트리밍 응답 예제

Flux로 실시간 스트리밍 하려면 .stream() 쓰면 된다. 채팅 앱에서 딱이다.

@GetMapping("/stream")
Flux<String> stream(@RequestParam String message) {
    return chatClient.prompt()
            .user(message)
            .stream()
            .content();
}

이거 연결해서 WebFlux 쓰면 토큰 단위로 응답이 쭉 흘러간다. 배포해보니 OpenAI 모델에서 특히 빠르게 느껴지더라.

"ChatClient that could not be found" 오류 해결

이 오류는 대체로 의존성 누락이나 버전 충돌, 자동 구성 실패 때 뜬다. 나도 OpenAI starter 추가했는데 뜨길래 pom.xml부터 확인했다.

1. 의존성 확인

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    <version>1.0.0-M1</version>  <!-- 최신 버전으로 -->
</dependency>

spring-ai-openai만 넣으면 ChatClient 패키지가 안 잡힌다. starter 버전 써야 자동 구성 된다.^1_4

2. Builder 주입 문제
Controller에서 private ChatClient.Builder chatClientBuilder; 필드 선언하고 @Autowired 안 하면 NullPointer. 생성자 주입으로:

public MyController(ChatClient.Builder builder) {
    this.chatClient = builder.build();
}

직접 필드에 넣지 말고 생성자에서 build.

3. 여러 ChatModel 있을 때
OpenAI + Ollama 두 개 쓰면 "No qualifying bean of type 'ChatModel'" 뜬다. 각 모델별 ChatClient 빈 따로 만들어:

@Bean
@Qualifier("openai")
ChatClient openAiClient(ChatClient.Builder builder) {
    return ChatClient.builder(openAiChatModel).build();
}

@Bean
@Qualifier("ollama")
ChatClient ollamaClient(OllamaChatModel ollamaModel) {
    return ChatClient.create(ollamaModel);
}

그리고 Controller에서 @Qualifier로 지정. 이게 제일 깔끔하다.^1_2

4. Milestone 리포지토리 추가

<repositories>
    <repository>
        <id>spring-milestones</id>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

M1, RC1 같은 버전은 여기서 끌어온다.

놓치기 쉬운 팁

  • ChatClient는 프로토타입 빈이라 매번 새로 build 가능. 싱글톤으로 고정 안 해도 된다.
  • .advisor()로 메모리나 RAG 추가 쉬움. 예: .advisor(new ChatMemoryAdvisor(chatMemory))
  • application.yml에 spring.ai.openai.api-key 설정 잊으면 런타임에서 터짐.

이렇게 해보니 안정적으로 돌아가더라. 공식 문서 예제 따라 하다 막히는 부분 위주로 정리해봤다. 실제 프로젝트에 넣어보고 싶으면 OpenAI 키부터 세팅해보시라.
^1_10^1_7^1_9

728x90
728x90
300x250

Java와 Spring 프레임워크 기반의 애플리케이션 개발 시 엑셀 파일의 읽기 및 쓰기 기능은 비즈니스 로직에서 필수적인 요소 중 하나다.

대량의 데이터를 시각화하거나 사용자가 업로드한 데이터를 시스템에 반영할 때 다양한 라이브러리가 활용된다.

 

Spring 엑셀 관련 라이브러리에 대해 각각 비교해보겠따.

 

1. Apache POI

Apache POI는 매~~~우 흔히 사용되는 표준같은 라이브러리다. 역사가 깊음..ㅋ

마이크로소프트 오피스 파일 형식을 다루는 오픈소스 프로젝트로, 엑셀뿐만 아니라 워드, 파워포인트 등 다양한 문서를 지원한다.

특징 및 장점 이 라이브러리는 엑셀의 거의 모든 기능을 제어할 수 있는 저수준 API를 제공한다.

셀의 스타일, 폰트, 수식, 병합 등 세밀한 디자인 조정이 가능하다. 또한 HSSF(구형 .xls)와 XSSF(신형 .xlsx) 형식을 모두 지원하며, 대용량 처리를 위한 SXSSF(Streaming XSSF) 방식도 제공한다.

 

단점 기본적인 XSSF 방식은 엑셀 파일을 읽거나 쓸 때 전체 데이터를 메모리에 로드한다.

이로 인해 데이터 양이 많아질수록 OutOfMemoryError가 발생할 위험이 크다.

또한 코드가 상당히 복잡하고 장황하여 유지보수가 어려울 수 있다.

 

//XSSF 쓰기 예제

Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Hello POI");

try (FileOutputStream fileOut = new FileOutputStream("poi_example.xlsx")) {
    workbook.write(fileOut);
} finally {
    workbook.close();
}

 

 

2. Excel Streaming Reader (xlsx-streamer)

Apache POI의 메모리 문제를 해결하기 위해 등장한 확장 라이브러리다. 주로 대용량 엑셀 파일을 읽을 때 사용한다.

특징 및 장점 POI의 편리한 인터페이스를 유지하면서도 데이터를 스트리밍 방식으로 읽어 메모리 점유율을 획기적으로 낮춘다. 임시 파일을 생성하여 데이터를 처리하므로 매우 큰 파일도 안전하게 읽을 수 있다. 기존 POI 코드를 크게 수정하지 않고 적용할 수 있다는 점이 매력적이다.

단점 데이터를 읽는 용도에 최적화되어 있어 쓰기 기능은 POI의 SXSSF를 그대로 사용해야 한다. 또한 임시 파일 관리 설정이 필요할 수 있다.

InputStream is = new FileInputStream(new File("large_file.xlsx"));
Workbook workbook = StreamingReader.builder()
        .rowCacheSize(100)    // 메모리에 보유할 행 수
        .bufferSize(4096)     // 버퍼 크기
        .open(is);            // 스트리밍으로 열기

for (Sheet sheet : workbook) {
    for (Row r : sheet) {
        for (Cell c : r) {
            System.out.println(c.getStringCellValue());
        }
    }
}

 

3. EasyExcel

Alibaba에서 개발한 EasyExcel은 POI의 복잡함과 메모리 문제를 동시에 해결하기 위해 설계된 고성능 라이브러리다.

특징 및 장점 가장 큰 특징은 메모리 효율성이다. 파일을 한 줄씩 읽어 처리하기 때문에 수백만 건의 데이터도 적은 메모리로 처리할 수 있다. 또한 어노테이션 기반으로 자바 객체(DTO)와 엑셀 시트를 직접 매핑할 수 있어 코드가 매우 간결해진다. 대규모 엔터프라이즈 환경에서 데이터 배치 처리에 매우 유리하다.

단점 POI에 비해 세부적인 서식 지정이나 복잡한 엑셀 기능 구현에는 제약이 있을 수 있다. 또한 오픈소스 생태계가 특정 기업 위주로 돌아간다는 점이 고려 대상이다.

public class ExcelData {
    @ExcelProperty("이름")
    private String name;
    
    @ExcelProperty("나이")
    private int age;
}

// 데이터 리스트를 파일로 저장
EasyExcel.write("easy_example.xlsx", ExcelData.class)
         .sheet("목록")
         .doWrite(dataList);

 

4. FastExcel

FastExcel은 속도와 메모리 절약을 최우선 목표로 하는 가벼운 라이브러리다.

특징 및 장점 매우 빠른 처리 속도를 자랑한다. XML 스트리밍 방식을 사용하여 대용량 데이터를 생성할 때 POI보다 우수한 성능을 보여준다. 의존성이 적어 프로젝트를 가볍게 유지할 수 있다.

단점 기능이 다소 제한적이다. 엑셀의 시각적인 스타일링보다는 데이터 자체를 빠르게 생성하고 읽는 작업에 특화되어 있다.

코드 예제 (스트리밍 쓰기)

try (OutputStream os = new FileOutputStream("fast_example.xlsx")) {
    Workbook wb = new Workbook(os, "MyApplication", "1.0");
    Worksheet ws = wb.newWorksheet("Sheet 1");
    ws.value(0, 0, "Fast Content");
    wb.finish();
}

 

 

<상세 지표 비교 평가>

 

라이브러리별 주요 지표를 5점 만점의 별점으로 평가한 결과다.

  읽기속도 쓰기속도 메모리 효율 기능성 안정도
Apache POI ★☆☆☆☆ ★☆☆☆☆ ★☆☆☆☆ ★★★★★ ★★★★★ ★★★★★
Streaming Reader ★★★★☆ - ★★★★☆ ★★☆☆☆ ★★★★☆ ★★★☆☆
EasyExcel ★★★★★ ★★★★★ ★★★★★ ★★★★☆ ★★★★☆ ★★★★☆
FastExcel ★★★★☆ ★★★★★ ★★★★★ ★★☆☆☆ ★★★☆☆ ★★☆☆☆

 

 

<라이브러리 비교 요약>

  주요 용도 난이도 특징
Apache POI 복잡한 서식/소량 데이터 높음 모든 기능 제어 가능, 업계 표준
Streaming Reader 대용량 읽기 전용 보통 POI 인터페이스 활용, OOM 방지
EasyExcel 대용량 읽기/쓰기 낮음 어노테이션 기반, 개발 속도 빠름
FastExcel 대용량 쓰기 특화 낮음 속도가 매우 빠름, 가벼운 의존성

 

 

결론.!!!! 프로젝트의 요구사항이 정교한 리포트 출력과 셀 병합, 복잡한 스타일링이라면 Apache POI가 가장 안전한 선택이다.

하지만 수만 건 이상의 데이터를 처리해야 한다면 EasyExcel이나 Streaming Reader를 사용하는 것이 서버 안정성 측면에서 필수적이다. 단순한 데이터 덤프 목적이라면 FastExcel이 가장 효율적인 대안이 된다. 서비스의 특성과 처리할 데이터의 규모를 먼저 파악한 뒤 적절한 도구를 선택하는 것이 중요하다.

728x90
728x90
300x250

git 사용 시에 자주 활용하는 명령어 예제를 정리한다. (순전히 내가 보기 위함..)

 

1. 환경 설정 (Configuration)

Git을 처음 설치하거나 새 환경에서 시작할 때 사용자 정보를 설정한다.

  • 사용자 이름 설정
  • git config --global user.name "Your Name"
  • 사용자 이메일 설정
  • git config --global user.email "your_email@example.com"
  • 설정 확인
  • git config --list

2. 저장소 시작 및 복제 (Init & Clone)

프로젝트를 Git으로 관리하기 시작하거나 원격 저장소를 로컬로 가져오는 단계다.

3. 변경 사항 기록 (Add & Commit)

작업한 내용을 스테이징 영역에 올리고 스냅샷으로 저장하는 과정이다.

  • 변경 파일 스테이징
  • git add file.txt # 특정 파일 git add . # 변경된 모든 파일
  • 커밋 생성-m 옵션을 통해 커밋 메시지를 함께 작성한다.
  • git commit -m "feat: 로그인 기능 추가"
  • 상태 확인현재 어떤 파일이 수정되었고, 스테이징되었는지 확인한다.
  • git status

4. 이력 확인 (Log & Diff)

지금까지 쌓인 커밋 내역과 변경점을 확인한다.

  • 커밋 히스토리 조회
  • git log git log --oneline # 한 줄로 요약해서 보기
  • 변경 사항 비교
  • git diff # 워킹 디렉토리와 스테이징 영역 비교 git diff --staged # 스테이징 영역과 마지막 커밋 비교

5. 브랜치 관리 (Branch & Merge)

독립적인 작업 공간을 만들고 합치는 Git의 핵심 기능이다.

  • 브랜치 생성 및 목록 확인
  • git branch feature-login # 생성 git branch # 목록 조회
  • 브랜치 전환
  • git switch feature-login # 최신 방식 git checkout feature-login # 기존 방식
  • 브랜치 병합현재 브랜치(보통 main/master)에 특정 브랜치의 변경 사항을 합친다.
  • git merge feature-login

6. 원격 저장소 상호작용 (Remote & Push/Pull)

팀원들과 코드를 공유하기 위해 서버와 통신한다.

7. 작업 되돌리기 (Reset & Revert)

실수를 바로잡거나 이전 상태로 돌아가야 할 때 사용한다.

  • 커밋 취소 (이력 삭제)
  • git reset --hard HEAD~1 # 마지막 커밋을 지우고 이전으로 완전히 복구
  • 커밋 취소 (새 커밋으로 반대 작업)
  • git revert <commit_id> # 기존 이력을 유지하면서 변경 사항만 되돌림
728x90
728x90
300x250

Spring Boot에서 아래처럼 생긴 에러 메시지 한 번쯤은 볼 수 있다.

 
 
Circular view path [index]: would dispatch back to the current handler URL [/index] again

겉으로 보면 템플릿이나 설정 문제 같지만, 대부분은 요청 URL이랑 뷰 이름을 똑같이 써서 생기는 경우다

 

 

스프링 MVC에서 @Controller 메서드가 문자열을 리턴하면, 그 값은 템플릿 파일 경로가 아니라 “뷰 이름(view name)”으로 처리된다.

 
@GetMapping("/welcome")
public String welcome(Model model) {
    model.addAttribute("message", "Hello");
    return "welcome"; // => templates/welcome.html
}

Spring Boot 기본 설정에서는 대략 이런 식으로 prefix / suffix가 잡혀 있다.

  • prefix: classpath:/templates/
  • suffix: .html

그래서 return "welcome"; 이면 src/main/resources/templates/welcome.html 을 찾게 된다.

문제는 URL이랑 뷰 이름을 이렇게 맞춰버렸을 때다.

 

 

@GetMapping("/index")
public String index() {
    return "index";
}
  • 요청 URL: /index
  • 뷰 이름: index

요청 경로와 뷰 이름이 그대로 겹치면, 내부에서 디스패치 과정이 꼬인다. 요청을 처리하고 다시 뷰를 찾아 넘기는 과정에서 같은 URL로 계속 포워딩하려고 하다 보니, 이걸 순환 경로로 판단해서 Circular view path 에러를 던진다.

에러 페이지를 커스터마이징하면서 /error 경로와 뷰 이름을 둘 다 error 로 맞춰버려도 비슷한 문제가 생긴다.

에러 핸들러와 에러 뷰가 서로를 계속 호출하는 느낌이 된다.

 

 

 

1) URL을 바꾸는 방법

가장 손이 덜 가는 방법은 URL을 바꾸는 거였다. 나는 홈 화면을 아예 루트(/)로 노출하도록 정리했다.

@Controller
public class HomeController {

    @GetMapping("/")
    public String home(Model model) {
        model.addAttribute("username", "jin");
        return "index"; // templates/index.html
    }
}
 
구성은 이렇다.
  • URL: /
  • 뷰 이름: index
  • 템플릿: src/main/resources/templates/index.html

이 조합이면 요청 경로와 뷰 이름이 직접 부딪치지 않기 때문에, Circular view path 에러가 나지 않는다.

 

 

 

2) 뷰 이름을 바꾸는 방법

반대로 /index 라는 URL을 유지하고 싶다면, 뷰 이름 쪽을 바꾸면 된다.

@Controller
public class HomeController {

    @GetMapping("/index")
    public String index(Model model) {
        model.addAttribute("username", "jin");
        return "home/index";
    }
}

템플릿 구조는 이렇게 맞췄다.

 
 
 

실제 프로젝트에서는 이런 식으로 디렉터리까지 포함해서 home/index, user/list 같이

뷰 이름을 조금 길게 가져가는 패턴이 더 많이 쓰인다.

URL 계층과 템플릿 폴더 구조를 어느 정도 맞추면서도, 경로와 뷰 이름을 완전히 1:1로 겹치게 만들지는 않는 편이다.

 

내가 삽질하면서 한 번쯤 같이 보게 됐던 포인트들도 정리해 보면.....

  • 컨트롤러 매핑 중복
    같은 URL(/index, /error 등)을 여러 컨트롤러나 메서드에서 매핑해두면, 실제로 어느 쪽이 호출되는지 헷갈리면서 디스패치가 꼬일 수 있다.
  • 뷰 리졸버/템플릿 경로 커스터마이징
    spring.thymeleaf.prefix, spring.thymeleaf.suffix 를 수정해뒀다면, 템플릿 경로가 그 설정에 맞게 옮겨졌는지 같이 봐야 한다. 템플릿을 못 찾고 에러 경로로 떨어졌다가 다시 순환에 빠지는 식으로 이어질 수 있다.
  • 에러 페이지 커스터마이징
    기본 Whitelabel 에러 페이지를 끄고 직접 /error 를 처리할 때, 컨트롤러 매핑과 뷰 이름을 둘 다 error 로 맞춰두면 아까 본 것처럼 순환 에러가 나기 쉽다. 에러 뷰를 error/default, error/404 이런 식으로 조금 더 구체적인 이름으로 나눠두는 게 안전했다.
  • 정적 리소스 경로와의 충돌
    정적 리소스 경로를 커스터마이징하면서 컨트롤러가 CSS/JS 요청을 가로채는 경우도 있다. 이때 그 요청을 처리하는 메서드가 또 템플릿 이름과 겹치는 값을 리턴하면 비슷한 종류의 문제가 생길 수 있다.

결국 이 에러를 보면 템플릿 파일부터 뒤지기보다는...

요청 URL이랑 뷰 이름이 그대로 겹치는 곳이 있는지 먼저 확인하는 게 훨씬 빠르게 해결되는 것 같다.

728x90
728x90
300x250

 
Cloudflare에서 도메인을 구매하는 방법에 대해 포스팅 해보겠다.
 
먼저 구매하고 싶은 도메인이 가능한지를 확인해봐야한다.
https://www.cloudflare.com/ko-kr/products/registrar/

Cloudflare Registrar | 도메인 등록 및 갱신

Cloudflare는 Cloudflare Registrar를 통해 간편한 원가 도메인 등록 및 갱신 서비스를 제공합니다. 추가 수수료 없이 도메인을 구매, 이전 및 관리하세요.

www.cloudflare.com

여기 Cloudflare Register 사이트에 들어가서 검색해보면 된다.
 

도메인 검색에다가 원하는 도메인을 풀네임으로 적어서 검색을 해보면..
나는 happy.com 이 있는지를 봤따.

역시나 있군..
그래서 대안으로 다른거를 추천해준다.. 해피걸스.net 뭐냐고요;;
 
 
 
아무튼.. 여기에서도 가능하고.. 아예 cloudflare에서 Domains 메뉴에서도 [Buy a domain]으로도 가능하다.
 

동일하게 Search..
 

내가 원하는 도메인이 가능하다!
Purchase로 구매하기 고고

1년단위로 도매인 구매가 가능하다.
cloudflare 도매인 구매 입력방법 작성방법은 아래와 같다. 
First name : 이름
Last name : 성 
적어주면된다.
 
참고로 아래 내용은 도메인구매 입력폼에 기입한 개인정보는 다 막아준다고 하니 참고하자.
Cloudflare Registrar redacts registrant personal information from its public WHOIS service; however, it cannot control whether the registry redacts personal information from its own WHOIS service. In some cases, the registry may display personal information in their WHOIS service.

전화번호, 국가 작성
Adress line 1 -> 번지수, 신주소
Adress line 2 -> 실제 동/호수
State -> 구
Postal code -> 우편번호

카드번호까지 입력을 하면 된다.
밑에 영수증 주소로 위에 적은 주소와동일하게 복사가 될건데 굳이 바꿀 필요는 없다.

Complete purchase를 통해서 결제까지 하면 완료!

짜잔 이렇게 구매완료 됐다는 페이지가 뜬다.
 
국내 도메인 호스팅 업체로 유명한 가비아보다 훨씬 더 싼거같다.
전반적으로 그냥 cloudflare가 제일 동일 도메인 단가가 낮은듯!
 
이상으로 cloudflare 도메인 구매 방법이 였다 안녕~
 
 

728x90
728x90
300x250

2026년에 새롭게 생기는 청년미래적금에 대해 정리해보겠다~~~
기존의 ‘청년도약계좌’가 5년이라는 긴 만기 때문에 부담스러웠던 분들이라면, 이번에 신설되는 3년 만기의 청년미래적금 소식에 주목해 주세요. 금융위원회와 관계 부처의 공식 보도자료를 기반으로 핵심 정보만 추려 정리해 드립니다.

1. 청년미래적금이란?

청년미래적금은 정부가 2026년 예산안을 통해 발표한 정책 금융상품으로, 청년들이 보다 현실적인 기간 내에 목돈을 마련할 수 있도록 설계되었습니다.

  • 핵심 목표: 짧은 기간(3년), 낮은 납입 부담, 실질적인 목돈 마련 지원
  • 출시 예정: 2026년 6월 중

2. 가입 대상 및 자격 조건 (공식 기준)

정부 발표에 따르면 아래 요건을 모두 충족하는 청년이 가입할 수 있습니다.

  • 연령: 가입일 기준 만 19세 ~ 34세 (병역 이행 기간 최대 6년 인정 시 만 40세까지 가능)
  • 개인소득: 총급여 6,000만 원 이하 (종합소득 4,800만 원 이하)
    • 소상공인: 연 매출 3억 원 이하인 경우 가입 가능
  • 가구소득: 가구원 소득 합계가 기준 중위소득 200% 이하

3. 상품 주요 내용 및 혜택

가장 궁금해하실 납입 조건과 정부 지원금 혜택입니다.
구분주요 내용

납입 기간3년 (36개월)
납입 한도월 최대 50만 원 (자유적립식)
정부 기여금일반형: 납입액의 6% / 우대형: 납입액의 12%
세제 혜택이자소득 비과세 추진 (전액 면제)

💡 우대형 대상자란? 중소기업에 신규 취업(입사 6개월 이내)하거나 저소득 구간에 해당하는 청년 등 특정 요건을 충족하는 경우 12%의 높은 기여금을 지원받습니다.

4. 예상 수령액 시뮬레이션

월 50만 원을 3년간 성실히 납입했을 때 받을 수 있는 금액(예시)입니다.

  • 일반형 (6% 지원): 원금 1,800만 원 + 기여금 108만 원 + 은행 이자 = 약 2,080만 원
  • 우대형 (12% 지원): 원금 1,800만 원 + 기여금 216만 원 + 은행 이자 = 약 2,200만 원
  • 기대 수익률: 정부 지원금과 비과세 혜택을 합산하면 연 10%~16% 수준의 적금에 가입하는 효과와 유사합니다.

5. 청년도약계좌 vs 청년미래적금 비교

기존 상품과 무엇이 달라졌는지 확인해 보세요.
비교 항목청년도약계좌 (기존)청년미래적금 (신규)

만기 기간5년3년 (축소)
월 납입 한도최대 70만 원최대 50만 원
정부 지원율3% ~ 6%6% ~ 12% (확대)
신규 가입2025년 말 종료 예정2026년 6월 개시 예정

6. 자주 묻는 질문 (FAQ)

  • Q: 기존 청년도약계좌 가입자도 갈아탈 수 있나요?
    A: 네, 금융위원회는 기존 청년도약계좌 가입자가 청년미래적금으로 전환(갈아타기)할 수 있는 방안을 마련하겠다고 공식 발표했습니다.
  • Q: 자영업자도 가능한가요?
    A: 네, 연 매출 3억 원 이하인 소상공인 청년도 가입 대상에 포함되었습니다.

마무리하며 2026년부터는 만기가 짧아진 만큼 청년들의 중도 해지율은 낮아지고, 자산 형성의 효능감은 더 높아질 것으로 기대됩니다. 정부의 최종 확정 공고가 나오면 다시 한번 상세한 신청 방법을 공유해 드리겠습니다!
출처: 금융위원회 보도자료 및 2026년 정부 예산안 상세 내역

728x90
728x90
300x250

 
데이터아키텍처 준전문가(DAsP) 합격 수기를 작성해보려고 한다.
워낙 정보가 너무 없는 자격증이라 내 후기가 도움이 되기를 바란다.
#DAsP후기 #DAsP합격후기
 
 
 

1. DAsP 시험 정보

DAsP 데이터아키텍처 준전문가라는 자격증으로 민간자격증이고 데이터 아키텍처의 전반적인 능력을 검증하는 시험이다. 
DAP는 전문가로 실기까지 포함된 시험 (난이도 굉장히 헬이라고 함;)
 
준전문가는 총 90분 시험시간동안 50문항을 푼다.

DAsP의 과목은 총 4개로 (전사아키텍처 이해, 데이터 요건 분석, 데이터 표준화, 데이터 모델링) 각 문항당 문항수가 상이하다. 배점은 같음!
 
DAsP 합격 기준은 총점 60점 이상이여야 하고,과목별로 40%미만 취득시에는 과락이 된다.

 
 
자격증 정보와 시험 기준에 대한 정보는 아래 공홈을 참고하면 더 정확하다!
 
https://www.dataq.or.kr/www/sub/a_02.do#none

데이터자격검정 - 데이터자격시험, DAP, DAsP, SQLP, SQLD, ADP, ADsP.

데이터자격시험, DAP, DAsP, SQLP, SQLD, ADP, ADsP.

www.dataq.or.kr

 
 
 

2. 합격 인증 및 공부 방법

나는 2025년에 58회차에 응시를 했다. 
가벼운 마음으로 공부를 시작했으나 문제때문에 고통을 꽤나 받아서 1트만 해보고 안되면 포기할 생각이였는데,
고맙게도 본 시험에서 문제가 술술 잘 풀렸고 기대이상의 높은 점수를 받아서 행복하게 책을 버릴 수 있게 되었다(?)
 
 
공부 방법은 그냥 정말 이론+실전문제 풀기 뿐이였다.
DAsP는 정말로 마이너한 자격증이여서 별로 시중에 나와있는 문제집 책도 없고 알려진 문제들도 없다.
이게 어떻게보면 참 막막할수도 있는데.. 오히려 책이 없으니 봐야할 책도 적고 명확해서 좋았다. (생각의 전환)

 
* 데이터 아키텍처 전문가 가이드 / 데이터아키텍처 자격검정 실전문제
 
나는 위의 2가지 책으로 공부했다. 하나는 이론이 담긴 두꺼운 책이고 하나는 실전문제집이다.
이 자격증에 대해 알아보신 분들은 알겠지만 책이 이거밖에 없다.
K data에서 공식적으로 나온 책이고, 놀랍게도 문제집은 2013년 버전이 가장 최신버전이다. (13년이나 흘렀네....)
 
최대한 공부기간은 짧고 굵게 가져가고 싶어서 2달로 잡았다.
직장병행+주말약속으로 순수 공부는 평일 저녁에만 진행했고
시험치기 1주 전만 주말에도 계속 문제를 풀고 또 풀면서 기억을 유지시켰다.
 
 
우선 데이터아키텍처 전문가 가이드 책을 통해서 지루하지만 독서한다는 생각으로 그냥 1회독을 전체 다 훑었다.
관련 업을 하는 사람이라면 익숙한 내용들이라서 어렵지는 않을 것이다.
다만 나는 1과목의 전사 아키텍처 이해 부분이 정말 어려웠다. 너무 이론적이고 단순 암기해야하는 용어가 너무 많아서 고역이였다.
그래서 1과목 보는게 너무 오래걸렸고 나머지는 이미 실무에서도 쓰고 있기에 술술 익혀졌다.
 
그 다음 과목별로 세부 내용별 중요도에 따라 특정 챕터만 더 유심하게 보았다.
데이터아키텍처 자격검정 실전문제 책에보면 중요도를 알려준다. 맨 앞장에 자격검정 안내를 보면 된다.
* 전사아키텍처 개요 > 전사아키텍처 정의 : 중요도 상
* 전사아키텍처 개요 > 전사아키텍처 프레임워크 : 중요도 중
* 정보 요구 사항 개요 > 정보 요구 사항 관리 : 중요도 중
...
이런식으로 표로 정리되어있는게 있다. 그래서 거기에서 중요도 상 으로 표시된 챕터를 좀 더 꼼꼼하게 봤다. 
 
마지막으로는 그냥 전문가 가이드와 데이터 자격검정 실전문제에 있는 문제를 풀고 또 풀었다.
특히 실전문제를 풀고 오답노트가 중요하다. 답안지에 있는 해설을 보면서 왜 안되는지 왜 틀렸는지를 이해하고 넘어갈 것! (밑에 꿀팁 참고)
 
 
 
그리고.. 시험을 보고나서는 아래 네이버 카페에서
같은 회차의 시험을 본 사람들과 문제를 복기하면서 가채점을 해봤다.
진짜 헷갈리는 문제들이 넘 많아서 가채점 하면서 약간 슬펐다가 그냥 운명에 맡기기로 했던 기억이 난다..
 
https://cafe.naver.com/sqlpd

데이터 전문가 포럼 (빅데이터분석기사... : 네이버 카페

빅데이터분석기사, ADP, ADsP, SQLP, SQLD, DAP, DAsP, BIS 자격증 취득 등 데이터 전문가 커뮤니티입니다.

cafe.naver.com

 
 
 아! 참고로 DAsP 책을 검색 하면 아래와 같은 책도 나오는데, (데이터아키텍처 준전문가 한 권으로 끝내기)
나는 별도로 보진 않았는데, 친구가 사서 본걸 보니까 이거는 정말 공부 1차적으로 다 끝낸사람이
이전 개념 복기하면서 외우는 용으로 사용할때 괜찮아 보이긴했다.
별도로 요약정리를 안했다면 시험장에 들고가는 용으로 괜찮을듯! 딱 모의고사에 나온 핵심 내용들을 짜깁기해서 만든 책이다.
But, 기본 지식이 없으면 진짜 뭔내용인지 모를정도로 자세한 설명은 없으니.. 이거만으로 끝내기에는 어려울듯

 

3. 꿀팁

 
개인적으로 DAsP시험은.. 한마디로 말장난을 잘하는 시험이라고 생각 된다.
 
예를들어 수박이라는 과일에 대해 설명한 것 중 맞는것은? 이라는 지문이 있고
선택지에 (1) 수박은 과일이고 겉은 노란색이다. 라고 있을때, 앞에 수박은 과일이고~라는 말만 대충 읽고 답으로 선택 하면 틀린다. 
하나의 선택지에 항상 옳은것과 틀린것을 적절히 섞어서 놓기때문에 단어 하나하나 꼼꼼히 봐야지 오답을 줄일 수 있다.
 
또, '틀린 것을 모두 고르시오' 라고 하면 보통은 2개를 고르게 되는데 실제 정답의 갯수가 2개가 아닌 3개인 경우도 있다.
기본적인 시험에 대한 고정관념도 깨지는 경우가 많았다. 고통스러웠음,,,,ㅠ ㅋㅋㅋ
 
 
그리고 가장 중요한 것은..
이 시험은 문제와 답을 달달 외워서 되는 시험이 아니고
정말로 개념에 대해서 이해를 했는가에 대해 초점이 맞춰진 것 같다.
왜냐면.. 기출문제처럼 지문과 선택지가 토시하나 안틀리고 동일하게 나오지 않고 비슷한 용어를 쓰면서 나온다.
그래서 책에서 없었던 용어가 나오기도하고 (?) 실전문제 답안지의 해설에 있는 문장이 나오기도 한다.
외워야겠다! 라기 보단 이해해야겠다! 라는 마음으로 접근하면 취득하는게 훨씬 수월 할 것 같다.
 
아무튼 DAsP공부하고 계신 분들 모두들 합격하시기를 !!!!!!!!!!!!!!!!!

728x90
728x90
300x250

 
A 클래스에서 B 클래스의 정보를 사용해야 할때, (DB로는 외래키 개념) JPA에서는 어떻게 설정하는지에 대해 적어보겠다.

 

1. 단방향 예제

@Entity
public class Restaurant {

    @Id
    @GeneratedValue
    private Long id;

    @ManyToOne
    @JoinColumn(name = "recommendation_history_id")
    private RecommendationHistory recommendationHistory;
}

식당을 추천하는 이력이 담는 로직이 있다고 치자. 그럼 이 소스의 의미는..
여러 Restaurant는 하나의 RecommendationHistory에 속한다.
외래키는 Restaurant 테이블에 생성된다.
 
 
 

2. 양방향 예제

하나의 추천이력 id 에는 여러개의 식당들이 나온다고 가정할 때, java 소스는 아래와 같다.
 
(1) Resturant 클래스

@ManyToOne
@JoinColumn(name = "recommendation_history_id")
private RecommendationHistory recommendationHistory;

어노테이션까지 의미를 종합해보면..
“Restaurant 테이블에 recommendation_history_id 컬럼이 있고
이 컬럼은 RecommendationHistory의 PK를 참조한다. (= 저쪽 PK를 우리쪽 FK로 사용한다) (@JoinColumn) ”
 
(2) RecommendationHistory 클래스

@OneToMany(mappedBy = "recommendationHistory",
           cascade = CascadeType.ALL,
           orphanRemoval = true)
@Builder.Default
private List<Restaurant> restaurants = new ArrayList<>();

이 소스를 해석해보면..
“RecommendationHistory 하나가 여러 개의 Restaurant를 가진다.
그리고 이 관계의 *주인은 Restaurant 쪽이다. (mappedBy) "
 
* 주인 = DB에서 FK 컬럼을 가진 엔티티  (객체의 주인, 부모/자식 개념이 아님!!)

 

3. 관계 방향별 어노테이션

1 : 1@OneToOne
1 : N@OneToMany
N : 1@ManyToOne
N : M@ManyToMany

 
 

728x90
728x90

+ Recent posts