최종 팀프로젝트 TIL(26)

jxxn_a·2023년 11월 14일
0

팀프로젝트

목록 보기
30/33

🐱 With All My Animal 🐶
💡 [ 26일차 11/14일 ] 💡

📌 오늘의 기술면접 질문 Q&A

1)접근제어자는 어떤게 있을까요?

✨ 접근제어자란?

  • 클래스, 인터페이스, 함수, 프로퍼티의 가시성을 제한할 때 사용한다.
  • 접근제어자를 통해 캡슐화 등의 객체지향 프로그래밍 원칙을 잘 지킬 수 있게 돕는다.

🚀 Private

  • Private 접근 제한자가 붙은 멤버는 해당 클래스 내부에서만 접근이 가능하다.
  • Private가 붙은 최상위 함수나 프로퍼티는 해당 파일 내에서만 접근이 가능하다.

🚀 Protected

  • protected 접근 제한자는 private랑 유사하지만, 하위 클래스에서는 접근이 가능하다.
  • 상위 함수나 프로퍼티에는 protected를 사용할 수없다.

🚀 Internal

  • internal 접근 제한자는 같은 모듈 내에서는 접근이 가능하다.
  • 모듈은 ntelliJ IDEA의 모듈, Maven의 프로젝트, Gradle의 소스 세트 등을 의미한다.

🚀 Public

  • public 접근 제한자는 어디서든 접근이 가능하게 한다.
  • 별도의 접근 제한자를 지정하지 않으면 public으로 간주한다.

2) foreground service와 background service의 차이점이 무엇인가요?

✨ Service란?

  • Android에서 Service는 주로 백그라운드에서 실행되는 오래 실행되는 작업을 위한 구성요소이다.
  • Service는 사용자 인터페이스를 가지지 않고, 서비스를 실행하는 Activity가 종료되더라도 백그라운드에서 계속 실행될 수 있다.

🚀 foreground service

  • 사용자에게 가시적인 작업을 수행한다.
  • 사용자의 직접적인 상호작용이 필요한 작업이거나 중단되어서는 안되는 작업을 수행 할 때 사용된다.
  • foreground service는 항상 알림을 통해 사용자에게 자신의 존재를 알려야한다.
  • 예시) 음악 재생, 파일 다운로드 등

🚀 background service

  • 사용자에게 직접적으로 보이지 않는 작업을 수행한다.
  • 주로 사용자가 직접적으로 인지하지 못하는 작업을 수행할 때 사용된다.
  • 사용자의 눈에 띄지 않기 때문에 시스템의 메모리 부족 상황에서는 시스템에 의해 종료될 수 있다.
  • 예시) 데이터 동기화, 알림 체크 등

📌 App 안에서 발생한 오류

🚨 startForResult

  • 에러가 발생하는 시기
    - HomepageFragment에서 게시물을 클릭했을 때
    - MypageFragment에서 내가 쓴 게시물을 클릭했을 때 등등

  • 해결 방안: 초기화 방식과 변수 선언 방식 변경하기

  • 수정 전 코드

 private val startForResult =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
            if (result.resultCode == Activity.RESULT_OK) {
                Log.d(TAG, result.resultCode.toString())
                deletedKey = result.data?.getStringExtra("deletedPostKey")
                    ?: return@registerForActivityResult
                rvAdapter?.deletePost(deletedKey)
            }
        }
        
---------------------------------------------------------------------------------------------------
        
        private fun setUpRecyclerView() {
        rvAdapter = HomeRVAdapter(boardList) { intent ->
            startForResult.launch(intent)
        }
  • 수정 후 코드
private var startForResult: ActivityResultLauncher<Intent>? = null
-------------------------------------------------------------------------------------------------------
 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d(TAG, "viewCreated 불리니")
        startForResult =
            registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
                if (result.resultCode == Activity.RESULT_OK) {
                    Log.d(TAG, result.resultCode.toString())
                    deletedKey = result.data?.getStringExtra("deletedPostKey")
                        ?: return@registerForActivityResult
                    rvAdapter?.deletePost(deletedKey)
                }
            }
-------------------------------------------------------------------------------------------------------
private fun setUpRecyclerView() {
        rvAdapter = HomeRVAdapter(boardList) { intent ->
            startForResult?.launch(intent)
        }
        binding.rvHome.apply {
            setHasFixedSize(true)
        _binding = null
    }

    override fun onDestroy() {
        startForResult = null
        super.onDestroy()
    }

🚨 ArrayIndexOutOfBoundsException : length=10; index=-1

  • 에러가 발생하는 시기
    - MypageFragment Like List 클릭했을 때

  • 에러가 발생한 이유
    - 인덱스 범위를 벗어나는 접근을 시도했을 때 발생한다.
    - RecyclerView에서 adapterPosition은 현재 View Holder가 binding 되어있는 아이템의 위치를 나타내지만, 아이템이 아직 binding 되지 않았거나, binding이 해제되었을 경우에는 -1이 되어 인덱스의 범위를 벗어나는 접근이 되어버린다.
    - adapterPosition이 유효하다는 것은 ViewHolder가 binding 된 상태라는 의미이지만, 그것이 반드시 list에 데이터가 있음을 보장하지 않는다.

  • 해결 방안: 접근 전에 해당 인덱스가 유효한지를 항상 확인하는 로직을 추가한다.
init {
            binding.root.setOnClickListener {
            
            // 아래 두 줄 추가하기
                val position = adapterPosition
                if (position != RecyclerView.NO_POSITION && list.size > position) {
                
                    val clickedItem = list[adapterPosition]
                    val uid = clickedItem.uid
                    val key = clickedItem.key
                    val category = clickedItem.category

0개의 댓글