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

Spring 에서 Application Context 는 그 자체로 IoC, DI 를 위한 빈 팩토리이면서 그 이상의 기능을 지니기도 한다. 스프링의 빈 팩토리와 애플리케이션 컨텍스트는 각각 기능을 대표하는 BeanFactory 와 ApplicationContext 라는 두 개의 인터페이스로 정의되어 있다. ApplicationContext 는 BeanFactory 인터페이스를 상속한 서브 인터페이스이다. 스프링 애플리케이션은 최소한 하나 이상의 IoC 컨테이너, 즉 애플리케이션 컨텍스트 오브젝트를 갖는다. 가장 간단하게 IoC 컨테이너를 만드는 방법은 ApplicationContext 구현 클래스의 인스턴스를 만드는 것이다. StaticApplicationContext applicationContext..
아이템 85. 자바 직렬화의 대안을 찾으라 직렬화는 공격 범위가 너무 넓고 지속적으로 더 넓어져 방어하기 어렵다는 근본적인 문제를 갖는다. ObjectInputStream 의 readObject 메소드를 호출하면서 객체 그래프가 역직렬화되기 때문이다. readObject 메소드는 클래스 패스 안의 거의 모든 타입의 객체를 만들어낼 수 있는 생성자다. 바이트 스트림을 역직렬화하는 과정에서 이 메소드는 그 타입들 안의 코드를 수행할 수 있다. (그 타입들의 코드 전체가 공격 범위 내에 들어간다는 뜻) 신뢰할 수 없는 스트림을 역직렬화하면 원격 코드 실행, 서비스 거부 등의 공격으로 이어질 수 있다. 공격자와 보안 전문가들은 자바 라이브러리와 널리 쓰이는 서드파티 라이브러리에서 직렬화 가능 타입들을 연구하여 ..

아이템 78. 공유 중인 가변 데이터는 동기화해 사용하라 synchronized 키워드는 해당 메소드나 블록을 한 번에 한 스레드씩만 수행하도록 보장한다. 한 객체가 일관된 상태를 가지고 생성되고, 이 객체에 접근하는 메소드는 그 객체에 Lock 을 건다. 락을 건 메소드는 객체의 상태를 확인하고 필요하면 수정한다. 동기화를 통해 객체가 항상 일관된 상태로 유지되게끔 할 수 있다. 또한, 동기화를 사용하지 않는다면 한 쓰레드가 만든 변화를 다른 쓰레드에서 확인하지 못할 수 있다. 동기화는 동기화된 메소드나 블록에 들어간 쓰레드가 같은 락의 보호 하에 수행된 모든 이전 수정의 최종 결과를 보게 해준다. 언어 명세상 long, double 외의 변수를 읽고 쓰는 동작은 원자적이다. 여러 쓰레드가 같은 변수를..

테스트 코드를 작성할 때에는 "Given-When-Then" 패턴과 "F.I.R.S.T" 전략을 사용할 수 있다. "Given-When-Then" 패턴은 테스트 코드를 표현하는 방식 중 하나이다. 각 테스트 코드를 세 개의 단계로 설정해서 각 단계의 목적에 맞게 코드를 작성한다. Given: 테스트를 수행하기 전에 테스트에 필요한 환경을 설정하는 단계이다. 테스트에 필요한 변수를 정의하거나 Mock 객체를 통해 특정 상황에 대한 행동을 정의한다. When: 테스트의 목적을 보여주는 단계이다. 실제 테스트 코드가 포함되며, 테스트를 통한 결괏값을 가져오게 된다. Then: 테스트의 결과를 검증하는 단계이다. When 단계에서 나온 결괏값을 검증하는 작업을 수행한다. (결과값이 아니더라도 이 테스트를 통해 ..
아이템 69. 예외는 진짜 예외 상황에만 사용하라 예외는 오직 예외 상황에서만 써야 하며, 일상적인 제어 흐름용으로 쓰여서는 안된다. 표즌적이고 쉽게 이해되는 관용구를 사용해야 하며, 성능 개선을 목적으로 과하게 머리를 쓴 기법은 자제한다. 잘 설계된 API 라면, 클라이언트가 정상적인 제어 흐름에서 예외를 사용할 일이 없게 해야 한다. 특정 상태에서만 호출할 수 있는 "상태 의존적" 메소드를 제공하는 클래스는 "상태 검사" 메소드도 함께 제공해야 한다. 예를 들어 Iterator 인터페이스의 next 와 hasNext 가 각각 상태 의존적 메소드와 상태 검사 메소드인 것이다. 이렇게 별도의 상태 검사 메소드가 있기 때문에 아래와 같은 for 문을 사용할 수 있다. (for-each 도 내부적으로 has..

아이템 57. 지역변수의 범위를 최소화하라 지역변수의 범위를 줄이는 가장 강력한 방법은 "가장 처음 쓰일 때 선언하는 것"이다. 거의 모든 지역변수는 선언과 동시에 초기화해야 한다. 초기화에 필요한 정보가 충분하지 않다면 선언을 미룬다. 메소드를 가능한 작게 유지하고 한 가지 기능에 집중하게 한다면, 지역변수의 범위를 더 좁힐 수 있다. 아이템 58. 전통적인 for 문보다는 for-each 문을 사용하라 for-each 문의 정식 명칭은 "향상된 for 문"이다. 반복자와 인덱스 변수를 사용하지 않으니 코드가 깔끔해지고 오류가 날 일이 없다. 반복 대상이 컬렉션이든 배열이든 for-each 문을 사용해도 속도는 그대로이다. 하지만 아래와 같은 상황에서는 for-each 문을 사용할 수 없다. 파괴적인 ..
트랜잭션은 ACID 라고 하는 원자성, 일관성, 격리성, 지속성을 보장해야 한다. 여기에서 격리성을 완벽하게 보장하려면, 트랜잭션을 거의 차례대로 실행시켜야 한다는 문제가 있다. 이렇게 하면 동시성 처리 성능이 매우 나빠진다. 이러한 문제로 ANSI 표준은 트랜잭션의 격리 수준을 4 단계로 나누어 정의한다. 순서대로 READ UNCOMMITTED 의 격리수준이 가장 낮고 SERIALIZABLE 의 격리수준이 가장 높다. READ UNCOMMITTED (커밋되지 않은 읽기) READ COMMITTED (커밋된 읽기) REPEATABLE READ (반복 가능한 읽기) SERIALIZABLE (직렬화 가능) 격리수준 DIRTY READ NON-REPEATABLE READ PHANTOM READ READ UNC..

아이템 49. 매개변수가 유효한지 검사하라 메소드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 이런 제약은 반드시 문서화해야 하며, 메소드 몸체가 시작되기 전에 검사해야 한다. /* * (현재 값 mod m) 값을 반환한다. 이 메소드는 * 항상 음이 아닌 BigInteger 을 반환한다는 점에서 remainder 메소드와 다르다 * * @param m 계수 (양수여야 한다.) * @return 현재 값 mod m * @throws ArithmeticException m 이 0 보다 작거나 같으면 발생한다. * */ public BigInteger mod(BigInteger m) { if (m.signum() = 0 && offset = 0 && length 0) throw n..