기술면접에 앞서 알고 있던 내용들과 RxJava에서 빈번하게 쓰일 것들을 추려 정리를 좀 해두기로 했다.
(질문의 경우 추가적으로 업데이트 예정)
Q: Why? 왜 RxJava를 사용하는가?
A: RxJava는 비동기 프로그래밍을 구현하도록 해주는 기술로써, 기존 동기식 프로그래밍에서 스레드간 경쟁구도로 인해 발생할 수 있는 이슈들을 제거하고, 프로그래밍의 중심을 데이터 우선으로 하게 됨으로써 서버통신 등 데이터가 중심이 되는 구조를 짜고자 할 때 유용하게 쓸 수 있기 때문이다.
- 멀티스레딩시 애로사항 및 Race Condition 관련 보기좋은 자료 https://www.slideshare.net/iamhjoo/ss-44214966
Q: Hot Observable과 Cold Observable의 차이가 무엇인가?
A: Hot Observable은 Observer의 존재 및 구독여부와 상관없이 데이터를 발행하고, Cold Observable은 Observer가 subscribe하게 될 경우에만 가진 데이터를 발행. 이때 Hot Observable을 구독하는 Observer들은 발행된 모든 데이터를 보장받기 어렵고, Cold Observable의 경우 준비된 데이터를 구독 시점에서 전부 받을 수 있음.
< Observable 관련 함수 정리 >
- just() : 입력한 데이터로 Observable 선언. 인자를 넣음으로써 subscribe시 자동으로 알림 이벤트 발생.
- subsribe() and Disposable 객체 :
subscribe를 통해 Observable 객체를 구독하고, 구독을 통해 Observable로부터 발행된 데이터를 수신. !! 반드시 subscribe를 해야 Observable이 데이터를 발행하기 시작함. Disposable은 Observable.subscribe로부터 리턴받을 수 있으며, dispose()를 통해 구독을 해지할 수 있음.
- create() : onNext, onComplete, onError등의 알림을 개발자가 직접 호출해야 하는 Observable.
- fromArray() : 입력한 배열을 소스로 Observable 객체를 생성
- fromIterable() : Iterater 인터페이스를 구현하는 클래스들을 소스로 Observable 생성. (ArrayList, ArrayBlockingQueue, HashSet, LinkedList, Stack, TreeSet, Vector)
- fromCallable() : 자바 클래스 Callable로부터 Observable 생성
- fromFuture() : get() 메소드 호출 이후 결과값이 나오기 전까지 Observable을 기다리게 됨.
- fromPublisher() : Java 9의 표준인 Flow API의 일부인 Publisher를 가지고 Observable을 생성
- Maybe : onSuccess, onError, onComplete 이벤트를 발생 가능한 Observable. 데이터 발행 없이도 onComplete 가능.
- AsyncSubject : 완료되기 이전 마지막 데이터만을 확인하며 이전 데이터는 무시. 완료와 동시에 마지막 데이터를 발행하고 종료.
- BehaviorSubject : 구독자가 구독을 하면 초기값 혹은 가장 최근값을 넘겨주는 클래스
- PublishSubject : 구독자가 구독을 하면 새로 발행된 값을 구독자에게 전달하고, 기본값이나 지나간 데이터는 다시 발행하지 않음.
- ReplaySubject : 구독자에게 데이터의 처음부터 끝까지를 발행. Hot Observable이자 Cold Observable처럼 행동하는 것임. 메모리 누수 주의.
- ConnectableObservable : subscribe한 구독자들에게 connect()이 실행된 시점부터 데이터를 발행 시작. connect은 어디에서든 한번 수행하면 됨.
< Rx 연산자 정리 >
기본
- map() : 전달받은 데이터를 원하는 형태로 변환
- flatMap() : 전달받은 데이터를 원하는 형태로 변환한 별도의 Observable을 반환.
- filter() : Observable로부터 받은 데이터 중 원하는 데이터만을 통과시킴
- reduce() : 각기 다른 데이터를 취합해 새로운 데이터로 변환.(map, filter, reduce 콤비네이션을 기억할 것.)
생성 연산자
- interval() : 설정한 시간 간격에 따라 데이터를 순차적으로 발행
- timer() : 설정한 시간 뒤에 단 한개의 데이터를 발행하고 onComplete
- range(n, m) : n부터 m까지의 데이터를 발행
- intervalRange(n,m, interval) : n부터 m까지의 데이터를 interval의 간격으로 발행.
- defer() : timer와 유사하지만 구독자가 subscribe를 하기 이전까지는 호출을 미루는 연산
- repeat() : 입력한 횟수만큼 데이터 발행 반복
변환 연산자
- concatMap() : 인터리빙(끼어들기)를 방지하고 들어온 데이터들 순서대로 Map function 수행
- switchMap() : 들어온 데이터를 concatMap처럼 처리하나 처리가 완료되기 이전 신규 input이 들어오면 이전 input의 처리 중단 이후 신규 input 처리 진행
- groupBy() : 들어오는 데이터를 형식에 따라 묶어 별도의 Observable로 반환
- scan() : 실행때마다 마지막 결과값을 토대로 중간결과 및 최종결과를 구독자에게 발행
결합 연산자
- zip() : 두개의 Observable로부터 데이터를 취합해 한개의 Observable을 리턴
- combineLatest() : 처음에는 각 Observable로부터 데이터를 발행한 후에는 어디에서 값을 발행하던 최신 값으로 갱신.
- merge() : 최신 데이터 여부와 상관없이 각 Observable로부터 발행하는 데이터를 그대로 출력.
- concat() : 입력된 Observable을 Observable 단위로 이어 붙여줌.
조건 연산자
- amb() : 여러개의 Observable중 먼저 데이터를 발행한 Observable의 데이터를 수신
- takeUntil() : 인자로 받은 Observable이 데이터를 발행하기 이전까지 데이터를 수신
- skipUntil() : 다른 Observable이 데이터를 발행한 이후 기존 Observabled의 데이터를 수신
- all() : onComplete까지 Observable에서 발행한 모든 데이터가 조건에 맞는지 확인해 boolean 값 return
기타 연산자
- delay() : 입력받은 Observable 데이터의 발행을 입력한 시간만큼 지연시킴.
- timeInterval() : Observable이 발행한 데이터간의 시간 간격을 보여줌.
< 스케줄러 > : RxJava가 실제 비동기 작업을 할 수 있도록 도와주는 역할.
- 뉴 스레드 스케줄러(Schedulers.newThread()) : 요청을 받을 때마다 새로운 스레드를 생성.
** Rx에서 쓰기 좋은 스케줄러는 계산 스케줄러, IO 스케줄러, 트램펄린 스케줄러임 **
- 계산 스케줄러(Schedulers.computation()) : IO작업을 하지 않는 스케줄러. CPU 갯수만큼 스레드를 생성.
- IO 스케줄러(Schedulers.io()) : 생성되는 스레드 개수가 다르고, 필요할 때마다 스레드를 계속 생성.
- 트램펄린 스케줄러(Schedulers.trampoline()) : 새로운 스레드를 생성하지 않고, 대기행렬을 자동으로 만들어 준다는 것이 다른 스레드와의 차이점.
- 싱글 스레드 스케줄러(Schedulers.single()) : 단일 스레드를 별도로 생성해 구독 작업을 처리.
- Executer 변환 스케줄러(Schedulers.from(executer)) : java.util.current 패키지에서 제공하는 실행자를 변환해 스케줄러를 생성.
- ObserveOn 활용하기 : subsrcibeOn은 구독자가 subscribe()를 호출했을 때 데이터 흐름을 발행하는 스레드를 지정하고, observeOn은 처리된 결과를 구독자에게 전달하는 스레드를 지정.
< 디버깅 >
- doOnNext() : Observable에서 onNext 이벤트 발생시 수행할 동작 정의
- doOnComplete() : Observable에서 onComplete 이벤트 발생시 수행할 동작 정의
- doOnError() : Observable에서 onError 이벤트 발생시 수행할 동작 정의
- doOnEach() : onNext, onComplete, onError 이벤트를 한번에 처리
- doOnSubscribe() : Observable을 구독했을 때의 동작 정의
- doOnDispose() : Observable을 Dispose했을 떄의 동작 정의
< 예외처리 >
- onErrorReturn() : 에러가 발생했을 때 에러 데이터를 대체할 데이터를 설정해 발행.
- onErrorResumeNext() : 에러가 발생했을 때 기존 구독했던 Observable을 대체하는 Observable을 정의 가능.
- retry() : onError 발생시 subscribe를 다시 호출. 인자로 재시도 횟수나 어떤 조건에서 재시도 할것인지 판단.
- retryUntil() : 특정 조건이 충족될때 까지만 재시도
- retryWhen() : error가 발생하면 조건을 통해 subscribe를 다시 시도. ( 꽤 복잡하니 마블 다이어그램으로 이해가 편할 듯.)
< 흐름제어 > : Observable의 데이터 발행 속도와 Subscriber 가 데이터를 받는 속도의 차이가 생기는 경우를 해결해주는 역할.
- sample() : 특정한 시간 동안 가장 최근에 발행된 데이터만 걸러줌. 아무리 많은 데이터가 들어와도 해당 구간중 들어온 마지막 데이터만을 리턴.
- buffer() : 일정 시간동안 데이터를 모아 한번에 발행. 인자로 모을 데이터의 갯수를 설정할 수 있음.
- throttleFirst(), throttleLast() : throttleFirst는 지정 조건시간에서 가장 첫번째 데이터를, throttleLast는 지정 조건시간에서 가장 마지막 데이터를 발행.
- window() : groupBy()와 비슷하나 여기에 count기능으로 원하는 갯수만큼의 데이터를 추려 Observable로 발행이 가능.
- debounce() : 지정한 시간중에 새 데이터가 들어오지 않은 경우 이를 발행. 빠른 속도로 들어오는 버튼 이벤트를 처리할 때 유용.
< 테스팅 및 Flowable >
- TestObserver : assertResult, assdertFailure, assertFailureAndMessage, awaitDone, assertComplete 등의 시나리오 지정 가능.
- Flowable : 옵션을 통해 OOM 에러를 방지 가능하도록 배압 설정이 가능한 Observable.
onBackpressureBuffer : 배압 문제 발생시 별도의 버퍼에 저장. (128개 버퍼가 기본으로 배정)
onBackpressureDrop : 배압 이슈 발생시 해당 데이터 무시
onBackpressureLast : 처리 못해 쌓이는 데이터를 무시하고 최신 데이터만 유지.
< 참조 >
http://www.yes24.com/Product/Goods/45506284
RxJava 프로그래밍
8가지 핵심 개념으로 쉽게 이해하는 리액티브 프로그래밍 입문서버나 애플리케이션은 다양한 데이터를 처리하느라 늘 분주하다. 그런데 데이터양이 기하급수적으로 늘면서 기존의 프로그래밍 방식으로 이를 처리하기가 점점 어려워지고 있다. 이에 데이터의 입출력 흐름에 따라 많은 사용자 요청을 한꺼번에 그리고 동시에 처리하는 프로그래밍 기법을 연구하기 시작했고, ...
www.yes24.com
'LANGUAGES, METHODLOGY > RxJava' 카테고리의 다른 글
[안드로이드 | Rx] Schedulers 주의 깊게 살펴보기 (0) | 2020.07.22 |
---|---|
[RxJava] RxJava 첫걸음. RxJava란 무엇인가? (0) | 2019.08.16 |