STREAM

· Java
스트림에서는 한 번만 연산을 수행할 수 있으므로 결과도 한 번만 얻을 수 있다는 것이 Java8 스트림의 가장 큰 단점이다. 스트림을 두 번 탐색하려면 IllegalStateException이 발생한다. 하지만 한 스트림에서 여러 결과를 얻어야 하는 상황이 있을 수 있다. 그러려면 한 번에 한 개 이상의 람다를 스트림으로 적용해야 한다. 즉, fork 같은 메서드를 이용해서 스트림을 포크(분기) 시키고 포크된 스트림에 다양한 함수를 적용해야 한다. 심지어 여러 연산을 각각의 스레드에서 병렬로 실행할 수 있다면 더 좋을 것이다. 하지만 Java8의 스트림에서는 이 기능을 제공하지 않는다. Spliterator(특히 늦은 바인딩 기능을 활용), BlockingQueue, Future를 이용해서 Java8에서..
· Java
스트림과 게으른 평가 스트림은 데이터 컬렉션을 처리하는 편리한 도구다. 효율적인 구현 및 여러 이유로 Java8 설계자들은 스트림을 조금 특별한 방법으로 java8에 추가했다. 그중 하나로 스트림은 단 한 번만 소비할 수 있다는 제약이 있어서 스트림은 재귀적으로 정의할 수 없다. 자기 정의 스트림 다음 코드처럼 소수 스트림을 계산할 수 있다. public boolean isPrime(int candidate) { int candidateRoot = (int) Math.sqrt((double) candidate); return IntStream.rangeClosed(2, candidateRoot) .noneMatch(i -> candidate % i == 0); } public Stream primes(i..
· Java
리액티브 스트림이란? 리액티브 프로그래밍은 리액티브 스트림을 사용하는 프로그래밍이다. 리액티브 스트림은 잠재적으로 무한의 비동기 데이터를 순서대로 그리고 블록 하지 않는 역압력을 전재해 처리하는 표준 기술이다. 역압력은 발행-구독 프로토콜에서 이벤트 스트림의 구독자가 이벤트를 소비하는 시간이 발행자가 이벤트를 제공하는 속도보다 느릴 때 문제가 발생하지 않도록 보장하는 장치다. 이런 상황이 발생하였을 때 부하가 발생한 컴포넌트가 완전 불능이 되거나 예기치 않는 방식으로 이벤트를 잃어버리는 등의 문제가 발생하지 않는다. 부하가 발생했을 때 발행자가 충분한 알림을 받을 수 있어야 한다. 실제 비동기 작업이 실행되는 동안 시스템에는 암묵적으로 블록 API로 인해 역압력이 제공되는 것이다. 안타깝게도 비동기 작업..
· Java
자바로 프로그램을 개발하면서 한 번이라도 NullPointerException을 껶지 않은 사람은 없을 것이다. NullPointerException은 모든 자바 개발자를 괴롭히는 예외다. 1965년 토니 호어(Tony Hoare)라는 영국 컴퓨터과학자가 힙에 할당되는 레코드를 사용하며 형식을 갖는 최초의 프로그래밍 언어 중 하나인 알골(ALGOL)을 설계하면서 처음 null 참조가 등장했다. 그는 구현하기가 쉬웠기 때무엔 null을 도입했다고 하였다. 하지만 여러 해가 지난 후 그는 null 및 예외를 만든 결정을 가리켜 십억 달러짜리 실수라고 표현했다. 모든 자바 프로그래머라면 NullPointerException이라는 귀차는 예외가 발생하는 상황을 몸소 겪었을 것이다. 값이 없는 상황을 어떻게 처리..
· Java
DSL(Domain-specific Languages, 도메인 전용 언어)란? DSL은 특정 비즈니스 도메인의 문제를 해결하려고 만든, 작은, 범용이 아닌 특정 도메인을 대상으로 만들어진 특수 프로그래밍 언어다. 예를 들어 쇼핑몰 플랫폼을 개발한다고 가정했을 때, 비지니스 도메인에는 상품을 결제하고 배송처리와 같은 개념이 포함된다. DSL에란 특정 비즈니스 도메인을 인터페이스로 만든 API라고 생각할 수 있다. (자바 8에서는 Stream, Collector 등 여러 가지 작은 DSL들이 추가되었다.) 자바에서는 도메인을 표현할 수 있는 클래스와 메서드 집합이 필요하다. DSL에서 동작과 용어는 특정 도메인에 국한되므로 다른 문제는 걱정할 필요가 없어서 특정 도메인의 복잡성을 더 잘 다룰 수 있고, 저수..
· Java
람다 테스팅 일반적으로 좋은 소프트웨어 공학자라면 프로그램이 의도대로 동작하는지 확인할 수 있는 단위 테스팅(unit testing)을 진행한다. 우리는 소스 코드의 일부가 예상된 결과를 도출할 것이라 단언하는 테스트 케이스를 구현한다. 보이는 람다 표현식의 동작 테스팅 일반적인 메서드는 이름이 존재하기 때문에 단위 테스트를 문제없이 진행할 수 있지만, 람다는 익명이므로 테스트 코드 이름을 호출할 수 없다. 따라서 필요하다면 람다를 필드에 저장해 테스트 할 수 있다. public class OrderProduct { private String name; private int count; private int price; .... } public static class Order { public stati..
· Java
코드 가독성 개선 코드 가독성이란 일반적으로 코드를 다른사람도 쉽게 이해할 수 있는 정도라고 생각하면 될 것 같다. 즉, 코드 가독성을 개선한다는 것은 우리가 구현한 코드를 다른 사람이 쉽게 이해하고 유지보수 할 수 있게 만드는 것을 의미한다. 코드의 가독성을 높이려면 코드의 문서화를 잘하고, 표준 코딩 규칠을 준수하는 등의 노력을 기울여야 한다. 익명 클래스를 람다 표현식으로 리팩터링 하기 하나의 추상 메서드를 구현하는 익명 클래스는 람다 표현식으로 리팩터링 할 수 있다. // 익명 클래스 사용 Runnable r1 = new Runnable() { public void run() { System.out.println("Run!!"); } } // 람다 표현식 사용 Runnable r2 = () -> ..
· Java
Spliterator 인터페이스란? Spliterator는 분할할 수 있는 반복자라는 의미이다. Iterator 처럼 Spliterator는 소스의 요소 탐색 기능을 제공한다는 점은 같지만 Spliterator는 병렬 작업에 특화되어 있다. 커스텀 Spliterator를 꼭 구현해야 하는 건 아니지만 Spliterator가 어떻게 동작하는지 이해한다면 병렬 스트림 동작과 관련한 통찰력을 얻을 수 있다. java8은 컬렉션 프레임워크에 포함된 모든 자료구조에 사용할 수 있는 디폴트 Spliterator 구현을 제공한다. public interface Spliterator { boolean tryAdvance(Consumer
· Java
포크/조인 프레임워크(Fork/Join Framework)란? 포크/조인 프레임워크는 병렬화할 수 있는 작업을 재귀적으로 작은 작업으로 분할한 다음에 서브태스크 각각의 결과를 합쳐서 전체 결과를 만들도록 설계되었다. 따라서 하나의 작업을 작은 단위로 나눠서 여러 쓰레드가 동시에 처리하는 것을 쉽게 만들어 준다. 이 알고리즘은 분할 후 정복(divide-and-conquer) 알고리즘의 병렬화 버전이다. 포크/조인 프레임워크에서는 서브태스크를 스레드 풀(ForkJoinPool)의 작업자 스레드에 분산 할당하는 ExecutorService 인터페이스를 구현한다. RecursiveTask 활용 스레드 풀을 이용하려면 RecursiveTask의 서브클래스를 만들어야 한다. 여기서 R은 병렬화된 태스크가 생성하는..
· Java
java7이 등장하기 전에는 데이터 컬렉션을 병렬로 처리하기가 어려웠다. 우선 데이터를 서브 파트로 분할해야 하고, 분할된 서브 파트를 각각의 스레드로 할당한다. 스레드로 할당한 다음에는 의도치 않은 레이스 컨디션이 발생하지 않도록 적절한 동기화를 추가해야 하며, 마지막으로 부분 결과를 합쳐야 한다. java7은 더 쉽게 병렬화를 수행하면서 에러를 최소화할 수 이도록 포크/조인 프레임워크(fork/join framework) 기능을 제공한다. 이번에는 스트림으로 데이터 컬렉션 관련 동작을 얼마나 쉽게 병렬로 실행하는지 살펴보자. 스트림을 이용하면 순차 스트림을 병렬 스트림으로 자연스럽게 바꿀 수 있다. 병렬 스트림이 내부적으로 어떻게 처리되는지 알아야만 스트림을 잘못 사용하는 상황을 피할 수 있다. 병렬..
beekei
'STREAM' 태그의 글 목록