240821 TIL - 면접

DoDoBest

·

2024. 8. 22. 00:39

사진: Unsplash 의 Sumudu Mohottige

 

 

 

오늘 면접을 보고 왔다. 과제테스트 30분 + 기술면접 1시간으로 진행했다.

 

과제테스트는 맥북을 이용해서 진행했는데, 나는 지금까지 맥북을 이용해본적이 없다. 맥마우스도 제공됐는데, 오른쪽 클릭 하는 방법을 몰라서 터치패드를 이용했다, 맥북 터치패드도 처음 써봐서 그런지 오른쪽 상단을 두번 눌러도 오른쪽 클릭이 잘 안 됐다.

그 외에 한영 전환, IDE 단축키 등 윈도우랑 다른 것이 너무 많아서 주어진 문제 조건을 다 만족하지 못한 것 같다.... 맥북 사야할까.....🤔

 

OS와 무관하게 과제테스트를 완료하지 못한 이유가 2가지 있다.

 

1. Activity LifecycleScope

 

Activity에서 DB에서 데이터를 가져오는 함수를 호출하고 있었고, 시간이 5초 이상 소요되어 exception이 발생했다.

activity의 lifecycleScope을 이용해 코루틴으로 돌려야겠다고 생각했다. lifecycleScope을 입력하는데, no reference 라고 나온다. Activity가 상속하는 클래스를 확인했다. Activity라고 적혀 있었다. 예전에 Ctrl+H를 눌러서 Activity의 상속 관계를 확인했던 기억이 났고, Activity는 분명히 아니었던 것 같다. 

 

그래서 ComponentActivity 또는 AppcompatActivity로 바꿨던 것 같은데, 여전히 lifecycleScope에 대해 no reference 오류가 나왔다. (지금 집에서 해보니 잘 된다...)

 

당황하기 시작했다... 시간이 30분 밖에 없었기 때문에 viewModel을 이용해서 viewmodelScope으로 처리하자고 생각했다. viewModels를 이용해서 ViewModel을 생성하기 위해 androidx.activity.activity-ktx 의존성을 추가해줬다. 그럼에도 by viewModels에 대해 no reference 오류가 발생했다. (지금 집에서 해보니 잘 된다...)

 

몰랐던 개념 정리하기

 

 

ComponentActivity

 

LifecycleOwner, ViewModelStoreOwner를 구현하는 최초의 클래스

 

 

LifecycleEvent가 ON_DESTROY일 때 viewModelStore의 clear 함수를 호출한다.

configuration change로 인해 ON_DESTROY가 호출된 경우, viewModel이 파괴되지 않음도 알 수 있다.

 

FragmentActivity 

 

onRequestPermissionResultCallback을 구현하고 있다. Fragment에서 Permission을 요청하면 Activity에서 permission에 대한 응답을 처리받는 이유가 궁금했는데, onRequestPermissionResultCallback을 상속받고 있기 때문이었다. Permission을 요청하면 Permission 처리 관련 Activity를 실행하기 때문에, Fragment가 아닌 Activity에서 callback 함수로 받는 것이 적절한 것 같기도 하다.

 

 

Fragment를 가지는 Fragment를 SDK 버전이 낮은 Fragment에서 사용하기 위함이라고 하는데 잘 와닿지 않는다. 나중에 FragmentActivity 관련 문제를 직면하면 별도로 글을 작성해보겠다.

 

FragmentActivity is for use with the backport of fragments found in the support-v4 and support-v13 libraries. The native implementation of fragments was added in API Level 11, which is lower than your proposed minSdkVersion values. The only reason why you would need to consider FragmentActivity specifically is if you want to use nested fragments (a fragment holding another fragment), as that was not supported in native fragments until API Level 17.

출처 : https://stackoverflow.com/a/73507038/11722881, https://stackoverflow.com/a/31297546/11722881

 

 

AppCompatActivity

 

오래된 Android 기기에 새로운 platform feature를 제공해줘야할 때 사용하는 Base Class다. 그 예로 ActionBar가 있는데, SDK 버전이 올라감에 따라 다양한 기능들이 ActionBar에 추가되었다. 그래서 SDK 버전에 따라 ActionBar가 다르게 동작할 수 있다.

AndroidX 라이브러리의 Toolbar를 AppBar 대신 이용하면 SDK 버전과 무관하게 일관된 동작을 제공하는 ActionBar를 구현할 수 있다.

 

 

즉, 호환성을 위해서 AppCompatActivity를 사용하는 것이다.

 

2. GridLayout의 spanSizeLookup

 

아래 그림과 같은 RecyclerView UI를 구현하기 위해서는 어떻게 해야 할까?

 

 

위와 같은 UI를 2년 전에 구현해보고, 그 사이에 구현하거나 생각해보지 않아서 방법이 떠오르지 않았다.

ItemViewType에 따라 가로로 View가 2개인 ViewHolder를 만들어야 할까? 라는 생각이 떠올라서 만들기 시작했는데, View 2개에 데이터를 ViewHolder로 전달되는 1개의 데이터로 채우는 것은 요구사항과 맞지 않았다. 그래서 이 요구사항은 당시에 해결하지 못했다.

 

2년 전에는 flexboxlayout을 이용해서 구현했었다.

https://github.com/google/flexbox-layout

 

GitHub - google/flexbox-layout: Flexbox for Android

Flexbox for Android . Contribute to google/flexbox-layout development by creating an account on GitHub.

github.com

 

그런데, 외부 라이브러리를 이용해서 구현하는 것을 요구하는 것은 아닌 것 같아 좀 더 찾아보니 GridLayoutManager에 spanSizeLookup이라는 클래스가 있었다.

 

데이터의 position에 따라 ViewHolder가 몇 칸(Span)을 차지할 것인지를 지정하는 것이다. 예를 들어 위 요구조건 같은 경우 아래의 조건을 이용하면 4번 째 아이템마다 3칸을 차지하도록 함으로써 구현할 수 있다.

 

val manager = binding.rv.layoutManager as GridLayoutManager

manager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
    override fun getSpanSize(position: Int): Int {
        return if ((position + 1) % 4 == 0) {
            3
        } else {
            1
        }
    }
}

 

차지하는 칸은 spanSize보다 작거나 같아야 한다. 그렇지 않으면 런타임에 Exception이 발생한다.

 

java.lang.IllegalArgumentException: Item at position 2 requires 4 spans but GridLayoutManager has only 3 spans.
	at androidx.recyclerview.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:553)