Group Anagrams — 정렬 키와 문자 개수 키로 애너그램 묶기
애너그램 문자열을 같은 그룹으로 묶는 LeetCode 49번, 정렬된 문자열을 키로 쓰는 풀이부터 문자 개수 배열을 해시 키로 바꾸는 `O(n * k)` 풀이까지 정리합니다.
1차 캐시, 변경 감지, flush — JPA 동작의 모든 기반
최신: JPA `merge` vs `persist` 완전 정복 — `detached` 엔티티를 어떻게 다뤄야 하나요?
ACID, 격리 수준, @Transactional 전파까지 한 흐름으로
최신: Spring `@Transactional` 완전 정복 — 전파 속성과 롤백 규칙은 어떻게 동작하나요?
격리 수준, MVCC, 락까지 — 읽기/쓰기 충돌을 다루는 원리
최신: 2단계 로킹 규약 완전 정복 — 2PL, Strict 2PL, 직렬 가능성까지
실행 계획, 인덱스, 배치 조회 — 느린 쿼리를 구조로 푸는 법
최신: 관리자 예약 목록 API `Broken pipe` 해결기 — 루프 안 N+1과 공유 DTO 반복 생성
루프 안의 개별 쿼리 · Fetch 전략 · @BatchSize 해결 도구
최신: 관리자 예약 목록 API `Broken pipe` 해결기 — 루프 안 N+1과 공유 DTO 반복 생성
OSI 계층부터 HTTP/3, TLS 핸드셰이크까지 차근차근
최신: DNS 완전 정복 — 재귀 질의, `TTL`, `A`/`AAAA`/`CNAME`, 권한 DNS까지
애너그램 문자열을 같은 그룹으로 묶는 LeetCode 49번, 정렬된 문자열을 키로 쓰는 풀이부터 문자 개수 배열을 해시 키로 바꾸는 `O(n * k)` 풀이까지 정리합니다.
문단에서 금지어를 제외하고 가장 많이 등장한 단어를 찾는 LeetCode 819번, 문장 부호 제거와 소문자 정규화, 해시 카운팅 풀이를 정리합니다.
문자 로그와 숫자 로그를 재정렬하는 LeetCode 937번, 로그를 identifier와 content로 나누고 문자 로그만 content, identifier 순으로 정렬하는 풀이를 정리합니다.
문자열이 유효한 팰린드롬인지 판정하는 LeetCode 125번, 정제 후 뒤집기 풀이부터 원본 문자열을 직접 훑는 투 포인터 `O(n)`/`O(1)` 풀이까지 정리합니다.
1부터 n까지의 숫자 중 배열에 나타나지 않은 값을 찾는 LeetCode 448번, 완전 탐색부터 존재 배열, 음수 제자리 마킹 풀이까지 정리합니다.
정수 배열에서 세 번째로 큰 서로 다른 값을 찾는 LeetCode 414번, 정렬 풀이부터 세 변수로 상위 3개를 한 번에 추적하는 `O(n)` 풀이까지 정리합니다.
학생 키 배열을 정렬했을 때의 기대 순서와 현재 순서를 비교해 다른 인덱스 개수를 세는 LeetCode 1051번, 정렬 비교 풀이부터 카운팅 정렬 풀이까지 정리합니다.
배열에서 짝수를 앞쪽으로, 홀수를 뒤쪽으로 배치하는 LeetCode 905번, 보조 배열 풀이부터 제자리 투 포인터 partition 풀이까지 정리합니다.
각 원소를 자기 오른쪽에 있는 값 중 최댓값으로 바꾸고 마지막 원소는 `-1`로 만드는 LeetCode 1299번, 완전 탐색부터 오른쪽에서 왼쪽으로 갱신하는 `O(n)`/`O(1)` 풀이까지 정리합니다.
배열이 엄격하게 증가한 뒤 엄격하게 감소하는 산 모양인지 확인하는 LeetCode 941번, 꼭대기 기준 검증부터 한 번 순회 풀이까지 정리합니다.
배열 안에 어떤 값 `n`과 `2 * n`이 서로 다른 위치에 존재하는지 확인하는 LeetCode 1346번, 완전 탐색부터 `HashSet`을 이용한 한 번 순회 풀이까지 정리합니다.
정렬된 배열에서 중복을 제자리 제거하고 고유 원소 개수 `k`를 반환하는 LeetCode 26번, 보조 배열 풀이부터 쓰기 포인터로 앞쪽 고유 값 구간을 만드는 `O(n)`/`O(1)` 풀이까지 정리합니다.
배열에서 특정 값을 제자리 제거하고 남은 길이를 반환하는 LeetCode 27번, 별도 배열 방식부터 앞쪽 유효 구간을 유지하는 `O(n)`/`O(1)` 풀이, 뒤쪽 스왑 변형까지 정리합니다.
정렬된 두 배열을 `nums1` 안에서 병합하는 LeetCode 88번, 별도 배열 풀이부터 뒤에서부터 채우는 제자리 `O(m + n)` 풀이까지 정리합니다.
고정 길이 배열에서 `0`을 복제하며 나머지를 오른쪽으로 미는 LeetCode 1089번, 별도 배열 `O(n)` 풀이부터 오른쪽에서부터 덮어쓰는 제자리 `O(n)`/`O(1)` 풀이까지 정리합니다.
정렬된 배열의 각 원소를 제곱한 뒤 다시 정렬된 배열로 만드는 LeetCode 977번, 제곱 후 정렬 `O(n log n)` 풀이부터 양끝 절댓값을 비교하는 투 포인터 `O(n)` 풀이까지 정리합니다.
배열에서 자릿수가 짝수인 수가 몇 개인지 구하는 LeetCode 1295번, 문자열 길이 풀이부터 나눗셈으로 자릿수 세기, 범위 비교 `O(n)` 풀이까지 정리합니다.
이진 배열에서 가장 긴 연속된 1의 길이를 구하는 LeetCode 485번, 구간을 매번 다시 세는 `O(n²)` 풀이부터 현재 길이와 최댓값만 유지하는 `O(n)` 풀이까지 정리합니다.
`magazine`의 문자들로 `ransomNote`를 만들 수 있는지 판정하는 LeetCode 383번, 느린 문자 제거 방식부터 해시맵 카운팅, 길이 26 배열 `O(n)` 풀이까지 정리합니다.
단일 연결 리스트의 중간 노드를 반환하는 LeetCode 876번, 배열에 노드를 모으는 풀이부터 길이를 세는 두 번 순회, slow/fast 포인터 `O(n)`/`O(1)` 풀이까지 정리합니다.
고객별 계좌 잔액 행렬에서 가장 큰 자산 합을 구하는 LeetCode 1672번, 행별 합 배열을 만드는 풀이부터 최댓값만 유지하는 `O(mn)`/`O(1)` 풀이까지 정리합니다.
배열의 각 위치까지의 합을 구하는 LeetCode 1480번, 매번 다시 더하는 `O(n²)` 풀이부터 누적 변수 `O(n)`, 입력 배열을 직접 바꾸는 `O(1)` 공간 풀이까지 정리합니다.
로마 숫자 문자열을 정수로 바꾸는 LeetCode 13번, 감산 조합을 직접 처리하는 풀이부터 왼쪽→오른쪽 lookahead, 오른쪽→왼쪽 스캔 `O(n)` 풀이까지 정리합니다.
정수가 앞에서 읽어도 뒤에서 읽어도 같은지 판정하는 LeetCode 9번, 문자열 변환 풀이부터 전체 숫자 뒤집기, 오버플로우 걱정을 줄이는 절반 뒤집기 `O(log x)` 풀이까지 정리합니다.
합이 `k`가 되는 두 수를 한 번씩만 써서 최대 몇 쌍을 만들 수 있는지 구하는 LeetCode 1679번, `O(n²)` 브루트포스부터 정렬 + 투 포인터 `O(n log n)`, 해시 카운팅 `O(n)`까지 정리합니다.
관리자용 예약 목록 API가 Broken pipe를 뱉던 원인을 추적해 루프 안 N+1 · 공유 Venue DTO 반복 생성 · 무제한 조회 세 가지를 구조로 풀고, DB 쿼리를 2,500회에서 5회로 줄인 과정을 정리합니다.
persist와 merge가 실제로 하는 일, Spring Data JPA의 save가 왜 둘을 섞어 쓰는지, detached 엔티티를 save로 저장할 때 생기는 구조적 위험, 그리고 find + modify 패턴이 왜 권장되는지를 정리합니다.
두 수직선이 만들 수 있는 최대 물의 양을 구하는 LeetCode 11번, `O(n²)` 브루트포스부터 왜 더 낮은 쪽 포인터만 움직이면 되는지까지 투 포인터 `O(n)` 풀이를 정리합니다.
문자열 `s`가 `t`의 부분 수열인지 판정하는 LeetCode 392번, `indexOf` 기반 순차 탐색부터 투 포인터 `O(|s| + |t|)`, 그리고 다중 질의를 위한 전처리 + 이진 탐색까지 정리합니다.
JPA에서 대량 INSERT/UPDATE가 느린 진짜 원인은 네트워크 왕복입니다. JDBC 배치, hibernate.jdbc.batch_size, order_inserts, MySQL의 rewriteBatchedStatements, 그리고 IDENTITY 전략이 배치를 막는 이유와 해결책을 정리합니다.
배열의 `0`을 뒤로 밀면서 나머지 순서를 유지하는 LeetCode 283번, 별도 배열 방식과 쓰기 포인터 스왑 방식을 비교하며 정리합니다.
연속된 같은 문자를 '문자 + 개수'로 압축하는 LeetCode 443번, 별도 버퍼 방식과 읽기/쓰기 포인터로 제자리 압축하는 방식을 비교하며 정리합니다.
자기 자신을 제외한 나머지 원소의 곱을 나눗셈 없이 구하는 LeetCode 238번, 브루트포스 `O(n²)`부터 접두사·접미사 곱 배열, 그리고 변수 하나로 `O(n)`/`O(1)`까지 정리합니다.
문자열에서 모음만 골라 순서를 뒤집는 LeetCode 345번, 별도 리스트 방식과 투 포인터 스왑 방식을 비교하며 정리합니다.
인접한 화단에 꽃을 동시에 심을 수 없을 때 `n`송이 배치가 가능한지 판단하는 LeetCode 605번, 그리디 선택이 왜 최적인지와 배열 수정 없이 `O(n)`/`O(1)`로 푸는 방법을 정리합니다.
Big-O 표기법이 무엇인지, 대표적인 시간 복잡도가 각각 어떤 코드 패턴에서 나타나는지, 공간 복잡도는 어떻게 세는지 단계별로 정리합니다.
두 문자열의 최대 공약 문자열을 구하는 LeetCode 1071번, 브루트포스부터 GCD 기반 O(n + m) 풀이까지 정리합니다.
flush가 언제 일어나는지, FlushMode별 동작 차이, OSIV가 커넥션을 언제까지 붙들고 있는지, 그리고 실무에서 open-in-view를 끄면 벌어지는 일들을 Hibernate/Spring Boot 레퍼런스 기준으로 정리합니다.
Spring AOP가 프록시 기반으로 동작한다는 사실이 @Transactional, @Async, @Cacheable이 같은 클래스 내부 호출에서 무력화되는 원인입니다. JDK 동적 프록시와 CGLIB의 차이, self-invocation이 프록시를 우회하는 이유, 네 가지 해결책을 정리합니다.
Spring의 @Transactional이 제공하는 7가지 전파 속성, 기본 롤백 규칙, readOnly와 timeout 힌트, 그리고 실무에서 자주 오해되는 REQUIRES_NEW와 NESTED의 동작을 Spring 레퍼런스 기준으로 정리합니다.
두 문자열을 교대로 합치는 LeetCode 1768번, 공통 구간 분리 방식과 단일 루프 방식을 비교하며 정리합니다.
삼중 반복 `O(n^3)`부터, `leftMin`/`rightMax` 두 배열을 쓰는 `O(n)`/`O(n)`, 그리고 변수 두 개로 `O(n)`/`O(1)`에 푸는 그리디까지, `first`/`second` 불변식을 기준으로 정리합니다.
JPA에서 N+1을 줄이는 세 가지 도구인 fetch join, @EntityGraph, @BatchSize는 해결하는 축이 각각 다릅니다. 단일 연관과 컬렉션, 페이징 여부, 재사용성 관점에서 상황별 선택 기준을 정리합니다.
미독 채팅 개수를 구하는 단순한 API가 커넥션 풀을 고갈시키던 원인을 추적해, `SELECT *` + 앱 레벨 `count`와 `@Convert(KmsStringConverter)` 조합이 만든 KMS Decrypt 호출 폭주를 드러내고, 단일 `COUNT(*)` 집계 쿼리로 전환해 해결한 과정을 정리합니다.
연관 관계 기본 Fetch 전략, 프록시로 구현되는 LAZY 동작, EAGER에서도 N+1이 생기는 이유, 컬렉션과의 조합에서 발생하는 카르테시안 폭발까지 JPA Fetch 전략의 내부 동작을 정리합니다.
JPA가 개발자를 대신해 엔티티 상태를 관리하고 SQL을 뒤늦게 내보내는 구조인 영속성 컨텍스트의 동작 원리를 엔티티 상태, 1차 캐시, 변경 감지, flush 시점 중심으로 정리합니다.
파티셔닝으로도 해결되지 않는 규모에서 DB를 여러 노드로 나누는 샤딩 전략과 그로 인해 새로 생기는 운영 문제를 공식 문서/표준 레퍼런스 기준으로 정리합니다.
수직 분할과 수평 분할의 차이, MySQL 8.4가 지원하는 RANGE/LIST/HASH/KEY 파티셔닝의 쓰임과 제약을 공식 문서 기준으로 정리합니다.
반정규화가 무엇인지, 어떤 읽기 병목을 줄이기 위해 쓰는지, 그리고 정합성·갱신 비용을 어떻게 감수해야 하는지 공식 문서 기준으로 정리합니다.
ACID 네 가지 속성이 각각 무엇을 보장하고 무엇은 보장하지 않는지, MySQL InnoDB 기준 구현 포인트와 함께 정리합니다.
SOLID 다섯 원칙을 암기식 정의가 아니라 변경 비용 관점에서 풀고, Java 예제와 JDK 사례로 어디에 적용할지 정리합니다.
비트 연산자가 무엇인지, `&`, `|`, `^`, `~`, `<<`, `>>`, `>>>`가 각각 어떻게 동작하는지, 2의 보수와 비트 마스크까지 한 번에 정리합니다.
2PL의 Growing phase와 Shrinking phase, Strict 2PL과 Conservative 2PL의 차이, 그리고 MySQL InnoDB를 2PL로만 보면 안 되는 이유를 정리합니다.
DNS가 무엇인지, 도메인 이름이 어떻게 IP 주소로 바뀌는지, 재귀 질의와 반복 질의, Root/TLD/권한 DNS, `TTL`, 주요 레코드 타입까지 실무 기준으로 정리합니다.
브라우저에서 `https://` 주소를 입력하면 어떤 일이 일어나는지, `DNS`, `TCP handshake`, `TLS 1.3 handshake`, 인증서 검증, `ALPN`, 실제 HTTP 요청 흐름까지 실무 기준으로 정리합니다.
TCP `4-way handshaking`이 무엇인지, 왜 연결 종료에 `FIN`과 `ACK`가 네 번 오가는지, `half-close`, `TIME_WAIT`, `CLOSE_WAIT`, `RST`와의 차이까지 실무 기준으로 정리합니다.
TCP와 UDP가 무엇이 다른지, 왜 하나는 연결형이고 다른 하나는 비연결형인지, 신뢰성, 순서 보장, 혼잡 제어, 메시지 경계, `QUIC` 관점에서 실무 기준으로 정리합니다.
IPv4와 IPv6가 무엇이 다른지, 왜 주소 체계가 바뀌었는지, `NAT`, 헤더 구조, `ARP`와 `NDP`, 단편화와 주소 설정 관점에서 실무 기준으로 정리합니다.
HTTP/1.1, HTTP/2, HTTP/3가 무엇이 다른지, 왜 같은 API라도 체감 성능이 달라지는지, `keep-alive`와 `multiplexing`, `QUIC`와 `HOL blocking` 관점에서 실무 기준으로 정리합니다.
OSI 7계층과 TCP/IP 4계층이 무엇이 다른지, 브라우저 요청 하나가 각 계층을 어떻게 통과하는지, 실무에서 계층별로 장애를 어떻게 나눠 보는지 정리합니다.
`Dirty Read`가 왜 실무에서 거의 안 보이는지, `Phantom Read`가 왜 MySQL InnoDB에서는 다른 문제처럼 관찰되는지 실제 발생 조건 중심으로 정리합니다.
`REPEATABLE READ`에서 일반 `SELECT`를 최신값처럼 믿었다가, 한 주문에 환불 이력이 두 번 쌓인 장애를 재현과 수정안으로 정리합니다.
HTTP 메서드의 멱등성과 `idempotency key` 기반 API 멱등성을 구분하고, 중복 결제·중복 주문을 저장과 재시도 관점에서 어떻게 제어할지 정리합니다.
DB 행 락, MySQL `GET_LOCK()`, Redis 분산 락이 각각 어떤 범위를 보호하는지 비교하고, 조건부 `UPDATE`나 `UNIQUE` 제약이 더 나은 경우까지 정리합니다.
낙관적 락과 비관적 락을 충돌률, 재시도 비용, 트랜잭션 길이 관점에서 비교하고, 조건부 `UPDATE`나 `UNIQUE` 제약이 더 나은 경우까지 정리합니다.
OFFSET/LIMIT 페이지네이션이 왜 뒤로 갈수록 느려지는지, 커서 기반 조회는 어떤 조건에서 유리한지, 정렬과 인덱스를 어떻게 설계해야 하는지 실무 기준으로 정리합니다.
핫 키와 동시 만료 때문에 캐시 miss가 폭주할 때, TTL 지터, single flight, stale-while-revalidate, 선갱신을 어떤 기준으로 선택할지 정리합니다.
캐시가 왜 필요한지, 어떤 데이터를 캐시해야 하는지, Cache Aside와 쓰기 전략, TTL과 무효화를 어떻게 판단해야 하는지 실무 기준으로 정리합니다.
N+1 쿼리가 무엇인지, 왜 성능을 망가뜨리는지, JPA와 서비스 레이어에서 어떻게 발생하는지, 그리고 어떤 방식으로 해결해야 하는지 정리합니다.
채팅 목록 전용 요약 API가 이름만 가벼웠던 이유를 추적하고, 응답 필드 최적화와 배치 조회로 DB 쿼리를 약 80% 줄인 과정을 정리합니다.
SELECT ... FOR UPDATE가 정확히 무엇을 잠그는지, 어떤 상황에서 필요하고 어떤 상황에서는 과한지, 인덱스와 트랜잭션 범위까지 실무 기준으로 정리합니다.
DB 커넥션 풀이 왜 필요한지, max pool size를 어떻게 봐야 하는지, 풀 고갈이 왜 발생하는지, HikariCP 핵심 옵션과 실무 점검 포인트를 정리합니다.
EXPLAIN 출력의 각 컬럼이 무엇을 뜻하는지, 옵티마이저가 왜 그 계획을 골랐는지, 조인과 서브쿼리는 어떻게 읽는지 예제와 함께 정리합니다.
인덱스가 있는데도 풀 스캔이 나오는 이유를 함수 가공, 암묵적 형변환, 복합 인덱스 순서, 선택도 관점에서 정리합니다.
MVCC가 왜 필요한지, Undo 로그와 스냅샷 읽기가 어떻게 동작하는지 정리합니다.
데이터베이스 락의 종류와 동작 원리, 낙관적·비관적 락 전략, 데드락 원인과 대처법을 예제와 함께 정리합니다.
트랜잭션 격리 수준이 왜 필요한지, 각 레벨에서 어떤 이상 현상이 발생하는지 예제와 함께 정리합니다.
인덱스가 왜 빠른지, 복합 인덱스 컬럼 순서가 왜 중요한지, EXPLAIN은 어떻게 읽는지 예제와 함께 정리합니다.
정규화가 왜 필요한지, 각 단계가 어떤 이상 현상을 해결하는지 예제 테이블과 함께 정리합니다.
`Service` 계층에 침투한 Protobuf, 상품 목록 N+1, 매 요청마다 DB 조회, 공백 검색 불일치를 해결한 과정을 정리합니다.
`innerJoin`으로 인한 누락, 불필요한 Redis 캐싱, 중복 모델 문제를 쿼리 최적화와 레이어 정리로 해결한 과정을 공유합니다.
리뷰 목록 40번 쿼리, 해시태그 N+1, 캐시 적중률 0%에 가까운 등급 뱃지 — 세 가지 성능 문제를 해결한 과정을 공유합니다.
LinkedHashMap 역직렬화 문제와 START_OBJECT vs START_ARRAY 에러를 Jackson DefaultTyping 관점에서 정리합니다.