자바 개발자라면 단위 테스트를 작성할 때 가장 먼저 손이 가는 게 바로 JUnit다. JUnit5는 JUnit4에 비해 많은 변화가 있었고, 특히 스프링 부트 2.2버전부터는 스프링 부트 스타터를 통해 별다른 의존성 설정 없이 바로 JUnit5를 쓸 수 있게 해줬다. (물론 스프링 부트를 안 써도 JUnit 의존성만 추가하면 바로 가능하다.)Junit5를 쓰면서 굳이 public 접근 제어자를 붙일 필요도 없다. 이는 테스트 메서드를 찾고 실행할 때 리플렉션(Reflection)을 활용하기 때문인데, 이 덕분에 접근제어자 관련 제약이 줄어든다.Reflection: 자바 프로그램이 실행 중에 클래스 구조나 메서드 정보를 파악하고, 접근이 불가능할 것 같은 private 멤버에도 접근할 수 있는 기술이다. ..
NestJS에서 정적 경로와 동적 경로 충돌 문제 해결하기NestJS로 프로젝트를 진행하면서 REST API 경로를 설계하던 중 예상치 못한 문제가 발생했다. mentor-registration과 :mentorId 경로가 충돌하면서, GET /api/mentors/mentor-registration 요청이 동적 경로로 매핑되어 버리는 현상이었다. 분명히 컨트롤러에 mentor-registration 경로를 명시했는데, 왜 이런 일이 발생한 걸까?문제 상황: 정적 경로와 동적 경로의 충돌아래와 같은 코드가 문제였다.@Get(':mentorId')async getMentorProfile(@Param('mentorId') mentorId: string) { return this.mentorService.ge..
요즘 NestJS로 사이드 프로젝트를 진행하면서 문득 아래 코드를 보고 이런 생각이 들었다.// 여기!static toDto(userAfterAuth: UserAfterAuth, user: User) { return { email: userAfterAuth.email, nickname: user.nickname, roles: userAfterAuth.roles, profileImage: user.profileImage, };}왜 NestJS에서는 Builder와 같은 역할을 하는 데코레이터가 없을까?만약 이 코드를 Spring에서 Lombok의 @Builder를 사용하면 이렇게 작성할 수 있다.public static UserDto toDto(UserAfterAuth userAf..
진짜 바보같은 실수지만 그래도 기록은 해야지... passport를 이용해 구글 login을 구현하던 중 save 단계에서 무한 츠쿠요미가 발생하는 문제가 발생했다.const googleStrategyConfig = new GoogleStrategy({ clientID: googleClientID, clientSecret: googleClientSecret, callbackURL: googleCallbackURL, scope: ['email', 'profile']}, (accessToken, refreshToken, profile, done) => { console.log("profile = ", profile) User.findOne({googleId: profile.i..
자바스크립트에서 this는 함수 호출 방식에 따라 다르게 바인딩된다. setTimeout 내에서 일반 함수를 사용하면 this가 객체를 가리킬 수 없다. 그러나 화살표 함수는 렉시컬 컨텍스트를 유지하므로, this가 객체를 가리키도록 만들 수 있다.기존 문제: setTimeout 내에서 일반 함수로는 this를 예상대로 사용할 수 없다.해결 방법: 화살표 함수를 사용해야만 this가 객체에 바인딩된다.추가 실험: 중첩된 setTimeout에서도 화살표 함수로 설정된 this는 변하지 않는다.반례 코드 (일반 함수 사용 시 this 문제)const timer = { title: "TIMER!", timeout: function () { console.log(this.title); /..
'크래프톤 정글'과 같은 부트캠프를 수료한 사람의 근황이라 하면 아마도 열심히 이력서를 돌리고 있다는 내용일것이다.정확히 들어맞았고 나 역시 열심히 이력서를 돌리고 있다. 크래프톤 정글은 한달에 한번꼴로 협력사에서 취업 설명회를 진행하는데 내게 아주 강렬한 인상을 줬던 기업이 있었다. 그때 발표하시던 분에 따르면 기업의 가장 큰 가치를 성장으로 설정하고, 3년뒤엔 어디든 갈 수 있는 개발자를 키우는게 목표라고 하셨다. 처음엔 이 말을 듣고 이게 대체 무슨말인가 싶었다. 자고로 기업이라고 하면 당연 이윤을 추구하는게 정상 아닌가?단순히 이상한 이야기라고 치부하기엔 설명해주시는 팀장님의 눈빛엔 확신이 담겨있었고, 이는 해당 기업에 대한 호기심을 불러일으켰다. 회사의 홈페이지에 들어가보니 '누구나 큰일 낼 수..
https://www.acmicpc.net/problem/2638간만에 만족스러운 풀이가 나와서 포스팅import sysfrom collections import dequeinput = sys.stdin.readline'''바깥공기부터 탐색만약 공기에 노출된 치즈를 발견할시 해당 치즈의 값을 +1 만약 그렇게 더한 치즈의 숫자가 2 이상일경우 melting cheese에 추가순회가 끝나면 melting cheese에 담겨있던 치즈를 다 녹인다.melting cheese를 탐색 queue에 append여기서 포인트는 melting count를 계속 유지해주며 작업 queue에 더해주는것같음필요한 자료형치즈 graphmelting count graph작업 queuemelting queuevisited'..
DTO에 담겨있는 LocalDateTime을 직렬화 하지 않고 그냥 ResponseBody에 넣어버리니 다음과 같이 list 형식으로 넘어가버리더라.이를 해결하기 위해 CustomLocalDateTimeSerializer를 제작하고 Server에서 문자열에서 포메팅해 Discord bot으로 넘겨주는 로직을 작성했다. DTOpackage study.surviveoutsidethejunglespring.algorithm.dto;import static study.surviveoutsidethejunglespring.config.JacksonConfig.*;import java.time.LocalDateTime;import com.fasterxml.jackson.databind.annotation.JsonS..
1. 학습 목표Synchronized를 ReentrantLock으로 최적화해보자2. 학습 내용ReentrantLockSynchronized 와 ReentrantLock 의 가장 큰 차이점은 Lock을 걸어주고 풀어주는 시점을 직접 조작함으로써 좀더 세밀한 조작이 가능하다는 점이다.Synchronized 은 자동 잠금해제에 속하고, ReentrantLock 은 명시적 잠금해제가 필요하다.ReentrantLock 은 tryLock() 같은 다양한 메서드를 지원하는데 이는 고성능의 동시성제어가 필요한 상황에서 더 유리하게 작용한다.그런 저번에 작성한 코드를 ReentrantLock으로 최적화해보자. lock.unlock(); try { // 과목의 현재 수강신청 인원 카운터 가져오기 (없으면 새로 생성..
1. 학습 목표synchronized 를 사용해 수강신청 로직 작성작업 큐를 생성해 Task 관리2. 학습 내용Controller Layer우선 memberEmail과 subjectName 을 받아오는 DTO를 정의했고 이를 전달하는 Controller 작성package study.threadsynchronized.registration;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import lombok.RequiredArgsCo..