본문 바로가기

분류 전체보기42

[아이템 50] 적시에 방어적 복사본을 만들라 클라이언트가 우리의 불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍을 해야 한다. Period.class final class Period { private final Date start; private final Date end; public Period(Date start, Date end) { if (start.compareTo(end) > 0) throw new IllegalArgumentException("start가 end보다 늦다."); this.start = start; this.end = end; } public Date getStart() { return start; } public Date getEnd() { return end; } } start와 end가 한번 .. 2022. 2. 15.
[아이템 49] 매개변수가 유효한지 검사하라 메서드와 생성자의 입력 매개변수의 값에 제약조건이 있다면 필수적으로 해야 할 것. 메서드에 대한 문서화. 메서드 몸체가 시작되기 전에 매개변수 유효성 검사. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. 검사를 제대로 하지 못하면 잘못된 반환 값을 던지거나, 메서드와 관련 없는 예외를 던질 수 있으니 주의해야 한다. 아래 코드는 문서화와 유효성 검사의 전형적인 예이다. 자바 7엔 Objects.requireNonNull 메서드가 추가되어 간편하게 null 검사가 가능하다. public static T requireNonNull(T obj) { if (obj == null) throw new NullPointerException.. 2022. 2. 14.
Spring Data Jpa의 N+1 문제 N+1 문제란 DB에서 데이터를 조회할 때 연관된 데이터를 추가로 쿼리문을 실행해 조회하는 현상을 뜻한다. 쿼리문이 추가로 실행되는게 무슨 대수냐 할 수 있지만 대부분의 DB는 Disk I/O와 Network I/O가 발생함으로 불필요한 쿼리가 실행되지 않게 해야 성능의 부담을 줄 수 있다. JPA에서 N+1 문제가 언제 발생하는지 알아보고 해결해 보겠다. 예를 위한 Person, Team 그리고 각각 Repository를 만들어 봤다. Person.class @Entity @Data @AllArgsConstructor @NoArgsConstructor @Builder public class Person { @Id @GeneratedValue private Long id; private String na.. 2022. 2. 7.
[아이템 26] 로 타입(raw type)은 사용하지 말라 아이템 26부터 제네릭에 대한 내용이다. 로 타입이란 타입 매개변수가 없는 제네릭 타입으로 List를 예로 들 수 있다. List rawList = new ArrayList(); // 로 타입 리스트 List strings = new ArrayList(); // 문자열을 담는 리스트 List integers = new ArrayList(); // 정수를 담는 리스트 rawList.add(1); rawList.add(1.1); rawList.add("raw"); rawList.add('r'); strings.add(1); // 컴파일 에러 로 타입은 Object를 넣을 수 있어 어떤 객체도 담을 수 있다. 그래서 문제가 되는데 예상치 못하게 넣지 말아야 할 객체를 넣었다면 형 변환 런타임 오류가 발생할 수.. 2022. 2. 7.
Java의 == 와 equals() Java에서 값을 비교하는 방법은 == 연산자와 equals() 메서드를 사용하는 것이다. == 연산자는 순수하게 값을 비교해주는 연산자이며, equals()는 논리적으로 같은 객체인지 비교하는 메서드이다. 예를 설명하기 위해 Person 클래스를 만들어보았다. name이 다르더라도 id 값이 같다면 동일 인물이다. class Person { Long id; // 주민등록번호 String name; // 이름 public Person(Long id, String name) { this.id = id; this.name = name; } } 일단 == 비교 연산을 해보았다. public static void main(String[] args) { Person p1 = new Person(1L, "홍길동").. 2022. 1. 14.
[Delivery] 여러 명의 Rider가 동시에 동일한 주문 배달을 접수할 때 이슈 Delivery 프로젝트의 배달 주문의 프로세스를 간략히 표현하면 위의 그림과 같습니다. 1. User는 장바구니에 담아 놓은 메뉴로 주문을 요청합니다. 2. Owner는 주문 요청을 승인합니다. 3. Rider는 승인된 주문을 배달 접수를 합니다. 4~5. 다른 Rider가 동일한 주문에 배달을 접수하면 예외를 발생합니다. 언뜻 보기에 문제가 없어 보이지만 그렇지 않았습니다. 여러 명의 Rider가 동시에 동일한 주문에 배달 접수할 때, 모든 Rider가 접수가 되는 문제가 생길 수 있습니다. DB엔 어떤 Rider가 저장될지는 아무도 모릅니다. 마치 멀티스레드 환경에 공유자원을 사용해 문제가 발생하는 이슈와 같습니다. 빨간색 부분은 주문의 상태를 보고 이미 다른 Rider가 배달 접수를 했다면 예외를.. 2022. 1. 7.