14 Oct 2024
테스트 관련 서적을 읽다보면 Hamcrest를 이용한 커스텀 매처를 구현해서 사용하는 경우를 볼 수 있는데, 직접 구현해보자.
TypeSafeMatcher란?
TypeSafeMatcher는 주로 JUnit이나 다른 테스트 프레임워크에서 사용되는 Matcher 클래스의 특수한 유형으로, 특정 객체의 타입에 안전한 비교를 제공하는 기능을 한다.
주로 Hamcrest 라이브러리와 함께 사용되며, 타입이 안전하게 매칭될 수 있도록 보장한다.
구성
TypeSafeMatcher : TypeSafeMatcher 클래스는 T 타입의 객체를 안전하게 처리할 수 있게 한다. 매칭을 수행할 때 T 타입을 명시하여 타입 안전성을 보장한다.
matchesSafely : 실제 매칭 로직을 구현한다.
describeTo : 매칭 실패 시 출력될 설명을 제공
예제
유저 이름이 일치하는지 확인하는 테스트 코드를 작성해보자.
먼저 TypeSafeMatcher 를 구현한다.
테스트 코드
실패 메시지 확인
07 Oct 2024
정규 표현식(Regular Expression, regex라고 많이 사용)은 문자열에서 특정 패턴을 검색하거나 대체, 추출할 때 사용되는 문자열의 규칙을 정의하는 언어다.
정규 표현식을 사용하면 텍스트에서 특정한 조건을 만족하는 부분을 찾거나, 그 부분을 변경하는 작업을 쉽게 할 수 있다.
기본 구성 요소
- 리터럴 문자: 그냥 문자열 그대로 찾고자 할 때 사용됨
- 예: “abc”는 “abc”라는 문자열을 찾는다.
- 메타문자: 특별한 의미를 가진 문자들이다.
- .: 임의의 한 문자 (개행 문자 제외)
- ^: 문자열의 시작
- $: 문자열의 끝
- []: 문자 클래스, 대괄호 안에 있는 문자 중 하나를 찾음
-
- () : 그룹화, 하위 패턴을 그룹으로 묶음
- 수량자: 반복을 나타내는 문자
- *: 0번 이상 반복
- +: 1번 이상 반복
- ?: 0번 또는 1번
- {n}: 정확히 n번 반복
- {n,}: n번 이상 반복
- {n,m}: n번 이상 m번 이하 반복
- 이스케이프 문자: 메타문자를 문자 그대로 사용하고 싶을 때 사용
- 예: .은 마침표를 의미하며, \은 백슬래시를 의미
- 문자 클래스: 특정 범위의 문자들을 지정할 수 있습니다.
- \d: 숫자와 동일 (0-9)
- \D: 숫자가 아닌 문자
- \w: 알파벳, 숫자, 밑줄(_)과 일치
- \W: 알파벳, 숫자, 밑줄이 아닌 문자
- \s: 공백 문자 (스페이스, 탭, 개행 등)
- \S: 공백 문자가 아닌 문자
예시
이메일 검증 정규식
전화번호 형식 검증
- 정규식 : ^(01[016789])-\d{3,4}-\d{4}$
- ^\d{3} : 숫자 3개로 시작
- ”-“ : 하이픈
- \d{3,4} : 숫자 3개 또는 4개
- ”-“ : 또 다른 하이픈
- \d{4}$ : 숫자 4개로 끝
자바에서 정규 표현식 사용하기
자바에서 정규 표현식을 사용하려면 Pattern 클래스와 Matcher 클래스를 사용하면 된다.
Spring validation에서 정규 표현식 사용하기
필드가 정해진 정규 표현식에 만족하게 하려면 @Pattern 어노테이션을 사용한다.
email 형식을 검증하는 @Email 어노테이션을 사용해도 된다.
30 Sep 2024
try-with-resources는 자바 7에서 도입된 문법으로, 자원을 자동으로 관리하고 닫을 수 있도록 도와주는 기능이다.
try-with-resources는 AutoCloseable 인터페이스를 구현하는 객체들을 사용하여 자원을 자동으로 닫을 수 있게 해준다.
AutoCloseable 인터페이스는 close() 메서드를 가지고 있는데, 이 메서드는 객체가 더 이상 필요하지 않을 때 호출되어 자원을 정리한다.
기본 문법
예제
데이터베이스를 사용하는 코드
직접 AutoCloseable 구현
try-with-resources를 사용해야 하는 이유
전통적으로 자원이 제대로 닫힘을 보장하는 수단으로 try-finally가 쓰였다.
하지만 예외는 try 블록과 finally 블록 모두에서 발생할 수 있어, 두 번째 예외가 첫 번째 예외를 완전히 먹어벼려, 스택 추적 내역이 남지 않아서 디버깅이 어려워 진다.
또한 명시적으로 finally 블록을 만들어야 해서 실수로 작성하지 않게 되는 문제를 제거해준다.
23 Sep 2024
뮤텍스(Mutex)와 세마포어(Semaphore)에 대해서 알아보자.
뮤텍스(Mutex)
뮤텍스는 상호 배제를 보장하는 잠금 메커니즘이다.
하나의 자원에 대해 한 번에 하나의 스레드만 접근할 수 있도록 하는 방식이다.
즉, 뮤텍스를 사용하면 동시성 문제를 방지하고 레이스 컨디션을 막을 수 있다.
스택오버플로우에 재밌는 예시가 있어서 가져와봤다!
예를 들어, 사무실에서 격한 토론을 할 때에 테이블에 장난감 닭을 집은 사람만
발언권을 얻고 나머지는 말을 하지 못한다고 가정해보자.
닭을 집은 사람이 말을 할 때엔 다른 사람들은 닭을 받을 때까지 기다렸다가 말을 할 수 있다.
말을 마치면 닭을 사회자에게 돌려주고 사회자는 다음 사람에게 닭을 전달한다.
여기서 닭을 Mutex로, 사람을 Thread로 바꾸면 Mutex라는 개념이 생긴다.
뮤텍스의 개념을 자바 코드로 알아보자.
synchronized 키워드는 자바에서 기본적인 뮤텍스 기능을 제공한다.
특정 블록이나 메서드에 대해 동기화를 하여 한 번에 하나의 스레드만 접근할 수 있게 해준다.
해당 테스트 코드를 실행하면 테스트가 성공하는 것을 볼 수 있다.
만약에 synchronized 키워드를 지우면 어떻게 될까?
테스트 숫자의 크기가 작으면 성공할 때도 있지만 동시성 문제가 발생하여 대부분 실패한다.
사람들이 서로 닭을 집어가는 상황인 것이다.
뮤텍스는 단일 자원에 대한 동시 접근을 방지하는 데 사용된다.
하지만 같은 스레드만 잠금을 해제할 수 있기 때문에, 잘못된 잠금 해제가 발생하면 데드락(교착상태)이 발생할 수 있다.
세마포어(Semaphore)
세마포어는 카운팅 기반의 동기화 기법으로, 여러 스레드나 프로세스가 동시에 접근할 수 있는 자원의 개수를 제한할 때 사용된다.
세마포어는 정수 값을 유지하며, 이 값은 자원에 접근 가능한 수를 나타낸다.
세마포어는 [도서관에 비유]https://en.wikipedia.org/wiki/Semaphore_(programming))해보자.
도서관에 스터디 룸이 10개가 있다고 가정하고, 한 번에 한 명의 학생이 사용할 수 있다고 가정하자.
학생들은 접수 데스크에서 스터디 룸을 요청해야 한다.
빈 스터디 룸이 없다면 학생들은 다른 학생이 룸을 내어줄 때까지 접수 데스크에서 기다려야 한다.
학생이 룸 사용을 마치면 학생은 데스크로 돌아와서 룸이 비어 있음을 알려야 한다.
세마포어는 자원의 개수를 제한하여 동시성을 제어하는 방법이다.
세마포어도 자바 코드로 알아보자.
자바에서 세마포어는 java.util.concurrent 패키지에 포함된 Semaphore 클래스로 제공된다.
- acquire(): 세마포어의 카운트를 하나 감소시키며, 카운트가 0이면 대기합니다.
- release(): 세마포어의 카운트를 하나 증가시킵니다.
여러 번 실행해봐도 연속으로 3번 이상 세마포어를 얻는 로그는 발견되지 않는다.
16 Sep 2024
자바에서 enum은 특정 값들의 집합을 표현하는 데 사용되는 특별한 데이터 타입이다.
enum 클래스는 주로 상태, 타입, 옵션 또는 특정 범위 내의 값을 나타내는 데 유용하다.
기본사용법
enum은 enum 키워드를 사용해서 정의한다.
모두 대문자로 작성하는 것이 관례다.
그냥 문자열 데이터를 사용하면 되는 데 왜 굳이 열거형 데이터를 사용할까?
enum 데이터를 사용하면 문자열만으로 사용하는 것보다 많은 장점을 가진다.
- 타입 안전성
열거형을 사용하면, 값이 미리 정의된 상수들로 한정되니, 잘못된 값이 사용되는 것을 방지할 수 있다. -> 컴파일 시점에서 오류를 발견할 수 있다.
- 가독성
열거형은 의미 있는 이름을 사용할 수 있어 코드의 가독성을 향상시킨다.
- 오타 방지
열겨형은 값을 미리 정의해 놓고, 해당 값만 사용할 수 있도록 제한하므로, 잘못된 값을 입력하는 실수를 방지할 수 있다.
- 비즈니스 로직을 코드로 표현
열거형은 값에 대해 추가적인 속성이나 로직을 추가할 수 있기 때문에 비즈니스 로직을 보다 명확하게 표현할 수 있다.
- 성능
열거형은 내부적으로 상수 값으로 처리되므로, 문자열에 비해 성능이 우수할 수 있다.
문자열은 equals() 메서드를 호출하는 과정이 필요하지만 열거형은 == 연산자로 비교할 수 있어 효율적이다.
enum과 인터페이스
enum은 인터페이스를 구현할 수 있다.
이를 통해 enum 값마다 다르게 동작하는 메서드를 정의할 수 있다.
enum과 싱글톤
자바의 enum은 내부적으로 객체의 인스턴스를 하나만 가지도록 보장된다.
enum 값은 각 값마다 하나의 객체 인스턴스만 존재하며, 이 객체는 JVM에서 유일하게 존재한다.
enum을 사용하면 다중 스레드 환경에서도 자원 공유가 안전하게 보장되며, enum 값이 final로 고정되기 때문에 jvm의 로딩 과정에서 한 번만 인스턴스 생성이 된다.
코드로 알아보자
참조값과 해시코드까지 동일하게 출력된다.