본문 바로가기

전체 글139

WebClient 사용할때 주의 (6편) WebClient 로 요청을 보내고 받은 응답 객체는 아래와 같다. 이때 message 값이 nullable 하다고 해보자. public class ResponseDto { private String id; @Nullable private String message; public String getMessage() { return message; } } ResponseDto 로 deserialize 한 후에 map 연산자를 이용해 message 를 가져오면 NPE가 발생한다. webClientBuilder ... 생략 .retrieve() .bodyToMono(ResponseDto.class) .map(responseDto -> responseDto.getMessage()) .onErrorResume(t.. 2021. 12. 15.
fixture monkey 로 예외 발생 테스트 fixture monkey 는 테스트 객체 라이브러리다. fixture 를 자동으로 만들어준다. 사용 예제를 하나 보자. 아래 Order 객체가 있다. import lombok.Data; @Data // lombok getter, setter public class Order { @NotNull private Long id; @NotBlank private String orderNo; @Size(min = 2, max = 10) private String productName; @Min(1) @Max(100) private int quantity; @Min(0) private long price; @Size(max = 3) private List items = new ArrayList(); @PastOr.. 2021. 12. 15.
[구현] 자물쇠와 열쇠 2020 카카오 신입 공채 문제다. 먼저 2차원 배열을 시계방향으로 90도 회전시키는 함수다. def rotate_a_matrix_by_90_degree(a): n = len(a) # 행 길이 계산 m = len(a[0]) # 열 길이 계산 # 90도 돌리기 위해서 n, m 위치 변경 result = [[0] * n for _ in range(m)] for i in range(n): for j in range(m): result[j][n-i-1] = a[i][j] return result a = [[0,0], [1,0], [0,1], [0,0]] # 결과 [[0, 0, 1, 0], [0, 1, 0, 0]] print(rotate_a_matrix_by_90_degree(a)) 다음 soultion 함수를 .. 2021. 12. 6.
application warm up warm up 은 애플리케이션 로딩 후, 타 서비스 api 커넥션 연결, db 커넥션 연결, 캐시 등의 작업을 미리 수행하는 것을 의미한다. 만약 warm up 을 하지 않으면 초기 요청들은 실패할 위험이 있고, 순단에 가까운 장애까지 발생할 수 있다. 그래서 서비스 규모가 클수록 warm up 은 필수가 된다. warm up 의 개념은 단순하다. 그래서 구현이 크게 어렵지 않다. 애플리케이션 배포 후 실제 사용자 요청을 받기 전에 미리 요청을 보내면 되기 때문에 스크립트로 구현하기도 한다. 하지만 이글에서 소개하는 방법은 spring-boot-actuator-health 를 이용한다. cf) 팀에서 사용중인 warm up 기능 중 핵심부분만 따로 정리했다. 먼저 spring-boot-actuate-he.. 2021. 12. 5.
[구현] 문자열 압축 2020 카카오 신입 공채 문제다. 먼저 단순히 1개 단위로 자르면 어떻게 만들수 있을까 생각하면서 cutByOne 함수를 만들었다. 문자열 s 전체를 for문 돌면서 targetChar 를 이용해 resultS를 만들어갔다. def cutByOne(s): resultS = '' count = 1 targetChar = 'F' for i in range(len(s)): if targetChar == 'F': targetChar = s[i] count = 1 continue if targetChar == s[i]: count += 1 else: if count == 1: resultS += targetChar count = 1 targetChar = s[i] else: resultS += str(count.. 2021. 11. 29.
json error stack trace print 여부 커스텀 프로퍼티 먼저 application.yml 에 원하는 커스텀 프로퍼티를 추가한다. 보통 deploy phase 에 따라 다르게 설정된다. response: print-stack-trace: true 다음으로 /resources/META-INF/spring-configuration-metadata.json 파일에 프로퍼티에 대한 메타데이터를 추가한다. { "groups": [ { "name": "response", "type": "com.toy.config.ResponseProperties", "sourceType": "com.toy.config.ResponseProperties" } ], "properties": [ { "name": "response.print-stack-trace", "type": "java... 2021. 11. 22.
[구현] 문자열 재정렬 알파벳 대문자와 숫자(0~9)로만 구성된 문자열이 입력으로 주어진다. 모든 알파벳을 오름차순으로 정렬하고 마지막엔 모든숫자들을 더한 값을 이어서 출력한다. 입력예시1 input : AJKDLSI412K4JSJ9D output: ADDIJJJKKLSS20 입력예시2 input : K1KA5CB7 output: ABCKK13 내가 작성한 코드는 try except 를 이용했다. 각 문자가 알파벳인지 숫자인지를 if문으로 비교할 수 도 있었지만 문제를 보고 즉시 생각나는것은 try except 였다. 문자 오름차순 정렬은 내장함수 sorted를 이용했기 때문에 쉬웠다. s = input() sum = 0 list = [] for i in range(len(s)): try: sum += int(s[i]) exc.. 2021. 11. 21.
slf4j error log 포맷 String 문자열을 Integer 로 바꾸면 NumberFormatException 이 발생한다. 문제가 되는 변수 s 와 예외인 e 를 에러로그로 같이 출력하고 싶다면 아래처럼 만들 수 있다. String s = "Hello world"; try { Integer i = Integer.valueOf(s); } catch (NumberFormatException e) { logger.error("Failed to format {}", s, e); } 그런데 해당 error 메서드 인자를 보면 String var1, Object var2, Obejct var3 다. 즉 exception 파라미터가 Object로 받게 된다. package org.slf4j; public interface Logger { .. 2021. 11. 17.
form data 를 string으로 변환하기 content type application/x-www-form-urlencoded 으로 request body를 보낼 때 key=value 쌍 string 을 만들기 위한 코틀린 코드다. List 데이터 구조를 string 으로 만드는 encode 함수가 핵심이다. 추가적으로 item list를 FormData 로 만들어 flatten 시키는 부분도 있다. typealias FormData = List class FormDataTest { @Test fun formDataToString() { val baseFormData = getBaseForm() val itemFormData = listOf( Item("1", "food"), Item("2", "cloth") ).map { it.toFormDat.. 2021. 11. 15.
[구현] 럭키 스트레이트 문제 : https://www.acmicpc.net/problem/18406 18406번: 럭키 스트레이트 첫째 줄에 점수 N이 정수로 주어진다. (10 ≤ N ≤ 99,999,999) 단, 점수 N의 자릿수는 항상 짝수 형태로만 주어진다. www.acmicpc.net N이 항상 짝수 자릿수로만 주어진다는 전제가 있어서, 홀수일 때를 고려하지 않아도 되서 편했다. 나는 단순하게 왼쪽, 오른쪽 각각 더해서 같은지 비교했다. s = input() half = len(s) // 2 left = 0 right = 0 for i in range(0, half): left += int(s[i]) for i in range(half, len(s)): right += int(s[i]) if left == right: .. 2021. 11. 14.
The synchronous communication drawback(timing) 시간은 종종 잘못 이해되는 이슈다. 두대의 컴퓨터가 통신하고 메세지를 교환할 때, 네트워크를 자연스럽게 신뢰하고 문제 없다고 가정한다. 그런데 만약 통신이 실패하다면? 실패를 전파(propagate)하거나 재시도(retry) 하도록 준비가 되어 있어야한다. 일반적으로 MSA 기반에서 서버 간 통신은 동기식(synchronous) HTTP 를 사용한다. 요청을 보내고 응답을 기다린 후 다음 실행을 계속한다. 동기식 호출은 추론하기 쉽다. 코드를 순차적으로 만들고 하나씩 실행시킨다. 하지만 동기식은 덜 고려되고 자주 오해를 불러일으키는 coupling 형태중 하나인 time-coupling 으로 이어진다. 여기서 파생되는 불확실성과 coupling 에 대해서 알아보자. 동기식으로 요청을 보낼 때 아래 3가지.. 2021. 11. 12.
Mono.defer 스택오버플로 글을 보면 Mono.defer 는 defer 안 코드를, 선언 시점이 아닌 실행 시점에 동작하게 해준다. 그래서 나는 한 context에서 여러번 subscribe 할 때 필요하겠구나로 이해했다. 하지만 그렇지 않은 상황에서도 defer 를 만나게 됐고 처음엔 왜 사용했는지 이해가 안됐다. 이해를 위해 아래 코드를 보자. id를 파라미터로 받아 Data를 얻어오는 메서드다. defer를 사용 안한다면 아래와 같이 switchIfEmpty 에 넣을 Mono를 따로 선언해야된다. 그래서 캐시에 값이 있으면 switchIfEmpty 를 실행 안시킴에도 항상 this.apiClient.getDataNoById(id) 메서드가 수행된다. // Mono.defer 사용 안한 코드 public Mono .. 2021. 11. 11.