이직을 준비하면서 간만에 면접을 보는데 기본을 물어봐서 답변을 하지 못하여 그에 대한 준비로 정리한 내용을 작성해 보려 합니다.
인터넷에 Android 면접 준비 관련 내용에서 많이 참고 하였습니다. 두서 없이 정리하였기 때문에 한번 정독하는 것이 좋을 수도 있고 필요한 내용만 사용하셔도 좋습니다.
RecyclerView와 ListView의 구현 방법
1. RecyclerView는 노출할 항목의 정보는 가진 class를 생성하고 그 항목을 가지는 ArrayList를 만듭니다.
2. Adapter를 생성하여 ArrayList를 Adapter의 생성자에서 받습니다.
3. Adapter에서 getItemCount에 ArrayList의 사이즈를 반환합니다.
4. onCreateViewHolder에서 ViewHodler를 생성합니다. 이때 각 항목의 UI xml을 받습니다.
5. onBindViewHolder에서 각 데이터를 항목 순서에 맞게 적용합니다. 이때 onBindViewHodler에서 position을 얻을수 있는데 이 position을 통하여 Adapter에서 받은 Arraylist의 index의 데이터를 적용합니다.
100개의 아이템과 ViewHolder 1개를 가진 RecyclerView의 동작 원리를 설명
ListView의 경우 사용자가 아래로 스크롤을 내리거나 위로 스크롤을 올릴 경우 화면에서 안보이는 일부 View들은 삭제되고 화면에 나타날 View들은 새로 생성이 됩니다. 즉, ListView가 처음 나타날 때 화면에 보이는 View들이 생성될 뿐만 아니라 스크롤 동작에 따라서 View들이 삭제되고 생성됩니다. 이런 비효율적인 방법을 탈피하기 위해 나타난 방법이 ViewHolder 입니다. 반복되거나 필요한 View를 미리 만들어 놓고 재 사용하는 방식입니다.
이런 방식을 찾안하여 Android에서 새로 나온 View RecyclerView 입니다. 이름 그대로 재활용하는 View 입니다. RecyclerView를 사용하면 사용자가 스크롤을 위나 아래로 이동했을 때 화면에서 사라지는 일부 뷰들이 삭제되는것이 아니라 다시 나타날 뷰로 재활용이 되어 집니다.
그래서 100개의 아이템을 보여줄 일부 View들을 만들고(View의 갯수는 지정된 크기에 따라 달라집니다) 그 뷰들을 재사용하면서 아이템을 보여줍니다. 그리고 RecycvlerView가 움직이면서 View의 갱신이 필요할 때 ViewHolder를 통하여 그 포지션에 맞는 View의 내용으로 갱신합니다.
네트워크 통신을 통해 이미지를 가져오는 뷰가 포함된 ListView또는 RecyclerView에서 빠르게 스크롤 시 생길 수 있는 이슈가 무엇이고 어떻게 수정 및 최적화를 할 수 있을 까요?
빠르게 스크롤 시 이미지가 로드되기 전에 ListView의 경우에는 View가 삭제될 수 있고, RecyclerView의 경우에는 View가 재사용 되는 문제가 발생할 수 있습니다. 이 문제를 해결 방법은
1. List들이 뜰 때 필요한 이미지들을 미리 다 받아 놓는 방법이 있습니다.
2. 이미지를 로드하다 View의 재사용 혹은 삭제가 발생할 경우 로드를 취소하거나 저장해두었다가 다시 로드합니다.
위 2가지 방법의 전제 조건은 비동기 이미지로드입니다.
또한 이미지 다운관련 오픈소스를 활용하여 처리할 수도 있습니다.
Inmutable 변수를 쓰면 좋은점
Mutable 변수를 사용 할 경우에는 어떤 스레드에서 접근강능할 경우 그 값을 변화 시킬 수 있습니다. 이에 따라서 수동으로 동기화를 해줘야하고, 그에 따른 복잡성과 실행 시간이 늘어날 수있습니다.
만일 Inmutable 변수를 사용한다면 스레드에서 그 변수에 대해서 신경 안 쓰고 접근하여 사용할 수 있습니다.(단 변형은 할 수 없습니다.)
즉, 스레드를 안전하게 만드는데 큰 역할을 합니다. 정리를 하면 1. 스레드의 안정성 2. 낮은 커플링 3. 참조의 투명성 4. 컴파일러 최적화 5.순수 함수 라 할 수 있습니다. (참고 https://readystory.tistory.com/105)
안드로이드에서 RxJava2 메모리 관리하는 법은 무엇이 있는가?
1. Disposable 인터페이스를 이용하여 명시적으로 해제한다. 해제 시 onCreate에서 subscirbe 하면 onDestroy에서 메모리참조를 해제 onResume에서 subscribe를 하면 onPause에서 메모리 참조를 해제
2. RxLifecycle 라이브러리를 사용 - Activity를 RxAppCompatActivity를 상속하여 생성하고, compose() 함수를 사용하여 RxLifecycle 라이브러리를 적용 합니다. 즉 Observable 생성 후 compose(bindToLifecycle())을 적용하여 compose() 함수로 Observable을 라이프사이클에 맞추어 동작하도록 합니다. 이렇게 할 경우 onCreate에서 subscribe를 하면 onDestory에서 메모리참조를 해제 onResume에서 subscribe를 하면 onPause에서 메모리참조를 해제가 동작하고 bindUntilEvent를 통해선 지정한 ActivityEvent 까지만 동작하도록 합니다.
3. CompositeDisposable 클래스를 이용하여 생성된 모든 Observable 을 안드로이드 라이프 사이클에 맞춰서 한번에 해제 할 수 있습니다. CompositeDisposable 를 생성하고 Observable을 생성할 때마다 CompositeDisposable 에 추가하여onDestroy가 발생하면 CompositeDisposable.dispose()하여 한번에 해제할 수 있습니다.
Parcelable 과 Serializable의 차이점
Serializable은 Android SDK가 아니라 JAVA 표준 인터페이스 입니다. Serializable은 해당클래스가 직렬화 대상이라 알려주기만 할 뿐 어떠한 매서드도 가지지 않는 단순한 마커인터페이스(Marker Interface) 이므로 사용자가 이용하기 매우 쉽습니다.(단순히 implement 해주면 됩니다.)
하지만 사용법이 쉬운 만큼 시스템 적인 비용이 비싸다는 단점이 있습니다. 사용자가 따로 처리를 하지 않지만 Srializable은 내부에서 Reflection을 사용하여 직렬화를 처리하는데, 이 Reflection이 동작하면서 많은 추가 객체를 생성하여 나중에 이 쓰레기들이 가비지 컬렉터의 타켓이 되고 가비지 컬렉터의 과도한 동작으로 인하여 성능 저하 및 배터리 소모가 발생합니다.
Parcelable은 Android SDK 인터페이스 입니다. Parcelable은 Reflection을 사용하지 않도록 설계되어 있습니다. 즉, Serializable과 다르게 사용자가 직접 처리 방법을 명시적으로 작성하여야 합니다. 그래서 Parcelable을 구현할 때 필수 매서드들을 포함하게되는데, 이 클래스들을 이해하기 어렵고, 새로운 기능을 추가하기 힘들어 지고, 마지막으로 코드의 추가로 클래스가 복잡해질 수록 유지 보수가 어려워 집니다.
간단하게 Serializable은 간단하지만 그만한 시스템적 비용을 지불해야하며, Parcelable은 시스템적은 비용은 적지만 구현및 복잡도, 그리고 코드 추가에 따른 유지보수가 힘든점이 있습니다.
안드로이드 에서 Unit Test가 필요 한 이유
1. 개발단계에서 초기오류를 감지할 수 있다.
2. 코드리팩토링을 할 수 있다.
3. 안정적인 개발 속도를 가질 수 있다.
Unit Test는 코드의 가장 작은단위의 코드를 테스트하는 코드입니다. 이 단위는 메소드 혹은 클래스가 되는 경우가 대부분이며, 특정 클래스/메소드가 예상한것 처럼 구동하는지를 테스트 하는 것입니다. 다시 말해, 특정 클래스의 모든 매소드가 구현한대로 작동하는지, 그리고 특정 클래스의 state가 구현한대로 올바른 state에 존재하는지등을 테스트하게 됩니다.
그리고 앱의 규모가 커지면 빌드하는 시간 및 테스트 UI로 입력하는 시간이 점점 길어지는데, 예를 등어 메일 ID형식을 체크하는 기능을 테스트 하기 위해 앱을 매번 빌드하는 것은 비효율 적이기 때문에 Unit test로 간편하게 테스트하여 확인 할 수 있습니다.
인플레이션(Inflation)이란 무엇인가?
Android에서 화면을 구성하는 방법은 xml 레이아웃을 사용하는데, 이 xml 레이아웃 파일의 내용은 애플리케이션이 실행될 때 메모리로 로디오디어서 객체화 됩니다. xml 레이아웃에 정의된 내용을 메모리 상에 객체화되는 과정을 인플레이션이라 합니다.
Intent를 통해 데이터 전달하는 과정에서 클래스 객체를 바로 전달하지 못하는 이유는 무엇이고 전달하기 위해서 어떤 처리가 필요한가? (이 문제의 답의 경우에는 제가 구글링을 통하여 공부하면서 적었지만 확실하지 않으니 참고만 하시면 좋을 것 같습니다.)
클래스 객체에는 변수 뿐만 아니라 다양한 함수들이 존재하는데 사실상 함수를 포함한 class는 코드일 뿐이고, 실질적인 데이터인 변수는 데이터 이므로 코드로 가질수 없다.( 코드와 데이터들이 저장되는 메모리 위치가 다르다고 생각해도 되는것 같습니다. 함수들은 method 영역에 데이터인 변수들은 heap 영역에 저장되기 때문) 그래서 직렬화를 통하여 class에서 변수부분만 전송할 수 있도록 합니다. (전송 시 송신측과 수신측에 동일한 class가 존재해야 합니다. 그래야 직렬화를 풀수있습니다.)그리고 이 직렬화는 Parcelable이나 Serializable을 상속받아 클래스 객체를 직렬화 할 수 있습니다.
(참고 - https://rockdrumy.tistory.com/1044)
추가 - 인텐트를 전달할때는 IPC를 이용한다. 그러나 프로세스간 통신시에는 메모리참조가 안된다. 그래서 파일에 쓰는 방식을 이용하는데 이 때 직렬화, 역직렬화를 통해 파일을 참조한다.
복수의 Fragment 간 데이터 전달 방법
Acitivty가 intent를 통해 데이터를 전달하는 것처럼 Fragment에서는 bundle을 사용하여 전달합니다. Bundle에 전달할 데이털르 담고, 호출할 Framgnet 인스턴스를 생성합니다. 그리고 Framgnet에 setArgument에 bundler을 저장하고, Fragment 가 호출 된 후 onCreateView에서 getArgument로 bundle의 내용을 수신합니다. 그리고 CustomFragment 만들어 Bundle을 따로 저장하도록 만들고 그 저장 데이터를 호출하는 방법도 있습니다.
Kotlin Android Extensions - 리사이클러의 뷰홀더에서 올바르게 사용하는 방법
https://www.androidhuman.com/lecture/kotlin/2017/11/26/kotlin_android_extensions_on_viewholder/
안드로이드 4대 컴포넌트
Activity - Activity는 UI화면을 담당하는 컴퍼넌트 입니다. Application은 한개 이상의 Activity를 가지여 합니다. 한번에 2개의 Activity가 display 될 수 없습니다. 다른 Application의 Activity를 부를 수 있습니다. Fragment를 통하여 화면을 분할 할 수 있습니다.
Broadcast - 방송 수신자로 안드로이드 이벤트와 정보를 받아 반응하는 컴포넌트 입니다. Broadcast가 발생하면 그 Broadcast 관련 filter가 등록된 recevier에서 바당서 서리합니다. Intent 객체로 broadcast를 전달합니다.
Service - 백그라운드에서 동작을 수행하는 컴포넌트 입니다. 백그라운드에서 실행.한번 실행하면 service를 종료하지 않으면 어플리케이션을 종료해도 동작합니다. 네트워크를 통한 테이터 작업 시에도 사용됩니다. (하지만 요즘은 workManager를 더 사용합니다.)
Content Provider - 데이터를 관리하는 컴포너트로 다른 어플리케이션의 데이터도 변경가능합니다. 파일 입출력이나 , SQLlteDB등이 있습니다.
안드로이드의 액티비티와 액티비티의 수명주기에 대해서 설명해보세요.
-Activity는 3가지 상태를 가집니다. 1.Resumed : focus를 가지고 있고 화면에 보이는 상태 2. Paused : focus는 없지만 화면에 보이는 상태 3. Stopped 화면에 보이지 않는 상태.
onCreate 엑티비티가 생성되었을 때 처음 호출. 뷰 바인드등 엑티비티의 초기 설정을 여기서 함
onRestart – 엑티비티가 중단되었다 다시 시작되기 전에 호출
onStart – 엑티비티가 화면에 보이기 직전 단계
onResume – 엑티비티가 화면에 보이고 사용자와 상호작용을 하기 직전에 호출
onPause – 다른 엑티비티가 나타나기 직전에 호출. 엑티비티가 일부 보이면 onPause 에서 멈춤
onStop - 다른 엑티비티가 나타나고 현재 엑티비티가 완전 표시되지 않게되면 호출
onDestroy – 엑티비티가 소멸이되기 전에 호출
참고 - https://developer88.tistory.com/69
프래그먼트의 생명주기에 대해서 설명하세요.
onAttach – onCreate – onCreateView – onActivityCreate - onStart – onResume – onPause – onStop – onDestroyView – onDestroy – onDeatch
onAttach – Fragment가 activity에 적용 될 때 호출
onCreate – framgnet를 초기화 해주는 부분 UI 초기화는 할 수 없다.
onCreateView –Layout inflate하는 부분. 여기서 View 객체를 얻을 수 잇으므로 UI binding을 할 수 있다.
onActivityCreate – Activity의 onCreate 호출되고 나서 호출되는 메소드. Activity와 Fragment 의 뷰가 모두 생성된 상태
onStart, onResume, onPause, onStop 모두 Activity와 유사 단 다른 Activity가 앞으로 나타나면 onPuase가 호출 된다.
onDestroyView- 프레그먼트와 관련된 view 제거 만약 되돌아 온다면 onCreateView로 나타난다.
onDestroy – onDestroyView가 호출되고 다음에 호출되는 메소드
onDetach – 엑티비티로부터 프레그 먼트가 완전히 해제될 때 호출되는 메소드
참고 - https://developer.android.com/guide/components/fragments?hl=ko
안드로이드의 메니페이스
어플리케이션과 관련된 정보를 xml 형식으로 작성된 파일입니다. Activity/ service/ broadcast/ application name/ icon /permission 등이 여기서 작성되어 집니다.
RxJava란 무엇인가?
비동기적 데이터 흐름 처리 프로그래밍 입니다. RxJava에서 핵심은 옵져버 패턴과 비동기입니다.
데이터의 변화가 일어나면 연관된 함수나 수식이 업데이트 되는 것을 말합니다.
코들린의 장점
1. 간결한 coding – data class
2. NullPointerException의 안전함.- 변수 선기 Non-nullable, nullable 을 정해야 합니다. 그리고 Safe Call, Elvis 연산자, 안전 캐스트 as?, non-null assertion, let등으로 Null 처리에 대해 더 안전해 졌습니다.
3. JAVA와 완전히 호완
4. 확장 함수
5. Immutality를 통해 멀티 스레드 사용에 대한 안전성 증가
안드로이드의 테스크란?
어플리케이션에서 Activity를 관리하는 스택입니다. 선입 후출 형태로 사용됩니다.
안드로이드의 Context란?
- 애플리케이션 환경에 대한 전역정보가 컨텍스트로 연결됩니다. Context는 구현이 Android 시스템에 의해 제공되는 추상 클래스입니다. 애플리케이션 별로 리소스 및 클래스에 대한 접근은 물론 Activity의 실행, 브로드 캐스팅 및 Intent수신과 같은 애플리케이션 레벨에 대한 호출을 허용합니다.
- 어플리케이션에 관하여 시스템이 관리하고 있는 정보에 접근하기,Context는 Android 시스템에 의해 제공되는 추상 클래스로. getPackageName(), getResource(), startActivity(), startService(), getSystemService()와 같이 시스템 레벨의 정보를 얻을수 있는 메소드를 쓸수 있습니다
Android에서 Application class란?
-안드로이드에서 Application Class란 어플리케이션 컴포넌트들 사이에서 공동으로 멤버들을 사용할 수 있게 해주는 편리한 공유 클래스를 제공합니다.
-어플리케이션 사이의 컴포넌트들이 공동으로 사용할 수 있기 때문에 공통되게 사용하는 내용을 작성해주면 어디서든 context를 이용한 접근이 가능 합니다.
-Application 객체의 멤버는 프로세스 어디에서나 참조 가능 (메소드도 마찬가지
-공통으로 전역 변수를 사용하고 싶을 때 Application 클래스를 상속받아 사용할 수 있다.
-안드로이드 앱이 시작하면 무조건 Application을 상속 받은 쪽을 먼저 탄다.
Application Context vs Activity Context
Application Context는 애플리케이션과 관련되어 있고 애플리케이션이 살아있는 동안 변경되지 않습니다. 그러므로 싱글톤이며 getApplicationContext()를 통해 Activity에서 접근할 수 있는 인스턴스 입니다. 이 Context는 애플리케이션의 생명주기와 관련되어있기 때문에 현재 Context와 분리된 어떤 Context가 필요하거나, 현재 Activity Scope을 벗어난 작업을 할때 필요합니다.
어떤 싱글톤 객체를 만들어야하고 해당 객체에 항상 Context가 필요한 경우에 Application Context를 전달하면 됩니다.
Application Context에 Activity를 참조하게 되면 Activity가 부서지더라도 참조가 유지되므로, Activity가 GC(가비지 콜렉팅)되지 않으므로 메모리 누수가 발생합니다.
다른 Context보다 가장 오래 보존될만한 Context가 필요할때만 getApplicationContext()를 사용합시다.
Activity Context는 액티비티와 관련이 있고, 액티비티가 부서지면 컨텍스트도 같이 부서집니다. 하나의 애플리케이션에서 여러 액티비티가 존재 할 수 있는데 때로는 특정 Activity Context를 다룰일이 생깁니다. 예를 들어 새로운 액티비티를 실행한다면, 액티비티(컨텍스트)가 필요합니다. 새로 띄워진 액티비티는 이전 액티비티와 연관되어진체로 액티비티 스택에 보관됩니다. Application Context를 이용하여 새로운 액티비티를 띄울수도 있지만 그럴경우 반드시 Intent.FLAG_ACTIVITY_NEW_TASK 플래그를 설정 해주어야합니다.
객체와 클래스
클래스 : 객체를 정의해 놓은 것
객체 : 클래스로 정의된 내용들을 메모리에 생성된 것
인스턴스 : 클래스로부터 객체를 만드는 과정을 인스턴스화라 하며, 어떤 특정 클래스로부터 만들어진 객체를 그 클래스의 인스턴스라 한다.
사용 패턴
Factory 패턴과 템플랫 패턴 싱글턴 패턴, 스트래티지 패턴, 옵저버 패턴
Java 기본형 정수 와 wrapper클래스 의 차이
기본형 정수는 자료형을 의미한다. 그래서 산술연산이 가능하지만 null로 초기화가 불가능하다.
반면 wrapper 클래스는 unboxing 하지 않으면 산술 연산이 불가능 하지만 null값을 처리할 수있다. Wrapper 클래스는 기본형 타입을 클래스와 시킨 것으로 데이터가 아닌 객체로 사용할 수 있는 방법을 제공한다.
자바에서 사용하는 자료구조
Stack, queue, List, Map(key와 value 쌍으로 저장하고, key를 통하여 호출.)set(순서도 없고 중복도 없음)
JVM 실행 구조
자바의 메모리 구조
https://jeong-pro.tistory.com/148
쓰레드간 통신 방법
1. 파이프 스트림을 사용하여 통신
2. 메세지를 통하여 전달
메시지 핸들러에 대해서 설명
Thread 간 통신 시 handler에 데이터를 보내기 위해 사용되는 데이터 저장 객체
Looper는
MainThread에서 Looper와 MessageQueue가 있는데 Message를 전달 받으면 MessageQueue에 들어가소 Looper 계속 동작하면서 선입 선출로 Message를 Handler에 전달하는 역할을 합니다.
백그라운드에서 UI업데이트를 하는 방법
runOnUiThread를 사용하거사 AsynckTask를 사용합니다. 또는 MainThread에서 Handler를 만들고 그 Handler를 사용하여 UI를 업데이트 할 수 도 있습니다.
AsynckTask의 경우 onPreExcute에서 사전 준비 작업을 하고 doInBackground에서 Back그라운드 작업을 수행합니다. 그리고 중간중간에 publishProgess를 호출하여 onProgressupdate 메서드에서 UI를 변경합니다. 그리고 모든 작업이 끝나고 onPostExcute에서 최종 작업을 합니다.
doInBackground의 return 값이 onPostExcute의 인자로 들어갑니다.
http통신이나 리소스 관리 등 시간 소요 시 구현방법
예전까지는 Service를 생성하여 그 작업을 수행 하였지만 oreo 이후부터는 백그라운드 작업에 제약이 생겼고, 현재 workManager가 생겨서 WorkManger로 백그라운드 작업을 수행함
ANR이란
Application Not Responding이라는 의미로 사용자가 action을 취해서 UI가 변경되어야 하는데 반응이 없을 경우 발생합니다. 즉 Application에서 UI 스레드 즉 MainThread가 멈춰서 응답이 없거나 너무 많은 시간을 들여서 동작하게 되면 발생합니다.
Restful API란? *Representation State Transfer의 약자
어떤 자원에 대해 CRUD 연산을 수행하기 위해 모든 자원을 URI로 요청하고 그에 대한 행위를 HTTP Method로 정의하는 방법. 그리고 상세 리소스내용은 json xml 등르로 표현
특징
서버 클라이언트 구조
각각의 URI는 별개의 요청으로 처리한다
캐시처리가 가능해야한다.
인터페이스가 일관되어야한다.
계층화되어야 한다. – client는 server에 요청을 보내고 server는 요청을 받으면 로드밸렁싱 암호화 사용자 인증 등의 단계를 거처 요청에 대한 비즈니스 로직을 처리하고 응답을 client로 보낸다.
URI 정보는 자원을 표현해야한다.
자원에 대한 행위는 HTTP Method로 표현한다. URI에 Http Method가 들어가면안됀다.
참고 -https://brainbackdoor.tistory.com/53
HttpURLConnection Okhttp를 사용하여 coding 할 수 있다.
Android 10
https://developer.android.com/about/versions/10
추가 면접관련 참고 사이트
https://brunch.co.kr/@oemilk/21
https://jw910911.tistory.com/18
안드로이드 구조
https://www.charlezz.com/?p=792
https://brunch.co.kr/@oemilk/68
안드로이드 면접대비 -1
안드로이드 면접대비 -2
안드로이드 면접대비 -3
안드로이드 면접대비 -4
현우의개발노트 -1
현우의개발노트 -2
현우의개발노트 -3
'2023년 이전 > 기타' 카테고리의 다른 글
Java 메모리와 GC (0) | 2020.02.06 |
---|