전체 글 100

선착순 재고, 왜 오버셀이 발생할까 — 동시성 문제 재현하기 (1편)

선착순 재고, 왜 오버셀이 발생할까 — 동시성 문제 재현하기 (1편)한정 수량 상품을 여러 사람이 동시에 구매하는 선착순 상황. 재고를 정확히 관리하지 못하면 재고보다 많이 팔리는 오버셀(oversell) 이 발생한다. 티켓팅에서 "서버 오류로 초과 예매" 같은 사고가 바로 이것이다.이 시리즈에서는 선착순 재고 차감의 오버셀 문제를 실제로 재현하고, 여러 동시성 제어 전략으로 해결하며 각각의 동작과 트레이드오프를 수치로 비교한다.1편 (이 글): 문제 정의 + No Lock으로 오버셀 재현2편: 비관적 락3편: 낙관적 락4편: 분산 락 (Redis)환경: Java 21, Spring Boot, PostgreSQL 16, Redis 7 (Docker)조건: 재고 100개, 동시 100건 구매(각 1개). ..

카테고리 없음 2026.09.02

[CS] Java의 원시 타입(Primitive Type)과 참조 타입(Reference Type)

Java – 원시 타입과 참조 타입, 메모리 관리Java에서 가장 기본적인 개념인 원시 타입과 참조 타입, 메모리 관리 방식에 대해 정리해보았다.1. 원시 타입(Primitive Type)Java에서 제공하는 가장 기본적인 데이터 타입이다.종류: byte, short, int, long, float, double, char, boolean값 자체를 저장한다.메모리에서는 스택(Stack)에 저장된다.스택 이해:스택은 “책상 위에 직접 올려놓은 값”과 같다. 바로 보고 쓸 수 있고, 변수 범위를 벗어나면 값도 사라진다.int a = 10; // a 변수에 값 10 저장int b = a; // b에 a 값을 복사a와 b는 서로 독립적이다.a를 바꿔도 b에는 영향이 없다.2. 참조 타입(Reference Ty..

JPA 프록시와 JOIN 과 JOIN FETCH 차이

JPA를 공부하다 보면 꼭 마주치는 개념이 있다. 바로 프록시(Proxy) 와 지연 로딩(Lazy Loading), 그리고 JOIN과 JOIN FETCH의 차이이다.이 개념들을 비유와 실제 코드로 정리해봤다.✅ 프록시(Proxy)란 무엇인가?JPA에서는 엔티티를 바로 불러오지 않고, 프록시 객체를 먼저 생성해두고, 실제 데이터가 필요할 때 DB에서 값을 가져오는 방식으로 지연 로딩을 구현한다.💡 비유하자면?넷플릭스에서 영화를 클릭하면 바로 재생되는 것이 아니라 썸네일만 먼저 보여주고,진짜 영화는 네트워크 연결이 될 때 로드되는 구조와 유사하다.💡 실제 코드 예시@OneToMany(mappedBy = "countryEntity", fetch = FetchType.LAZY)private List city..

[Spring] BaseTimeEntity와 사용되는 어노테이션의 기능

프로젝트를 위해 등록일과 수정일 데이터를 넣어주기 위해 BaseTime 클래스를 생성했다.각 요소들의 특징을 자세히 알아보았다!  코드는 다음과 같이 작성했다😊 @Getter@MappedSuperclass@EntityListeners(AuditingEntityListener.class)public abstract class BaseTimeEntity { @Column(updatable = false, nullable = false) @CreatedDate private LocalDateTime createdAt; // 등록일 @Column @LastModifiedDate private LocalDateTime modifiedAt; // 수정일}  사용한 어노테이션의 역할..

[git] GitHub에 올린 파일 삭제하기 with 히스토리

항상 깃헙에 파일을 잘못 올려서 깃헙 레파지토리를 삭제하고 다시 생성하고 올렸었다.물론 위의 경우는 일단 이미 완성된 프로젝트를 올려두는데 목적이 있는 경우였다. 하지만 매번 이런 식으로 프로젝트를 올릴 순 없었다. git이 생소해서 야매로 어영부영 넘겼지만 이젠 익숙해져야 할 필요가 있다.  👀문제 상황완성된 프로젝트를 gitHub에 올려두었다. 하지만 중요한 정보가 있는 application.properies 혹은 yml 파일이 그대로 push가 되는 바람에 삭제를 하고 싶은데, gitHub 삭제를 하게 되면 history가 남게 된다. 그렇담 노출되지 않길 원하는 정보들이 그대로 '나 삭제되었어요~'하고 알리는 꼴이다. 그렇기 때문에 파일과 history 모두 삭제될 수 있도록 해보자..! 🤓해..

개발 공부 2024.11.15

[Java]Enum과 final상수

ErrorCode를 관리하기 위해 Enum을 사용하는 방법은 가독성과 유지보수성을 높이는 좋은 방법이다.그래서 예외처리 구현을 위해 ErrorCode를 작성하는 중 fianl 상수가 먼저 선언되면 에러가 발생하는 것을 볼 수 있었다. 그래서 enum과 final 상수의 역할과 기능에 대해 찾아보게 되었다. 👀문제 상황다음과 같이 ErrorCode를 작성했다. @Getter@RequiredArgsConstructorpublic enum ErrorCode { ALREADY_REGISTERED_USER(HttpStatus.BAD_REQUEST, "이미 가입된 회원입니다."), NOT_FOUND_ACCOUNT(HttpStatus.BAD_REQUEST, "찾을 수 없는 계정입니다."); priv..

[git] origin/main refusing to merge unrelated histories 에러 발생

IntelliJ에서 git을 연동하여 pull 작업을 하는 도중 에러 창이 뜨면서 Pull failed되었다.  정확히는 아래와 같은 에러가 발생 하였다. * branch main -> FETCH_HEAD = [up to date] main -> origin/main refusing to merge unrelated histories 현재 로컬 브랜치와 깃허브 원격 브랜치 간에 서로 관련이 없는 커밋 히스토리가 있어서 Pull refusing이 되었다.   * branch main -> FETCH_HEAD = [up to date] main -> origin/mainfatal: refusing to merge unrelated histories 콘솔창을 ..

개발 공부 2024.11.15

99클럽 코테 스터디 14일차 TIL - 스택/큐

문제백준 10845 [큐]문제 링크:  https://www.acmicpc.net/problem/10845 해결 방법LinkedList로 큐를 생성 각 입력 값에 일치하는 연산 구현코드import java.io.BufferedReader;import java.io.InputStreamReader;import java.io.IOException;import java.util.LinkedList;import java.util.Queue;public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(Sys..

카테고리 없음 2024.11.11

99클럽 코테 스터디 13일차 TIL - 스택/큐

문제백준 12605 [단어순서 뒤집기]문제 링크:  https://www.acmicpc.net/problem/12605 해결 방법split()으로 공백 기준으로 단어를 분리Collections.reverse() 메서드로 분리된 단어의 순서를 뒤집기String.join()로 단어들을 이어 붙임코드import java.util.*;public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int N = Integer.parseInt(scanner.nextLine()); // 테스트 케이스 개수 for (int i..

카테고리 없음 2024.11.09

99클럽 코테 스터디 12일차 TIL - 스택

문제백준 10828 [스택]문제 링크:  https://www.acmicpc.net/problem/10828 해결 방법push, pop 메소드를 제공하는 Deque 사용switch-case문을 사용하여 스택 명령어 처리push X: 스택에 값을 추가pop: 스택에서 최상위 값을 제거하고 출력 / 스택이 비어있으면 -1을 출력size: 스택의 크기를 출력empty: 스택이 비어있는지 여부를 1(비어있음) 또는 0(비어있지 않음)으로 출력top: 스택의 최상위 값을 출력 / 스택이 비어있으면 -1을 출력코드import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.ArrayDe..