본문 바로가기
[혜화 맛집] 엄마가 튀겨준 것 같은 생선가스 - 돈가스 보라 이전에 방문한 적 있는 혜화의 가성비 돈까스집 '돈가스 보라' 생선까스 7천원. 이전 방문 대비 모든 메뉴 가격이 1000원씩 올랐다.... 엄마가 튀겨준 돈까스 같은 느낌의 장점과 가격적 장점이 잘 어울어진 집이었는데... 가성비가 안 좋아졌다... ㅠ 생선까스가 바삭하게 잘 튀겨지긴 했는데, 생선살이 충만하진 않았다. 전체적으로 딱 배부른 양이긴 한데.. 뭔가 메인 메뉴를 적게 먹은 그 아쉬운 느낌... 가격이 올라서.. 재방문 의사가 없어졌다.. ㅠㅠ 500원씩만 올랐어도 재방문 했을텐데, 한번에 1000원씩은 너무 한 것 같다.. ㅠ 끝! 2022. 2. 6.
[혜화 맛집] 칸다소바 - '아부라 소바' 라는 녀석을 먹어봤습니다! 마제소바 맛집 칸다소바. 마제소바가 너무 맛있어서 다른 메뉴는 손도 안 갔지만, 오늘은 특별한 게 먹고 싶다. 그래서 이번에는 '아부라 소바' 를 도전! 가격은 1만원! '아부라' 는 일본어로 '기름' 이란 뜻. 즉 '기름 소바' 라는데.. 감바스처럼 기름에 듬뿍 담긴 면인 걸까 기대감 만발.. 파가 엄청나게 올라가 있는 독특한 비쥬얼.. 저 아래 무엇이 깔려 있을가 엄청난 기대. 국물(혹은 기름)이 듬뿍 있는 소바인줄 알았는데 이것도 비빔면 형태. 약간 기름이 들어가 있으며, 살짝 매콤한 파가 많이 들어간 비빔면이다. 고추기름을 뿌려 먹는 것은 이 녀석이 잘 어울림. 마제소바와 비교하자면, 고소한 맛은 마제소바가 더 강함. 이 녀석도 마제소바와 마찬가지로 밥을 비벼먹을 수 있음. 고추기름 듬뿍 뿌려 비.. 2022. 2. 5.
[kotlin] CoroutineContext 에 대한 이해 - Kotlin coroutine 의 핵심은 CoroutieContext interface 이다. 모든 launch, async 같은 coroutine builder 는 첫번째 param 으로 CoroutineContext 를 받는다. 이 coroutine builder 들은 CoroutineScope interface 의 extension function 으로 정의되어 있으며, abstract read-only property 로 coroutineContext 를 가지고 있다. - fun CoroutineScope.launch( context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT,.. 2022. 2. 3.
[coroutine] Back-pressure 대응하기 - Back pressure 는 한국어로 "배압" 이라고 하며, Flow 의 세계에서는 emit 되는 속도보다 collect 되는 속도가 느린 현상을 이야기한다. (돼왕: input 이 쌓여 buffer 가 필요한 상황) 이에 대한 해결방법은 여러가지가 있겠다. - 아래와 같은 기본 로직이 있다고 하자. 이 로직은 emit 은 1초 단위로 되는데, collect 는 3초 이상을 소비한다. 즉 back pressure 가 발생하는 것이다. var start = 0L fun currTime() = System.currentTimeMillis() fun emitter(): Flow = (1..5) .asFlow() .onStart{ start = currTime() } .onEach{ delay(1000) p.. 2022. 2. 2.
[coroutine] withContext vs async - withContext 와 async 를 언제 어떻게 쓰면 좋을까? - 동일한 구문을 돌리는 경우 withContext 가 async 보다 약 2배의 성능이 좋았다는 테스트 결과가 있다. https://stackoverflow.com/questions/50230466/kotlin-withcontext-vs-async-await for(1..1_0000_0000){ withContext(context){ // do sth } } vs for(1..1_0000_0000){ async(context){ // do sth }.await() } 메모리 사용량은 큰 차이가 없다고 한다. - 직접 성능 측정해 보았다. launch { val duration = measureTimeMillis { for (i in .. 2022. 2. 1.
[Android] Kotlin and Flow usage # Flow 는 'emit' 으로 data 를 발행하고, 'collect' 로 data 를 받아본다. # DataStore, Retrofit, Room, WorkManager 등에서 Flow 를 지원하고 있다. # flow builder 로 flow 를 쉽게 만들 수 있으며 이 녀석은 suspend block 을 받는다. # collect 역시 suspend block 을 받는다. # final operator 가 지정되기 전까지 flow 는 emit 하지 않으며, downstream 순서대로 로직이 수행된다. # Android UI 에서 collect 를 사용하기 위해서는 아래와 같은 방법이 사용된다. Flow.asLiveData():LiveData // 아래 2개를 추천함 Lifecycle.repea.. 2022. 1. 31.
[Coroutine] Exception handling in coroutine # coroutine builder 에 exception 이 발생하면 parent 를 cancel 하고, parent 가 cancel 되면 모든 children 을 cancel 시킨다. (exception propagation) Stop breaking my coroutines # Exception propagation 은 job 을 기반으로 작동하기 때문에 try-catch 로 잡히지 않는다. SupervisorJob # SupervisorJob 은 한 child 의 exception 이 parent 와 다른 children 을 cancel 시키지 않는다. # 일반적인 실수는 parent coroutine 에 SupervisorJob 을 전달하는 것이다. 예를 들면 launch 에 SupervisorJ.. 2022. 1. 30.
[Coroutine] Coroutine scope functions Approaches before coroutine scope functions # GlobalScope 은 EmptyCoroutineContext 를 사용하므로 다음과 같은 단점을 갖는다. 취소하기 어렵다. -> memory leak, cpu res 낭비 Parent 의 scope 속성을 상속하지 않는다. -> unit test 가 어렵다. # GlobalScope 을 사용하지 않기 위해 CoroutineScope 을 전달하는 경우가 있는데, 이는 또 다른 단점을 야기할 수 있다. 전달받은 scope 를 계속 다른 곳으로 전달하여 사용할 수 있으며, 이 경우 한 곳에서 발생한 exception 이 원하지 않는 다른 job 들을 모두 취소시킬 수 있다. (SupervisorJob 을 사용하지 않았다면) E.. 2022. 1. 29.
[Dagger] Assisted Injection # Assisted injection 은 object 를 만들 때 몇몇 param 은 DI framework (Dagger 등) 로부터 주입받고, 나머지는 user 에 의해 creation time 에 제공받는 것을 이야기한다. Factory 가 이 param 들을 조합해서 object 를 생성한다. Dagger assisted injection # Dagger 의 assisted injection 을 사용하려면, constructor 에 @AssistedInject 를 마킹하고, assisted param 들에 대해 @Assisted 를 마킹해줘야 한다. class MyDataService @AssistedInject constructor( dataFetcher: DataFetcher, @Assiste.. 2022. 1. 28.
반응형