Backend/☕️ Java(32)
-
[kotlin] 돌려돌려 돌림판~ 룰렛 게임 구현하기
📌 서론 룰렛 게임을 한 번쯤 해본 적이 있을 것이다. 빙글빙글 돌아가는 원판에는 구역별로 상품이 걸려있고 돌아가는 원판이 속도를 잃을 때쯤 멈추는 곳의 당첨 막대가 가리키는 상품을 얻게 된다.이런 룰렛 게임을 코드로 구현하려면 어떻게 해야할까? 필자는 백엔드 개발자이기에 UI를 그리는 것보단 어떤 원리에 의해 상품이 당첨되는지 초점을 두게 됐다. 만약 원판이 여섯 개의 구역으로 나뉘어 있다면 각각 1/6의 당첨확률을 가진다고 생각할 수 있다. 하지만 세상일이 원래 생각대로 되던가요? 좋은 상품은 항상 빗나가고 상대적으로 값어치가 떨어지는 상품만 자주 걸리는 게 차가운 자본주의의 현실이다 like 윤루카스. 프로그램으로 구현된 룰렛 게임은 각 구역의 당첨확률을 세팅할 수 있기에 값어치가 높은 상품보단 ..
2024.07.03 -
[Java] 1급 컬렉션으로 리팩토링
목차 서론 배경 설명 및 요구사항 Before Refactoring 일급 컬렉션이란? After Refactoring 일급 컬렉션 사용시 이점 요약 및 결론 서론 일급 컬렉션의 개념을 모호하게 알고 있었는데, 이번 기능 개발을 통해 일급 컬렉션을 사용해야 이유와 사용 후 코드 응집력이 높아지는 것을 직접 경험한 내용을 공유합니다. 배경 설명 및 요구사항 호텔 도메인의 백오피스를 개발하고 있다. 호텔에 등록된 객실을 한눈에 볼 수 있는 페이지에서 객실의 순서를 클릭-드래그하여 변경할 수 있는 기능이 개발 사항이었다. 검은 박스로 표시된 두 객실의 순서를 변경하는 것으로 인접한 객실의 순서 뿐만 아니라 인접하지 않은 객실의 순서도 드래그로 변경할 수 있어야 했다. 추가로 아래 이미지의 검은 박스로 표시된 요..
2024.02.02 -
[Java] LocalDateTime toString() 00초 일 때 발생한 문제
문제 상황 알림 메시지 테스트 중 발견한 문제. 가장 최근도착한 알림의 활동 시간(ex. n초 전, n시간 전)이 업데이트되지 않는 현상을 발견했다. 앱을 껐다 켜도 여전히 가장 최신 알림의 0초 전은 변하지 않았다. 곧바로 해당 알림이 적재된 테이블을 확인했다. 해당 시간은 테이블의 데이터가 생성되는 순간(created_date) 를 기준으로 표시된다. 위의 하이라이트 된 부분이 문제의 알림 데이터다. 해당 데이터베이스는 mysql 을 사용중이고 created_date 컬럼은 datetime 타입이다. 솔직히 해당 데이터의 초단위(00)를 보자마자 느낌이 싸했다. 설마.. 해당 데이터가 api response 로는 어떤 형태로 나가는지 확인하면, 대충 아래 이미지다. 초가 생략된 문자열이 나가기 때문에..
2024.01.05 -
[Java] 안전하게 파일 삭제하기
목차 1. File.delete() 2. Files.delete() 3. 해당 파일이 존재하는 디렉토리(폴더)까지 모두 삭제 자바에서 메모리에 존재하는 파일을 삭제하는 방법을 알아보자. 안전하게 파일을 삭제하고 해당 파일이 존재하는 폴더 내부를 모두 삭제하는 방법까지 알아보겠다. 1. File.delete() 가장 간단하게 File 클래스에 존재하는 delete method 를 직접 호출하는 방법이 있다. File 인스턴스에서 직접 delete() 를 호출하는 방법이다. public class SimpleTest { @Test public void FILE_SIMPLE_DELETE() { File file = new File("./test"); file.delete(); } } 해당 delete() 메서..
2023.12.22 -
[Java] 런타임에 메서드를 전달한다는게 무슨 말일까?
모던 자바 인 액션 초반 부엔 일급 객체가 등장한 배경을 설명하면서 아래와 같은 구절이 나온다. 만약 런타임에 메서드를 전달할 수 있다면, 즉 메서드를 일급 시민으로 만들 수 있으면 프로그래밍에 유용하게 활용할 수 있다. (넹?) 문맥상, 일급 객체(시민)를 메서드의 인자로 할당할 수 있어 생기는 이점에 대해 설명하는 내용이지만, 런타임에 메서드를 전달한다는 말이 쉽게 와닿지 않는다. 런타임 메서드 전달이 무슨 의미일까? 우선 런타임은 문자 그대로 프로그램이 실행되는 시간을 의미하는데, 이미 애플리케이션이 실행된 시점에 메서드를 객체와 연동하여 전달하고 호출하는 기법을 의미한다. 프로그래밍의 람다 표현식이나 콜백 함수, 디자인 패턴에선 전략패턴 등 여러 방법으로 구현할 수 있다. 이러한 기법의 공통점은..
2023.07.17 -
Optional, ifPresentOrElse 로 간단한 리팩토링
ifPresentOrElse 를 이용한 (초)간단 리팩토링 프로세스 1. userEmail 로 회원이 존재하는지 확인 2. Optional 타입의 findUser 반환 3. Optional 값이 비어있으면 userEmail 을 가지는 회원이 없다는 뜻이므로, newUser 엔티티를 저장 (repository.save()) . 4. Optional 값이 존재 시, findUser 의 토큰값 갱신 5. @Transactional 어노테이션으로 인해, 더티체킹 후 영속화 진행 기존.java @Transactional private void createUser(String userEmail, Token token) { Optional findUser = userRepository.findUserByEmail(u..
2023.03.09 -
Map 타입의 forEach (feat. Biconsumer)
Biconsumer 공부하다가 Map 타입에 forEach 를 실행시키면 어떤 인자가 나오는지 알게 됐다. 보통 Map 타입을 iterable 하게 사용하는 경우엔, 아래처럼 향상된 for 문을 작성했다. void 테스트() { Map map = new HashMap(); for (String s : map.keySet()) { System.out.println("s = " + s); } for (Integer value : map.values()) { System.out.println("value = " + value); } for (Map.Entry stringIntegerEntry : map.entrySet()) { System.out.println("stringIntegerEntry.getKey(..
2023.01.31 -
InputStream 사용시 발생한 간단 장애 회고
배경 회사에서 이미지-저장 API를 개발 및 유지 보수 하고 있습니다. 클라이언트에서 이미지를 전송하면 해당 이미지를 S3에 저장하는 모듈입니다. 기획 정책상 S3 에 저장하기 전, 용량을 줄이고자 리사이즈 작업을 선 진행 후 S3 에 업로드 합니다. 사건 S3 에 저장된 이미지 중, 리사이즈 된 이미지의 용량이 0byte 로 나타나는 케이스가 간헐적으로 발생했습니다. 0byte 이미지는 무엇을 의미하는 걸까요? 그렇습니다. 이미지가 유실됐다는 거죠 😇 다행인 점은 리사이즈 전, 원본 사이즈의 이미지도 별도로 S3 에 저장하기 때문에 큰 장애로 이어지진 않았습니다. 원인 규명 다시 사건으로 돌아가서, 사건의 전날 상용 배포 커밋을 우선 비교했습니다. 리사이즈 된 이미지에서 0byte 이슈가 발생했으니, ..
2023.01.01 -
[Java] long 에서 int "안전하게" 형변환 / 타입 캐스팅
1. primitive type long -> int 당연한 얘기지만 원시형 long 타입은 intValue() 메서드를 사용할 수 없다. 원시형은 메모리 주소에 저장된 '값 자체' 만 가질 뿐, 그 외의 메서드 등은 가지지 못하기 때문이다. 때문에 primitive type 인 long 을 int 형으로 변환하려면, Long.valueOf() 메서드로 우선 감싸줘야 한다. Long.valueOf() 메서드 내부는 아래와 같다. 원시형 l 변수를 new Long() 의 인자로 넣어 참조형으로 리턴한다. 2. long 에선 8 바이트인 내가, int 에선 4 바이트?.? int 는 4 바이트, long 은 8 바이트를 메모리로부터 할당받는다. 즉 int 는 -2,147,483,648 ~ 2,147,483,..
2022.12.17