클래스 관계 3가지: 참조, 합성, 조합 정리
·
카테고리 없음
1. 참조 관계 (Association)"서로 알고는 있지만, 각자 독립적으로 존재"class Student( val id: Long, val name: String)class Course( val id: Long, val title: String, val students: List // 학생을 "참조")학생은 수업 없이도 존재할 수 있음수업은 학생 없이도 존재할 수 있음수업이 폐강돼도 학생은 사라지지 않음 다이어그램 표현┌─────────────┐ ┌─────────────┐│ Student │ │ Course │├─────────────┤ ├─────────────┤│ - id │ 실제 예시상품 ↔ 재고class Product( ..
루퍼스 부트캠프 2기 수료 후기
·
외부활동/루퍼스 2기
서론루프팩 백엔드 L2 코스가 1월 3일 부로 마무리되었습니다.10주간 주말 휴식마저 반납하며 온 에너지를 쏟았습니다. 퇴근 후 녹초가 된 몸을 이끌고 멘토링을 듣고, 새벽까지 과제와 씨름한 날도 많았습니다. 쉽지 않았지만, 지금 돌이켜보면 개발자로서 한 단계 도약한 10주였습니다.커리어, 이직, 성장에 대한 고민을 안고 계신 분이라면 루퍼스에서 그 답을 찾을 수 있다고 자신 있게 말씀드립니다.루퍼스를 신청한 계기신청 전 일주일은 고민했습니다. "2년 전에 부트캠프 들었는데, 또?"솔직히 당시에는 이직 성공 직후라 긴장이 풀렸습니다. 부트캠프 과정을 대충 따라갔고, 끝나고 나서 복습도 안 했습니다. 결과는? 배운 내용이 전부 휘발됐습니다. 돈과 시간만 날린 셈이었죠. 그렇게 1년이 흘렀습니다. 돌이켜보니..
Semaphore 사용 시 InterruptedException을왜 복구해야 하는가 — 그리고 스레드 인터럽트는 왜 발생하는가
·
카테고리 없음
개요대량 푸시 발송 로직을 구현하면서 Semaphore를 이용해 동시 HTTP 요청 수를 제한했다.이 과정에서 InterruptedException을 처리하며 다음과 같은 코드를 적용했다.catch (InterruptedException e) { Thread.currentThread().interrupt() throw e}처음 보면 단순한 예외 처리처럼 보이지만,이 코드는 자바의 스레드 인터럽트 모델을 정확히 이해했을 때만 의미가 드러난다. 이 글에서는 다음 질문에 답한다.스레드 인터럽트는 왜 발생하는가?InterruptedException은 왜 특별한가?왜 인터럽트 플래그를 복구해야 하는가?이 처리가 왜 실무에서 중요한가?1. 스레드 인터럽트는 왜 존재하는가스레드 인터럽트는 에러도 아니고, ..
Kotlin + JPA: DTO Projection에서 "Cannot instantiate query result type" 에러 해결하기
·
카테고리 없음
문제 상황우리 프로젝트는 Spring Boot + Kotlin + JPA 환경에서 Kotlin JDSL을 사용해 타입 세이프한 쿼리를 작성하고 있었다. 새로운 요구사항으로 회원 조회 시 createdAt 필드를 추가해야 했고, 단순히 DTO에 필드를 추가했다. data class MemberQueryDto( val id: String, val name: String, val email: String, val isActive: Boolean, val isEmailVerified: Boolean, val createdAt: Long, // 새로 추가한 필드 )Entity에도 필드가 있고, JDSL 쿼리에서도 select 절에 추가했다. 완벽해 보였다..
[루퍼스/루프백 2기] 코더에서 엔지니어로: 이커머스로 돌아본 10주간의 성장 기록
·
외부활동/루퍼스 2기
개요TDD에서 시작해 설계, 도메인 모델링, 동시성 이슈, 조회 성능, 장애 내성, 이벤트 분리, 메시지 큐까지.10주 동안 백엔드 개발 전반을 관통하는 흐름을 경험했다. 이 글을 쓰는 지금, 루프백 첫 수업을 들었던 나와 비교해보면 분명히 성장했다고 말할 수 있다. 단순히 코드를 잘 작성하는 사람이 아니라, 문제를 구조적으로 바라보고 선택의 이유를 설명할 수 있는 엔지니어로 나아가기 위한 출발점이 된 시간이었다. 전체 여정 요약1~2주차: 기본기 다지기1주차에는 TDD와 테스트 코드의 역할을 배웠다.테스트 코드를 작성하는 것 자체는 어렵지 않지만, 좋은 테스트를 작성하는 일은 전혀 다른 문제라는 점을 체감했다. 좋은 테스트는 두 가지 기준을 만족해야 한다.코드가 변경되었을 때, 의미 있는 실패를 하는 ..
[Loop:PAK] 10주차 WIL
·
외부활동/루퍼스 2기
🧠 이번 주에 새로 배운 것배치 프로그램을 작성할때 Spring Batch를 쓰는 이유를 잘 몰랐습니다. 공부하면서 batch가 다양한 기능들을 추상화 하였습니다. 중간 실패시 해당 부분부터 재시작, 특정 에러 발생시 스킵, 재시도, 배치 실행 정보를 보관하는 메타 데이터 등 Spring Batch를 사용하면 batch 작업을 편리하게 할수있는 장점을 여실히 깨달았습니다.Spring batch의 chunk 방식화 tasklet 방식을 혼합해서 사용할 수 있는 점을 새로 알게 되었습니다. batch를 chunk 방식으로 돌리기 전후 데이터 검증, 외부 메신저 발송은 tasklet으로 작성하는게 적절함을 알았습니다. 💭 이런 고민이 있었어요chunk 방식의 writer에서 oom 발생 이슈가 있었습니다...
[Loop:PAK] 9주차 WIL
·
외부활동/루퍼스 2기
🧠 이번 주에 새로 배운 것대용량 트래픽 환경일 경우 랭킹 집계와 계산을 분리해서 반영하는 테크닉을 알게 되었습니다. 초 실시간은 보장되지 않지만, 쓰기 부하를 완화하기 위한 결과임을 알았습니다.텀블링 윈도우, 슬라이딩 윈도우 개념을 알게되었고, 슬라디이 윈도우 기법으로 랭킹을 구현하는 방법을 알게 되었습니다. 콜드 스타트가 없는 장점이 있지만 구현이 복잡한 단점이 있습니다. 💭 이런 고민이 있었어요조회, 주문, 좋아요 이벤트의 랭킹 집계시 랭킹 일자를 어떤 시간으로 반영해야할지 고민이였습니다. 멘토님이 선호한 시간은 client가 보내준 시간 이였습니다.score가 동일할 경우 일관된 정렬을 보장하기 위해 tie-breaker를 적용하였습니다. productId 저장시 고정된 자리수를 0으로 채워(..
[루퍼스/루프백 2기] 이커머스 실시간 랭킹 구현기 - Redis ZSET부터 윈도우 설계 관점에서 콜드 스타트 해결까지
·
외부활동/루퍼스 2기
TL;DRRedis ZSET으로 일간 실시간 랭킹을 구현조회/좋아요/주문 이벤트를 가중치로 합산해 점수를 누적윈도우 교체 시 생기는 콜드 스타트는 캐리오버 또는 “전날 10% + 오늘 90%” 가중합으로 완화텀블링 윈도우는 쉽고 명확하지만 콜드 스타트가 생기며, 슬라이딩 윈도우는 자연스럽지만 구현 난이도가 높음.들어가며이커머스에서 랭킹은 “유저가 어떤 상품을 발견하느냐”를 바꾸는 중요한 영역입니다.문제는 실시간성과 성능을 동시에 만족시키기 어렵다는 점이다. DB의 ORDER BY만으로는 높은 트래픽을 감당하기 어렵고, 윈도우가 바뀌는 순간 랭킹이 비는 콜드 스타트 문제도 생깁니다.이번 미션에서는 Redis ZSET을 기반으로 1일 단위 실시간 랭킹을 구현하고, 이벤트 가중치 합산과 콜드 스타트 완화 방식..
[Loop:PAK] 8주차 WIL
·
외부활동/루퍼스 2기
🧠 이번 주에 새로 배운 것카프카의 정의를 새롭게 배웠습니다. 단순 고성능 메시지 큐가 아닌 분산 로그 저장소 이며, 로그가 쌓이는 거대한 시스템에 가깝습니다.카프카 컴포넌트 구성 요소를 학습하였습니다. 컨슈머 그룹과 파티션의 관계, 리밸런싱, 카프카 렉 등 새로운 용어들을 알게 되었습니다. 이론적 학습 단계라 아직은 와닿지 않지만, 꾸준히 학습해가며 내것으로 체화시켜야 겠습니다.카프카의 핵심은 메시지를 잃지 않고 단 한번만 처리되게 보장하는 것입니다. producer는 최소 1번의 메시지 발행을, consumer는 정확히 한번만 처리하는 책임을 가지고 있습니다.실무에서 카프카 도입이 트래픽과는 크게 연관이 없다는 것입니다. 중요한건 기능 동작과 팀원의 숙련도 입니다. '장시간 실행되는 복잡한 작업',..
[루퍼스/루프백 2기] Kafka At-Least-Once 전송과 Consumer 멱등성 구현기
·
외부활동/루퍼스 2기
TL;DRProducer의 At-least-once 전송과 Consumer의 Exactly-Once 처리를 보장하기 위한 방법을 제시합니다.멱등성 보장을 위한 이벤트 핸들링 테이블과 이벤트 로그를 저장하는 감사 로그 테이블을 분리한 이유를 설명 합니다.카프카를 어떤 배경과 요구사항에서 사용하는 것이 적절한지 살펴봅니다.0. 들어가며지난주에는 Spring의 ApplicationEvent를 활용해서 이벤트 구조를 설계하였습니다. 이번주에 새로운 요구사항이 생겼습니다. 카프카 기반 이벤트 파이프라인을 구현하세요. 이 글에서는 실제 주문 시스템에 Kafka를 도입하면서 겪은 시행착오를 공유합니다. At-Least-Once 전송에서 발생하는 중복 메시지 문제를 어떻게 해결했는지, 그리고 왜 테이블을 분리해야 했는..