Java에서 한글을 2바이트로 처리하기
2023. 8. 10. 21:53
카테고리 없음
🚀 Problem php → java로 컨버팅을 하고 php 서버의 api와 java 서버의 api의 응답 데이터를 완전히 동일하게 맞추는 방식으로 테스트를 진행했다. 기능을 바꾸는 것이 아닌 코드 컨버팅만 했기 때문에 php서버의 응답과 100% 동일해야 했다. 발생 문제 문자열을 최대 150로 잘라야 했다. php에서는 기본 api를 사용해서 문자열을 자르면 바이트 기준 150개로 자른다. 이때 한글은 2바이트로 인식한다. 하지만 java는 문자열 자체를 기준으로 두기 때문에 2배 적게 길이가 측정됐다. 예를 들면 아래와 같다. 언어 자를 길이 타겟 문자열 결과 php 4 안녕하세요 안녕 java 4 안녕하세요 안녕하세 java에서 StringUtils.left(string, limit)를 사용했다...
아스키 코드와 유니코드 그리고 인코딩과 디코딩
2023. 8. 10. 21:52
카테고리 없음
🚀 아스키 코드와 인코딩 컴퓨터의 저장 단위 컴퓨터의 기본 저장 단위는 Byte이다. 1Byte는 8bit를 의미하고, 1byte는 2^8에 해당하는 256개의 값을 저장할 수 있다. 즉, 우리가 컴퓨터에서 사용하는 모든 문자는 이 Byte에 담기는 것이다. ASCII(American Standard Code for Information Interchange) 아스키는 1960년대에 미국에서 정의한 문자 부호 표준이다. 컴퓨터와 통신을 하기 위해서 정의된 부호이다. 컴퓨터는 이진수만 다룰 수 있기 때문에 0, 1을 제외하고 다른 것을 읽을 수 없다. 그래서 최종적으로 문자는 이진수로 바껴서 컴퓨터에 저장된다. 우리가 사용하는 문자를 컴퓨터 언어로 어떤 식으로 표현할지 약속을 정하게 되는데 그게 아스키 코..
URL Encoding의 공백 인코딩 방식 +와 %20
2023. 8. 10. 21:50
카테고리 없음
🚀 URL 인코딩 알기 URL 인코딩은 웹 브라우저와 웹 서버가 URL을 안전하게 송신하기 위한 인코딩 방식이다. 보통 유니코드의 Charset인 UTF-8 방식을 사용한다. 공백 문자 +, %20 URL 인코딩을 보면 공백을 + 또는 %20으로 표현되는 경우가 있다. +는 레거시로 많이 쓰였고, %20이 표준이기 때문에 %20이 주로 쓰인다. 무엇을 사용해야 하는가는 정답은 없고, 정하기 나름이기 때문에 규칙을 정하고 따르는 것이 중요하다. 🚀 Problem URL 인코딩 공백의 문제가 있었다. URL로 넘어오는 것(location)은 “안녕하세요%20저는%20덕입니다”라고 요청하는 상태였다. 하지만 서버에서 올바른 URL인지 체크하는 과정에서 DB에 저장되어 있는 url 정보에서 “안녕하세요 저는 덕..
Instant, LocalDateTime, Instant 차이와 활용
2023. 8. 10. 21:48
카테고리 없음
🙏 서론 현재 우리 회사에서는 모든 날짜는 UTC 타임존을 기반으로 한다. 이 과정에서 타임존에 대한 이해가 제대로 잡힌 분들과 잡히지 않는 분들이 있는 것 같다. 코드를 보면, LocalDateTime과 Instant가 섞여서 사용되고 있다. 같은 로직임에도 불구하고. 나도 제대로 잡히지 않는 사람 중 한 명이다. 타임존에 대해서 한 번 정리를 했지만, 아직도 UTC를 채택하는 이유에 CTO님께 설명을 들었음에도 공감을 떠나서 이해를 제대로 하지 못한 상황이다. 이번 기회에 LocalDateTime과 Instant로 타임존에 대한 이해도를 조금 더 높일 목적이다. 🙏 Instant, LocalDateTime, ZoneDateTime 차이점 및 특징 LocalDateTime Java 1.8 로컬 타임존을..
Query DSL에서 MySQL FIELD Function 사용하기
2023. 8. 10. 21:48
카테고리 없음
🏋🏽 서론 Query DSL을 사용하다 보면, DB Function을 지원하지 않는 것들이 많이 있다. 나는 파라미터로 온 Id 목록을 기준으로 sorting할 필요가 있어서 field function이 필요했다. 그 과정에서 겪은 issue를 살펴보자. 🏋🏽 트러블 슈팅 기존 방법 Expressions를 사용했는데 동적 쿼리를 활용하기 위함일 뿐이다. private static SimpleTemplate template(Path column, List ids) { return Expressions.simpleTemplate(Integer.class, "FIELD({0}, {1})", column, String.join(", ", String.join(", ", ids)) ); } 처음에는 이 코드에는 ..
Java Cloneable
2023. 8. 10. 21:46
카테고리 없음
🧐 Cloneable 정의 단순히 복사를 위한 marker interface이다. marker interface는 아무것도 존재하지 않는 interface를 의미한다. interface를 구현하고, super.clone()을 호출하면 사용할 수 있다. 만약 interface를 구현하지 않는 클래스가 호출하게 되면 CloneNotSupportedException가 발생한다,. 피상 복사(Shallow Copy)이다. clone() 메서드의 기본 제공은 Object 클래스가 제공한다. java.lang 패키지에 위치하므로, Import가 필요없다. 🧐 주의 사항 피상 복사(Shallow Copy)이다. 💡 처음에 Cloneable 구현체의 복사가 Deep Copy로 이루어져서 필드도 모두 Deep Copy를..
테스트로 도메인 지식을 유출하면 안된다.
2023. 8. 10. 21:45
카테고리 없음
서론 회사에서 단위 테스트 스터디를 하면서 챕터 11에서 테스트로 도메인 지식을 유출하면 안된다는 내용을 봤다. 좋은 내용 같아서 정리한다. 본론 문제점 무의미한 검증 거짓 음성(거짓 성공) 도메인 로직과 강결합 calculateTotalPrice()를 테스트할 경우 테스트는 통과하게 된다. 하지만 무의미한 검증이다. 문제점을 알아보자. class Payment { private double price; public Payment(double price) { this.price = price; } public double calculateTotalPrice() { return price * 1.1; } public double getPrice() { return price; } } @Test void 무..
MySQL rand() SubQuery 실행 계획
2023. 8. 10. 21:44
카테고리 없음
문제 만약 아래 쿼리를 돌리면 결과는 어떻게 나올까? 나는 랜덤으로 사용자를 1명 뽑아서 그 사용자 1명을 조회할 줄 알았다. user table id name 1 name1 2 name2 3 name3 select * from users where id = ( select id from users order by rand() limit 1 ); -- 애초에 쿼리를 아래와 같이 쓰면 되지 않나라고 생각할 수 있지만 이건 실행 계획을 이해하기 위한 예제일 뿐이고, -- 내가 실제로 겪은 문제는 다른 테이블 간 조인이 걸려 있어서 이렇게 할 수 없는 상황이었고, -- 이로 인해 rand() 서브 쿼리에 대한 실행 계획을 알기 위함에 이외 같은 예제를 선택했다. select * from users order ..