시니어 iOS 개발자 면접 질문과 답변

Milad Bonakdar
작성자
Swift, SwiftUI, 아키텍처, 동시성, 성능, Core Data, 오프라인 동기화, 보안을 다루는 실전형 시니어 iOS 면접 질문입니다.
소개
시니어 iOS 면접은 Swift와 Apple 프레임워크 지식을 실제 제품 의사결정에 연결할 수 있는지 확인합니다. 아키텍처, 상태 관리, 동시성, 성능, 영속성, 보안, 실제 앱에서의 트레이드오프를 설명해야 합니다.
이 가이드는 결정을 먼저 말하고, 피하려는 실패 모드를 설명하며, Xcode 도구나 코드 기법까지 제시하는 답변을 연습하도록 구성되어 있습니다. 시니어 답변은 문서 암기가 아니라 코드 리뷰에서 신뢰할 수 있는 실무성이 있어야 합니다.
고급 Swift & 언어 기능 (6개 질문)
1. Swift의 메모리 관리 및 ARC (자동 참조 카운팅)에 대해 설명하십시오.
답변: ARC는 클래스 인스턴스에 대한 참조를 추적하고 관리하여 메모리를 자동으로 관리합니다.
- 작동 방식: 각 클래스 인스턴스에는 참조 횟수가 있습니다. 횟수가 0에 도달하면 인스턴스가 할당 해제됩니다.
- 강한 참조: 기본값입니다. 참조 횟수를 증가시킵니다.
- 약한 참조: 참조 횟수를 증가시키지 않습니다. 인스턴스가 할당 해제되면 자동으로
nil이 됩니다. - 미소유 참조: 참조 횟수를 증가시키지 않지만 인스턴스가 항상 존재한다고 가정합니다.
- 순환 참조: 두 객체가 서로에 대한 강한 참조를 유지하여 할당 해제를 막을 때 발생합니다.
희소성: 매우 흔함 난이도: 어려움
2. Swift의 제네릭이란 무엇이며 왜 유용한가요?
답변: 제네릭을 사용하면 모든 유형에서 작동할 수 있는 유연하고 재사용 가능한 함수와 유형을 작성할 수 있습니다.
- 장점: 코드 재사용성, 타입 안전성, 성능 (런타임 오버헤드 없음)
- 타입 제약 조건: 제네릭 타입을 특정 프로토콜 또는 클래스로 제한합니다.
- 연관 타입: 프로토콜에서 자리 표시자 타입을 정의하는 데 사용됩니다.
희소성: 흔함 난이도: 중간
3. escaping 클로저와 non-escaping 클로저의 차이점을 설명하십시오.
답변:
- Non-escaping (기본값): 클로저는 함수가 반환되기 전에 실행됩니다. 컴파일러가 더 잘 최적화할 수 있습니다.
- Escaping (
@escaping): 클로저는 함수보다 오래 지속됩니다 (속성에 저장되거나 비동기적으로 호출됨).self를 명시적으로 캡처해야 합니다.
희소성: 흔함 난이도: 중간
4. map, flatMap 및 compactMap의 차이점은 무엇입니까?
답변: 이들은 컬렉션을 변환하기 위한 고차 함수입니다.
map: 각 요소를 변환하고 결과 배열을 반환합니다.compactMap:map과 같지만nil값을 필터링합니다.flatMap: 중첩된 배열을 단일 배열로 평탄화합니다.
희소성: 흔함 난이도: 쉬움
5. Swift의 속성 래퍼에 대해 설명하십시오.
답변: 속성 래퍼는 속성이 저장되는 방식을 관리하는 코드와 속성을 정의하는 코드 사이에 분리 계층을 추가합니다.
- 기본 제공 예: SwiftUI의
@State,@Published,@AppStorage - 사용자 지정 래퍼: 재사용 가능한 속성 동작을 정의합니다.
희소성: 중간 난이도: 어려움
6. Result 타입이란 무엇이며 어떻게 사용됩니까?
답변:
Result는 성공 또는 실패를 나타내는 열거형으로, 오류 처리를 더 명시적으로 만듭니다.
- 정의:
enum Result<Success, Failure: Error> - 장점: 타입 안전 오류 처리, 더 명확한 API 계약, 비동기 코드에 대한 함수 throw보다 더 좋습니다.
희소성: 흔함 난이도: 중간
아키텍처 패턴 (5개 질문)
7. MVVM (Model-View-ViewModel) 패턴에 대해 설명하십시오.
답변: MVVM은 UI 로직을 비즈니스 로직에서 분리하여 코드를 더 테스트 가능하고 유지 관리 가능하게 만듭니다.
- Model: 데이터 및 비즈니스 로직
- View: UI (UIViewController, SwiftUI View)
- ViewModel: 프레젠테이션 로직, 뷰를 위한 모델 데이터 변환
- 장점: 테스트 가능 (ViewModel에는 UI 종속성이 없음), 재사용 가능한 ViewModels, 명확한 관심사 분리
희소성: 매우 흔함 난이도: 중간
8. 코디네이터 패턴이란 무엇이며 왜 사용해야 합니까?
답변: 코디네이터 패턴은 탐색 로직을 뷰 컨트롤러에서 분리합니다.
- 문제: UI 로직과 혼합된 탐색 로직이 있는 거대한 뷰 컨트롤러
- 해결책: 코디네이터는 탐색 흐름을 처리합니다.
- 장점: 재사용 가능한 뷰 컨트롤러, 테스트 가능한 탐색, 명확한 앱 흐름
희소성: 중간 난이도: 어려움
9. iOS에서 의존성 주입에 대해 설명하십시오.
답변: 의존성 주입은 객체가 내부적으로 생성하는 대신 의존성이 객체에 제공되는 디자인 패턴입니다.
- 장점: 테스트 가능성 (모의 객체 주입), 유연성, 느슨한 결합
- 유형:
- 생성자 주입: 이니셜라이저를 통해 의존성을 전달합니다 (가장 일반적).
- 속성 주입: 초기화 후 의존성을 설정합니다.
- 메서드 주입: 의존성을 메서드 매개변수로 전달합니다.
희소성: 흔함 난이도: 중간
10. 리포지토리 패턴이란 무엇입니까?
답변: 리포지토리 패턴은 데이터 액세스 로직을 추상화하여 데이터 작업에 대한 깔끔한 API를 제공합니다.
- 장점: 중앙 집중식 데이터 로직, 데이터 소스 전환 용이 (API, 데이터베이스, 캐시), 테스트 가능
- 구현: 리포지토리는 여러 데이터 소스 간에 조정합니다.
희소성: 중간 난이도: 중간
11. MVC, MVP 및 MVVM의 차이점을 설명하십시오.
답변:
- MVC (Model-View-Controller):
- Apple의 기본 패턴
- 컨트롤러는 Model과 View 사이를 중재합니다.
- 문제: 거대한 뷰 컨트롤러
- MVP (Model-View-Presenter):
- Presenter는 모든 UI 로직을 처리합니다.
- View는 수동적입니다 (데이터만 표시).
- MVC보다 더 나은 테스트 가능성
- MVVM (Model-View-ViewModel):
- ViewModel은 데이터 스트림을 노출합니다.
- View는 ViewModel에 바인딩됩니다.
- 반응형 프로그래밍에 가장 적합합니다 (Combine, RxSwift).
희소성: 흔함 난이도: 어려움
성능 및 최적화 (5개 질문)
12. 테이블 뷰 및 컬렉션 뷰 성능을 어떻게 최적화합니까?
답변: 여러 전략이 스크롤 성능을 향상시킵니다.
- 셀 재사용:
dequeueReusableCell을 올바르게 사용하십시오. - 무거운 작업 피하기:
cellForRowAt에서 비용이 많이 드는 계산을 수행하지 마십시오. - 이미지 최적화:
- 이미지를 표시 크기로 조정합니다.
- 이미지 처리에 백그라운드 스레드를 사용합니다.
- 디코딩된 이미지를 캐시합니다.
- 미리 가져오기:
UITableViewDataSourcePrefetching을 구현합니다. - 높이 캐싱: 계산된 셀 높이를 캐시합니다.
- 투명도 피하기: 불투명 뷰가 더 빠르게 렌더링됩니다.
희소성: 매우 흔함 난이도: 중간
13. Instruments와 성능 프로파일링에 사용하는 방법에 대해 설명하십시오.
답변: Instruments는 Xcode의 성능 분석 도구입니다.
- 일반적인 Instruments:
- Time Profiler: CPU 집약적인 코드를 식별합니다.
- Allocations: 메모리 할당 및 누수를 추적합니다.
- Leaks: 메모리 누수를 감지합니다.
- Network: 네트워크 활동을 모니터링합니다.
- Energy Log: 배터리 사용량을 분석합니다.
- 워크플로:
- 앱 프로파일링 (Cmd+I)
- instrument 선택
- 앱 기록 및 상호 작용
- 호출 트리 및 타임라인 분석
- 병목 현상 식별
희소성: 흔함 난이도: 중간
14. 메모리 누수를 감지하고 수정하는 방법은 무엇입니까?
답변: 메모리 누수는 더 이상 필요하지 않은 객체가 할당 해제되지 않을 때 발생합니다.
- 일반적인 원인:
- 순환 참조 (강한 참조 순환)
self를 강하게 캡처하는 클로저weak로 표시되지 않은 대리자
- 감지:
- Instruments Leaks 도구
- Xcode의 메모리 그래프 디버거
- 증가하는 메모리 사용량 감시
- 수정:
- 대리자에
weak또는unowned사용 - 클로저에서
[weak self]또는[unowned self]사용 - 순환 참조 끊기
- 대리자에
희소성: 매우 흔함 난이도: 중간
15. 앱 시작 최적화를 위해 어떤 기술을 사용합니까?
답변: 더 빠른 앱 실행은 사용자 경험을 향상시킵니다.
- 지연 로딩: 필요할 때만 객체 초기화
- Dylib 로딩 줄이기: 동적 라이브러리 최소화
application:didFinishLaunching최적화:- 중요하지 않은 작업을 백그라운드로 이동
- 무거운 초기화 지연
- 바이너리 크기: 더 작은 바이너리가 더 빠르게 로드됩니다.
- 무거운 작업 피하기: 메인 스레드를 차단하지 마십시오.
- 측정: Instruments의 앱 시작 템플릿 사용
희소성: 흔함 난이도: 중간
16. 이미지 캐싱 및 로딩을 어떻게 처리합니까?
답변: 효율적인 이미지 처리는 성능에 매우 중요합니다.
- 전략:
- 메모리 캐시: 빠른 액세스, 제한된 크기
- 디스크 캐시: 영구적, 더 큰 용량
- 다운로드: 네트워크에서 가져오기
- 라이브러리: SDWebImage, Kingfisher (캐싱 자동 처리)
- 사용자 지정 구현:
희소성: 흔함 난이도: 어려움
동시성 및 비동기 프로그래밍 (4개 질문)
17. Swift에서 async/await에 대해 설명하십시오.
답변: Swift 5.5에 도입된 Swift의 최신 동시성 모델입니다.
- 장점: 완료 처리기보다 깔끔한 구문, 더 쉬운 오류 처리, 컴파일러 강제 스레드 안전성
- 키워드:
async: 일시 중단될 수 있는 함수를 표시합니다.await: 일시 중단 지점을 표시합니다.Task: 새로운 비동기 컨텍스트를 만듭니다.actor: 스레드 안전 참조 타입
희소성: 매우 흔함 난이도: 어려움
18. Swift에서 액터란 무엇입니까?
답변: 액터는 데이터 경합으로부터 가변 상태를 보호하는 참조 타입입니다.
- 스레드 안전성: 한 번에 하나의 작업만 액터의 가변 상태에 액세스할 수 있습니다.
- 자동 동기화: 컴파일러는 안전한 액세스를 강제합니다.
- 메인 액터: UI 업데이트를 위한 특수 액터
희소성: 중간 난이도: 어려움
19. Combine 프레임워크에 대해 설명하십시오.
답변: Combine은 Apple의 반응형 프로그래밍 프레임워크입니다.
- 핵심 개념:
- Publisher: 시간이 지남에 따라 값을 내보냅니다.
- Subscriber: 값을 받습니다.
- Operator: 값을 변환합니다.
- 장점: 선언적, 구성 가능, 기본 제공 연산자
- 사용 사례: 네트워킹, 사용자 입력 처리, 데이터 바인딩
희소성: 흔함 난이도: 어려움
20. 직렬 큐와 동시 큐의 차이점은 무엇입니까?
답변: 디스패치 큐는 작업을 직렬 또는 동시적으로 실행합니다.
- 직렬 큐: FIFO 순서로 한 번에 하나의 작업을 실행합니다. 작업은 이전 작업이 완료될 때까지 기다립니다.
- 동시 큐: 여러 작업을 동시에 실행합니다. 작업은 FIFO 순서로 시작되지만 어떤 순서로든 완료될 수 있습니다.
- 메인 큐: UI 업데이트를 위한 특수 직렬 큐
희소성: 흔함 난이도: 중간
Core Data & 영구 저장 (3개 질문)
21. Core Data 아키텍처와 주요 구성 요소에 대해 설명하십시오.
답변: Core Data는 Apple의 객체 그래프 및 영구 저장 프레임워크입니다.
- NSManagedObjectModel: 스키마 정의 (엔터티, 속성, 관계)
- NSPersistentStoreCoordinator: 컨텍스트와 저장소 간의 조정
- NSManagedObjectContext: 객체를 위한 작업 메모리 (스크래치 패드와 유사)
- NSPersistentStore: 실제 저장소 (SQLite, 바이너리, 메모리 내)
희소성: 흔함 난이도: 중간
22. Core Data에서 동시성을 어떻게 처리합니까?
답변: Core Data 컨텍스트는 스레드 안전하지 않습니다. 적절한 동시성 패턴을 사용하십시오.
- 컨텍스트 유형:
- 메인 큐 컨텍스트: UI 작업을 위해
- 개인 큐 컨텍스트: 백그라운드 작업을 위해
- 모범 사례:
- 스레드 간에 관리 객체를 전달하지 마십시오.
- 컨텍스트 작업에
perform또는performAndWait를 사용하십시오. - 컨텍스트 간에 객체 ID를 전달하십시오.
희소성: 중간 난이도: 어려움
23. NSFetchedResultsController란 무엇이며 언제 사용합니까?
답변:
NSFetchedResultsController는 테이블/컬렉션 뷰에 대한 Core Data 결과를 효율적으로 관리합니다.
- 장점:
- 자동 변경 추적
- 메모리 효율적 (배치)
- 섹션 관리
- 자동 UI 업데이트
- 사용 사례: 테이블/컬렉션 뷰에서 Core Data 객체 표시
희소성: 중간 난이도: 중간
시스템 설계 및 모범 사례 (2개 질문)
24. 오프라인 우선 모바일 앱을 어떻게 설계하시겠습니까?
답변: 오프라인 우선 앱은 인터넷 없이 작동하고 연결되면 동기화됩니다.
- 아키텍처:
- 진실 소스로서 로컬 데이터베이스 (Core Data, Realm)
- 서버와 조정하는 동기화 계층
- 충돌 해결 전략
- 전략:
- 낙관적 UI: 변경 사항을 즉시 표시하고 백그라운드에서 동기화합니다.
- 큐 작업: 실패한 요청을 저장


