전체 글 294

코드트리 채광 로봇 시뮬레이션

dp인 것은 빠르게 눈치챘으나, dp를 구현하는 단계에서 좀 구리게 생각했다.우선 시간 역행을 안했을 때의 dp값을 모두 구하고, 현재 값이 어느 방향에서 왔는지 저장하여 backtime 함수로 T만큼 돌아가서 해당 dp값을 빼준 값을 더하는 전략을 취했다.즉 dp[n-1][n-1]+dp[i][j]-dp[backi][backj]+map[backi][backj] 이다.다만 이 점화식을 수립할 때 하나를 그냥 넘어갔는데, 처음부터 격자의 끝에 도달하는 최대 경로에 항상 시간역행한 backi, backj가 있을 것이라고 생각하고 했다. 근거는 없지만 왠지 그러지 않을까? 라는 생각에 그렇게 했다.0 10 10 100 0 0 100 0 0 1025 15 5 0T=2일때, 이..

EC2 배포 v1

JDK - 자바 개발을 위한 키트Java EE, Java SE 등JDK에 포함되어야 하는 3가지-컴파일러-JVM-JRE(명령어 집합)JAVA_HOME 환경변수를 통해 JDK 의 여러버전 중 실행시킬 버전을 지정 가능 demon - 백그라운드에서 while문으로 계속 실행되고 있는 프로세스 docker는 운영체제 커널은 미포함, EC2에서는 운영체제 지원ec2 서버에 ssh로 안전하게 인증하기 위해 rsa 방식으로 키 페어 지급. 공개키는 ec2에, 개인키는 다운로드됨 mobaxterm - ssh 원격 접속 지원, putty같은 거ip주소가 아닌 도메인으로 세션 연결 해도 됨 ex) abc.aa.kr 서킷 스위칭 - 하나의 회선을 할당받아 다이렉트하게 연결된 전선에 전류를 흘려보내 이진수 데이터를 전송하는..

Project 2026.07.19

코드트리 -현대 기출 11차 1번 : 디지털 로직 패턴 검사

hashmap과 2진수 변환을 이용하는 문제였다. 처음에는 dp쪽을 생각을 했으나 패턴의 가짓수가 2^60이 최대기에 안될 거라고 생각하고, 해시맵을 생각했다.단순히 처음엔 해시맵에 60자리 스트링을 그대로 저장하는 방식으로 접근했는데, 이러면 60*백만이라 6천바이트로 메모리 초과가 났다. 그래서 패턴 값을 int로 바꿔서 4바이트*백만으로 하려했으나, 60자리 숫자는 int도, long도 처리할 수가 없다. 여기서 지피티 도움을 좀 받았는데, 결국 패턴이 0과 1이므로 이진수에서 십진수로 변환을 하면 2^60이라 long 안에 처리를 할 수 있다. 뭔가 당연한 생각인데 왜 그냥 60자리로 처리하려했는지 ...//S는 0과 1로 이루어짐//K hm; static int ans = 0; st..

코드트리 - 현대 기출 11차 2번 : 편안한 워크

한 세네달만에 알고리즘 푸는 거 같은데 잘 생각이 안나서 해설을 봤다.우선 문제 조건에서 K재귀 형식으로 격자를 탐색하고 방문한 곳은 메모이제이션 처리하는 방식인데, 방식은 근접하게 접근했으나 구현이 쉽지 않았던 것 같다. 격자를 4방향으로 탐색할 때 어차피 낮은곳에서 높은 곳으로 올라왔기에 다시 낮은 곳으로 갈 수가 없다.시간복잡도는 O(N^2*K) 재활 열심히 하자 import java.util.Scanner;//N*N///인접한 높이 차들 간의 최댓값이 최소가 되는 해//등산로의 길이는 K이상//N= 0 && x = 0 && y grid[i][j]){ ans = Math.min(ans, Math.max(grid[nx][ny] - grid[i][j], solve(nx, n..

Redis 없이 재고 예약을 처리 — Shopify의 SKIP LOCKED 전략

들어가며 "재고 예약은 Redis로 해야 한다." 분산 시스템을 공부하다 보면 자연스럽게 자리잡히는 통념이다. 빠른 인메모리 연산, TTL 기반 만료, 단순한 SETNX 락 — 얼핏 완벽해 보인다. 그런데 Shopify는 블랙프라이데이 2025를 앞두고 이 구조를 뒤집는 선택을 했다. Redis를 걷어내고, MySQL 하나로 재고 예약을 처리하기로 한 것이다. 결과는? 분당 510만 달러 규모의 트래픽을 쓰기 CPU 50% 미만으로 소화했다. 이 글에서는 그 핵심 아이디어인 SELECT ... FOR UPDATE SKIP LOCKED를 중심으로, Shopify가 어떤 문제를 어떻게 풀었는지 따라가 본다.기존 Redis 구조의 한계 Shopify의 구 시스템은 재고 장부(MySQL)와 예약 ..

뉴스 2026.06.02

MyBatis N+1 문제

들어가며 MyBatis로 1:N 관계를 매핑하다 보면 N+1 문제라는 단어를 어김없이 만난다. 공식 문서에도, 강의 자료에도, 면접 단골 주제로도 나온다. 그런데 처음 들었을 때 내 솔직한 반응은 이랬다. "그래서 쿼리 하나 더 나가는 건데, 그게 그렇게 문제야?" Nested Select 방식을 보면 부모 1번 + 자식 1번, 총 2번. 그게 뭐가 그리 큰 문제인가 싶었다. 결론부터 말하면 그 이해가 처음부터 틀렸다. N+1의 N은 부모 행 수다. 회원이 1만 명이면 10,001번이라는 뜻. 그리고 "1만 번"이라는 횟수 자체보다, 왜 그 횟수가 치명적인지가 진짜 핵심이다.1. N+1이 정확히 뭔가 MyBatis에서 1:N 관계 매핑은 두 가지 방식이 있다. 에 resultMap=을 ..

Project/Spring 2026.05.18

Spring MVC 심화 — @ModelAttribute부터 @ControllerAdvice, MockMvc 테스트 전략까지

들어가며 Spring MVC의 기본인 DispatcherServlet과 @Controller 흐름을 익히고 나면, 그 다음 벽이 있다. 파라미터 바인딩을 어떻게 깔끔하게 처리하느냐, 예외가 터졌을 때 어디서 잡느냐, 그리고 Controller를 어떻게 테스트하느냐. 이 글에서는 그 세 가지를 순서대로 정리한다. @ModelAttribute, @CookieValue, Flash Scope / @ControllerAdvice 예외 처리 / MockMvc 기반 테스트 전략.1. 요청 파라미터 바인딩 — @ModelAttribute, @CookieValue@RequestParam의 한계 단순 파라미터 1~2개는 @RequestParam이 충분하다. 그런데 회원가입 폼처럼 필드가 수십 개면? 파라미터를..

Project/Spring 2026.05.13

Spring MVC — DispatcherServlet이 요청을 처리하는 11단계 흐름

들어가며 Spring Boot로 웹 개발을 시작하면 @Controller, @GetMapping을 자연스럽게 쓰게 된다. 그런데 HTTP 요청이 들어와서 JSP나 JSON으로 응답이 나가기까지 내부에서 정확히 무슨 일이 일어나는지 설명하라고 하면 막히는 경우가 많다. 오늘은 Spring MVC의 심장인 DispatcherServlet이 요청을 처리하는 흐름을 11단계로 정리해봤다.Spring MVC 이전 — 서블릿 방식의 문제 Spring MVC를 이해하려면 먼저 그 이전 방식이 어떤 문제를 가졌는지 알아야 한다. 전통적인 FrontController 서블릿에서는 action 파라미터로 분기했다.String action = req.getParameter("action");switch (actio..

Project/Spring 2026.05.12

Spring AOP

들어가며 Spring을 공부하다 보면 @Transactional이나 @Cacheable을 아무 생각 없이 붙여쓰게 된다. 그런데 이게 대체 어떻게 동작하는 걸까? 내가 호출한 메서드에 트랜잭션 처리 코드를 직접 작성한 적이 없는데. 그 비밀이 바로 AOP(Aspect Oriented Programming)다. 오늘은 AOP가 왜 필요한지부터, 실제로 내부에서 어떻게 동작하는지까지 정리해본다.문제 상황 — 반복되는 코드가 나를 괴롭힌다메서드를 하나 작성한다고 생각해보자.public void insert(Buddy buddy) { log.debug("buddy: " + buddy); // 로깅 long start = System.currentTimeMillis(); ..

Project/Spring 2026.05.11

Spring DI/어노테이션

들어가며 Spring을 처음 배울 때 가장 낯선 개념이 의존성 주입(DI, Dependency Injection)이다. 어노테이션 몇 개 붙이면 객체가 알아서 주입된다는데, 대체 내부에서 무슨 일이 벌어지는 걸까? 이 글에서는 DI가 왜 필요한지부터 시작해서 명시적·묵시적 DI의 차이, @SpringBootApplication 내부 구조까지 한 번에 정리해본다.왜 DI가 필요한가 — 4단계 진화세탁기 사용자(WasherUser)가 세탁기(Washer)를 사용하는 상황으로 생각해보자.1단계 — 직접 생성public class WasherUser { private Washer washer = new SWasher(); // 소형 세탁기 직접 생성} 소형 세탁기를 대형으로 바꾸려면 WasherU..

Project/Spring 2026.05.06