성장일기

내가 보려고 정리하는 공부기록

전체 글 215

[Spring/테스트] N+1을 테스트 코드로 막아본다면 - 쿼리 카운트 테스트 도입기

N+1은 보통 사후에 발견된다. 더미데이터를 잔뜩 넣고 API 테스트를 하는 도중에 너무 느려서 발견한다던가, 코드리뷰로 발견한다던가 보통 그런식으로 발견해왔다. 물론! 처음부터 N+1이 발생하지 않도록 구현하는게 가장 좋겠지만, 놓칠때도 종종 있다. 요즘은 AI로 코드를 짜는 일이 훨씬 많기 때문에, 더더욱 놓칠때가 많았다. 한 번 fetch join으로 고치고 나서도, 누군가가 연관 엔티티를 lazy하게 건드리는 코드를 추가하면 또다시 N+1이 발생한다. 이런 문제를 겪다보니 문득 테스트코드로 만들면 CI를 돌릴 때 잡을 수 있지 않을까? 하는 생각을 하게 되었다. 로직을 짤 때 쿼리가 몇 번 나가는지를 안다면 수를 비교해서 N+1 발생을 인지할 수 있다. 쿼리가 나가는 수는 Hibernate에서 ..

백엔드/스프링 2026.06.18

[JPA] @OneToOne LAZY의 함정 - N+1 해결하기

작년에 시작한 프로젝트를 최근 리팩토링 하기 시작했다. 지금도 감자지만 더더욱 감자일 때 작성한 코드다 보니, 리팩토링 할 부분이 많았고 오늘은 찜 관련 기능의 리팩토링을 진행했다. 우리 프로젝트에선 모임과 운동을 찜할 수 있었고, 각각의 찜 목록 조회에서 N+1 문제가 있어서 이를 해결하는 게 목적이었다. 문제의 발견N+1을 해결하기 위해 주로 fetch join을 사용해왔고, 찜과 관련한 눈에 보이는 연관 객체들을 fetch join으로 한 번에 가져오도록 수정했다. 그러고 쿼리 카운트 테스트를 돌렸는데 실패했다. N+1문제가 해결되지 않았다는 뜻이었다.북마크 찜 목록 N+1 회귀 테스트 > 찜한 운동 목록 - 찜 개수와 무관하게 고정된 쿼리 수만 실행한다 FAILED북마크 찜 목록 N+1 회귀 테..

백엔드/JPA 2026.06.17

[DB] 쿼리 튜닝은 무엇인가 (3) - 복합 인덱스에서 순서가 중요한 이유

지난 게시글에서는 B-tree와 B+tree가 어떤 원리인지를 배웠고, 키를 정렬된 순서로 보관한다는 것도 배웠다. https://wanna-developer02.tistory.com/219 [DB] 쿼리 튜닝은 무엇인가 (2) - 인덱스 (B-tree와 B+tree)지난 게시글에서는 쿼리 튜닝이 무엇인지에 대해 다루었고, 이번 게시글에서는 인덱스에 대해 이어서 정리하려고 한다. 지난 게시글은 아래 링크를 참고하면 된다.https://wanna-developer02.tistory.com/2wanna-developer02.tistory.com 이번 게시글에서는 칼럼 여러개를 묶어 하나의 인덱스로 만들면 어떻게 될지 알아보려 한다. 목차는 다음과 같다.복합 인덱스란칼럼 순서를 정하는 방법 1. 복합 인덱스란..

카테고리 없음 2026.06.08

[DB] 쿼리 튜닝은 무엇인가 (2) - 인덱스 (B-tree와 B+tree)

지난 게시글에서는 쿼리 튜닝이 무엇인지에 대해 다루었고, 이번 게시글에서는 인덱스에 대해 이어서 정리하려고 한다. 지난 게시글은 아래 링크를 참고하면 된다.https://wanna-developer02.tistory.com/218 [DB] 쿼리 튜닝은 무엇인가 (1) - 랜덤 I/O와 쿼리 튜닝프로젝트를 진행하면서 조회 성능을 올리기 위해 인덱스를 건 적이 있다. 어떨 때는 성능이 개선되지만, 어떨 때는 오히려 성능이 안 좋아지기도 한다. "인덱스를 많이 걸면 성능이 저하된다" 라wanna-developer02.tistory.com 인덱스는 점프를 통해 데이터의 위치를 찾아내는데 그 원리는 무엇인지에 대해 정리해볼 예정이다. 목차는 다음과 같다.정렬배열과 이진 탐색의 한계B-tree 와 B+tree 클러..

데이터베이스 2026.06.08

[DB] 쿼리 튜닝은 무엇인가 (1) - 랜덤 I/O와 쿼리 튜닝

프로젝트를 진행하면서 조회 성능을 올리기 위해 인덱스를 건 적이 있다. 어떨 때는 성능이 개선되지만, 어떨 때는 오히려 성능이 안 좋아지기도 한다. "인덱스를 많이 걸면 성능이 저하된다" 라는 이야기를 많이 들어봤는데, 그 이유가 무엇인지 정리해보려고 한다. 목차는 아래와 같다.순차 I/O vs 랜덤 I/O쿼리 튜닝이란 무엇인가인덱스가 성능을 저하시키는 경우에 대하여 1. 순차 I/O vs 랜덤 I/O결론적으로 조회 성능은 "몇 행을 읽었는가" 보다는 "디스크에 점프를 몇 번 했는가"로 결정된다. 디스크는 데이터를 물리적으로 연속된 블록 단위로 저장하는데, 데이터를 읽기 위해서는 그 위치로 이동해야한다. 이때 나오는 개념이 순차 I/O와 랜덤 I/O이다. 순차 I/O물리적으로 인접한 블록을 연속해서 ..

데이터베이스 2026.06.07

[시큐리티] 세션과 JWT의 비교와 보안 취약점 알아보기

회원가입과 로그인을 구현하는 과정에서 인증 처리를 하는 방식에는 크게 세션방식과 토큰방식(JWT)이 있다. 대부분 프로젝트에서는 JWT를 사용하는 것을 많이 봤고, 나 또한 JWT를 사용했었다. 문득 JWT가 더 선호되는 이유가 궁금해져 세션과 토큰방식의 차이점을 정리해보려고 한다. HTTP는 기본적으로 무상태(stateless) 프로토콜이기 때문에, 서버는 방금 요청을 보낸 사람을 기억하지 못한다. 로그인이라는 기능은 본질적으로 이 사용자가 누구인지 계속 기억하고 있어야 성립하기 때문에, 상태를 유지해야 한다. 상태를 유지하는 방식 중 하나가 세션과 JWT 방식이다. ✅ 세션과 JWT 비교세션 방식 세션방식은 서버에서 사용자의 상태를 저장해두고, 클라이언트에게는 그 정보를 가리키는 무의미한 식별자만 ..

[백준] 11729: 하노이 탑 이동 순서 (재귀를 푸는 사고 흐름 고치기) - JAVA

백트래킹을 공부해볼까 하다가 재귀를 먼저 학습했다. 정말 유명한 문제이지만, 재귀를 공부하면서 풀어보았다. 이번 게시글은 하노이 자체보다는 재귀를 공부한 내용에 초점을 맞춰볼까 한다. 원래 나는 재귀를 풀 때, 코드 흐름을 계속 따라들어가면서 풀었다. 그래서 복잡한 문제를 만나면 풀기 힘들고 이해가 전혀 되지 않았다. 이걸 견뎌내면서 모두가 풀고 있는 줄 알았는데 공부를 하면서 귀납적 풀이라는 걸 알게 되었다. 수학을 공부할 때 나오는 귀납법과 같다고 생각하면 된다. 귀납법1. BaseCase에서 명제가 참2. N일 때 명제가 참이라고 가정3. 위 가정을 이용해 N+1일때도 명제가 참임을 증명 즉, 절차지향적으로 코드를 따라들어가는 게 아니라, 가능하다는 걸 전제하고 문제풀이를 진행하는 방식인 것이다...

[Spring] DB와 JPA Persistence Context 불일치 해결하기 - trouble shooting

뚱땅뚱땅 개발을 하고있던 어느 날,, 투표가 존재하는 공지사항 삭제가 안 된다는 연락을 받았다. 로그를 열심히 뒤져서 에러로그를 발견했다. 에러 로그를 바탕으로 조금 찾아본 결과, DB와 Persistence Context 불일치로 인한 오류가 발생한 것이었다. JPA를 공부하다보면 영속성 컨텍스트, Persistence Context라는 단어를 많이 접하게 되는데, 이번 기회에 개념을 정리해보고자 한다. 영속성 컨텍스트 (Persistence Context) 먼저 영속성이란, 데이터나 객체가 프로그램 종료 후에도 사라지지 않고 지속되는 특성을 의미한다. 그렇다면 영속성 컨텍스트는 JPA가 엔티티를 관리하는 저장소로 appication과 데이터베이스 사이에 있는 메모리 속 1차 캐시라고 이해하면 된다..

백엔드/JPA 2026.03.21

[SQL] MySQL에서 재귀 구현하기 (프로그래머스 - 멸종위기의 대장균 찾기)

나는 SQL 기본 문법밖에 모르는 사람이다. 코딩테스트 공부를 하던 중, 재귀로 풀어야 하는 문제를 만났는데 아무리 생각해도 이전의 값을 가져와야 하기 떄문에 내가 아는 방식으로는 풀어낼 수 없었다. 그래서 찾아보았는데, SQL문법에도 재귀가 있었다. 그래서 이거를 정리해보고자 한다. 재귀를 이용해야 했던 문제는 아래 링크로 달아두었다.https://school.programmers.co.kr/learn/courses/30/lessons/301651 프로그래머스SW개발자를 위한 평가, 교육의 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr 간단한 문제설명문제를 간단히 설명하자면, 균이 번식을 하고 균의 부모id가 주어진다. 결론적으로는 자식이 없는 균의..

코딩테스트/SQL 2026.03.14

[Spring] AOP + SpEL을 활용한 Resource 기반 접근 제어 구현하기

방학동안 진행한 프로젝트에서 권한과 관련된 부분을 맡게 되었다. 그동안 프로젝트를 하면서 권한에 대해 깊게 고민해본 적이 없었는데, 이번 기회를 통해 다양한 경험을 해볼 수 있었다. 그 중에서 권한 로직을 구현하면서 사용한 SpEL과 AOP에 대해 정리해보려고 한다. 목차는 다음과 같다.SpELSpEL이란?SpEL을 사용하는 이유와 이점AOPAOP란?AOP를 사용하는 이유와 이점프로젝트에서의 사용기1. SpEL (Spring Expression Language)SpEL이란,SpEL은 Spring 프레임워크에서 제공하는 표현식 언어로, Spring 컨테이너와 런타임객체를 대상으로 값을 evaluate 할 수 있는 표현식 언어이다. 더보기SpEL로 값을 평가하는 방법SpEL은 Spring 컨테이너(Bean)..

백엔드/스프링 2026.02.13