본문 바로가기

분류 전체보기17

[#3] 정확히 트랜잭션이 롤백 되었을 때 장바구니를 복원하기 -TransactionSynchronization afterCompletion (Rollback hook) @Transactional을 적용하여 어떠한 메소드를 실행한다면 롤백이 되었을 때 DB에 관련된 추가, 삭제등 로직은 @Transactional에 적용되어있는 AOP 로직에 의해 저절로 롤백이 됩니다. 하지만 레디스나 다른 스토리지에 어떠한 데이터를 추가하거나 삭제할 시 이를 수동으로 롤백시켜줘야 합니다. try-catch문을 이용하여 롤백되었을 때 로직을 처리해줄 수 있기는 합니다. 보통은 @Transactional 메소드 안에서 try catch문을 이용하여 RuntimeException이나 Error가 생겼을 시 롤백이 되면 catch문에서 잡는 방식으로 롤백이 되었을 때 로직을 수행하는데 이는 문제점이 있습니다. 롤백이 되었을 때 RuntimeException이나 Error가 생겨서 catch문 .. 2020. 10. 15.
[#2] Redis에 한번에 많은 데이터 추가 시 네트워크 병목 개선하기 - Redis Pipeline 이용하기 문제 상황 예를들어 레디스에 리스트를 저장하였고 그 리스트에 한번에 여러개의 원소를 추가하는 상황이라고 가정해보겠습니다. 레디스에 기본적으로 한번의 추가 연산을 하면 O(1)시간이 들며 요청을 보내고 다음과 같이 응답 값을 받습니다. 레디스는 싱글스레드와 이벤트루프 기반으로 비동기방식으로 요청을 처리하기 때문에 고성능입니다. 하지만 기본적으로 TCP 기반의 네트워크 모델을 따르기 때문에 네트워크 I/O 에서 병목이 생길 수 있는 가능성이 있습니다. 하지만 매번 요청을 할 때마다 응답값을 받기 때문에(요청을 보내고 응답을 받을때까지는 blocking이 됩니다) 한번에 수십만개의 요청을 보낸다면 이 응답값을 매번 받는 것도 부하가 생길 수 있습니다. 즉, 레디스 서버에 반복문을 돌며 여러번 리스트의 원소를 .. 2020. 10. 8.
불량 사용자 [2019 카카오 겨울 인턴쉽] C++ DFS Set 을 이용한 풀이 처음엔 단순히 for문으로 완전탐색을 하면 풀릴 줄 알았다. 하지만 생각해보니 user_id와 banned_id의 개수는 총 8개 이하이므로 다중 for문으로는 전체 개수를 구할 수 없었다. 따라서 브루트 포스방식으로 풀려면 DFS를 적용해야했다. 2번 테스트케이스의 예로 들면 user_id의 인덱스는 0부터 4까지이고 banned_id의 인덱스는 0부터 2까지이다. 따라서 user_id의 인덱스 banned_id의 인덱스 012 0 1 2 013 0 1 2 014 0 1 2 023 0 1 2 024 0 1 2 034 0 1 2 021 0 1 2 023 0 1 2 ... 102 0 1 2 103 0 1 2 이런식으로 서로 같은 문자열인지 체크한다. *를 빼고 같은 문자열인지 포문을 돌며 한글자씩 체크한다.. 2020. 9. 12.
경주로 건설 - 카카오 2020 C++ DFS 코딩테스트 풀이 다들 BFS풀고 공식해설도 BFS로 풀었다. BFS로 풀든 DFS로 풀든 상관 없지만 핵심은 완전탐색 과 메모이제이션 이 있어야 시간초과가 나지 않고 정답을 맞출수있다. 완전탐색이라는 방향에서 BFS나 DFS어느것으로 풀어도되는데 많은 블로그에서 DFS로 풀면 틀린다는 듯이 말을 해서 풀이를 올리게 되었다. 충분히 짧은 시간내에 정답이 가능하다. 핵심은 cost배열(메모이제이션) 에 최소비용을 계속 갱신해주고 이 최소비용보다 높다면 그 지점으로 이어지는 경로자체를 return시키는 것이다. #include #include #include int dr[4]={0,1,0,-1}; int dc[4]={1,0,-1,0}; int visited[30][30]={0,}; int cost[30][30]={0,}; u.. 2020. 9. 11.
보석 쇼핑 [카카오 2020 인턴 코딩테스트] C++ 투포인터 간단 명확 풀이 전형적인 투포인터 문제이다. 다음과 같이 for(int i=0;igems.size()) break; } 배열의 범위가 최대 10만 이므로 브루트 포스방식으로 푼다면 O(n^2)이 된다. 이는 정확성 풀이에서는 다 맞출 수 있지만 효율성 풀이에서 통과할 수 없다. 따라서 투포인터 방식으로 다음과 같이 풀어야 한다. 정답 코드 #include #include #include #include #include #include using namespace std; bool comp(pair a,pair b) { if(a.second-a.first == b.second-b.first) return a.first=gems.size()) break; m[gems[hi]]=hi; hi++; } } sort(v.begin.. 2020. 9. 6.
[#1] 서버가 여러대면 로그인 정보는 어디에 저장할까? - Sticky Session, Session Clustering, Redis Session Storage 크게 많이 사용하는 로그인 방식으로는 세션방식과 토큰방식이 있습니다. 이 글은 세션 방식에 대해 다룹니다. 세션 방식은 보통 서버에 로그인 정보를 저장합니다. Scale-out을 하기 전에는 한대의 WAS 서버로 세션을 처리했습니다. 하지만 서버의 대수를 늘린 후에는 세션을 어디에 저장할 것인지라는 이슈가 발생합니다. 만약 1번 서버에 어떤 사용자의 세션을 저장하고 배달 주문을 하는 Request가 2번 서버로 전달된다면 B서버에는 이 사용자의 세션이 없기 때문에 로그인이 유지되지 않는 문제가 발생합니다. 따라서 이러한 Session 정합성 문제를 해결해야했고 여러 가지 방법을 고민해보았습니다. 첫째로 고려한 방법은 Sticky Session입니다. Sticky Session은 어떠한 사용자의 세션이 1.. 2020. 9. 2.
백준 8980번 택배 골드4 그리디 알고리즘으로 풀었다. 받는 마을 기준으로 정렬을 시킨다. 1 5 10 2 3 40 3 4 40 이런경우에도 조건을 만족하려면 받는 마을 기준으로 정렬을 시켜야 최적해를 구할 수 있다. #include #include using namespace std; typedef struct Box { int sendi; int reci; int boxn; } Box; bool comp(Box a,Box b) { if(a.reci==b.reci) return a.sendi >n>>c>>m; Box arr[m]; for(int i=0;i>arr[i].sendi>>arr[i].re.. 2020. 6. 11.