[Contact]
[Career]
現) 채널코퍼레이션 - Lv 4. Backend Engineer
前) 차이코퍼레이션(포트원) - Backend Engineer
[Education]
現) F-Lab 백엔드 멘토
現) JSCODE 백엔드 멘토
前) 우아한테크코스 5기 백엔드 리뷰어 & 3기 백엔드 수료생
講義
受講レビュー
- チャネルトークの面接官が直接教えるCS面接対策 - データベース編
- チャネルトークの面接官が直接教えるCS面接対策 - データベース編
- チャネルトークの面接官が直接教えるCS面接対策 - Java編
- チャネルトークの面接官が直接教えるCS面接対策 - データベース編
- チャネルトークの面接官が直接教えるCS面接対策 - ネットワーク&ウェブ編
投稿
Q&A
Boolean 컬럼 인덱스와 Cardinality에 따른 실행 계획에 대하여
안녕하세요, 소준영님!좋은 질문입니다. 말씀하신 이해가 맞습니다.강의에서는 카디널리티를 인덱스 효율을 판단하는 대표적인 기준으로 설명했지만, 실제 실행 계획은 값의 분포와 선택도, 예상 조회 행 수, Covering Index 여부, MRR 적용 여부 등을 함께 고려해 결정됩니다.Boolean 컬럼도 데이터가 한쪽으로 치우쳐 있다면, 소수 값을 조회할 때는 인덱스가 효율적일 수 있습니다. 예를 들어 true가 전체의 0.1%라면 WHERE flag = true에는 인덱스가 유리할 수 있지만, 나머지 99.9%를 조회하는 WHERE flag = false에는 Full Table Scan이 더 유리할 수 있습니다.또한 같은 선택도라도 조회 대상 행이 PK 순서상 가까운 범위에 모여 있는지, 테이블 전체에 흩어져 있는지에 따라 실제 페이지 접근 비용이 달라질 수 있습니다. 이런 의미에서 Secondary Index 컬럼과 Clustered Index 순서 사이의 correlation도 성능에 영향을 줄 수 있습니다.정리하면 카디널리티는 절대적인 기준이라기보다 중요한 판단 요소 중 하나이며, 최종적으로는 실제 데이터 분포와 EXPLAIN ANALYZE 결과를 함께 확인하는 것이 가장 정확합니다.다만, 강의에서는 이를 모두 다루기에 과하다고 생각하여 가장 일반적인 판단 기준인 카디널리티를 대표적으로 설명하였습니다!
- いいね数
- 1
- コメント数
- 1
- 閲覧数
- 52
Q&A
파이프라이닝
안녕하세요, Cola님!말씀하신대로, HTTP/1.1의 파이프라이닝은 하나의 TCP 연결에서 이전 요청의 응답을 기다리지 않고 여러 HTTP 요청을 연달아 보낼 수 있게 한 기능입니다.다만 여기서 중요한 점은, 요청은 연달아 보낼 수 있지만 응답은 요청 순서대로 처리되어야 한다는 것입니다.예를 들어 클라이언트가 A, B, C 요청을 연달아 보냈는데 A 요청의 응답이 오래 걸리면, B와 C 응답이 준비되어 있더라도 A 응답보다 먼저 클라이언트에게 전달될 수 없습니다. 그래서 앞 요청 하나가 뒤 요청들의 응답을 막는 Head-of-Line Blocking 문제가 남아 있었습니다.즉, 파이프라이닝은 “요청을 보내는 쪽의 대기 시간”은 줄였지만, “응답을 받는 쪽의 순서 대기 문제”까지 해결하지는 못했습니다. 그래서 실무에서는 HTTP/1.1 파이프라이닝이 널리 쓰이지 않았고, 이후 HTTP/2에서는 멀티플렉싱으로 한 연결 안에서 여러 요청과 응답을 더 독립적으로 처리할 수 있게 개선되었습니다!
- いいね数
- 1
- コメント数
- 1
- 閲覧数
- 58
Q&A
질문있습니다.
안녕하세요, 조성우님!큰 그림은 맞게 이해하셨어요. 다만 한 가지 디테일을 추가로 알아 주셔야 합니다. 기본 분류는 말씀하신 그대로입니다.읽기만 수행 (가시성만 보장하면 충분): volatile읽기 + 쓰기 (원자성도 필요): synchronized 또는 Atomic 다만 알아두시면 좋은 점은, synchronized는 원자성뿐 아니라 가시성 문제도 함께 해결한다는 점이에요. 자바 메모리 모델(JMM)이 락 획득/해제 시점에 다음을 보장하기 때문입니다. 락 획득 (synchronized 진입): CPU 캐시를 무효화하고 메인 메모리에서 최신 값을 다시 읽어옴락 해제 (synchronized 종료): 변경된 값을 메인 메모리로 flush 즉 synchronized 블록에 진입하거나 빠져나갈 때마다 메모리 배리어가 동작해서 가시성이 자연스럽게 보장됩니다. Atomic 클래스들도 내부적으로 volatile 변수와 CAS 연산을 사용하기 때문에 마찬가지로 가시성을 함께 보장하고요. 정리하면 이렇습니다.가시성만 필요할 때 → volatile (가장 가볍고 성능 좋음)원자성도 필요할 때 → synchronized 또는 Atomic (둘 다 가시성도 자동 해결)
- いいね数
- 1
- コメント数
- 2
- 閲覧数
- 78
Q&A
팬텀리드 해결 예시 질문
안녕하세요, Cola님!정확히 짚어주셨습니다. 좋은 지적 감사합니다. 말씀하신 대로 SELECT ... FOR UPDATE WHERE id = 5에서 id가 PK이고 해당 row가 존재한다면, InnoDB는 갭락 없이 레코드 락만 걸립니다. MySQL 공식 매뉴얼(17.7.3 Locks Set by Different SQL Statements in InnoDB)에도 명시되어 있는 동작이에요. "For a unique index with a unique search condition, InnoDB locks only the index record found, not the gap before it." 실제로 performance_schema.data_locks 테이블에서 확인하시면 X, REC_NOT_GAP(record lock only)으로 찍히는 케이스에 해당합니다. 전체 락 동작을 정리하면 다음과 같습니다. InnoDB 락 동작 정리 (REPEATABLE READ 기준)Unique Index + 정확한 값 + row 존재 => Record lock만 (갭락 X)Unique Index + 정확한 값 + row 없음 => Gap lockNon-Unique Index => Next-key lock (Record + Gap)범위 조건 (BETWEEN, >, Next-key lock (Record + Gap) InnoDB가 팬텀 리드를 막기 위해 기본적으로 next-key lock을 사용하는 큰 그림은 그대로 맞지만, 질문하신 케이스(Unique Index 단일 매치)는 유일성 보장 자체가 팬텀을 원천 차단하기 때문에 InnoDB가 최적화로 레코드 락만 거는 예외 케이스에 해당해요. 자료의 예시(WHERE id = 5)는 next-key lock이 실제로 걸리는 케이스(범위 조건 또는 Non-Unique Index)로 교체하고, 위의 락 동작 정리 표를 보강 자료로 추가해두겠습니다. 디테일까지 정확하게 짚어주신 덕분에 자료가 한 단계 더 정밀해질 것 같아요. 정말 감사합니다! 참고 링크MySQL 공식 매뉴얼 17.7.3 — 표의 모든 케이스가 명시되어 있습니다https://dev.mysql.com/doc/refman/8.0/en/innodb-locks-set.html당근 테크 블로그 — MySQL Gap Lock 다시보기 — Real MySQL 8.0 공저자(백은빈)가 작성한 한국어 설명, 그림과 예시가 풍부합니다https://medium.com/daangn/mysql-gap-lock-다시보기-7f47ea3f68bc
- いいね数
- 1
- コメント数
- 1
- 閲覧数
- 78
Q&A
MySql
안녕하세요, Cola님!좋은 질문이에요. 정확히는 MySQL(InnoDB)이 사용하는 인덱스 구조는 B+Tree가 맞습니다. 다만 강의에서 B-Tree를 다룬 건 면접 빈출 패턴을 고려한 선택이에요. 면접에서는 보통 "인덱스 자료구조를 설명해주세요" 또는 "B-Tree를 설명해주세요"라는 식의 질문이 훨씬 자주 나오고, B+Tree는 그 위에 얹어지는 변형 구조라 B-Tree를 먼저 정확히 이해하시면 B+Tree는 자연스럽게 따라옵니다. B+Tree는 B-Tree에서 다음 두 가지가 추가/변경된 형태로 보시면 됩니다.데이터는 leaf node에만 저장 (internal node는 key만 가짐)Leaf node끼리 연결 리스트로 이어져 범위 검색에 유리 균형 트리 특성, 분할/병합 동작, 탐색 시간 복잡도 같은 핵심 메커니즘은 B-Tree와 동일합니다. 그래서 면접에서 "MySQL의 인덱스는 어떻게 동작하나요?" 같은 질문이 들어오면, B-Tree 설명을 베이스로 깔고 → "InnoDB는 이 위에서 B+Tree로 변형해 leaf node에만 데이터를 저장하고, leaf끼리 연결 리스트로 묶어 범위 검색을 빠르게 만들었다" 정도로 풀면 깊이 있는 답변이 됩니다. 즉 B-Tree는 베이스, B+Tree는 그 위의 특화 구조로 이해해주시면 강의에서 B-Tree를 다룬 의도가 자연스럽게 이어집니다.
- いいね数
- 1
- コメント数
- 2
- 閲覧数
- 73
Q&A
멀티스레드
안녕하세요, Cola님! 람다와 스트림이 멀티스레드 환경에 안전하다는 건 "순수 함수로 사용한다는 전제 아래" 안전하다는 의미예요.스트림 API는 각 연산이 stateless하고 부수효과를 일으키지 않는다는 것을 전제로 설계되어 있습니다. 이 전제만 지키면 parallelStream()으로 병렬 처리해도 race condition 없이 안전하게 동작합니다. Java 공식 문서에서도 스트림 연산은 stateless해야 한다고 명시되어 있고요. 말씀하신 대로 람다 내부에서 외부 변수를 수정하거나 공유 상태에 부수효과를 일으키면 당연히 안전하지 않습니다. 다만 이 경우는 스트림이 안전하지 않은 게 아니라, 함수형 프로그래밍의 설계 원칙을 사용자가 깬 것이라고 보시는 게 맞아요. 자료에서 "안전하다"고 한 건 의도된 사용 방식, 즉 순수 함수로 작성하는 경우를 전제한 표현입니다. 면접에서는 "스트림은 stateless한 순수 함수로 작성하는 것을 전제로 설계되어 있어서, 이 약속만 지키면 parallelStream()에서도 안전하게 동작합니다. 부수효과가 있는 람다를 쓰면 그건 함수형 원칙을 깬 것이지 스트림의 한계는 아닙니다" 정도로 답변하시면 됩니다.
- いいね数
- 1
- コメント数
- 2
- 閲覧数
- 72
Q&A
성능 오버헤드
안녕하세요, Cola님!사실 일반적인 시스템에서 instanceof로 인해 성능 상의 큰 문제가 되는 건 많지는 않습니다.정확히는 상속의 깊이가 깊어지고, 해당 상속으로 이어지는 클래스가 많을 경우 이들을 순회하면서 타입을 찾는데요! 이러한 수십 ~ 수백 개 이상의 클래스가 상속 구조로 연결된 형태가 많은 거대한 애플리케이션이라면 문제가 생길 여지가 있습니다. 물론 이보다는 다형성을 깨뜨리는 점이 더 메인 문제점이지만, 성능 오버헤드도 알아두면 좋겠어서 자료로 포함하게 되었습니다.
- いいね数
- 1
- コメント数
- 2
- 閲覧数
- 74
Q&A
volatile에 대해 질문 있습니다.
안녕하세요, Cola님!꽤 좋은 질문을 해주셨네요 ㅎㅎ 두 설명은 사실 모순되는 게 아니라 서로 다른 측면을 다루고 있습니다.우리 자료의 설명: 가시성 문제가 왜 발생하는지 => 코어별 캐시 구조가 근본 원인다른 자료의 설명: volatile이 어떻게 해결하는지 => happens-before와 메모리 배리어 우리 자료에서 설명하는 "코어별 캐시로 인한 가시성 문제"는 자바 메모리 모델 학습의 표준 출발점이고, 멀티 코어 환경에서 각 CPU 코어가 독립적인 캐시를 갖기 때문에 가시성 문제가 발생한다는 점은 정확한 설명입니다. Cola 님이 보신 다른 자료는 volatile이 이 문제를 어떻게 해결하느냐를 다루는 부분이에요. Java 5(JSR-133) 이후 volatile은 happens-before 관계 형성과 메모리 배리어 삽입으로 동작하며, 이 메모리 배리어가 실행될 때 결국 CPU 캐시 일관성을 강제 동기화하는 효과를 냅니다. 두 설명은 같은 현상의 원인과 해결 메커니즘을 각각 다루는 것이라, 충돌이 아닌 상호 보완 관계입니다.면접에서 만약 둘을 묶어서 답변하시고 싶다면, 아래 형태를 고려해보시면 됩니다! "멀티 코어 환경에서 각 코어가 독립적인 캐시를 갖기 때문에 가시성 문제가 발생합니다. volatile은 happens-before 관계와 메모리 배리어를 통해 이 캐시 간 동기화를 강제하여, 다른 스레드가 최신 값을 읽을 수 있게 보장합니다."
- いいね数
- 2
- コメント数
- 2
- 閲覧数
- 105
Q&A
GC 알고리즘
안녕하세요, Cola님!Mark and Sweep을 핵심 키워드로 가져가시는 건 충분히 괜찮습니다. Mark는 모든 GC 알고리즘의 공통 출발점이라, 어느 컬렉터를 쓰더라도 "GC Root에서 시작해 reachable 객체를 마킹한다"는 점은 동일하기 때문이에요. 다만 면접 답변을 더 풍성하게 가져가시려면, Mark and Sweep 외에 함께 알아두시면 좋은 알고리즘 두 가지가 있습니다.Mark and Compact: 마킹 후 살아남은 객체를 한쪽으로 모아 정리 → Mark and Sweep의 단편화 문제를 해결, Old Generation에서 사용Copying: 살아남은 객체를 다른 영역으로 복사 → Young Generation의 Eden ↔ Survivor 사이 이동에 사용 전체 구조로 정리하면 이렇습니다.[GC의 큰 틀] └ Mark and Sweep (마킹 → 정리) [영역별 정리 방식] ├ Young Generation : Copying └ Old Generation : Mark and Sweep / Mark and Compact 면접에서 "GC 동작 원리"가 메인 질문으로 나오면 Mark and Sweep을 출발점으로 답변하시고, 후속 질문이 들어올 때 위 두 알고리즘으로 확장하시면 됩니다!
- いいね数
- 1
- コメント数
- 2
- 閲覧数
- 75
Q&A
Mark and Sweep
안녕하세요, Cola님!자료의 "Mark and Sweep" 표현은 마킹을 통해 비활성 객체를 정리한다는 GC 동작의 큰 흐름을 통칭하는 의미로 사용한 것입니다. Mark는 모든 GC 알고리즘의 공통 1단계라, GC의 핵심 원리로 함께 언급되는 경우가 많습니다. 더 엄밀한 알고리즘 분류로는 영역별로 나뉩니다.Young Generation (Eden ↔ Survivor): Copying 방식 (말씀해 주신 내용)Old Generation: Mark and Sweep / Mark and Compact
- いいね数
- 1
- コメント数
- 1
- 閲覧数
- 74




