기술면접에 앞서 알고 있던 내용들과 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
'LANGUAGES, METHODLOGY > RxJava' 카테고리의 다른 글
[안드로이드 | Rx] Schedulers 주의 깊게 살펴보기 (0) | 2020.07.22 |
---|---|
[RxJava] RxJava 첫걸음. RxJava란 무엇인가? (0) | 2019.08.16 |