Comparator 와 오버플로우
·
개발
Java 에서는 정렬 기준을 정하기 위하여 Comparator 를 구현한다. Comparator 안에 compare 메소드를 구현하면 되는데,해당 메서드에서 return 한 값에 따라 두 원소의 자리를 변경할 것인지, 아닌지를 결정한다.여기서 return 값이 음수라면 변경하고, 아니라면 변경하지 않는다. 이러한 특성을 활용하여 두 원소를 뺄셈하는 방식으로 Comparator 를 많이 구현한다 (아래 코드처럼) class Student implements Comparator { int age; int grade; Student(int age, int grade) { this.age = age; this.grade = grade; } @Override public int compare(Studen..
JWT + Redis with 블랙리스트 (BlackList)
·
개발
JWTJsonWebToken의 준말로 주로 사용자 인증시에 사용되는 기법이다.(정의는 예전에 쿠키/세션/토큰의 차이점을 작성한 글이 있으니 참고 https://whiporithm.tistory.com/88 )그래도 장점을 살펴보자면 서버에서 상태를 저장하고 있는 세션과 달리, 아래와 같은 장점들이 존재한다.Stateless(무상태) 구조JWT는 서버에서 별도의 세션 저장소(메모리, DB, Redis 등)에 사용자 정보를 저장하지 않는다. 토큰 자체에 인증 정보를 담고 있기 때문에, 서버가 확장(수평 확장, 여러 대)되어도 별도의 세션 동기화가 필요 없다. 이로 인해 분산 시스템이나 마이크로서비스 아키텍처에 적합하다.빠른 인증 처리매 요청마다 서버가 DB나 Redis에서 세션을 조회할 필요 없이, 토큰의 ..
[Java/Spring] Client IP 를 가져오는 법
·
개발
IP 가져오기시스템에서 접속 로그를 저장하거나, 특정 IP에 대하여 분기 처리를 하는 등여러 상황에 클라이언트의 IP가 필요한 경우가 있다. 가장 쉽게, 컨트롤러단에서 HttpServeltRequest 객체에서 IP를 가져 올 수 있다.@RequestMapping("/some-path")public String someMethod(HttpServletRequest request) { String clientIp = request.getRemoteAddr(); // ... return "result";} 정확히는 HttpServletRequest 의 부모 클래스인 ServleRequest에서 제공하고 있는 메소드로, IP를 반환한다. IPv6 -> IPv4운영체제와 jvm 의 기본 설정으로..
Base64 와 Base64Url Safe
·
개발
Base64와 관련하여 개발을 진행하다가, java.lang.IllegalArgumentException: Illegal base64 character 5f 와 같은 에러가 발생했다. 해당 오류는 Base64로 인코딩 된 데이터를 디코딩 할 때 발생했었는데, 원인을 알고보니 Base64Url Safe 로 인코딩한것을 Base64로 디코딩할려다가 발생한것이었다. 두개의 차이점은 뭘까? Base64우선 개념을 알아보자면, Base64 는 이미지와 같은 바이너리 데이터를 전송할 수 없는 환경에서 데이터를 인코딩하여 보내기 위해 사용된다. 예로 HTTP 요청, 이메일 환경등이 있다. 한마디로 바이너리 데이터를 읽을 수 있는 ASCII 데이터로 변환하는 과정이다. 인코딩 과정"A" 라는 데이터를 인코딩해서 보낸다..
SMTP 란 ? (Java / Oracle 기반 구현 )
·
개발
메일 구현은 해보았으나 SMTP 를 정확히 이해하지 못한 거 같아 글을 작성하게 되었다.이메일은 어떻게 전송될까? 인터넷 이메일 시스템 구조를 볼 때 크게 3개의 요소로 구분할 수 있다. 1. User Agent 사용자 장치이며, 메일을 작성하거나 읽기 등의 기능을 수행한다.일반적으로 컴퓨터나 스마트폰 등을 생각하면 된다.  2. Mail Server메일을 송수신을 제어하고, 다수 사용자들의 메일박스를 관리한다.구글이나 네이버와 같은 메일 서버들을 칭한다. 메일 서버는 메일 전송을 위한 출력큐 (outgoing message queue) 와, 메일을 관리하는 메일박스 (mail box) 를 지닌다. 3. SMTP (Simple Mail Transfer Protocol) 메일을 전송할 때 사용되는 프로토콜..
2364 - Count Number of Bad Pairs (Java)
·
LeetCode
문제https://leetcode.com/problems/count-number-of-bad-pairs/description/  풀이문제는 i 일 때 j - i != nums[j] - nums[i]. 인 쌍을 몇 개 찾느냐인데 이 문제는 반대로 생각해야 쉽게 풀린다.  우선 위 식을 "정리" 해볼 수 있는데, 정리하면 nums[j] - j != nums[i] - i 형태로 만들 수 있다. 이제 반대로 생각해보자. 총 쌍의 개수에서 우리는 위 조건에 부합하지 않는 쌍을 찾으면 답을 구할 수 있다.위 조건의 반대는?  j > i 일 때  nums[j] - j == nums[i] - i 이다. 이 말을 풀어보면 내가 j일 때 나보다 작은 값 i 가 있을때 nums[j] - j == nums[i] - i 를 ..
380 - Insert Delete GetRandom O(1) (Java)
·
LeetCode
문제https://leetcode.com/problems/insert-delete-getrandom-o1/?envType=study-plan-v2&envId=top-interview-150  풀이set 의 형태에서, random 값을 뽑아낼 수 있는 자료구조를 만드는 문제이다. 우선 insert 와 remove 를 O(1)에 할려면 set이나 map과 같은 자료구조는 필수적으로 필요하다. 그리고  random 값을 O(1)로 뽑아내기 위해서는 리스트나 배열이 필수적이다. 해당 배열의 사이즈를 활용해서 랜덤 인덱스를 뽑고, 그 값에 한 번에 접근할 수 있으니 말이다. 난 map 과 배열의 조합으로 문제를 해결했다.  우선 배열의 끝을 가리키는 lastIdx 를 선언하고, 이를 -1로 초기화 한다. 다음은 ..
1765 - Map of Highest Peak (Java)
·
LeetCode
문제 https://leetcode.com/problems/map-of-highest-peak/description/  풀이설명이 조금 장황하지만, 단순 bfs 문제이다. 물이 시작하는곳을 체킹한다음,queue에 각각의 좌표를 넣어주고 그 지점에서부터 bfs 탐색을 시도하면 된다. 방문여부로 더 퍼트릴지를 검사하고, 퍼트릴때 값은 기존값+1로 선언해서 진행하면 된다. 코드import java.util.*;// 1로부터 bfs 를 수행하면 끗class Solution { static class Node { public int x; public int y; public Node (int x, int y){ this.x = x; ..
2638 - 치즈 (Java)
·
백준
문제https://www.acmicpc.net/problem/2638 풀이단순한 BFS 문제이다. 문제의 조건에 보면 가장자리에는 치즈가 항상 없다고 표시된다.BFS를 "치즈가 없는 가장자리" 에서 시작하면 치즈안의 빈 공간은 탐색을 안하면서, 겉에 있는 치즈를 카운트 할 수 있다. 그렇게 바깥쪽에서 탐색을 하다가 이동시에 치즈이면 해당하는 치즈 방문 카운트를 증가시켜준다. 그렇게 BFS 탐색이 한 번 끝나면, 각 치즈의 방문 카운트를 체크해서 2 이상이면 지워주면 된다. 이 과정을 치즈가 모두 없어질때까지 수행하면 해결! 코드import java.io.BufferedReader;import java.io.InputStreamReader;import java.util.*;// 2변 이상에 닿은 치즈 ->..
1238 - 파티 (Java)
·
백준
문제https://www.acmicpc.net/problem/1238 풀이다익스트라 문제이다. 단순히 n개 각각 마을에서 x 마을로의 최단 거리를 다익스트라로 구하고,그리고 x 마을에서 n개의 마을로의 최단거리를 다익스트라로 구해도 풀리긴한다. x마을에서 n개 마을로의 거리는 한번만에 다 구할 수 있으나,n개의 마을에서 x 최단거리를 구하기 위해서는 n + 1 번의 다익스트라를 돌아야하기에 굉장히 비효율적이다. 해결법은 간선의 방향을 반대로 하고 다익스트라를 수행하면 n 개의 마을에서 x 로 가는 가중치를 한번에 구할 수 있다.n개 각각 마을에서 x로 향하는 길들을 반대로 설정하고 x에서의 다익스트라를 수행하면,그건 각 마을에서 x로 향하는 최단거리가 된다. 이렇게 하면 단 두번의 다익스트라로 문제를 풀..