전체 글 121

Redisson 분산락 waitTime · leaseTime 적절한 값 찾기

1. 배경 — 왜 설정값이 중요한가뇌이싱 프로젝트에서 방 입장 로직에 Redisson 분산락을 적용했다.방 입장 시 두 개의 락이 순차적으로 걸린다.lockExecutor.executeWithLock(USER_LOCK_PREFIX, userId, () -> exitIfInAnotherRoom(...));lockExecutor.executeWithLock(ROOM_LOCK_PREFIX, roomId, () -> performEnterRoomLogic(...));USER_LOCK 으로 다른 방에 이미 접속 중인 유저를 처리하고, ROOM_LOCK 으로 방 입장 로직의 원자성을 보장하는 구조다.두 락이 필요한 이유는 보호해야 하는 자원이 다르기 때문이다.USER_LOCK (userId 키) — 동일 유저가 여..

카테고리 없음 2026.06.21

데브코스 파이널 프로젝트 회고 : 뇌이싱

안녕하세요. 저에게 큰 성장을 안겨주었던 데브코스 파이널 프로젝트를 회고해보려 합니다. 1. 팀 빌딩 이전 프로젝트까지는 랜덤으로 팀배정이 되었는데요. 파이널 프로젝트는 자기 PR을 노션으로 적고 기간내에 자유롭게 팀빌딩을 해야했습니다. 아무래도 데브코스는 온라인 과정이라 같은 팀을 하지 않으면 다른 분들과는 대화할 기회가 없었는데 각자 개인 블로그나 팀 활동 notion 같은 것들을 관찰하며 다른 분들을 눈여겨봐 왔습니다.(마치 인스타 피드 구경하듯 구경했어요..) 어차피 팀빌딩해야할거 적극적으로하자는 마음으로 (ENFP모드) 팀빌딩 기간이 시작되자마자 총 3분께 먼저 DM 드렸습니다 팀 빌딩 기간이 시작되자마자 평소 점 찍어둔(?) 세 분께 먼저 DM을 드렸습니다.1번 팀원: 1차 프로젝트를..

회고 2026.03.17

끊김 없는 사용자 경험을 위한 WebSocket 세션 복구 (재연결) 구현

안녕하세요. 오늘은 데브코스에서 진행했던 프로젝트인 온라인 게임 플랫폼(뇌이싱)에서 구현했던 재연결 로직 개발 과정을 기록해보려합니다. 1. 재연결의 필요성 실시간 퀴즈 서비스를 개발하며 가장 큰 고민은 사용자 이탈이었습니다. 웹소켓 특성상 네트워크가 1초만 끊겨도 세션이 종료되는데, 게임을 진행하던 유저가 새로고침 한 번에 퀴즈방에서 튕겨 나간다면 사용자 경험이 저하될 것을 우려해 실수로 끊겨도 다시 돌아올 수 있는 안정적인 게임 환경을 만드는 것이 이번 구현의 목표였습니다. 2. 설계 재연결 로직을 구현하기 위해 크게 세 가지 장치를 설계했습니다.감지: SessionDisconnectEvent와 커스텀 HeartbeatMonitor를 통해 유저의 상태를 실시간으로 추적합니다. 유예: 유저가 dis..

시간 복잡도 이해하기

코딩테스트 준비를 하면서 시간 복잡도에 대한 이해를 빼놓을 수가 없기에 정리해본다. 시간 복잡도란? 입력크기 n이 변화함에 따라 연산 횟수의 증가 추세를 보는 기준 시간 복잡도를 표현할 때는 빅오(Big-O) 표기법을 사용한다. 1. O(1) — 상수 시간int x = 1; int y = 2; System.out.println(x+y);입력 크기랑 상관없이 항상 1번만 실행되므로 O(1) 로 표현할 수 있다. 2. O(n) - 선형for(int i =0; in 이 커질 수록 for문의 반복 횟수가 늘어나므로 O(n) 로 표현할 수 있다. 3. O(n²) — 이중 반복문 for(int i =0; i 중첩 for문을 사용하여 n*n 만큼 실행되므로 시간 복잡도는 O(n²) 로 표현할 수 있다.(⚠️ 가..

JWT 기반 로그인 구현하기

데브코스 2차 프로젝트에서 JWT 기반으로 회원가입, 로그인을 구현했던 과정을 기록해보고자한다. 1) 배경 & 목표 왜 JWT? 세션 방식에 비해 서버를 여러대로 늘려도 동기화 없이 동작해(Stateless) 수평 확장에서 유리하다는 특징이 있다.이 프로젝트는 React 기반 SPA라서 요청마다 Authorization 헤더로 Access 토큰으로만 통신하면 프론트–백 연동이 단순해진다.단점보안을 위해 Access 토큰의 유효기간을 짧게주고 Refresh 블랙리스트를 구현하였다. 목표 회원가입/로그인/토큰 재발급/로그아웃 플로우 완성 2) 시스템 개요 스택 : Java21, Spring Boot 3.4.5, Spring Security, JPA, MySQL, Redis3) 요구사항 정의 회원가입..

프로그래머스- [level 2] 튜플 - 64065 (Java)

성능 요약메모리: 97.1 MB, 시간: 47.06 ms구분코딩테스트 연습 > 2019 카카오 개발자 겨울 인턴십채점결과정확성: 100.0합계: 100.0 / 100.0제출 일자2025년 08월 16일 01:25:43문제 설명셀수있는 수량의 순서있는 열거 또는 어떤 순서를 따르는 요소들의 모음을 튜플(tuple)이라고 합니다. n개의 요소를 가진 튜플을 n-튜플(n-tuple)이라고 하며, 다음과 같이 표현할 수 있습니다.(a1, a2, a3, ..., an)튜플은 다음과 같은 성질을 가지고 있습니다.중복된 원소가 있을 수 있습니다. ex : (2, 3, 1, 2)원소에 정해진 순서가 있으며, 원소의 순서가 다르면 서로 다른 튜플입니다. ex : (1, 2, 3) ≠ (1, 3, 2)튜플의 원소 개수는 ..

toArray(new String[0]); 이 권장되는 이유

https://hwangsehee.tistory.com/6 프로그래머스 - 오픈채팅방(java)문제 설명오픈채팅방카카오톡 오픈채팅방에서는 친구가 아닌 사람들과 대화를 할 수 있는데, 본래 닉네임이 아닌 가상의 닉네임을 사용하여 채팅방에 들어갈 수 있다.신입사원인 김크루는 카hwangsehee.tistory.com 코딩테스트를 풀다가 List -> Array 변환 시toArray(new String[list.size()]); 보다 toArray(new String[0])으로 넘겨주는 방법이 더 권장된다는 피드백을 듣고 어째서인지 궁금해서 정리하게 되었습니다. 메모리 사용 효율성(멀티 스레드 환경에서)toArray(new String[list.size()])는 toArray() 메서드가 호출될 때마다 ..

데브코스 1차 프로젝트 회고

2025.04.22부터 ~ 30일까지 진행된 데브코스 1차 프로젝트에 대한 회고록을 써보려고 합니다. 프로젝트 주제1차 프로젝트는 주제가 정해져있는 프로젝트여서 부담없이 할 수 있겠다고 생각했습니다. 덕분에 아이디어 회의는 패스하고 바로 설계 단계로 넘어갔습니다. 🤓 설계주제가 정해져있었지만 api 명세를 준건 아니라서 메인 기능을 다 같이 정의하고 화면 설계서를 작성했습니다.(제안서쓰고 화면설계 그린게 헛고생한건 아니였음을 느꼈달까요 ..) 나중에 강사님이 피드백 주실 때는 일정관리 문서가 없는 점을 지적해주셨습니다.(모두가 알고 있었지만 안한ㄱ..WBS 꼭 쓰기 ) 화면 설계서까지 진행해보니 생각보다 화면, 기능이 많이 나왔습니다. 화면 설계서를 그리고 나서 상세 기능을 추가하였고, 그걸 토..

회고 2025.05.03

DTO 변환 Mapper 클래스로 분리하기

상황DTO 를 request , response 용도로 나누기로했다. JPA로 저장하기 위해DTO -> Entity 로 변환하는 코드를서비스단에서 구현하고보니 클린 코드 원칙에 위배되는 느낌을 지울 수 없었다.팀원 한 분이 변환 책임을 Mapper 클래스에 분리하자는 의견을 주셨고이를 반영하여 매핑 로직을 Mapper 클래스로 분리하게 되었다. 구현public class ProductMapper { public static Product productCreateRequestToEntity(ProductCreateRequest productCreateRequest) { int price = Integer.parseInt(productCreateRequest.getPrice().repl..

git : fork 떠온 repository merge, commit, push 순서

이번 프로젝트에서 은근히 시간을 많이 잡아 먹은 git ! 회사에서는 svn을 쓰고세상 밖으로 나와서 5년만에 git 쓰려니까 정말 어렵더군요 .. ^_^ 그래도 이번 프로젝트를 통해확실히 감 잡고 갑니다. 우리 팀 브랜치 전략 dev 브랜치를 기준으로 feature, style 등등 작업하고있는 기능에 대한 접두사/이슈번호로 브랜치를 생성 후 작업이 끝나면 dev 브랜치로 merge 하고 최종적으로 dev 브랜치를 master(main) 브랜치로 merge 한다. git 작업 흐름 우선 저는 팀 repository를 fork 떠서 개인 저장소를 만들었습니다. 이 저장소를 origin 으로 이름 붙이고 원본 팀 저장소를 upsteram으로 이름 붙였습니다. 그러면 총 3개의 저장소가..

프로그래밍/Git 2025.05.03