본문 바로가기

분류 전체보기

(18)
전략 패턴으로 리팩토링하기 기획자로부터 새로운 기능 요청을 받을 때, 기존 기능과 비슷하지만 세부적으로 다른 요구사항이 있을 때가 있다. 이럴 때 API를 새롭게 만들기 보단 기존 컨트롤러를 재사용하면서도 새로운 기능을 유연하게 추가하고 싶었다.  문제 상황아래 예시 상황과 코드는 실제 회사의 기획과 코드가 아니며 포스팅을 위해 유사하게 만든 것 뿐이다. 기존에는 한국에서만 진행하던 이벤트를 글로벌에서도 운영하려는 요구사항이 생겼다. 해당 이벤트의 기본적인 기능은 동일하다.특정 기간 동안 특정 아이템을 할인된 가격에 구매 가능하다.이 때 아이템 목록은 기간마다 변경된다. 구매 시 보상을 지급하고, 사용자에게 알림을 전송한다.그러나 보상 지급 방식이 다르다. 한국 서비스의 경우 아이템을 3번 구매해야 보상을 지급한다. 글로벌 서비스..
RestAssured로 인수 테스트 작성하기 애플리케이션을 개발할 때 기능이 정상적으로 동작하는지 확인하는 것은 매우 중요하다. 단순히 코드 단위에서 검증하는 것을 넘어, 실제 사용자의 입장에서 요구사항이 잘 반영되었는지 인수 테스트(Acceptance Test)를 통해 확인할 수 있다.인수 테스트란?인수 테스트는 소프트웨어 개발에서 기능이 구현된 후, 사용자가 기대한 대로 동작하는지를 검증하는 과정이다. 인수 테스트에서 인수(Acceptance)는 승인이라는 의미로, 클라이언트가 기능을 검토하고 승인하는 단계에서 수행되는 테스트이다. 따라서 인수 테스트가 통과되면, 해당 기능이 요구사항을 만족하므로 작업을 종료할 수 있다. 인수 테스트는 단위 테스트나 통합 테스트보다 더 넓은 범위를 검증하는데, 그만큼 실행 비용이 높은 편이다. 그리고 Sprin..
ObjectMapper는 스프링 빈으로 주입받기 도입회사 데이터베이스에 JSON 형태의 데이터를 많이 저장하고 있다. 이 데이터를 String, Map, JsonNode로 받아서 DTO로 변환하는 작업을 수행해야 한다. @NoArgsConstructor(access = AccessLevel.PRIVATE)public final class Mapper { private static final ObjectMapper objectMapper = new ObjectMapper();} 따라서 위 코드처럼 new 키워드로 인스턴스화한 ObjectMapper를 이용해 POJO 객체로 변환했다. 하지만 팀원이 ObjectMapper는 인스턴스화 할 때와 스프링 빈으로 주입받아서 사용할 때 설정값이 다르므로 주의해야한다고 말씀해주셨다. 이번 글에서 Spr..
@RedisHash 주의해서 사용하기 도입프로젝트에서 @RedisHash를 사용하여 기능을 구현했다. Spring Data Redis의 @RedisHash는 자바 객체를 레디스의 Hash 데이터구조에 자동으로 매핑한다. 그리고 CrudRepository를 확장한 인터페이스를 사용하면, 데이터의 CRUD 작업을 쉽게 구현할 수 있다. 하지만 인덱싱을 위한 데이터는 만료시간이 지나도 삭제되지 않아 데이터가 계속 쌓이고 예상하지 못한 명령어가 발생한다. 예제를 통해 주의할 점을 자세히 알아보자. @RedisHash 주의점예제 코드@Getter@NoArgsConstructor(access = AccessLevel.PROTECTED)@RedisHash(value = "member")public class Member { @Id privat..
삶의 지도 글또 10기에 지원하기 위해 작성한 글입니다. [공대와 거리가 먼 문과생] 고등학생 때 문과생이였고 자연스래 문과 학과로 진학했다. 국제 정치에 대해 배우는 학과로 수업은 나름 재밌었다. 어릴 때부터 호기심이 많아 대학에서 새로운 것을 배운다는 것만으로도 즐거웠었다. 하지만 당시 '문송합니다'가 유행했고, 졸업 후 취업을 생각하면 막막함한 있었다. 그래서 반수를 통해 조금이라도 취업이 잘된다는 경영학이나 경제학을 가고자 했다. 하지만 열심히 하지 않았으니 당연히 반수는 실패했다.  [특별한 21살 ✨] 성인이 되는 나이인 20살은 특별한 나이다. 나에게 20살은 그리 특별하지 않았다. 반수한다고 학점 관리에 소홀히 했고, 휴학도 했고, 친구랑 어울리지도 않았다. 그렇다고 수능 공부를 열심히 한 것도 아니..
2024 스프링 캠프 다녀온 후기 지난 5월 25일 토요일 2024 스프링 캠프에 다녀왔다. 인프런에서 참여자를 모집했는데 1분만에 마감될 정도로 치열했다. 치열했지만.. 나는 성공해서 다녀오고 이렇게 후기까지 작성하고 있다😁 올해 1월에 개발자 컨퍼런스를 다녀온 이후로 두 번째 컨퍼런스이다. 같이 듣는 데브코스 사람들과 근처에서 간단하게 점심을 먹고 컨퍼런스장으로 향했다. 들어서자마자 등록을 한 뒤 키트를 나눠주셨는데, 손 선풍기, 키캡, 리무버 스티커였다. 부모님이 손 선풍기를 사용해보시더니 바람이 세다고 좋아하셨다. 컨퍼런스에서 들은 세션은 총 다섯 개로 동시성의 미래 - 코루틴의 버츄얼 스레드, Spring AI : LLM에도 봄이 찾아오다, 왜 나는 테스트를 작성하기 싫을까?, 실전! MSA 개발 가이드, AutoParams를..
2024 DND 해커톤 참여 후기 개발자 오픈 채팅방을 통해 IT 연합 동아리인 DND에서 해커톤이 열린다는 소식을 들었다. 개발자를 지망했을 때부터 해커톤을 참여하고 싶었기에 지원서를 작성했다. (컴퓨터를 전공했으면 해커톤은 해봐야지라고 생각했던것 같기도...) 지원서에는 경험을 바탕으로 사이드 프로젝트의 열정과 협업을 통한 성장을 지향함을 드러냈다. 합격 발표 시간이 되었을 때 두근거리는 마음으로 메일함을 열어보니 기쁘게도 선발이 되었다는 메일을 도착해있었다.  해커톤 시작 일주일 전부터 디스코드에 참여해서 팀 빌딩을 했다. 나는 감사하게도 데브코스에서 인연을 맺은 분이 컨택을 해주셨고 팀 빌딩을 마칠 수 있었다. 우리 팀은 온라인 미팅을 통해 미리 공개된 키워드, 일상과 지역에 부합하는 주제를 생각해봤다. 그리고 백엔드끼리 따로 모..
[Architecture] 사용자 수에 따라 시스템 설계하기 한 명의 사용자를 지원하는 시스템에서 시작하여 몇 백만 사용자를 지원하는 시스템을 설계하자.단일 서버와 데이터베이스모든 컴포넌트가 단 한 대의 서버에서 실행되는 간단한 시스템을 설계하면 아래 그림과 같다. 웹 앱, 데이터베이스 캐시 등이 전부 서버 한 대에서 실행된다.  사용자가 늘면 서버 하나로는 충분하지 않아서 여러 서버를 두어야 한다. 웹과 모바일 트래픽을 처리하는 서버(웹 계층)와 데이터베이스 서버(데이터 계층)을 분리하면 각각을 독립적으로 확장해 나갈 수 있다.  관계형 데이터베이스는 자료를 테이블과 열, 칼럼으로 표현한다. SQL을 사용하면 여러 테이블에 있는 데이터를 그 관계에 따라 join하여 합칠 수 있다. 반대로 비 관계형 데이터베이스인 NoSQL은 일반적으로 join 연산은 지원하지 ..
[DB] MySQL 엔진 아키텍처 파헤쳐보기 MySQL 전체 구조4MySQL의 전체 구조는 MySQL 엔진, 스토리지 엔진, 핸들러 API으로 나뉜다.MySQL 스레딩 구조MySQL 서버는 프로세스 기반이 아닌 스레드 기반으로 동작한다. MySQL 서버에서 동작하는 스레드는 포그라운드(Foreground) 스레드와 백그라운드(Background) 스레드로 구분된다. 포그라운드(Foreground) 스레드는 최소 MySQL 서버에 접속된 클라이언트의 수만큼 존재한다. 그리고 커넥션 종료 후 스레드 캐시(Thread cache)로 돌아간다. 포그라운드 스레드는 MySQL의 데이터 버퍼나 캐시로부터 가져오고 없으면 직접 디스크의 데이터나 인덱스 파일로부터 데이터 읽어오는 역할을 한다. 다만 InnoDB는 데이터 버퍼나 캐시까지만 포그라운드 스레드가 처리..
[트러블 슈팅] 인덱스 컨디션 푸시다운, 인덱스를 이용한 정렬, 커버링 인덱스로 슬로우 쿼리 튜닝하기 도입지난 글에서 단건 반복 쿼리를 벌크 SELECT 쿼리로 변경함으로써 n + 1문제를 해결했다. 더 나아가 JMeter로 성능 테스트를 진행하여 얼만큼 성능이 높아졌는지 비교해보았다. 이번 글에서 실행 계획을 분석하고 쿼리를 튜닝한 뒤 다시 JMeter로 성능 테스트를 진행한 경험을 소개한다. 인덱스 생성과 인덱스 컨디션 푸시다운n + 1 문제를 해결한 /api/v1/missions/matching 엔드포인트는 쿼리가 총 3번 전송된다. 아래는 첫 번째로 전송되는 쿼리이다. 미션(missions), 미션 카테고리(m_categories), 지역(regions), 미션 북마크(mission_bookmarks) 총 4개의 테이블을 조인하고 있다. 그리고 미션에 10만개, 미션 카테고리에 8개, 지역에 42..