티스토리 뷰
개요
# 참고
모던 자바 인 액션
# 개요
모던 자바 인 액션을 읽고 다음에 대해 알아보고자 한다.
* 자바8버전 이후 어떤 기능이 있는지?
* 자바8버전 이후 어떤 장점이 있는지?
* 자바8버전 이후 기능들을 어떻게 사용해야 하는지?
* 명령형 프로그래밍과 함수형 프로그래밍은 어떤 차이가 있는지?
# 1장의 로드맵
- 자바가 거듭 변화하는 이유
- 컴퓨팅 환경의 변화
- 자바에 부여되는 시대적 변화 요구
- 자바8 이후 기능의 핵심
1장. 자바 8, 9, 10, 11 : 무슨 일이 일어나고 있는가?
1-1. 자바8 이후를 사용해야 하는 이유
1-1-1. 가독성
자바 역사를 통틀어 가장큰 변화가 자바8에서 일어났다.
위 코드는 우리가 사과의 무게를 정렬할때 사용하는 고전적인 익명함수 이다.
반면 위에 코드는 자바8이후 기능들을 이용하여 작성한 사과의 무게를 정렬하는 코드이다.
이로 인해 자바8이후의 기능들이 사용하면 가독성이 매우 좋아진다는 장점이 있다는 것을 알 수 있다.
1-1-2. 병렬성
요즘 대부분의 CPU는 멀티코어를 가지고 있다. 이와 같이 하드웨어적인 변화도 자바8에 영향을 주었다. 지금까지 자바는 대부분 하나의 코어만을 사용하였다. 물론 나머지 코어를 사용할 수 있는데, 나머지 코어를 활용하려면 스레드를 사용해야 한다. 하지만 스레드를 사용하면 관리가 어렵고 많은 문제가 발생할 수 있다는 단점이 있다. 자바는 이러한 병렬 실행 환경을 쉽게 관리하고 에러가 덜 발생하는 방향으로 진화 하려고 노력하였다. 자바8에서는 병렬 실행을 단순한 방식으로 접근할 수 있는 방법을 제공한다.
1-1-3. 다양한 기능
자바8은 간결한 코드, 멀티코어 프로세서의 쉬운 활용이라는 두 가지 요구사항을 기반으로 새로운 기술들을 제공한다.
- 스트림API
- 메서드에 코드를 전달하는 기법
- 인터페이스의 디폴트 메서드
Stream API
자바8은 데이테베이스 질의 언어에서 표현식을 처리하는 것처럼 병렬 연산을 지원하는 스트림이라는 새로운 API를 제공한다.
메서드에 코드를 전달하는 기법
스트림 덕분에 자바8이후 에서는 "메서드에 코드를 전달"하는 기법과 인터페이스의 디폴트 메서드를 제공하게 된다. 또한 메서드에 코드를 전달하는 기법을 이용하면 새롭고 간결한 방식으로 동적 파라미터화를 구현할 수 있다.
1-2. 왜 아직도 자바는 변화하는가?
1-2-1. 멀티 프로세스
자바의 하드웨어 중립적인 메모리 모델 떄문에 멀티코어 프로세서에서 병렬적으로 수행되는 스레드는 싱글코어에서의 동작과 달리 예기치 못한 상황을 일으킬 수 있다. 또한 최근 프로그래밍 언어 생태계는 많이 변화 되었다. 프로그래머는 빅데이터라는 도전에 직면하면서 멀티코어를 통해 효과적으로 처리할 필요성이 커졌다. 즉, 병렬 프로세싱을 활용해야 하는데 지금까지의 자바로는 충분히 대응할 수 없다.
1-2-2. 스트림 처리
스트림(Stream)이란?
스트림이란 한 번에 한 개씩 만들어지는 연속적인 데이터 항목들의 모임이다.
유닉스와 스트림의 파이프라인 구성은 비슷한 구조를 가진다. 스트림API의 핵심은 기존에는 한번에 항목을 처리했지만 자바8에서는 데이터베이스의 질의처럼 고수준으로 추상화해서 일련의 스트림으로 만들어 처리할 수 있다는 것이다. 또한 스트림 파이프라인을 이용해서 입력 부분을 여러 CPU코어에 쉽게 할당할 수 있다는 부가적인 이득을 얻을 수 있다. 스트림은 한 번에 한 개씩 만들어지는 연속적인 데이터 항목의 모임이며, 입력 스트림에서 데이터를 한개씩 읽어 들이며 마찬가지로 출력 스트림으로 데이터를 한 개씩 기록한다. 즉, 어떤 프로그램의 출력 스트림은 다른 프로그램의 입력 스트림이 될 수 있어 스레드라는 복잡한 작업을 사용하지 않으면서도 공짜로 병렬성을 얻을 수 있다.
1-2-3. 동적 파라미터화로 메서드에 코드 넘기기
자바8에서는 메서드를 다른 메서드의 인수로 넘겨주는 기능을 제공한다. 이를 동적 파라미터화라고 부른다. 스트림API는 연산의 동작을 파라미터화할 수 있는 코드를 전달한다는 사상에 기초하기 때문이다.
1-2-4. 병렬성과 공유 가변 데이터
자바8이후에서는 병렬성을 얻는 대신 포기해야 하는 것이 있다. 코드의 동작 방식을 조금 변경해야 한다는 귀찮음을 포기하고 스트림을 통해 다른 코드와 동시에 실행하더라도 안전하게 실행될 수 있다.
안전하게 실행할 수 있는 코드를 만들기 위해서는 공유된 가변 데이터에 접근하지 말아야 한다. (순수 함수, 부작용 없는 함수, 상태 없는 함수 / 이후 18,19장에서 설명)
그렇다면 두 프로세스가 공유된 변수를 동시에 바꾸려 하면 어떻게 될까? 자바8 이전에는 synchronized를 이용해서 공유된 가변 데이터를 보호하는 규칙을 만들었다. 하지만 synchronized 시스템 성능에 악영향을 미친다(많은 성능적 이점을 포기해야 한다). 반면 스트림을 이용하면 쉽게 병렬성을 활용할 수 있다.
1-3. 자바 함수
자바에서 함수라는 용어는 메서드와 같은 의미로 사용된다. 자바의 대부분은 객체로 구성이 되어 있다. 배열, 리스트, 맵, 클래스(인스턴스), Integer, int, double, new 등등.. 객체이거나 값을 가지고 있다. 그런데 왜 함수가 필요할까?
프로그래밍의 핵심은 값을 바꾸는 것이다. 자바에서는 모든 구조체를 자유롭게 전달할 수 있다면 일급시민이라 할 수 있고 전달할 수 없는 구조체는 이급시민이라고 할 수 있다. 다양한 구조체등 대부분은 일급시민이지만, 메서드나 글래스등을 이급 시민에 해당한다. 그 이유는 메서드와 클래스는 그 자체로 값이 될 수 없기 때문이다. 런타임에 메서드를 전달할 수 있다면, 즉 메서드를 일급시민으로 만들면 프로그래밍에 유용하다. 따라서 자바8에서는 이급시민을 일급시민으로 바꿀수 있는 기능을 추가 했고 동적 파라미터화 역시 이 개념에서 시작한다.