본문 바로가기
  • 개발하는 곰돌이

분류 전체보기221

[Kotlin] 백준 3107 : IPv6 문제 링크 3107번: IPv6 첫째 줄에 올바른 IPv6 주소가 주어진다. 이 주소는 최대 39글자이다. 또한, 주소는 숫자 0-9, 알파벳 소문자 a-f, 콜론 :으로만 이루어져 있다. www.acmicpc.net 문제 해설 문자열 파싱 문제. 조건에 맞게 축약된 IPv6를 원래 IPv6로 복원해야 한다. 문제에서 주어진 두가지 조건을 역순으로 생각해보자. 0으로만 이루어져 있는 하나 이상의 연속된 그룹을 하나 골라서 콜론 2개(::)로 바꿀 수 있다. IPv6는 8 그룹의 16진수로 구성되어 있다. 즉, 축약되지 않은 원래 형태는 7개의 콜론으로 16진수 그룹을 나누게 된다. 즉, 축약된 IP 주소에서 콜론의 개수가 7개가 되도록 보충을 해주면 된다. split()으로 문자열을 분리하면 빈 문자열이.. 2024. 2. 20.
[Spring Boot] AOP를 이용해서 DB에 API 로그를 남겨보자 목차 들어가기 전에 현재 운영중인 서비스는 API 로그를 파일로 기록하고 있다. 그런데 서버가 이중화되어 있고 그 외에도 몇가지 불편한 점이 있어서 DB에 로깅을 해보면 어떨까 하는 생각이 들었다. 서버가 이중화되어 있다보니 특정 로그를 확인하려면 양쪽 서버 모두 확인해야 한다. → 사실상 가장 불편했던 점 특정 요청건에 대한 로그를 찾아보기 어렵다. 요청 일자가 모호할 경우에 여러 파일을 열어서 확인해야하는 경우 등 일자별, 시간대별 요청 건수 확인이 어렵다. 특정 요청이 처리되고 있는 도중에 다른 요청이 들어오면 로그에 혼선이 생겨서 어떤 요청에 대한 응답인지 파악하기 어려워진다. 이런 이유들로 인해 파일 대신 DB에 API로그를 남겨보려고 했는데 어차피 모든 API의 중복 로직이니까 AOP를 사용해.. 2024. 2. 6.
[JPA] 트랜잭션의 전파와 UnexpectedRollbackException 이슈 목차 들어가기 전에 지금까지 스프링부트 프로젝트에 JPA를 사용하면서 트랜잭션이 필요한 메소드에 기계적으로 @Transactional 어노테이션을 붙여서 사용하다가 처음 보는 예외를 맞닥뜨렸다. 트랜잭션에 rollback-only가 마킹되어 자동으로 롤백되었다고 한다. 이게 도대체 무슨 말인가 싶어서 관련 내용을 찾아보고 정리해본다. 문제 상황 DB에 API 호출 이력을 남기기 위해 컨트롤러에 @Transactional(dontRollbackOn = [Exception::class])을 달아주고 트랜잭션이 필요한 서비스 계층의 메소드들에 @Transactional을 달아준 상황이었다. 대충 아래와 같은 느낌이라고 보면 될 것 같다.(실제 코드가 아닌 상황 재현을 위한 코드) @Transactional(d.. 2024. 1. 29.
[Kotlin] 백준 25240 : 가희와 파일 탐색기 2 문제 링크 25240번: 가희와 파일 탐색기 2 Q개의 질문에 대해, 연산이 성공하면 1을 실패하면 0을 출력해 주세요. 각 질문에 대한 답은 한 줄에 하나씩 출력해 주세요. www.acmicpc.net 문제 해설 리눅스의 파일 권한과 관련된 문제. 관련 지식이 있다면 어렵지 않게 풀 수 있다. 우선 각 권한을 2진수로 바꿔보자. \begin{align*} 000 &\to 권한 없음\\ 001 &\to 실행 가능\\ 010 &\to 수정 가능\\ 011 &\to 실행 및 수정 가능\\ 100 &\to 읽기 가능\\ 101 &\to 읽기 및 실행 가능\\ 110 &\to 읽기 및 수정 가능\\ 111 &\to 읽기, 수정, 실행 모두 가능 \end{align*} 여기서 \(2^2\)에 해당하는 비트는 읽기.. 2023. 12. 30.
[Spring Boot] @Value 대신 생성자 바인딩을 통해 프로퍼티 값을 바인딩하고 관리해보자 목차 들어가기 전에 스프링부트 프로젝트를 개발하다 보면 운영/개발 등의 환경에 따라 코드에 들어가야 하는 값이 달라지는 경우가 있다. 단순히 현재 서버가 어떤 서버인지를 확인해줄 문자열이 될 수도 있고, 다른 API를 통해 서비스를 제공하는 프로젝트라면 해당 API를 제공하는 서버 호스트가 될 수도 있다. 이렇게 구동 환경에 따라 달라지는 값들은 yml파일 또는 properties 파일에서 프로파일을 나눠서 관리하고 실제 코드에서는 @Value로 값을 바인딩해서 사용하게 된다. 그런데 @Value로는 final 변수에 값을 바인딩하려면 롬복으로 생성자를 선언하는 방식을 사용할 수 없기 때문에 변경사항이 발생했을 때 굉장히 귀찮아진다. 이 경우 생성자 바인딩이라는 방식을 통해 프로퍼티 설정 값을 수월하게 .. 2023. 12. 21.
[Kotlin] 백준 11082 : 소수를 분수로 문제 링크 11082번: 소수를 분수로 Cube World에서는 모든 유리수를 소수로 표시하고, Baekjoon World에서는 모든 유리수를 분수로 표시합니다. 이때문에 두 나라 간에 오랜 기간 동안 전쟁을 치뤘고, 마침내 서로의 생각을 존중하기로 www.acmicpc.net 문제 해설 소수의 형태로 주어지는 유리수를 기약분수로 치환해야 한다. 우선 입력으로 주어지는 수는 정수, 유한소수, 순환소수 3가지의 경우로 구분할 수 있다. 각 경우에 대해서 생각해보자. 정수인 경우 예제 1과 같이 단순히 분자가 입력으로 주어진 수이고 분모가 1인 형태로 나타내면 된다. println("$decimal/1") 유한소수인 경우 소수부의 길이가 \(n\)이라고 할 때, 유한소수를 분수로 나타내는 가장 쉬운 방법은 .. 2023. 12. 11.
[Kotlin/Java] JUnit을 사용한 단위 테스트에서 System.in을 사용하는 콘솔 입력 로직 테스트하기 목차 들어가기 전에 간단한 토이 프로젝트를 진행하던 중에 콘솔을 통해 사용자로부터 값을 입력받아서 처리하는 로직을 구현하게 되었다. 이 로직을 테스트하기 위해 단순히 IDE로 프로젝트를 실행해서 돌려볼 수도 있었지만 입력받아서 처리하는 로직만 테스트를 하고 싶었기 때문에 단위 테스트로 구현하고자 했다. 그런데 그냥 평범하게 콘솔 입력을 하면 되겠지라는 생각과는 달리 단위 테스트에서는 콘솔 입력을 사용할 수 없었다. 하지만 단위 테스트에서도 콘솔로 입력하지 않을 뿐이지 표준 입력을 사용하는 로직을 테스트하는 방법을 찾을 수 있어서 정리해두려고 한다. 테스트를 하려는 기능 fun readConfig() = System.`in`.bufferedReader().run { val host = input("Host.. 2023. 12. 7.
[Gradle] 순수 자바/코틀린 Gradle 프로젝트를 실행 가능한 jar 파일로 빌드하기 목차 들어가기 전에 종종 스프링부트를 사용하지 않은 간단한 순수 자바/코틀린 프로젝트를 빌드해서 실행할 일이 있다. 스프링부트를 사용하지 않는 경우에는 bootJar 명령이 없어서 jar 명령으로 빌드할 수밖에 없는데 이렇게 생성된 jar 파일은 java -jar 명령어로 실행해도 제대로 실행되지 않는다. 이러한 현상이 발생하는 이유와 해결법을 정리해두고자 한다. 왜 gradle jar로 생성한 jar 파일은 실행되지 않을까? 기본적으로 Gradle의 jar 명령은 프로젝트의 소스 파일들을 컴파일한 후 jar 파일의 형태로 압축한다. 그리고 이 과정에서 MANIFEST.MF 파일이 생성되어 jar 파일에 추가된다. 터미널에 jar tf {jar 파일명}을 입력하면 jar 파일의 내부 구조를 확인해볼 수 .. 2023. 11. 28.