전체 글

문제https://www.acmicpc.net/problem/19238풀이위 문제의 핵심을 나열해 보며 아래와 같다.택시의 현재 위치 기준 가장 가까운 고객을 태워서 목적지에 데려다 준다.만약, 거리가 가까운 고객이 여러 명일 경우 행과 열이 작은 고객을 먼저 태운다.고객을 태우기 전 택시의 위치에서 고객의 위치까지 이동하는 동안 소비된 연료를 총 연료에서 차감한다. 그리고 목적지에 도착하면 손님이 탑승한 위치에서 목적지 까지의 연료를 차감한 후, 고객의 위치부터 목적지까지 이동하면서 소비한 연료의 양의 2배를 채운다.단, 연료가 떨어지면(0이 되면) 즉시 운행을 종료한다.모든 고객을 목적지에 데려갔을 때, 남아있는 연료의 양을 결과로 출력한다.모든 고객을 목적지에 데려가지 못할 경우, -1을 결과로 출..
서론초기에 프로젝트를 구성할 때, 프로젝트 리포지토리를 Private로 구성하고 application.yml 파일에 민감한 정보들을 넣은 후 올렸다. 이후에 다른 프로젝트에 지원할 때, 해당 프로젝트 리포지토리가 Private 상태이다 보니 공유하는 데 어려움이 있었다. 따라서 Github Secret으로 yml 파일을 관리하고, application.yml은 gitignore로 안 올라가도록 설정한 뒤 리포지토리를 Public으로 설정해보겠다.본문1. github action workflow 작성gradle.yml(2번 과정 외 나머지 부분 코드는 생략)name: CI/CD using GitHub Actions & Dockeron: push: branches: [ "main" ] pull_re..
OSIV와 성능 최적화OSIV(Open Session in View)는 하이버네이트 영속성 컨텍스트로 데이터베이스  커넥션 범위 유지 전략이다.spring.jpa.open-in-view: true가 기본값으로 되어 있다. 이는 기본적으로 하이버네이트는 OSIV를 ON 한다는 의미이다. 애플리케이션을 실행하면 아래와 같은 WARN 로그를 남기는데 이를 고려하지 않으면 나중에 장애로 이어질 수 있다.WARN 4381 --- [ restartedMain] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during v..
이번에는 주문내역에서 추가로 주문한 상품 정보를 추가로 조회하는 부분에 대하여 진행한다. 앞에서는 XtoOne(OneToOne, ManyToOne) 관계만 있었지만 이번에는 컬렉션인 일대다 관계(OneToMany)를 조회하고, 최적화하는 방법에 대해 정리한다.주문 조회V1 : 엔티티를 직접 노출@GetMapping("/api/v1/orders")public List ordersV1() { List all = orderRepository.findAllByString(new OrderSearch()); for (Order order : all) { order.getMember().getName(); // 객체 LAZY 강제 초기화 order.getDelivery().ge..
주문 + 배송 정보 + 회원을 조회하는 API를 만드는 부분으로 지연 로딩 때문에 발생하는 성능 문제를 해결해가며 진행한다.참고로 이번 부분은 정말 중요하며 실무에서 JPA를 사용하려면 100% 이해해야 한다!!!간단한 주문 조회V1 : 엔티티를 직접 노출이전 글에서 작성했던 것처럼 엔티티를 직접 노출하는 것은 좋지 않다.order -> member와 order -> delivery는 지연 로딩이다. 따라서 실제 엔티티 대신에 프록시가 존재한다.jackson 라이브러리는 기본적으로 이 프록시 객체를 json으로 어떻게 생성해야 하는지 모르기 때문에 예외가 발생한다.이는 Hibernate5JakartaModule을 스프링 빈으로 등록하여 해결할 수 있다.@GetMapping("/api/v1/simple-o..
JPA 활용 1편에서는 JPA로 도메인을 설계하고, Repository와 Service에 로직을 구현했으며, Thymeleaf로 화면단을 구현했다. JPA 활용 2편에서는 이전에 작성한 로직을 기반으로 API를 개발하여 다양한 방법으로 최적화와 DTO 활용을 적용한다.API 개발 - 회원 등록 APIV1 : 엔티티를 RequestBody에 직접 매핑한다.@PostMapping("/api/v1/members")public CreateMemberResponse saveMemberV1(@RequestBody @Valid Member member) { // 이렇게 Member를 외부에 노출시키면 안되며 DTO를 파라미터로 받아야 함 Long id = memberService.join(member); ..
문제https://www.acmicpc.net/problem/1629풀이그냥 단순하게 풀면 BufferOverflow 및 시간 초과가 발생하므로 분할 정복을 활용해야 하며, 지수 법칙과 모듈러 방식을 사용하여 진행해야 한다. 지수 법칙은 a^(n+m) = a^n * a^m으로 이를 활용하여 지수가 짝수인 경우와 홀수인 경우의 전개를 보면 아래와 같다.이를 트리 구조로 표현해 보면 아래와 같이 되는 것을 확인할 수 있다.여기까지만 간단하게 코드를 작성해보면 아래와 같다.public static long pow(long A, long exponent) { // 지수가 1일 경우 A^1 이므로 A % C를 리턴 if (exponent == 1) return A % C; /..
문제https://www.acmicpc.net/problem/1074풀이좌측의 그림은 8x8로 이를 4등분을 하면 우측의 그림이 된다. (row, column)의 좌표까지의 칸수를 계산하는 건데, 한 변은 2^N으로 정의한다. 예를 들어 r=4, c=3,N=3 일 때, 일단 한 변의 길이는 8이 되므로 cut(8, 4, 3)가 실행된다. half는 4등분을 했을 때, 4등분 한 사각형의 한 변의 길이이다. 첫 번째로 쪼개졌기 때문에 한 변의 길이인 half = 4가 된다.1 사분면의 시작 값인 0의 좌표 = (0, 0)2 사분면의 시작 값인 16의 좌표 = (0, half)3 사분면의 시작 값인 32의 좌표 = (half, 0)4 사분면의 시작 값인 48의 좌표 = (half, half)구하려는 좌표가 ..
문제https://www.acmicpc.net/problem/1780풀이색종이의 수가 모두 같은 수라면 이 색종이를 그대로 사용하지만 좌측의 그림과 같이 모두 같은 수가 아니라면 우측 그림처럼 9등분을 한다.현재는 row와 column 모두 9이므로 9등분을 하면 나눠진 색종이의 size는 이전의 size/3이 되어 3이 된다.나누어진 색종이를 좌표로 표현해보면 위와 같이 표현할 수 있다.N이 9 일 때의 결과를 보면 위 그림과 같이 나오는 것을 알 수 있다.Codeimport java.io.*;import java.util.StringTokenizer;public class Main { static int N; static int [][] arr; static int [] answer ..
문제https://www.acmicpc.net/problem/11725풀이해당 문제는 루트 없는 트리에서 각 노드의 부모를 찾아야 한다. 트리의 루트를 1로 정했을 때, 각 노드의 부모를 구하여 출력해야 한다. 우선 노드의 개수인 N을 입력받고, 이후 N-1개의 줄에서 두 노드의 연결 정보를 인접 리스트 구조로 입력는다.그리고 DFS를 시작하여 루트 노드(1)를 방문 처리하고, 연결된 모든 노드를 탐색하면서 각 노드의 부모 노드를 찾는다. DFS는 재귀적으로 호출되며, 현재 노드를 방문 처리하고, 연결된 노드 중 방문하지 않은 노드를 탐색하면서 부모 노드를 설정한다. 모든 노드의 부모를 찾은 후, 2번 노드부터 순서대로 부모 노드를 출력한다. Codeimport java.io.*;import java.u..