티스토리 뷰
우아한테크코스 레벨3가 끝나갈 무렵, 학습 돌아보기 인터뷰를 진행했다.
나는 6명으로 이루어진 조에 배정되어 인터뷰이 1명, 인터뷰어 3명, 옵저버 2명으로 진행했다.
사전에 준비해간 자료를 토대로 질문을 하고 그에 대한 답변을 하는 방식이었다.
옵저버는 인터뷰 과정을 관찰하고 그에 대한 피드백을 전달한다.
인터뷰 20분 + 피드백 10분으로 진행했다.
인터뷰 때 받은 질문과 답변, 피드백들을 정리해 보려고 한다.
인터뷰 사전 자료
인터뷰를 위한 사전 자료를 같은 조 크루들끼리 공유해야 했다.
레벨3 팀 프로젝트를 하며 학습/협업한 내용을 A4 한 장 내외로 정리하는 것이었는데,
나는 내가 팀에 기여한 점과 협업 측면에서 배운 점들을 자세히 작성했다.
여러 주제를 얕게 적는 것보다는, 한 두개의 주제를 자세히 작성하는 것이 인터뷰어가 질문하기에도 수월할 것 같았다.
아래는 내가 작성한 인터뷰 자료다.
크게 개발에 대한 주제 2개와 협업 주제 1개를 작성했다.
막상 내가 배운 점을 적으려니 A4 한 장 내외라는 분량이 짧게 느껴졌다.
쓰고 싶은 내용은 많은데 그 중 가장 핵심적인 내용만을 남기는 것이 어려웠다.
작성하면서 레벨3 팀 프로젝트에 대한 전체적인 회고를 할 수 있었는데,
추후 취준하면서 자소서를 쓸 때도 이 문서가 도움이 될 것 같다.
조금 더 추상화를 하고 5~6개의 주제를 작성해도 좋았을 것 같다.
인터뷰 준비
론칭 페스티벌 준비와 코로나 확진 이슈로.. 인터뷰 준비할 시간이 너무 없었다.
인터뷰를 위해 약 2시간밖에 시간을 쓰지 못했다.
각 주제에 대해 4~5개 정도 예상 질문을 뽑고, 예상 질문에 대한 답변을 작성했다.
작성한 답변을 한두 번 정도 소리내서 대답해보는 방식으로 간단히 준비했다.
아래 토글에 내가 준비했던 예상 질문을 정리해보았다.
면접 예상 질문은 챗지피티한테 부탁하면 정말 최고다. 강추.
<WorkManager를 사용한 백그라운드 폴링 작업> 예상 질문
1. WorkManager를 사용한 이유
2. WorkManager에서 Worker와 CoroutineWorker의 차이점
3. WorkManager에서 백그라운드 작업이 실패했을 때 어떻게 처리할 수 있는지
4. 앱이 종료되거나 기기가 재부팅되어도 백그라운드 작업이 유지되게 하는 방법
5. Dispatchers.Default란?
<주소 검색 다이얼로그> 예상 질문
1. 안드로이드 앱에서 로컬 HTML 파일을 WebView로 표시할 때 발생할 수 있는 문제점
2. WebViewAssetLoader의 역할
3. WebView에서 JavaScript와 Kotlin 간의 통신 방법을 설명
4. JavaScript와 Kotlin 간의 통신 시 발생할 수 있는 보안 문제는 무엇이 있고 이를 어떻게 방지할 수 있는지
5. 웹뷰의 webViewClient란?
6. 서버에 HTML 파일을 두지 않고 로컬에 둔 이유
<협업 과정> 예상 질문
1. 협업 과정에서 스트레스를 받았던 상황은 무엇이었고, 어떻게 해결했는지
2. 스크럼 시 안건을 구체적으로 공유하자는 제안은 어떻게 팀의 소통에 기여할 수 있었는지
3. 팀원이 시간 약속을 잘 지키지 않는 경우 어떻게 대처할 것인지
인터뷰 진행
내 인터뷰 차례에는 인터뷰어는 빙티, 케이엠, 해음이었고 옵저버는 악어, 알송이었다.
안드로이드 코치님인 제임스도 같이 질문을 하셨고 피드백도 주셨다. 😊
질문과 답변을 다 기억하기는 어려울 것 같아서, 클로바 노트로 인터뷰 과정을 모두 녹음했다.
아래는 받은 질문과 그에 대한 답변을 순서대로 정리한 것이다. (스압 주의..)
이번 프로젝트에서 본인이 맡은 역할을 간단히 소개
두 번째 스프린트에서는 약속을 개설하고 출발 시간에 알림을 보내는 기능을 구현을 했다. 그 안에서 약속에 필요한 정보들을 입력하는 부분을 구현했다. 또한 주소 검색 API를 통해 주소 검색 다이얼로그를 호출을 하고, 사용자가 주소를 검색을 하면 그에 해당하는 도로명 주소들이 뜨는 기능을 구현했다.
기능을 구현하면서 어려웠던 점
주소 검색 쪽이 조금 어려웠다. 주소 검색 API가 따로 API 키를 발급해서 호출하는 방식이 아니라 정형화된 HTML 문서가 있었다. 이 HTML을 WebView로 띄워야 하는 상황이었다. WebView를 사용하는 것이 처음이었고, 그 HTML을 서버에 배포를 할지 아니면 로컬에서 띄울지를 고민하는 과정이 어려웠다.
이 프로젝트에 어떤 기능이 있는지, 그런 기능을 어떻게 구현했는지 간략하게 설명
한마디로 요약을 하자면 지각을 방지할 수 있도록 도와주는 앱이다. 지각하지 않기 위해서 출발지와 도착지 그리고 약속 시간을 입력을 하면 지각하지 않도록 나가야 하는 최소 시간에 알림을 보내준다. 사용자 위치를 기반으로 친구들이 지각을 할지 안 할지 그리고 몇 분 후에 도착을 할지를 실시간으로 확인할 수 있다.
주소 검색 API는 어떤 걸 사용했는지, 그리고 그 API 선택 이유
카카오에서 제공하는 API를 사용했다. 키를 발급하지 않고 바로 사용할 수 있다는 점이 간편하고, API에 대한 자료도 많았기 때문에 러닝 커브가 낮다고 생각했다.
사람들이 보통 도로명 주소를 외우고 다니지 않을 텐데, 상호명이 아닌 도로명 주소를 검색해야 하는 API를 선택한 이유
그 부분은 고려를 못한 채로 API를 선택했다. 그런데 UT 인터뷰에서 동일한 피드백이 와서, 추후에 반영하려고 백로그에 넣어둔 상태다.
WebView에서 자바스크립트랑 앱이랑 통신하는 방법에 대해 설명
자바스크립트와 코틀린이 통신할 수 있는 함수를 만들 수 있다. 먼저 그 함수를 코틀린으로 작성한다. 그 함수 안에 @JavascriptInterface라는 어노테이션을 붙이면 자바스크립트에서 그 함수를 호출할 수 있다. 그 함수를 호출 하기 위해서는 WebView에 JavascriptInterface를 등록을 해야 한다. JavascriptInterface를 그 함수가 포함된 클래스로 등록을 하고, 그 클래스에 대한 식별자를 같이 등록을 해준다. 그러면 자바스크립트에서 그 식별자를 통해서 함수에 접근을 할 수 있다.
WorkManager를 사용한 백그라운드 폴링 작업 기능을 구현하셨다고 하셨는데 WorkManager에 대해서 간단히 설명해 주실 수 있나요?
WorkManager는 백그라운드에서 작업을 수행할 수 있도록 도와주는 친구다. 백그라운드에서 수행할 작업 단위가 Worker가 있다. WorkManager는 큐 형태로 사용이 되는데, 이 큐에 Worker들을 등록을 해서 작업을 예약한다.
백그라운드 작업 수행을 할 수 있는 여러 안드로이드 컴포넌트 중 WorkManager를 선택한 이유
먼저 어떤 기능을 구현하기 위해서 WorkManager을 사용을 했냐면, 친구들의 실시간 위치 정보를 기반으로 지각을 할지 안 할지를 알려주는 기능이었다.
이 기능을 구현하기 위해서는 앱을 사용하지 않아도 사용자의 위치를 서버로 요청을 보내야 한다. Service나 AlarmManager는 Doze 모드에서는 예약한 작업이 수행되지가 않고, 기기를 재부팅하면 예약한 작업이 사라진다고 알고 있다. 그런데WorkManager는 그거를 내부적으로 다 처리를 해주고 있기 때문에 선택했다.
그리고 A 화면에서 작업을 예약하고, B 화면에서 예약한 작업의 결과를 받아와서 비동기로 ui를 갱신을 해줬어야 했다. WorkManager에서 예약한 작업의 결과를 LiveData로 반환해주는 API가 있었기 때문에, 그 기능을 활용하기 위해서 WorkManager를 사용했다.
작업을 예약해둔 상태에서 서버 API가 변경된 경우 오류가 발생할 것 같은데, 그에 대한 방어 코드가 있나?
예약한 작업이 실패하면 따로 재시도해주는 방식은 아직 구현하지 않았다.
WorkManager의 Work에 doWork()라는 함수를 오버라이드를 해서 어떤 작업을 수행을 할지를 정의를 할 수가 있다. 그 반환 값이 Result인데, Result.retry()라는 객체를 반환하면 실패한 작업에 대해 자동으로 재시도를 해준다. 그래서 네트워크 연결이 끊겼다거나 에러를 반환을 했다거나, 사용자 위치 권한을 받아올 수 없을 경우 재시도를 하는 방식으로 구현하면 될 것 같다.
Service나 AlarmManager는 재부팅했을 때 데이터 관리가 어렵다고 했는데, 어렵지만 불가능한 건 아닌 것 같다. Service나 AlarmManager를 사용해서 재부팅했을 때 계속해서 이 동작을 하게 하려면 어떻게 해야할까?
REBOOT 브로드캐스트라는 게 있다. 이거를 매니패스트에 등록을 해주고 재부팅 시에 어떤 작업을 수행할지 구현한다. 그 안에서 예약된 작업을 다시 예약을 해주는 등의 코드를 구현하면 Service나 AlarmManager에서도 충분히 가능할 것 같다.
AlarmManager와 달리 Doze 모드에 대한 고려를 할 필요가 없어서 WorkManager를 사용했고 했는데, AlarmManager에서는 Doze 모드를 어떻게 피할 수 있을까?
Doze 모드 시에서도 예약한 정확한 시점에 작업을 수행할 수 있는 함수가 따로 있는 걸로 알고 있다.
(setExactAndAllowWhileIdle()를 말하고 싶었음.)
Doze 모드를 회피하려면 어떤 방법을 써야하는가?
이 부분은 공부가 조금 더 필요한 것 같다.
WorkManager에 작업들을 예약해두고 폴링 방식으로 가져온다고 했는데, 안드로이드 핸들러랑 되게 비슷한 방식인 같다. 혹시 핸들러에 대해 알고 있나?
스레드 작업의 결과를 대신 전달해 주는 객체라고 알고 있는데 정확히는 잘 모르겠다.
WorkManager를 통해 ui를 업데이트를 한다고 했는데, 어떤 방식인지 자세히 설명
먼저 WorkManager의 작업을 예약을 할 때 tag를 통해서 그 작업의 식별자를 구분할 수 있다. 이 tag를 약속의 id로 지정을 했다. 작업 결과가 필요한 화면에서 tag 통해서 예약한 작업의 결과를 LiveData로 받아온다. 그리고 WorkManager가 이 작업을 수행할 때마다 LiveData의 값을 변경해 주기 때문에, 이 LiveData를 Activity에서 옵저빙해서 ui를 변경했다.
WorkManager가 ViewModel과 비슷한 역할을 하고 있는 것 같다. 별도의 스레드나 디스패처 전환 없이 바로 수행을 하고 있나?
Workr에서도 Worker랑 CoroutineWorker가 있다. CoroutineWorker를 사용하면 기본적으로 Dispatchers.Default를 사용하는 것으로 알고 있다. 이 디스패처를 따로 변경하지 않고 사용했다.
코틀린의 접근 제한자의 종류가 어떤 게 있고, 각각의 접근 범위는 어떻게 되나?
public, private, internal, protected가 있다.
public은 모든 곳에서 접근할 수 있고 private은 그 클래스 내에서만 접근할 수 있다. 그리고 internal은 같은 모듈 내에서만 접근을 할 수 있고 protected는 자기 자신을 상속받은 자식들만 접근할 수 있다.
WorkManager로 작업을 요청할 때 WorkRequest라는 게 있다. WorkRequest의 종류는 어떤 게 있고, 그 중 어떤 걸 사용했나?
종류로는 한 번 작업을 요청하는 친구가 있고 주기적으로 작업을 요청하는 친구가 있는 걸로 알고 있다. 이 프로젝트에는 주기적으로 요청하는 친구가 적합했는데, 이 주기적인 작업을 취소하는 방법은 따로 제공하고 있지 않았다. 그래서 한 번 요청을 할 수 있는 친구를 사용했는데, 이 요청을 여러 번 호출하는 방식으로 구현했다.
(한 번 작업 요청은 OneTimeWorkRequest, 주기적 작업 요청은 PeriodicWorkRequest을 말하고 싶었음..)
만약 주기적으로 여러 번 요청을 해야 하면서 취소를 해야 한다면 어떻게 구현할 것인가?
취소해야 할 시점에도 작업을 예약해서, 그 시점이 되면 작업을 취소하는 코드를 수행할 수 있도록 구현을 할 것 같다.
WorkManager를 사용하시면서 버그가 났다거나 사용하기 불편했던 점
이 부분은 잘 생각이 나지 않는다. (ㅠㅠ)
서버 통신을 할 때 통신 라이브러리는 어떤 걸 사용?
Retrofit을 사용했다.
왜 Retrofit을 사용했고, 다른 어떤 라이브러리와 비교했는가?
다른 라이브러리를 검토하지는 않았다. 안드로이드 팀원 모두가 Retrofit를 잘 알고 있는 상태였고, 새로운 기술을 배울 시간이 줄어든다고 생각을 해서 Retrofit을 사용했다.
Retrofit을 사용할 때는 역직렬화 라이브러리도 선택을 해야 한다. 어떤 라이브러리를 선택했고, 왜 그 라이브러리를 선택했는가?
Moshi 라이브러리를 사용했다. gson이라는 라이브러리와 비교를 해서 선택했다. gson은 코틀린과의 상호 호환성이 좋지않고, null이 들어가는 경우 그 값이 무시된다고 알고 있다. Moshi는 코틀린과의 친화성도 좋고 사용해보지 않은 기술이었기 때문에 학습을 하고 싶어서 Moshi를 사용하게 되었다.
데이터 레이어를 어떻게 구성했는가?
Repository 패턴만 사용하고 있다.
Repository 패턴이란?
외부에서 데이터를 가져오든 내부에서 데이터를 가져오든 데이터를 가져오는 방식을 추상화해서, View나 ViewModel에서 데이터의 세부 출처를 알 수 없도록 추상화하는 패턴이다.
DataSource도 사용했나?
DataSource는 사용하지 않았다. 데이터가 들어오는 방식이 여러 곳인 경우에만 적합한 패턴이라고 알고 있다. 현재는 우리 서버에서만 데이터를 가져오고 있기 때문에 Repository 패턴만 사용하는 것이 적합하다고 판단했다.
내부/외부 데이터 출처를 추상화하기 위해 사용하는 것이 레포지토리 패턴이라고 했는데, 서버에서만 데이터를 가져오면 굳이 레포지토리 패턴을 적용하지 않아도 되는 거 아닌가?
추후에 다른 방식으로 데이터를 가져올 수 있다고, 충분히 변경 가능성이 있다고 생각을 해서 Repository 패턴으로 추상화를 했다. DataSource로 추상화하지 않은 이유는 너무 과한 추상화가 될 것 같았고, 추상화의 적절한 수준을 지키기 위해서 Repository 패턴만 사용했다.
협업할 때 힘들었던 점
이번 프로젝트를 하면서 성향을 조금 깨닫게 되었다. 나는 통제적인 성향인데, 이 통제적인 성향을 함께 협업하는 팀원에게도 강요하고 있었다. 그리고 구체적으로 팀원이 어떤 일을 하고있는지 계속해서 파악하고 싶어하고, 빠른 파악이 되지 않을 때는 큰 스트레스로 다가왔다.
어떻게 해결했는가?
먼저 우리팀은 매일 아침 스크럼을 진행한다. 스크럼 때 자신의 진행 상황을 최대한 구체적으로 공유하자라는 제안을 했다. 예를 들어서 어떤 기능 개발을 할 예정이다라고 하기보다는 어떤 기능을 개발하고 있는데 어떤 버그가 발생을 해서 PR은 언제까지 올릴 것 같다라고 구체적으로 말하는 방식이었다. 현재까지 잘 지켜지고 있고, 이를 통해서 제 통제적인 성향도 스트레스를 덜 받게 되었고 협업의 효율성도 증가하게 되었다.
인터뷰 피드백
알송
좋은 점
- WorkManager에 대해 잘 알고있음.
- 기술을 사용한 판단 기준이 논리적임.
- 동작 원리를 잘 알고있음.
- 비언어적 표현이 적절함.
- 모르면 모른다고 하지 않고, 공부가 더 필요할 것같다는 답변
- 협업 관련해서 자신의 성향을 파악하고 반성, 해결한 점이 좋았음
아쉬운 점
- 라이브러리 선택 이유가 일관적이지 않음.
- 통신 라이브러리는 이미 익숙한 기술이기 때문에 선택했지만, 직렬화 라이브러리는 학습하기 위해 선택함.
- 통신 라이브러리와 직렬화 라이브러리의 선택 이유가 일관적이지 않음.
- Repository, DataSource 관련 → 지나친 추상화를 처음에 답변하면 좋았을듯.
악어
좋은 점
- ㅠㅠ
아쉬운 점
- 프로젝트 설명 관련
- 프로젝트 단위로 질문을 했는데, "두번째 스프린트에서는~"이라고 대답한 점.
- 면접관 입장에서는 몇번째 스프린트인지는 궁금하지 않음.
- 불필요한 손짓. 의미있는 손짓이 아니었음.
- 답변이 명확하지 않았음.
- 어떤 기술을 선택할 때 비교하지 않은 점이 아쉽다.
- 정형화된 답변 잘 해주었지만, 조금 더 딥하게 답변해도 좋을 것 같음.
- 질문을 받았을 때 당황하는 표정.
- 질문을 공격으로 받아들이지 말기.
- 내가 놓친 점을 짚어주었을 때, "그런 방법도 있겠네요~"와 같이 능청스러움으로 넘기기.
제임스
좋은 점
- 질문한 인터뷰어의 시선을 끝까지 마주침.
아쉬운 점
- 능청스러움 가지기.
- 면접관이 왜그렇게 질문했는지 역질문을 해보기.
- 즉석에서 이해하는 리액션. "이건 다음에 적용해보겠습니다~"와 같은 답변으로 명석한 느낌주기. 능청스러운 연기.
인터뷰 후기
질문이 엄청 많다. 대답을 짧게 한 것도 아닌데 유독 받은 질문이 많은 것 같다.
답변까지 다시 정리하고 보니 부족한 점이 많이 보인다.
특히 프로젝트에 대한 전반적인 설명, 라이브러리 선택 이유에 대해 많이 횡설수설한 것 같다.
틀린 대답도 있을 것 같은데, 구체적인 답변은 참고만 하길 바란다.
레벨1, 2까지는 각자 학습한 내용을 되돌아보는 시간을 가졌었는데, 강제성이 없었다.
인터뷰는 강제성+위기감 조성+확실한 메타인지를 할 수 있어 좋았다. 이번 인터뷰를 레벨1, 2에도 했으면 좋았을 것같다.
다른 크루들 인터뷰 질문들도 되새기면서, 내가 어떤 부분이 부족한지 확실한 메타인지가 되었다.
일단 레벨1, 2때 배웠던 내용들을 복습하고 기술 선택 이유를 구체적으로 생각해봐야할 것 같다.
예전 같았으면 남들에게 부족한 모습을 보여줬다는 생각에 오랫동안 아쉬워했을 것 같다.
그런데 이제는 이 인터뷰가 평가가 아닌 내 발전을 위한 과정임을 알기 때문에 아쉬움이 길게 남지는 않는다.
부족한 점은 더 채워나가면 된다!
저번 취준할 때보다 아는게 더 많아졌음을 확실히 느낀다.
예전에는 자신감도 없고 엄청 떨려했는데, 이제는 면접에 대한 자신감도 생겼다.
지금은 그래도 어느정도 알고있는 질문들이 나오니까 재밌다.
끝!
🙂
'woowacourse' 카테고리의 다른 글
[우아한테크코스] 안드로이드 레벨2 쇼핑 장바구니 미션 회고 (0) | 2024.06.28 |
---|---|
[안드로이드/우아한테크코스] MVP의 Presenter에서는 context를 알아도 될까? (0) | 2024.06.28 |
[우아한테크코스] 안드로이드 레벨2 영화 극장 선택 미션 회고 (3) | 2024.05.17 |
[우아한테크코스] 안드로이드 레벨2 영화 티켓 예매 미션 회고 (1) | 2024.05.07 |
[우아한테크코스] 안드로이드 레벨1 오목 미션 회고 (0) | 2024.04.12 |