티스토리

뇌세포CPR
검색하기

블로그 홈

뇌세포CPR

dooduz.tistory.com/m

DooDuZ 님의 블로그입니다.

구독자
9
방명록 방문하기

주요 글 목록

  • 프로그래머스 - 봉인된 주문 참가 신청을 할까말까 하다 결국 안 했던 2025 프로그래머스 코드챌린지...의 2차 예선 문제입니다.문제를 보고 26진수를 떠올릴 수 있고 진수 변환 방법만 알고있다면 쉽게 해결할 수 있습니다.lv3 난이도에 비해 비교적 쉽게 나온 편에 속하는 것 같습니다. 크게 복잡하지 않아서 풀이를 간단하게 적어보면금지된 주문을 이용해 적절한 n의 위치를 설정할 때 26진수 -> 10진수 변환이재설정된 n을 다시 주문으로 변환할 때 10진수 -> 26진수 변환이 한 번씩 사용됩니다. 아래는 제출 코드입니다.import java.util.*;class Solution { char[] alp = new char[26]; Map indexes = new HashMap(); PriorityQueue.. 공감수 1 댓글수 0 2025. 2. 19.
  • [예약 구매 프로젝트] 가상 스레드 적용 더 많은 요청을 견딜 수 있게 하기이전 포스팅에서 캐싱 전략을 사용해 동시성과 성능 개선을 거쳤지만, 여전히 남아있는 문제가 있었습니다. 바로 처리 가능한 동시 요청 수에 대한 것이었는데요. 여태까지 진행한 대부분의 테스트는 스레드 1000개 x 루프 5번을 기준으로 진행했습니다. 한 번에 5000개의 스레드를 사용하지 않은 이유는 단순했습니다. 안정성이 보장되는 요청의 개수가 1000개였기 때문이죠. 제 목표는 10000개의 요청을 한 번에 받아내는 것이었고, 2000개 요청만 진행돼도 종종 HttpHostConnectException이 발생하는 기존 성능은 목표에 한참 못 미치는 것이었습니다. 요청 처리 속도가 빨라질수록 더 많은 요청을 받아낼 수 있었기 때문에, 조금이라도 성능을 개선하고자 Java.. 공감수 1 댓글수 0 2024. 8. 6.
  • Virtual Thread 신기술이란...Java 21부터 정식 릴리즈된 가상 스레드에 대해 알아보려고 합니다. 우아한 테크 채널의 발표 영상과 우아한 기술 블로그의 글을 많이 참조했습니다. 기술적으로 정확한 정보를 전달해 준 우아한 테크와 달리 이 글은 제 추측이 많이 가미되었습니다. 부디 정보로 받아들이기보다는 이런 경험과 생각을 한 사람이 있구나 정도로 봐주시면 감사하겠습니다. [참고 링크] 우아한 테크 세미나 - Java의 미래, 가상 스레드 우아한 기술 블로그 - Java의 미래, Virtual Thread JEP 444: Virtual Threads Java의 미래, Virtual Thread | 우아한형제들 기술블로그JDK21에 공식 feature로 추가된 Virtual Thread에 대해 알아보고, Thread, R.. 공감수 0 댓글수 0 2024. 8. 5.
  • [예약 구매 프로젝트] Test Code 테스트 그거 어떻게 하는 건데프로젝트를 진행하면서 어려운 부분이 정말 많았지만, 그중에서도 가장 스트레스받았던 부분이 바로 테스트였습니다. 다른 건 공부해서 하면 되겠다 싶었는데 테스트는 어떻게 짜야하나 도저히 감이 잡히질 않았습니다. 하여 정리해 보는 좌충우돌 테스트코드 작성기... 테스트에 대한 정확한 정보를 정리하는 글은 아니고, 제 이해가 어떤 식으로 변화했는지에 대한 글입니다. 아래 카테고리 역시 서로 구분되는 개념으로 나눈 게 아니라 제가 인지한 순서대로 구성했습니다. Unit먼저 단위 테스트 입니다. 코드를 작은 단위(ex - 기능) 별로 분리해서 테스트하는 것을 말합니다. 쉽게 생각하면 메서드 단위의 테스트부터, 메서드 내부에 적용할 로직에 대한 테스트라고 할 수 있을 것 같습니다. 먼저 .. 공감수 0 댓글수 0 2024. 7. 30.
  • BOJ 3653 - 영화 수집 푸는데 3일 걸렸고요. 진짜 너무너무 괴로웠고요...맨날 실버 풀다가 오랜만에 플레 함 해볼까 했다가 대가리 시원하게 박살났음니다.다시는 플레를 조심성 없이 고르지 않으리... 푸념은 여기까지 하고, 아래는 문제입니다.영화로 10만 개로 젠가 하는 미친놈이 너 말고 또 있을까 상근아?죄송합니다. 문제 볼게요. 사실 문제 유형 파악부터 굉장히 애먹었습니다. 이분 탐색인가? 하니 정렬 데이터가 아니고, 그리디인가? 하니 모든 비용이 1입니다. 최단 거리, 최소 비용 알고리즘인가? 하면 사실 적용법이 떠오르지 않았고요... 설마 트리겠어? 했는데 아니나 다를까 트리였습니다. 그것도 딱 한 번 해봤던 세그먼트 트리요... 세그먼트 트리는 구간 정보를 다룰 때 유리한 자료구조입니다. 일반적으로 구간 합, 구간 최.. 공감수 4 댓글수 0 2024. 7. 30.
  • [예약 구매 프로젝트] 상품 조회 캐싱 추가 적용 - 성능 테스트 더 더 빠르게, 최적화는 끝이 없다지난 캐싱 전략 글에서 조회 캐싱까진 진행하지 못해서 아쉽다는 말을 포스팅 말미에 적었었지요. 이전엔 DB write 작업을 효율적으로 하기 위한 캐싱을 적용했다면, 오늘은 Read에 대한 캐싱을 적용하고 성능이 얼마나 개선되었는지 말해보려 합니다. 재고 캐싱에 대한 글은 아래 링크로! [예약 구매 프로젝트] 캐싱 전략 적용예약 구매 프로젝트지난달 말부터 대규모 동시 요청 상황을 가정한 예약 구매 프로젝트를 진행 중입니다. 예약 구매라는 말이 와닿지 않는다면 온라인 티켓팅, 한정판 도서/앨범 구매 등을 떠올dooduz.tistory.com  public ProductDto getProduct(Long productId) { String key = String.val.. 공감수 1 댓글수 0 2024. 7. 27.
  • [Spring Security] Session vs Token Session - StatefulSpring Security는 기본적으로 formLogin을 통한 Session 방식 인증/인가를 지원합니다. 다른 처리 없이 UserDetails와 UserDetailsService를 구현하고 로그인하면 JSESSIONID라는 쿠키가 발급되는 걸 볼 수 있습니다. 로그인된 사용자의 정보는 서블릿 컨테이너의 Session Storage에 저장되어 사용되는데 이처럼 사용자 정보를 서버가 기억해두는 것을 stateful이라고 표현합니다. 요청이 인증 관련 쿠키를 포함하고 있으면 쿠키에 담긴 키를 통해 session에 접근하고 로그인된 사용자인지 검증합니다. 프로젝트 규모가 작고 트래픽이 크지 않을 경우, 간편하게 구현할 수 있는 세션 방식 로그인은 좋은 선택지 중 하나일 수 .. 공감수 2 댓글수 0 2024. 7. 25.
  • [예약 구매 프로젝트] 동시 주문 요청 처리 수요는 많고 공급은 적다지금 진행 중인 예약구매 프로젝트의 메인 주제는 짧은 시간에 몰리는 대규모 트래픽을 처리하는 것입니다. 특정 브랜드들의 콜라보 한정 상품이나 온라인 티켓팅 등을 생각해 보면, 사려는 사람은 많고 제공되는 자원은 한정적인 것이죠. 그래서 대규모 트래픽이라고 하면 서버 부하나 성능에 대한 생각이 먼저 떠오르는 게 사실입니다. 그러나 막상 기능을 구현하다 보면 먼저 마주치게 되는 문제가 있습니다. 많은 요청이 하나의 자원을 바라보고 조작하려 하게 되는, 이른바 동시성 이슈입니다. 동시 주문 시나리오편의상 하나의 아이템이 남아있고 아이템을 구매하기 위한 무수히 많은 요청이 들어오는 상황을 가정해 보겠습니다. 지난 포스팅에 올렸던 기본 주문 플로우를 사용한다고 가정해 보죠. 아이템에 대한 .. 공감수 1 댓글수 0 2024. 7. 24.
  • [예약 구매 프로젝트] 캐싱 전략 적용 예약 구매 프로젝트지난달 말부터 대규모 동시 요청 상황을 가정한 예약 구매 프로젝트를 진행 중입니다. 예약 구매라는 말이 와닿지 않는다면 온라인 티켓팅, 한정판 도서/앨범 구매 등을 떠올려보면 좋습니다. 프로젝트 요구 사항에 따르면 동시 1만 건 요청 시 데이터 정합성이 유지돼야 하고 사용자 경험도 일정 수준 이상으로 확보해야 합니다. 이번 글에선 사용자 경험, 즉 응답 속도 개선을 위해 어떤 방법을 선택했는지 적어보려 합니다. 아래는 기본 기능 구현 때 짜놓은 주문 로직 시퀀스입니다.1. 클라이언트의 주문 요청이 들어옵니다.2. 서버는 주문 목록의 상품 재고를 DB에서 확인합니다.3. DB는 재고 정보를 반환합니다.4. 재고가 충분하다면 주문 수량만큼 재고를 차감하고 DB에 반영합니다.5. 반.. 공감수 3 댓글수 4 2024. 7. 23.
  • [예약 구매 프로젝트]Spring Security - JWT 적용 Stateless이번 프로젝트를 진행하면서 가장 많이 한 생각은 서버 리소스를 어떻게 하면 조금이라도 아낄 수 있을까 하는 것 이었습니다. 동 시간대 수만명의 동시 접속을 고려해야하는 상황에서 로직 하나, 스레드 하나의 비용을 최소화 시켜야 했습니다. 이번엔 서버 리소스를 아끼는 첫 번째 관문 Stateless 로그인에 대해 다룹니다. Spring Security와 JWT를 사용하여 구현했습니다.   [Spring Security] Session vs TokenSession - StatefulSpring Security는 기본적으로 formLogin을 통한 Session 방식 인증/인가를 지원합니다. 다른 처리 없이 UserDetails와 UserDetailsService를 구현하고 로그인하면 JSESS.. 공감수 1 댓글수 0 2024. 6. 26.
  • Serial GC / Parallel GC / G1 GC Serial GC가장 단순한 가비지 컬렉터로 하나의 스레드를 사용하여 GC를 수행한다. 여기서 말하는 스레드는 CPU의 물리적인 처리 단위를 의미 한다. GC 발생 시 Stop The World가 발생하며 사용하는 스레드가 적은 만큼 그 시간도 길다. Minor GC에선 Mark(unreachable 인스턴스 마킹)과 Sweep(메모리 해제)이, Old GC에선 Compact(메모리 단편화 해소)까지 진행된다. Parallel GCSerial GC가 싱글 스레드를 사용했다면, Parallel GC는 Minor GC에서 멀티 스레드를 사용하여 GC를 수행한다. 스레드가 늘어나는 만큼 Serial GC에 비해 상대적으로 Stop The World 시간이 짧다. Serial GC와 마찬가지로 Mark - Sw.. 공감수 1 댓글수 0 2024. 6. 19.
  • JVM Stack / Heap - GC StackJVM 내부에서의 스택은 스레드(Thread)가 독립적으로 실행되는 메모리 영역을 의미한다. Stack 영역에 스레드가 올라가고, 스레드마다 Call Stack / Program Counter Resister / Native Method Stack이 할당된다.  Call Stack메서드가 실행되면 메서드 정보를 담은 Stack Frame이 Call Stack으로 push 된다. 이때 Call Stack은 지역 변수 정보를 담은 Local Variable Array, 연산 정보를 담은 Operand Stack, 호출된 메서드에 대한 포인터 등이 포함되어 있다. public static void main(String[] args) { int a = 5; int b = 6; print.. 공감수 0 댓글수 0 2024. 6. 19.
  • BOJ 11726 - 2 x n 타일링 DP란 무엇인가... 답을 알고 보는데도 한참 걸렸던 문제다. 패턴을 손으로 하나하나 그려가면서 경우의 수가 피보나치 수열과 동일하게 증가한다는 걸 알게 됐는데, 항상 그렇게 된다는 걸 증명하지 못해서 3시간은 시간을 더 쓴 것 같다. 결국 답에 도달하고 보니 이렇게 간단했나... 싶어서 허망했다만, 결국 대부분의 DP문제가 그런 것 같기도 하다. 여하튼 문제를 보면  \( 2 \times n \) 타일을 채워야하기 때문에 \( 2 \times 1 \) 타일은 하나로도 칸을 채워갈 수 있지만, \( 1 \times 2 \) 타일은 위 아래로 두개를 붙여야만 칸을 채울 수 있다. 결국 타일을 채울 수 있는 도형은 위의 세 도형 뿐이다. 필자는 이걸 넓이 1과 2로 순열을 만들어서 풀려고 했었는데 대차게 실.. 공감수 0 댓글수 0 2024. 6. 17.
  • Docker Container Docker리눅스 컨테이너 기반의 오픈소스 플랫폼. 애플리케이션을 컨테이너 단위로 격리하여 실행하고 배포한다. Container가상화 기술의 하나로 호스트 운영체제 위에 여러 개의 격리된 환경을 생성하는 기술이다. 도커(Docker)에서 컨테이너란 애플리케이션과 그 실행 환경을 패키징하여 독립적으로 실행할 수 있는 가볍고 표준화된 단위다. 전통적인 가상 머신(VM) 보다 훨씬 빠르고 빠르게 실행될 수 있다.Virtualization가상화란 물리적인 컴퓨터 자원을 가상으로 분리하여 여러 개의 가상 컴퓨터 환경을 만들어내는 기술이다. 하나의 OS에서 다른 OS에만 지원되는 애플리케이션을 실행시켜야 한다고 가정해 보자. 컴퓨터의 Physical Machine은 Host OS가 사용하고 있기 때문에, OS는 또.. 공감수 1 댓글수 0 2024. 6. 16.
  • Counting Sort 좁은 범용성주어진 엘리먼트의 크기를 비교해서 정렬하는 일반적인 정렬 알고리즘과는 달리 각 엘리먼트의 개수를 세어 그 위치를 결정하는 정렬 알고리즘이다. 특히 엘리먼트의 값 범위가 좁을 때 매우 높은 퍼포먼스를 보여준다. 하지만 엘리먼트의 개수가 적더라도 값의 범위가 넓은 경우에는 메모리 사용성과 성능이 급격히 떨어지기 때문에, 좁은 범위의 정수 정렬에 적합하며 범용적으로 사용하기는 어렵다. 시간 복잡도\( O(n + k) \) 로 작동한다. 여기서 n은 엘리먼트의 개수이고, k는 범위를 의미한다. 엘리먼트의 범위가 좁은 경우 빠른 속도를 보여준다. 안정 정렬(Stable Sort)같은 값이라면 정렬 전의 순서가 유지되는 안정 정렬이다. 엘리먼트의 수를 세면서 해당 값의 가장 마지막 위치를 저장한 후, 해.. 공감수 1 댓글수 0 2024. 6. 14.
  • Merge Sort 분할 정복(Divide and Conquer)배열을 좌/우로 반씩 나눠가면서 최소 단위까지 내려간다. 이후 올라오면서 각 단위를 병합(merge)하면서 정렬하는 방식이다. 재귀로 구현하는 게 일반적이며, 각 단위를 절반씩 나누며 내려가기 때문에 재귀 깊이는 \( \log n \)이 되고, 각 깊이마다 전체 엘리먼트를 순회하며 병합하므로 \( O(n) \)의 시간복잡도가 발생한다. 모든 정렬을 수행했을 때 항상 \( O(n \log n) \) 의 시간복잡도를 보장받는다.  안정 정렬(Stable Sort)정렬 과정에서 같은 우선순위를 가진 데이터가 정렬 후에도 순서가 유지되는 것을 안정적(Stable)이라고 표현한다. 분할 과정에서 데이터는 정렬되지 않은 상태이므로 원래 위치를 유지하고, 병합 과정에서도 .. 공감수 2 댓글수 0 2024. 6. 14.
  • Spring Security 인증(Athentication)인증이란 사용자가 누구인지 확인하는 단계를 의미한다. 로그인을 예로 들면, 아이디와 패스워드를 통해 인증에 성공하는 경우 사용자 정보, 권한 등이 포함된 토큰이 발급된다. 일반적으로 JWT(Json Web Token) 형식을 사용한다.인가(Authorization)인가란 인증을 통해 검증된 사용자가 애플리케이션 내부의 리소스에 접근할 때 접근 주체(principal)가 해당 리소스에 접근할 권리가 있는지 확인하는 과정을 말한다. 일반적으로 사용자가 인증 단계에서 발급받은 토큰은 인가 내용을 포함하고 있으며, 사용자가 리소스에 접근하면서 토큰을 함께 전달하면 애플리케이션 서버는 토큰을 통해 권한 유무 등을 확인해 인가를 수행한다.Spring Security스프링 시큐리티는 애.. 공감수 2 댓글수 0 2024. 6. 13.
  • JPA Dirty Checking JPA는 엔티티의 상태 변화를 감지하여 변경된 내용이 있는 경우 Update SQL을 처리한다.  Service에서 특정 Entity를 가져오라고 하면 EntityManager는 DB에서 해당 값을 찾아 가져온 후 PersistenceContext에 Entity를 저장하고, 동시에 loadedState에 해당 Entity의 초기 상태를 저장한다.  가져온 Entity의 값을 변경하게 되면 즉시 DB에 반영되는 게 아니라 persistenceContext 내부에 있는 entityInstance의 value가 바뀐다.만약 위 상태에서 다시 객체의 상태를 원래 값으로 업데이트한다면 트랜잭션이 commit 하더라도 update query는 실행되지 않는다. loadedState에 있는 값과 현재 entity I.. 공감수 0 댓글수 0 2024. 6. 10.
  • BOJ 11834 - 홀짝 이분 탐색 카테고리 문제만 연달아 풀다가 마주쳐서인지 쉽게 접근이 가능했지만 평소에 봤다면 꽤 힘들만했을 것 같다. 입력 값이 10^100인 걸 보면 어쨌건 시간복잡도가 log n이어야겠다 하는 게 이분 탐색과 연결 지을 힌트라면 힌트겠다. 그 외 숫자에 대한 접근은 간단하다. 짝수는 2의 배수이므로 홀수 -> 짝수 / 짝수 -> 홀수로 넘어가는 경우 모두 1만 더해주면 홀/짝이 바뀌게 된다. 반대로 짝수/홀수 상태가 유지돼야 할 때는 2씩 증가하면 된다. 값이 변하는 양은 정해져있고, 우리는 규칙만 찾으면 된다. 앞부분부터 하나씩 살펴보자.먼저 초항에서 다음 항으로 넘어가는 부분이다. 홀 / 짝 / 홀 / 짝 순으로 나오는 수열이고, 초항이 홀수 1이므로 n = 2일때 올 숫자는 n = 1에서 1증가한.. 공감수 0 댓글수 0 2024. 6. 9.
  • Java Compile 코딩을 처음 시작했을 때 Java 컴파일에 대한 내 인상은 아래와 같았다.Java 소스코드는 자바 컴파일러에 의해 컴파일된다.컴파일은 파일 저장 시 즉시 일어난다.그리고 놀랍게도 이 생각은 최근까지 이어져왔는데, 이번에 기술 면접 대비 공부를 하면서 Java의 compile과정을 설명하라는 질문을 마주치게 됐다. 저장하면 컴파일러가 하는 게 컴파일이다. 이 말이 내가 사용하는 환경에서 틀린 말은 아니지만 면접에서 저렇게 대답할 순 없는 노릇이었다. 그러다 작년 원티드 프리온보딩에서 진행했던 Java GC 세션이 떠올랐다. 강사님이 굉장히 디테일한 부분까지 설명해 주셔서 여태 참여한 챌린지 중 가장 만족도가 높은 세션이었는데, 강의 초반 Java와 JVM에 대해 논하면서 컴파일에 대한 얘기를 했던 기억이 .. 공감수 0 댓글수 2 2024. 6. 7.
  • BOJ 10868 - 최솟값 가장 먼저 떠오른 건 우선순위 큐였지만 당연하게 시간 초과가 났습니다. 사실 제출할 때도 그렇게 큰 기대 없이 냈기 때문에 다른 로직을 생각해야 했고... 그러다가 합병 정렬 진행 과정이 불현듯 스쳐갔습니다. 시간 복잡도를 줄이려면 반드시 트리 구조여야 할 텐데, 합병정렬에서 분할 정복을 통해 모든 엘리먼트를 최소 단위까지 쪼갠 기억이 난 것이죠.  합병 정렬을 그림으로 그리고, 위 과정에서 정렬 대신 최솟값만 취하면 훨씬 빠르지 않을까? 하는 생각이었습니다. 쪼갠 후, 정렬 과정을 생략하고 최소 값만 모아봤습니다. 이렇게 보니 시간 초과를 극복할 수 있다는 예감이 강하게 듭니다. 이제 트리를 만들고, 범위 값을 찾는 과정을 생각해 보겠습니다. 배열이 있고, 트리의 노드는 포함한 범위 정보와 그 범위 안.. 공감수 1 댓글수 0 2024. 6. 4.
  • BOJ 3080 - 아름다운 이름 [Java / Python] 상근이가 뭐 하고 살든 알 바 아니지만 이런 이상한 짓은 좀 안 했으면 좋겠다. 사람이름은 타고나길 이쁜 거지 뭘 위치를 정해가며 아름답네 마네 한단 말인가... 여하튼 참여 중인 캠프에서 문제는 던져줬고, 나는 풀어야 하는 입장이었다. 문제만 보면 어떤 규칙인지는 알겠는데, 그냥 사전순 정렬하면 끝나는 거 아닌가 하는 생각이 든다. 필자는 예제 데이터를 보고나서야 문제가 요구하는 조건을 이해할 수 있었다. 예제를 먼저 살펴보자. 예제 1번은 비교적 쉽다. I로 시작하는 문자 하나와 J로 시작하는 문자가 2개 있으므로, J문자들을 정렬하는 2가지 경우에 앞뒤로 IVO를 붙여주는 걸 생각할 수 있다. 그렇게하면 2 * 2로 4가 나온다. 이 추측이 맞는지 아래 예제로 확인해 보자   문자의 한 열씩 비교하.. 공감수 0 댓글수 0 2024. 6. 2.
  • BOJ 2568 - 전깃줄 2 이름이 재밌어 보여서 골랐는데, 직전에 풀었던 BOJ 12015 가장 긴 증가하는 부분 수열과 동일한 문제다. A의 번호를 index, B를 value로 생각하면 이 문제와 동일한 방법으로 남겨야 할 줄의 개수를 찾을 수 있다. BOJ 12015 - 가장 긴 증가하는 부분 수열 2단계별 풀어보기 DP단락에 있는 BOJ 11053 - 가장 긴 증가하는 부분 수열과 동일한 문제입니다.다만 입력값의 범위가 크게 늘어난 만큼, 풀이 방법에 개선이 필요합니다. 먼저 입력이 1 인 BOJ 11053의dooduz.tistory.com 그러나 이번에는 길이만 구하는 게 아니라, 몇 번 줄을 잘라냈는지 함께 보여줘야 한다. 기존 방법에선 index에 상관없이 dp[n]의 길이별 최소값을 저장했는데, 이번엔 해당 인덱스에.. 공감수 2 댓글수 0 2024. 5. 29.
  • BOJ 12015 - 가장 긴 증가하는 부분 수열 2 단계별 풀어보기 DP단락에 있는 BOJ 11053 - 가장 긴 증가하는 부분 수열과 동일한 문제입니다.다만 입력값의 범위가 크게 늘어난 만큼, 풀이 방법에 개선이 필요합니다. 먼저 입력이 1 인 BOJ 11053의 풀이입니다.public class Main { static int[] dp; static int[] arr; static int N; public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); N = Integer.parseInt(br.readLine()); .. 공감수 1 댓글수 0 2024. 5. 27.
    문의안내
    • 티스토리
    • 로그인
    • 고객센터

    티스토리는 카카오에서 사랑을 담아 만듭니다.

    © Kakao Corp.