목록전체보기 (302)
elevne's Study Note

1. 예외 처리 JPA 표준예외는 크게 트랜잭션 롤백을 표시하는 예외와, 그렇지 않은 예외 두 가지로 분류할 수 있다고 한다. 이 중 트랜잭션 롤백을 표시하는 예외는 심각한 예외로, 복구해서는 안된다고 한다. (이 예외가 발생하면 트랜잭션을 강제로 커밋해도 트랜잭션이 커밋되지 않고 RollbackException 이 발생한다) 트랜잭션 롤백을 표시하지 않는 예외는 심각한 예외가 아니므로 개발자가 트랜잭션을 커밋할지 롤백할지를 판단하면 된다. 서비스 계층에서 데이터 접근 계층의 구현 기술에 직접 의존하는 것은 좋은 설계라고 할 수 없다. 이는 예외에 있어서도 마찬가지이다. 서비스 계층에서 JPA 의 예외를 직접 사용하면 JPA 에 의존하게 된다. 스프링에서는 이를 해결하기 위해 데이터 접근 계층에 대한 예..

하이버네이트는 엔티티를 영속 상태로 만들 때 컬렉션 필드를 하이버네이트에서 준비한 컬렉션으로 감싸서 사용한다. 예를 들어, ArrayList 타입으로 Member 리스트를 가지고 있는 Team 엔티티를 em.persist() 메소드를 통해 영속 상태로 만들고 나서 다시 Member 리스트를 확인해보면 org.hibernate.collection.internal.PersistentBag 타입으로 바뀌어있는 것을 확인할 수 있다. 하이버네이트는 컬렉션을 효율적으로 관리하기 위해 엔티티를 영속 상태로 만들 때 원본 컬렉션을 감싸고 있는 내장 컬렉션을 생성해서 이 컬렉션을 사용하도록 참조를 변경한다. 하이버네이트는 이런 특징 때문에 컬렉션을 사용할 때 아래와 같이 즉시 초기화해서 사용하는 것을 권장한다. @En..

Logback 은 Spring MVC 에서 로그를 남길 때 사용되던 log4j 의 후속 로그 라이브러리이다. SLF4J 의 구현체로, SLF4J 의 API 를 그대로 사용할 수 있다. 이는 spring-boot-starter-web 에 포함되어 있으니 따로 dependency 를 추가해줄 필요 없다. 로그를 사용할 때에는 로깅으로 인한 side effect 가 생기게 해서는 안된다. 예를 들어, 로그를 남기는 로직에서 예외가 발생하여 프로그램이 정상적으로 동작하지 않는 일이 생겨서는 안된다는 뜻이다. 각 로그에는 해당 로직에서 사용된 데이터와 설명이 들어가야 하며, 로그에는 사용자의 개인정보와 같은 민감한 정보가 들어가서는 안된다. 메소드의 input, output 을 로그로 남기면 debugger 을 ..

아이템 42. 익명 클래스보다는 람다를 사용하라 예전에는 자바에서 함수 타입을 표현할 때, 함수객체라고 불리는 추상 메소드를 하나만 담은 인터페이스 (드물게는 추상클래스) 를 사용했다. 이러한 함수객체를 만드는 주요 수단은 익명클래스였다. public void test1(List words) { words.sort(new Comparator() { public int compare(String s1, String s2) { return Integer.compare(s1.length(), s2.length()); } }); } 전략패턴처럼, 함수 객체를 사용하는 과거 객체지향 디자인 패턴에는 익명클래스면 충분했다. 하지만 익명 클래스 방식은 코드가 너무 길다. 이 대신에 람다식을 사용할 수 있다. 익명 클..

아이템 34. int 상수 대신 열거 타입을 사용하라 열거타입은 일정 개수의 상수 값을 정의한 다음, 그 외의 값은 허용하지 않는 타입이다. (사계절, 태양계의 행성, 카드게임 카드 등) 자바에서 열거타입을 지원하기 전에는 정수 상수를 한 묶음 선언해서 사용했었다고 한다. 이러한 방식은 타입 안전을 보장하지도 못하고, 표현력도 좋지 않다. 또 이러한 정수 열거 패턴을 사용한 프로그램은 깨지기 쉽다. 평범한 상수를 나열한 것 뿐이라 컴파일하면 그 값이 클라이언트 파일에 그대로 새겨진다. 컴파일하면 그 값이 클라이언트 파일에 그대로 새겨지며, 상수의 값이 바뀌면 클라이언트도 반드시 다시 컴파일해야 한다. 정수 상수는 문자열로 출력하기도 까다로워 디버깅할 때에도 좋지 않다고 한다. (정수 대신 문자열 상수를 ..
최단경로 알고리즘은 말 그대로 가장 짧은 경로를 찾는 알고리즘이다. 최단경로 알고리즘 유형에는 다양한 종류가 있는데, 상황에 맞는 효율적인 알고리즘이 이미 정립되어 있다고 한다. 1. 다익스트라 최단 경로 알고리즘 다익스트라 최단 경로 알고리즘은 그래프에서 여러 개의 노드가 있을 때, 특정 노드에서 출발하여 다른 노드로 가는 각각의 최단 경로를 구해주는 알고리즘이다. 다익스트라 최단경로 알고리즘은 기본적으로 그리디 알고리즘으로 분류된다. 매번 가장 비용이 적은 노드를 선택해서 임의의 과정을 반복하기 때문이다. 출발 노드를 설정한다 최단 거리 테이블을 초기화한다 방문하지 않은 노드 중에서 최단 거리가 가장 짧은 노드를 선택한다 해당 노드를 거쳐 다른 노드로 가는 비용을 계산해서 최단 거리 테이블을 갱신한다..

다이나믹 프로그래밍, 동적 프로그래밍은 연산 속도와 메모리 공간을 최대한으로 활용할 수 있게끔 해주는 효율적인 알고리즘이다. 다이나믹 프로그래밍으로 해결할 수 있는 대표적인 문제로 피보나치 수열 문제가 있다. 수학자들은 점화식을 통해 수열의 항이 이어지는 형태를 간결하게 표현한다. 피보나치 점화식은 인접 3 항 간 점화식이다. 이러한 점화식에 따라 실제로 피보나치를 구하는 함수를 작성하면, 재귀함수를 작성해볼 수 있다. 하지만 재귀함수를 사용하면, f(n) 함수에서 n 의 값이 커질수록 수행 시간이 기하급수적으로 늘어나게 된다. ( n 이 30 일 때, 약 10 억 가량의 연산을 수행한다) 재귀함수를 사용하는 것보다는, 다이나믹 프로그래밍을 사용하면 효율적으로 문제를 해결할 수 있다. 아래 조건들이 만족..

스프링 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 이는 트랜잭션 범위와 영속성 컨텍스트의 생존 범위가 같다는 뜻이다. (트랜잭션을 시작할 때 영속성 컨텍스트를 생성하고 트랜잭션이 끝날 때 영속성 컨텍스트를 종료한다. 같은 트랜잭션 안에서는 항상 같은 영속성 컨텍스트에 접근한다) 여러 스레드에서 동시에 요청이 와서 같은 엔티티 매니저를 사용해도 트랜잭션에 따라 접근하는 영속성 컨텍스트가 다르다. (스프링 컨테이너는 스레드마다 각각 다른 트랜잭션을 할당한다) 스프링이나 J2EE 컨테이너는 트랜잭션 범위의 영속성 컨텍스트 전략을 기본으로 사용한다. 트랜잭션은 보통 서비스 계층에서 시작하므로 서비스 계층이 끝나는 시점에 트랜잭션이 종료되면서 영속성 컨텍스트도 함께 종료된다. 따라서 조..