[Case Study] SLASH 22 - 왜 은행은 무한스크롤이 안 되나요
·
개발 공부/기타
일반 은행과 토스뱅크의 거래 내역 조회 방식 비교 및 시스템 아키텍처일반 은행 앱의 거래 내역 조회 방식의 불편함일반 은행 앱은 거래 내역 조회 시 상단에 기간 설정을 요구한다. 지정된 기간만큼만 스크롤하여 조회할 수 있으며, 그 이상을 조회하려면 유저가 직접 조회 기간을 변경해야 한다. 반면, 트위터, 인스타그램, 카카오톡 등 많은 인터넷 서비스들은 기간 설정을 요구하지 않고, 스크롤만 계속하면 십수 년 전의 글까지 나열되는 우아한 스크롤 UI를 제공한다. 일반 은행이 이러한 불편한 인터페이스를 제공하는 이유는 시스템 아키텍처 때문이다.은행 시스템의 일반적인 분리 구조 (채널계와 계정계)계정계 (Core Banking System)실제로 유저의 돈을 다루며 원본 데이터가 저장되는 영역이다. 장애나 오류..
엄청 커다란 파일 다운로드
·
개발 공부/Spring
만약 서버 → 클라이언트로 큰 크기의 파일을 생성해서 반환해야 된다고 생각해보자. 예를 들어 전체 유저에 대한 통계 데이터를 생성 + 압축해서 클라이언트에게 반환해야 한다고 해보자. 만약 완성된 전체 데이터의 크기가 3GB 라고 하면 메모리가 3GB 이하인 (혹은 그 이상이어도) 서버는 버티지 못하고 OOM 으로 죽어버릴 것이다. 또한 통계성으로 유저에 대한 이런저런 정보를 모두 모아야 해서, 생성하는데 시간이 오래걸리는 데이터라면 timeout 도 발생할 가능성이 있다. 이러한 문제를 어떻게 해결하면 좋을까??1. 스트리밍 다운로드가장 먼저 생각난 해결책은 스트리밍으로 파일을 반환하는 방법이다. 일반적으로라면 아래의 과정을 따를텐데, 1. 전체 유저에 대한 데이터 생성2. `.zip` 으로 압축3. 클..
자바 Collector 구조 (feat. groupingBy() 사용법)
·
개발 공부/Java
Collectors의 groupingBy() 메서드를 사용하면 아래와 같이 데이터 스트림을 맵으로 편리하게 반환할 수 있어서 프로젝트나 알고리즘 문제를 풀 때 종종 사용했었다. 그런데 쓸 때마다 groupingBy() 메서드의 API 문서를 보며 아 이렇게 쓰는 거였지 하고 그대로 따라 치곤 했다.public class GroupingByTest { @Getter static class Person { private final int age; private final String name; public Person(int age, String name) { this.age = age; this.name = name; ..
테스트에서만 @Async 적용되지 않도록 하기
·
개발 공부/Spring
⭐️ 방법 매우 간단함 주의.. 문제 상황 알림 발송 로직을 비동기로 처리하고 테스트를 수행하려니 아래와 같이 알림 발송을 검증하는 테스트가 깨지는 문제가 생겼다. 원인은 비동기 메서드인 notificationService.send()가 완료되기 이전에 값이 생성되었는지를 검증하려고 했기 때문이다. 더 큰 문제로, 비단 알림 발송 자체를 검증하는 테스트 뿐만 아니라 다른 테스트에서도 해당 테스트가 수행하는 로직이 특정 작업을 마치고 알림 발송을 수행하는 경우 동일하게 비동기 로직이 수행되어 테스트가 깨지고 있었다. 그 예시로, 위의 경우 테스트 완료 후 수행하는 reset.sql 에서 알림 테이블을 지울 때 존재하지 않던 알림이 (비동기로 실행되어) 회원 테이블을 지울 때 존재하게 되는 상황이다. 때문에..
[플랭고] 주요/부가 로직 트랜잭션 분리하기 - TransactionalEventListener와 REQUIRES_NEW
·
개발 공부/Spring
플랭고는 친구와 함께 일정을 수정하고 장소를 추가하는 등 일정 공유 기능을 제공한다. 이때 새로운 일정에 초대되거나, 일정 초대를 수락/거절하거나 공유 중인 일정이 수정되는 등의 상황에 알림(자체 알림 목록 + 푸시)이 발송되도록 기능을 구현해두었다.기존에 알림을 발송하는 흐름은 다음과 같다. 먼저 일정 서비스에서 알림을 발송해야 하는 경우에 알림 DTO를 만들어 알림 서비스를 호출한다. 그러면 알림 서비스는 알림을 생성하고 외부 서비스인 FCM을 통해 대상 회원의 기기로 푸시 알림을 보낸다.이러한 흐름으로 알림을 발송하면 위 그림처럼 일정 -> 알림 -> 외부 서비스를 거치는 흐름 전체가 하나의 트랜잭션으로 묶이게 된다. 이런 식으로 코드를 구현하면 크게 다음과 같은 문제가 생길 수 있다고 생각했다. ..
[플랭고] JPA delete() 쿼리 안 나가는 문제 해결
·
개발 공부/Spring
💥 문제 상황 JPA를 사용하다가 xxxRepository.delete(Entity entity) 메서드를 통해 엔티티를 삭제하고 싶었는데 아무리 해도 delete 쿼리가 발생하지 않는 문제가 있었다. 엔티티 삭제 코드 @Transactional public void rejectOrExitSchedule(Long memberId, Long scheduleId) { Schedule schedule = findScheduleById(scheduleId); validateMemberNotOwner(memberId, schedule); ScheduleMember scheduleMember = findScheduleMemberByMemberIdAndScheduleId(memberId, scheduleId); sc..
[플랭고] JPQL fetch join + where절 사용 방법과 조건
·
개발 공부/Spring
프로젝트 개발 중에 fetch join 과 where 절을 함께 사용하고 싶은 상황이 생겼다. 아무생각 없이 코드를 치다가 순간 섬뜩해서 영한님 JPA 강의 자료를 뒤져보니 역시.. fetch join의 대상에 별칭을 주고 where 절에서 필터링하는건 불가능하다고 되어있었다. 그래서 고민을 좀 해봤는데 고민을 할수록 다음과 같은 고민들이 꼬리에 꼬리를 물고 생겨났다. fetch join은 별칭을 아예 줄 수 없나? where 절에 XToOne 쪽 필드를 조건으로 주는 경우는 어떻게 동작하나? fetch join 말고 join은 사용 해도 되는건가 그럼? 이 경우에는 어떻게 동작하지? 애초에 fetch join을 왜 where 절과 함께 사용하면 안 되는거지..? … JPA의 어려움에 멘붕이 올뻔했지만 ..
[플랭고] 일대일에서 일대다로 변경 시 validation 관련 문제 (Custom ConstraintValidator)
·
개발 공부/Spring
문제 상황 개발 중인 애플리케이션 플랭고의 '기록하기' 기능은 현재 1장의 이미지만 첨부할 수 있다. 이를 20장까지 첨부할 수 있도록 변경하는 작업을 진행했다. (사진은 2023 인프콘 🥹) 먼저 다음과 같은 작업들을 진행했다. 1. 이미지 url을 저장할 DiaryImage 테이블, 엔티티 생성 @Getter @NoArgsConstructor(access = PROTECTED) @Entity public class DiaryImage extends BaseTimeEntity { @Id @GeneratedValue(strategy = IDENTITY) private Long id; @ManyToOne(fetch = LAZY) @JoinColumn(name = "diary_id") private Diar..
[플랭고] 스프링 시큐리티 실패 핸들러 에서 직접 예외를 던지면 안 되는 이유
·
개발 공부/Spring
문제 상황 개발 중인 프로젝트에서 json 형태로 로그인을 처리하기 위해 AbstractAuthenticationProcessingFilter을 상속받는 커스텀 AuthenticationFilter를 구현하고 시큐리티에 필터로 등록해 사용하려고 했다. 다음과 같이 커스텀 Json 로그인 처리 필터를 구현하고 public class JsonEmailPasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter { ... @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws Au..
[알고리즘 - 구현] 자물쇠와 열쇠
·
개발 공부/알고리즘
☀️ 시작 이번 문제는 2020 카카오 신입 개발자 블라인드 채용 1차 코딩 테스트의 3번 문항 '자물쇠와 열쇠' 문제이다. 카카오 해설을 보면 출제 의도는 2차원 배열을 다룰 수 있는가 이다. 📖 문제 문제 링크 이 문제는 MxM 크기의 key 배열과 NxN 크기의 lock 배열이 주어지는데 M