본문 바로가기

전체 글

(161)
[231126] Arrays.asList에서 사용할 때 주의할 점 Arrays.asList는 읽기만 가능하다 💬 Arrays.asList는 여러 값을 한 번에 입력해 List를 만들어주는 메서드입니다. 저는 이것을 자주 애용했습니다. 회사에서 이번에 API를 개발하면서 사용을 했는데 Arrays.asList를 통해 만들어진 List에 add 호출을 할 때 예외가 터졌습니다. 읽기만 가능한 이유? ✅ Arrays.asList로 List를 만들 경우 ArrayList가 하나 만들어집니다. 이 ArrayList안의 멤버 변수에 크기가 고정된 배열이 할당 되기 때문입니다. ➡ asList의 매개변수는 가변인자이며 각 값들이 합쳐진 배열로 만들어져 들어갑니다. public static List asList(T... a) { return new ArrayList(a); }​ ➡ ..
[231119] 출석체크 API를 테스트하면서 발견한 버그 출석체크 API 테스트 💬 출석체크를 통해 보상을 주는 이벤트가 있기 때문에 생각하지 못한 문제가 있는지 확인하기로 했습니다. API를 여러 번 호출을 해보면서 실제 예상하는 대로 동작을 하는지 테스트를 진행했습니다. ✔ 발견한 문제 1 💢 Redis와 DB에 들어가는 등록 시간을 불일치하는 현상이 발견되었습니다. 이는 단순하게 몇 초차이가 나는 것이었지만 23시 59분 59초에 입력이 들어온다면 날짜별로 출석체크 하는 API에서는 문제가 될 수 있었습니다. ✅ Redis와 DB 시간을 일치시켜주기 위해 DB에 now()를 사용하지 않고 서버의 시간을 Redis와 DB에 직접 넣어주었습니다. 💢 위에서 나온 문제는 해결이 되었지만 23분 59분 59초에 넣은 데이터가 다음 날로 들어가는 현상이 발견되었습..
[231102] MySQL 데이터 분석을 위한 SQL 작성... 더 나아지기 데이터 건수가 많아 💬 건수가 2억 건 이상이 되니 데이터를 원하는 형태로 추출하는 것이 너무 느렸습니다. 30분 이상.. 1시간 이상 돌려도 원하는 동작이 완료되지 않았습니다. 그래서 저번에 6년 차 개발자님이 조언해 주신 대로 적용을 해보기로 했다. ✔ Explain 💬 먼저 각 쿼리에 대한 실행 전략을 확인하기 위해 Explain을 사용을 해보았다. 내가 작성한 쿼리는 2억 건을 그대로 가져다가 쓰는 형식으로 실행이 된다는 것을 확인할 수 있었다. 문제를 확인했으니 이것을 개선하기 위한 방법을 고려해 보았다. ✔ Where로 데이터의 건수 줄이기 💬 전체 기간으로 잡았던 것을 1년 기간으로 줄여보았다. 줄여보니 확실히 Explain에서 보여주는 Row 건수는 줄어드는 것을 확인할 수 있었다. 하지만..
[231030] MySQL 데이터 분석을 위한 SQL 작성 어려움... 데이터 분석 의도 💬 회사에서 조회 속도 향상을 위해 일정 주기로 데이터를 통합하기로 했습니다. 데이터 분석을 통해 기준을 세우고 코드를 작성해 특정 시간이 되면 배치 작업이 돌아가도록 하기로 했습니다. ✔ 데이터 분석을 하며 느낀 문제점 💬 데이터 건수가 많다보니 JOIN, WHERE 등이 들어가면 실행이 몇 십분 씩 걸린다는 것이었습니다. 거기에 더해 제가 SQL를 미숙한 것까지 합쳐져서 더 나은 방안을 제시할 수가 없었다는 것이었습니다. ✔ 문제점을 해결하기 위한 노력 💬 내가 짠 SQL문에서 더 나은 방향성은 없는지 인터넷을 찾아보면서 고쳐보는 수밖에 없다고 판단했습니다. ➡ 1번 문제점은 IN을 통해 데이터가 유효성을 검사하고 있었습니다. 찾아보니 IN은 모든 컬럼값을 직접 비교를 하기 때문에 ..
[231029] S3 데이터 이전하기 S3 데이터 이전 💬 인생퍼즐 사이드 프로젝트에서 AWS 계정을 변경하면서 S3 저장소를 옮겨야 했습니다. 새로 S3를 만들고 기존 데이터를 전부 이동시키기로 했습니다. ✔ 기존 S3에서 데이터 받기 ✅ AWS CLI를 통한 다운로드 ➡ aws s3 cp s3://itmca-public . --recursive ➡ 하위 파일들까지 전체 복사하기 위해 --recursive 옵션을 사용 ✔ 다운 받은 데이터를 새로운 S3에 업로드 ✅ AWS CLI를 통한 업로드 ➡ aws s3 sync ./ s3://lifepuzzle-public ✔ 결과 ✅ 정상적으로 전체 데이터가 새로운 S3에 업로드 된 것을 확인
[231022] Mybatis 파라미터 #과 $의 차이 Mybatis 파라미터 받는 방식 💬 회사를 다니면서 Mybatis 코드를 보게 되었습니다. 코드에 #과 $ 기호를 사용하여 파라미터로 전달하고 있었습니다. 코드를 이해하기 위해 두 기호의 차이가 무엇인지 알아보기로 했습니다. 또한 각각 어디에 사용이 되는지도 궁금했습니다. 이후에 제가 작성하게 되면 적절한 곳에 사용하기 위해서입니다. ✔ 파라미터 # (Binding Variable) 1. 쿼리문이 파싱이 되면 해당 쿼리문을 재활용 2. 값에 자동으로 ''가 붙음 3. PreparedStatement여서 SQL Injection 공격을 예방할 수 있음 ✔ 파라미터 $ (Literal Variable) 1. 값이 들어올 때마다 쿼리문을 매번 파싱을 하여 사용 2. 값에 자동으로 ''붙지 않음 ➡ 문자열 입..
[231008] JWT는 어디에 저장을 해야할까? JWT 저장 장소 💬 기존에 작성했던 로그인 코드를 리팩터링 하는 과정에서 문득 궁금증이 생겼다. JWT에 Stateless라는 장점을 가진 대신 보안에 취약하다는 단점을 가지고 있는데, 이를 위해 어디에 저장하는 것이 좋을까? JWT 저장 후보군 ✔ 웹 스토리지 💬 웹 스토리지는 XSS(Cross-Site Scripting)에 취약해서 스크립트를 통해서 JWT가 쉽게 탈취될 수 있다는 문제를 가지고 있다. 실제로 스크립트를 통해서 토큰 확인이 가능한지 아래와 같이 테스트를 해보았다. ✔ 쿠키 💬 그에 반해 쿠키는 간단한 설정으로 XSS(Cross-Site Scripting)을 막을 수 있다. 하지만 CSRF(Cross Site Request Forgery)에는 취약하다는 문제가 있다. 결론 💬 보안적인..
[230923] Java PriorityQueue와 Comparator 사용하기 PriorityQueue 사용 💬 알고리즘 문제에서 저장한 데이터를 우선순위에 따라 추출해야 했습니다. 이 경우 가장 먼저 떠오르는 것이 우선순위 큐(Heap)였습니다. Java에서 제공하는 자료구조였기에 쉽게 적용해 볼 수 있었습니다. ✔ 메커니즘 💬 Java에서 제공하는 PriorityQueue는 Comparator를 지정하지 않으면 제너릭에 입력한 타입의 Comparator 가져다가 씁니다. 이번에는 Integer를 사용했기 때문에 숫자의 크기에 따라 우선순위가 정해졌습니다. ✔ 절댓값 크기로 우선순위 정하기 💬 문제에서 절댓값 크기와 절댓값이 같은 경우 숫자의 크기로 우선순위가 정해져야 했습니다. Integer Comparator를 사용하면 원하는 우선순위를 얻을 수 없습니다. 별도의 Compar..