1. 컴퓨터 시스템에서 CPU, RAM, 저장 장치의 역할과 이들이 어떻게 상호작용하는지 설명해주세요.

💡 힌트: 앱 실행 과정을 단계별로 생각해보세요.

  • 저장 장치에서 앱 바이너리 로드
  • RAM에 코드와 초기 데이터 적재
  • CPU가 명령어 실행
  • 필요시 추가 리소스 로드

답변:

CPU는 메모리에 저장된 명령어를 읽어 들이고, 해석하고, 실행하는 장치입니다. RAM에는 현재 실행되는 프로그램의 명령어와 데이터를 저장합니다. 전원을 끄면 저장된 내용이 사라지는 휘발성 저장 장치입니다. 보조 기억 장치에는 전원이 꺼져도 보관할 프로그램을 저장합니다. RAM보다 느리지만 많의 양의 데이터를 저장할 수 있습니다.


앱을 실행할 때 이 구성 요소들이 어떤 순서로, 어떻게 상호작용하여 앱 화면을 보여주게 되나요?

답변:

사용자가 홈 화면에서 앱 아이콘을 누르면, 운영체제는 보조 기억 장치에 저장된 앱 바이너리(코드와 리소스)를 읽어 들여 RAM에 적재합니다. CPU는 RAM에 적재된 명령어 차례대로 읽어와 해석하고 실행합니다. 실행 과정에서 필요한 리소스 등이 추가로 보조 기억 장치나 네트워크에서 로드되어 RAM에 적재되고, CPU는 이를 다시 처리합니다. CPU는 이렇게 메모리에 준비된 코드와 데이터를 순차적으로 처리하며, 결과를 화면에 전달합니다.

RAM이 부족하면 iOS 시스템은 어떤 동작을 할까요? 이것이 앱 개발 시 왜 중요할까요?

답변:

iOS 시스템에서 사용 가능한 여유 메모리(free memory)의 용량이 부족해지만, 우선 백그라운드에서 대기 중인 앱을 종료하여 메모리 공간을 확보합니다. 그럼에도 충분한 메모리를 확보할 수 없다면, 실행 중인 앱에 메모리 공간이 부족하다는 경고를 보내고, 앱은 가능한 한 빨리 이미지, 미디어 파일 등 크기가 큰 리소스를 해제하는 방식으로 대응해야 합니다.

모바일 디바이스는 한정된 메모리 자원을 갖고 있으므로, 개발자는 앱이 자원을 효율적으로 사용하도록 설계해야 합니다. 적절한 메모리 관리 전략없이 앱이 필요 이상으로 많은 메모리 공간을 점유한다면 프리징이나 크래시와 같은 심각한 성능 문제가 일어날 수 있습니다.

CPU 속도, RAM 용량, 저장 장치 속도 중 어떤 것이 앱의 ‘체감 속도’에 가장 큰 영향을 미칠 수 있을까요? 이유와 함께 설명해주세요.

답변:

앱의 ‘체감 속도’에는 보조 기억 장치의 속도가 가장 큰 영향을 줍니다. 앱 실행 시 먼저 보조 기억 장치에 저장된 앱 바이너리를 읽어 들여 RAM에 적재해야 하는데, 이 과정이 느리면 CPU 속도가 아무리 빠르고, RAM 용량이 충분해도 실행까지 시간이 지연됩니다.

iOS의 A-시리즈 칩셋에서 CPU와 GPU가 메모리를 공유하는 Unified Memory Architecture가 앱 개발에 미치는 영향은 무엇인가요?

답변:

iOS의 A-시리즈 칩셋은 통합 메모리 구조를 사용하여 CPU와 GPU가 동일한 메모리 공간을 공유합니다. 따라서 개발자는 CPU에서 처리한 데이터를 GPU로 전달할 때 별도의 복사 비용을 고려할 필요가 없습니다. 이는 메모리 사용 효율을 높이고, 데이터 전송에 소요되는 시간과 자원을 절약하여 성능 최적화에 유리해집니다.


2. CPU와 메모리 간의 데이터 교환은 어떻게 이루어지나요?

답변:

시스템 버스(System Bus)를 통해 CPU와 메모리 간의 데이터 교환이 이루어집니다. CPU가 메모리 속 내용을 읽어들이려면 CPU는 제어 버스로 ‘메모리 읽기’ 제어 신호를 내보내고, 주소 버스로 읽고자 하는 주소를 내보냅니다. 그러면 메모리는 데이터 버스로 CPU가 요청한 주소에 있는 내용을 보냅니다. 메모리에 어떤 값을 저장할 때도 마찬가지입니다. 데이터 버스를 통해 저장할 값을, 주소 버스를 통해 저장할 주소를, 제어 버스를 통해 ‘메모리 쓰기’ 제어 신호를 내보냅니다.

데이터 교환 속도를 높이기 위해 컴퓨터 시스템에는 어떤 장치들이 사용되나요?

답변:

데이터 교환 속도를 높이기 위해 CPU의 L1·L2 캐시나 RAM이 사용됩니다. 일반적으로 CPU와 RAM 간의 데이터 전송은 매우 빠르지만, 다른 장치와의 속도는 그렇지 못합니다. 따라서 CPU가 자주 사용하는 데이터는 L1·L2 캐시나 RAM에 저장해 빠르게 주고받을 수 있도록 하고, 사용 빈도가 낮은 데이터는 RAM이나 보조 기억 장치에 저장해 두었다가 필요할 때 불러와 사용합니다.

버스(Bus)란 무엇이며, 어떤 종류가 있나요?

  • CPU와 RAM 이외 버스를 통해 연결되는 다른 장치들은 무엇이 있을까요?

답변:

버스는 메인보드에 연결된 부품들이 서로 정보를 주고받을 수 있는 통로입니다. CPU와 메모리 등 컴퓨터의 핵심 부품을 연결하는 핵심 버스를 시스템 버스라고 합니다. 시스템 버스는 주소 버스, 데이터 버스, 제어 버스로 구성되어 있습니다. 주소 버스는 주소를 주고받는 통로, 데이터 버스는 명령어와 데이터를 주고받는 통로, 제어 버스는 제어 신호를 주고받는 통로입니다.

CPU와 RAM뿐만 아니라 보조 기억 장치나 입출력 장치도 버스를 통해 연결될 수 있습니다.

캐시 메모리의 개념과 역할에 대해 설명해주세요.

  • 캐시 히트(Cache Hit)와 캐시 미스(Cache Miss)는 무엇이며, 성능에 어떤 영향을 미치나요?

답변:

캐시 메모리는 CPU의 연산 속도와 메모리 접근 속도의 차이를 줄이기 위한 저장 장치입니다. CPU와 메모리 사이에 위치하고, 레지스터보다 용량이 크고 메모리보다 빠릅니다. CPU가 사용할 가능성이 높은 데이터를 미리 예측하여 저장함으로써, CPU가 메모리에 직접 접근하는 시간을 줄이고 전체 성능을 향상시킵니다.

이때 자주 사용될 것으로 예측한 데이터가 실제로 들어맞아 캐시 메모리 내 데이터가 CPU에서 활용될 경우를 캐시 히트(Cache Hit)라고 합니다. 반대로 예측이 틀려 RAM에서 필요한 데이터를 직접 가져와야 하는 경우를 캐시 미스(Cache Miss)라고 합니다. 캐시 미스가 발생하면 필요한 데이터를 (비교적 속도가 느린) 메모리에 직접 가져와야 하기 때문에 전체 성능이 낮아집니다.


3. 캐시의 지역성(Locality) 원리에 대해 설명해주세요.

답변:

캐시 메모리는 참조 지역성의 원리에 따라 RAM으로부터 가져올 데이터를 결정합니다. ‘CPU는 최근에 접근했던 메모리 공간에 다시 접근하려는 경향’을 시간 지역성이라 하며, 이는 변수 초기화 시 해당 변수 값을 여러 번 사용하는 경우가 대표적인 예시입니다. ‘CPU는 접근한 메모리 공간 근처를 다시 접근하려는 경향’을 공간 지역성이라 하며, 배열을 순회할 때 특정 시점에 접근이 멈추더라도 이후 인접한 요소에 다시 접근할 가능성이 높은 경우가 대표적인 예시입니다.

시간적 지역성과 공간적 지역성의 구체적인 예를 코드로 설명해주실 수 있나요? (예: 반복문, 배열 순회)

답변:

let num = 2
for i in 0...9 {
    print("\(num) * \(i) = \(num * i)")
}

구구단을 출력하는 과정에서 numi 변수가 여러 번 사용되고 있습니다. 이렇게 ‘최근에 접근했던 메모리 공간에 다시 접근하려는 경향’을 시간적 지역성이라고 합니다.

let nums = [1, 2, 3, 4, 5]
for i in nums {
    print(i)
}

배열 요소를 출력하는 과정에서 0번째 요소에 접근한 직후, 바로 인접한 메모리 주소의 요소들에 연속적으로 접근합니다. 이렇게 ‘접근한 메모리 공간 근처에 접근하려는 경향’을 공간적 지역성이라고 합니다.

지역성 원리를 잘 활용하지 못하게 작성된 코드는 어떤 성능 문제를 일으킬 수 있을까요?

답변:

지역성 원리를 지키지 못한 코드는 CPU가 원하는 데이터가 캐시에 존재하지 않는 캐시 미스가 자주 발생할 수 있습니다. 이 경우 CPU는 훨씬 느린 RAM에서 데이터를 가져와야 하므로 메모리 지연(latency)이 커지고, CPU가 데이터를 기다리느라 작업이 지연되어 현상(파이프라인 스톨)이 발생해 전체 연산 효율이 떨어집니다.


4. CPU 아키텍처의 종류(예: ARM, x86)의 각 특징에 대해 설명해주세요.

답변:

x86 아키텍처는 주로 개인용 컴퓨터나 서버에서 사용되며, CISC(Complex Instruction Set Computing) 명령어 셋을 기반으로 합니다. CISC는 명령어의 길이가 길고, 복잡하며, 한 사이클에 여러 작업을 수행할 수 있는 명령어를 사용합니다. 그만큼 하드웨어 자원을 많이 소모하고 전력 효율이 낮지만, 호환성이 좋다는 특징이 있습니다.

반면, ARM 아키텍처는 주로 모바일 기기나 맥북 등에서 사용되며, RISC(Reduced Instruction Set Computing) 명령어 셋을 기반으로 합니다. RISC는 명령어가 짧고 단순하며, 대부분 명령이 한 사이클 내에 실행됩니다. 이러한 단순한 구조 덕분에 전력 효율이 뛰어나다는 특징이 있습니다.

특징x86ARM
지시 유형복합(CISC)단순(RISC)
전력 효율중간, 개선 중높음, 배터리 수명에 최적화됨
하드웨어 설계개별 CPUSoC, 모듈형
주요 용도데스크톱, 서버모바일, 임베디드 시스템

(출처: x86 아키텍처 대 ARM: 종합 비교)

iOS 기기는 주로 어떤 아키텍처를 사용하며, 그 이유는 무엇일까요?

답변:

iOS 기기는 ARM 아키텍처를 사용합니다. ARM은 RISC 명령어 셋을 기반으로 하며, 전력 효율이 높고 발열이 적어 배터리 성능이 중요한 모바일 기기에 적합합니다.

과거 인텔 기반의 x86 아키텍처를 사용하던 맥북 역시 2020년 이후 애플 실리콘(M1)으로 전환하면서 ARM 아키텍처를 채택했습니다. 이 전환을 통해 성능은 크게 향상되었지만, 동시에 전력 효율도 유지하거나 오히려 개선되어 배터리 사용 시간이 늘어나는 효과를 얻었습니다.

iOS 시뮬레이터는 보통 어떤 아키텍처에서 실행되며, 실제 기기와 어떤 차이가 있을까요? 이것이 개발에 어떤 영향을 미칠 수 있나요?

답변:

iOS 시뮬레이터는 실행되는 호스트 기기의 아키텍처를 그대로 따라갑니다. 즉, 과거 인텔 기반의 맥북에서는 x86 아키텍처에서 시뮬레이터가 실행되었고, 현재의 애플 실리콘 기반 맥북에서는 ARM 아키텍처에서 시뮬레이터가 실행됩니다.

시뮬레이터는 실제 기기를 사용하지 않고도 빠르게 개발 중인 앱을 테스트할 수 있는 개발 도구입니다. 하지만 실제 기기의 하드웨어 센서나 민감한 데이터 접근 권한(예: HealthKit, Bluetooth, 카메라 등)과 관련된 기능은 시뮬레이터에서 테스트할 수 없습니다.

또한, 시뮬레이터는 실제 동작을 완벽하게 재현하지 못하기 때문에 CPU 성능, 네트워크 환경 등에서 실제 기기와 다른 결과가 나타날 수 있습니다. 따라서 최종 검증 단계에서는 반드시 실제 기기에서 테스트를 진행해야 안정적인 품질을 보장할 수 있습니다.

iOS 기기에서 사용되는 AP(Application Processor)의 특징과 역할에 대해 설명해주세요.

  • iOS AP에는 CPU 외에 어떤 중요한 구성 요소들이 포함되어 있으며, 이들이 앱 성능에 어떻게 기여하나요? (예: GPU, Neural Engine)

답변:

iOS 기기에서 사용되는 AP(Application Processor)는 앱 실행, 멀티태스킹, 메모리 관리 등 전반적인 시스템 성능을 담당하는 핵심 부품입니다.

AP는 크게 CPU, GPU, 뉴럴 엔진(Neural Engine) 등으로 구성됩니다. CPU는 앱의 로직 실행과 전반적인 연산을 담당합니다. GPU는 그래픽 렌더링과 영상 처리 등을 담당하며, UI 애니메이션·게임 같은 그래픽 중심 작업에 우위를 점합니다. 뉴럴 엔진은 머신러닝 및 AI 연산에 특화된 코어로 LLM·사진 보정과 같은 작업을 빠르고 전력 효율적으로 수행합니다.

추가로, 보안 칩(T2, Secure Enclave)도 함께 동작하여 Face ID, FileVault 클래스 키, 키체인 등의 민감한 데이터를 안전하게 저장하고 보호합니다.

  • SoC(System on a Chip)의 개념은 무엇인가요?
    • SoC 설계가 모바일 기기에서 중요한 이유는 무엇일까요? (예: 전력 효율, 기기)

답변:

SoC(System on a Chip)는 이름 그대로 하나의 칩 안에 CPU, GPU, 메모리 등 여러 하드웨어 구성 요소가 집적되어 있는 반도체 칩을 말합니다.

SoC 설계가 모바일 기기에서 중요한 이유는 전력 효율과 공간 효율을 동시에 확보할 수 있기 때문입니다. 여러 부품이 단일 칩에 집적되면 데이터 전송 경로가 짧아져 전력 소모가 줄고, 발열도 감소하며, 전체 시스템의 크기를 줄일 수 있습니다. 이 덕분에 연산 처리 속도도 향상되어 모바일 환경에서 고성능과 저전력을 동시에 달성할 수 있습니다.


5. iOS 앱이 백그라운드로 전환될 때 메모리 부족으로 종료되는 이유는 무엇인가요?

답변:

iOS는 한정된 메모리 자원을 효율적으로 관리하기 위해, 우선순위가 낮은 백그라운드 앱을 필요에 따라 종료(terminate)할 수 있습니다.

사용자가 실행하는 다른 앱이 메모리를 많이 사용하는 경우, 운영체제는 현재 실행 중인 앱의 안정적인 동작을 보장하기 위해 백그라운드 앱을 종료(suspend → terminate)하여 메모리 공간을 확보합니다.

이는 전체 시스템 성능을 유지하고 앱 간의 자원 경쟁으로 인한 성능 손실을 방지하기 위한 조치입니다.

iOS의 메모리 압력(Memory Pressure) 단계는 어떻게 구분되며, 각 단계에서 시스템이 취하는 조치는 무엇인가요?

  • Normal, Warning, Urgent, Critical 각 단계에서 시스템이 자동으로 수행하는 작업은?
  • 개발자가 각 단계에서 취해야 할 조치의 우선순위는?

답변:

메모리 압력(Memory Pressure)은 시스템의 메모리 여유 정도에 따라 정상(Normal), 경고(Warning), 긴급(Urgent), 위험(Critical) 단계로 구분됩니다.

Normal 단계는 메모리가 충분히 여유 있는 상태로, 시스템이나 개발자가 별도의 조치를 취할 필요가 없습니다.

Warning 단계는 메모리 사용량이 점차 증가하고 있음을 의미하며, 시스템은 백그라운드 앱을 종료하여 메모리 공간 확보를 시도합니다. 개발자는 이미지 캐시나 불필요한 객체 등 중요도가 낮은 리소스를 가능한 한 빠르게 해제해야 합니다.

Urgent 단계는 시스템의 메모리 부족이 심화된 상태로, 시스템은 거의 모든 백그라운드 앱을 종료헤 메모리 공간 확보를 시도합니다. 개발자는 즉시 더 이상 필요하지 않은 대용량 리소스를 적극적으로 해제해야 합니다.

Critical 단계는 더 이상 메모리 공간 확보가 불가능한 상태로, 커널이 직접 개입하여 앱을 강제로 종료하거나, 시스템을 재부팅할 수 있습니다. 이 단계에서 개발자는 크래시를 방지하기 위해 가능한 한 모든 리소스를 해제해야 합니다.

백그라운드 앱이 종료되는 우선순위는 어떻게 결정되나요? (마지막 사용 시간, 메모리 사용량 등)

답변:

제트샘(jetsam)은 iOS와 macOS에서 메모리 상태를 실시간으로 모니터링하며, 메모리 부족이 발생했을 때 커널 레벨에서 프로세스를 종료하는 메커니즘입니다. 시스템이 메모리 부족 상황을 감지하면, 제트샘은 현재 실행 중인 프로세스의 목록을 확인하고 우선순위 밴드(priority band)에 따라 프로세스를 순차적으로 종료합니다

제트샘은 Kernel, Launchd, SpringBoard 등 핵심 시스템 프로세스에 높은 우선순위를 부여하고, 포그라운드 앱, 오디오, VoIP 앱 등에 중간 우선순위를 부여합니다. 반면 백그라운드 앱, 일시 중지된 앱, 캐시된 앱 순서로 낮은 우선순위를 가지며, 메모리가 부족할 때 이러한 프로세스부터 종료됩니다.

우선순위는 단순히 메모리 사용량만으로 결정되지 않고, 앱의 권한(entitlement), 프로세스의 역할(포그라운드·백그라운드 여부), QoS(Quality of Service), 입출력 또는 네트워크 등의 실시간 처리 여부, 백그라운드 모드 지원 여부 등의 요소에 따라 달라집니다.

PriorityValueExamples
Idle0
Idle (Deferred)1
Background (Opportunistic)2
Background3
Mail4Apple Mail
Phone5Phone app
UI Support8Keyboard extension
Foreground Support9Share extension
Forground10Forground application
Audio and Accessory12
Conductor13
Home16SpringBoard
Executive17
Important18
Critical19

(출처: conradev/jstsamctl)

앱이 백그라운드에서 종료되기 전에 받을 수 있는 알림은 무엇이며, 이때 어떤 작업을 해야 하나요?

답변:

앱이 메모리 부족 상황이 발생하면, UIKit은 먼저 앱 델리게이트의 applicationDidReceiveMemoryWarning(_:) 메서드를 호출합니다. 이어서 현재 활성화된 UIViewController의 [didReceiveMemoryWarning()] 메서드가 호출되며, iOS는 동시에 UIApplication.didReceiveMemoryWarningNotification 노티피케이션을 보내 앱 전체에 메모리 부족 상황을 알립니다.

이 시점에서 개발자는 사용하지 않는 캐시나 이미지, 대용량 객체 등의 리소스를 즉시 해제하거나 압축해 시스템이 앱을 강제로 종료하는 상황을 피하도록 해야 합니다.

백그라운드에서도 계속 실행이 허용되는 앱 유형(음악, 네비게이션 등)은 어떤 특별한 권한을 사용하나요?

답변:

일반적으로 iOS 앱은 백그라운드로 전환되면 일시 중지(suspended) 상태로 전환되어 실행이 중단됩니다. 그러나 특정 백그라운드 모드(Background Modes)를 가진 앱은 예외적으로 계속 백그라운드에서도 실행될 수 있습니다.

대표적인 백그라운드 모드로 오디오, 위치 서비스, VoIP, 블루투스 등이 있으며, 이러한 권한을 가진 앱은 시스템이 허용한 범위 내에서만 실행되며, 여전히 배터리·자원 절약을 위해 엄격한 제한을 받습니다.


6. 프로세스와 스레드의 차이점, 그리고 iOS에서의 프로세스와 스레드 관리 방법에 대해 설명해주세요.

답변:

프로세스(Process)는 실행 중인 하나의 프로그램이며, 독립적인 메모리 공간과 자원을 가지고 실행됩니다. 부포 프로세스는 여러 자식 프로세스를 포크(fork)할 수 있으며, 각 프로세스는 서로의 메모리에 직접 접근할 수 없습니다.

반면 스레드(Thread)는 프로세스 내부에서 실행되는 작업의 흐름 단위이며, 동일한 프로세스 내의 다른 스레드와 힙 메모리 공간을 공유하지만, 스택은 독립적으로 가집니다. 스레드는 가벼운 실행 단위로서 프로세스 내에서 동시 작업을 수행할 수 있게 합니다.

iOS에서는 하나의 앱이 하나의 프로세스로 실행되며, 필요에 따라 여러 스레드를 생성해 동시 처리를 수행합니다. 스레드 관리는 주로 GCD(Grand Central Dispatch)를 통해 이루어지며, GCD가 자동으로 스레드 생성·삭제를 하며 자동으로 최적화합니다.

하나의 앱 내에서 여러 프로세스를 사용하는 경우가 흔한가요? 아니라면 왜 스레드를 주로 사용할까요?

답변:

iOS 앱은 일반적으로 단일 프로세스 구조로 실행됩니다. 하나의 앱에서 여러 프로세스를 동시에 실행하게 되면, 프로세스 간 자원을 공유하거나 전달하기 어렵고, IPC(Inter-Process Communication) 비용이 높아지므로 개발 복잡도와 오버헤드도 크게 증가합니다. 또한 각 프로세스는 독립적인 힙과 스택을 가지기 때문에, 컨텍스트 스위칭 비용도 스레드보다 훨씬 큽니다.

반면 스레드(Thread)는 같은 프로세스 내에서 힙 메모리를 공유하므로, 생성과 전환이 훨씬 가볍고 효율적입니다. 이런 이유로 iOS는 앱 내부의 동시 작업 처리를 위해 멀티 프로세스가 아닌 멀티 스레딩 방식을 사용합니다.

다만, 위젯(Widget Extension)이나 키보드 확장(Keyboard Extension) 등은 별도의 프로세스로 실행됩니다. 이는 확장 기능이 크래시로 종료되더라도 본 앱에 영향을 주지 않도록 하기 위한 설계입니다.

멀티스레딩이 필요한 이유는 무엇인가요?

  • Main 스레드에서 시간이 오래 걸리는 작업을 처리하면 어떤 문제가 발생할 수 있나요? 구체적인 예를 들어 설명해주세요.

답변:

멀티스레딩은 앱의 반응성(responsivness)을 유지하기 위해 필요합니다. 각 스레드는 자신이 맡은 작업을 순차적으로 처리하며, 일반적으로 UI 렌더링과 사용자 입력 처리는 메인 스레드(Main Thread)에서 이루어집니다.

만약 메인 스레드에서 네트워크 통신이나 파일 I/O 등 시간이 오래 걸리는 작업을 수행하면, 메인 스레드가 차단되어 화면이 멈춘 것처럼 보이거나 터치 입력이 무시되는 현상이 발생할 수 있습니다.

iOS에서 GCD(Grand Central Dispatch)는 어떤 역할을 하나요?

  • GCD를 사용하지 않고 스레드를 직접 생성하고 관리할 때 발생할 수 있는 어려움은 무엇일까요?

답변:

GCD(Grand Central Dispatch)는 작업을 큐로 보내고, 시스템이 효율적으로 스레드를 할당하여 병렬로 실행할 수 있도록 관리하는 기술입니다. 이를 통해 개발자는 직접 스레드를 생성하거나 관리하지 않고도 비동기 작업을 손쉽게 처리할 수 있으며, 결과적으로 앱의 반응성과 성능을 향상시킬 수 있습니다.

GCD를 사용하지 않고 스레드를 직접 관리하면, 스레드 생성·해제 시점을 일일이 제어해야 하고, 스레드를 제대로 해제하지 않으면 메모리 오버헤드나 스케줄링 오버헤드가 발생할 수 있습니다. 또한, 교착 상태나 우선순위 역전 문제를 직접 처리해야 하므로 유지보수를 어렵게 합니다.

  • GCD의 DispatchQueue 종류(Serial, Concurrent)의 사용 목적에 대해 설명해주세요.

답변:

직렬 큐(Serial Queue)는 작업들을 하나의 스레드에서 순서대로 처리하여, 작업 간의 순서를 보장하고 동시성 문제를 방지하는 데 도움이 됩니다. 반면, 동시 큐(Concurrent Queue)는 여러 스레드에서 동시에 작업을 실행해 병렬로 처리가 가능하며, 전체 처리 속도를 향상시킬 수 있습니다. 다만, 동시 큐에서는 작업이 완료되는 순서를 예측할 수 없습니다.

iOS에서 앱이 백그라운드에서 실행될 때 스레드 우선순위는 어떻게 변경되나요?

  • Quality of Service (QoS) 클래스와 스레드 우선순위의 관계는 무엇인가요?
  • iOS의 런루프(RunLoop)와 스레드의 관계를 설명해주세요.

답변:

앱이 포그라운드에서 백그라운드로 전환되면, iOS는 배터리 수명과 시스템 자원 보호를 위해 해당 앱의 스레드 우선순위를 자동으로 낮춥니다. 이때 대부분의 작업은 QoS(Quality of Service) 클래스 중 가장 낮은 background 수준으로 전환됩니다.

런-루프는 스레드와 밀접한 관계를 가지며, 스레드가 이벤트를 지속적으로 감시하고 처리할 수 있도록 합니다. 특히 메인 스레드는 기본적으로 런-루프를 가지고 있어 사용자 입력, UI 업데이트 등을 주기적으로 처리합니다. 반면, 백그라운드 스레드에는 런-루프가 없습니다.


7. 메모리 관리 기법 중 iOS에서 사용되는 방식과 그 특징에 대해 설명해주세요.

💡 힌트: ARC vs GC 비교 시 고려사항

  • 성능: 실시간 처리 vs 주기적 처리
  • 예측 가능성: 즉시 해제 vs 불확실한 타이밍
  • 오버헤드: 참조카운팅 vs 마킹 & 스위핑

답변:

iOS에서는 ARC(Automatic Reference Count)를 통해 메모리를 관리합니다. ARC는 객체가 메모리에 유지되어야 하는지 여부를 참조 카운트로 판단합니다. 어떤 인스턴스를 참조하는 변수가 하나라도 존재하면 참조 카운트가 1 이상으로 유지되어 메모리에 남고, 모든 참조가 해제되어 카운트가 0이 되면 ARC가 자동으로 메모리에서 해제합니다.

자동 참조 카운팅(ARC)은 어떻게 동작하나요?

  • ARC가 자동으로 메모리를 관리해주는데, 개발자가 여전히 메모리 관리에 신경써야 하는 이유는 무엇인가요?

답변:

ARC는 참조 카운트를 자동으로 증가(retain) 또는 감소(release)시켜 메모리를 관리합니다. 개발자가 직접 메모리 해제를 수행할 필요는 없지만, 강한 참조 간의 순환 참조는 ARC가 자동으로 해제하지 못합니다. 이러한 경우 객체들이 서로를 참조한 채 메모리에서 해제되지 않아, 앱이 종료될 때까지 유지되는 메모리 누수(Memory Leak)가 발생할 수 있습니다.

  • 강한 참조(Strong Reference), 약한 참조(Weak Reference), 미소유 참조(Unowned Reference)는 각각 언제 사용해야 하나요?

답변:

강한 참조(Strong Reference)는 객체가 메모리에서 해제되지 않도록 유지해야 할 때 사용합니다. 일반적으로 인스턴스를 변수에 할당하면 강한 참조가 됩니다.

약한 참조(Weak Reference)는 참조 카운트를 증가시키지 않으며, 주로 순환 참조를 방지해야 할 때 사용합니다. 참조 대상이 자신보다 먼저 해제될 가능성이 있는 경우에 적합하며, 대상이 해제되면 자동으로 nil​로 변경됩니다.

미소유 참조(Unowned Reference) 역시 참조 카운트를 증가시키지 않지만, 참조 대상이 자신보다 먼저 해제될 가능성이 없다는 것이 확실한 경우에 사용합니다.

  • 순환 참조(Retain Cycle)는 무엇이며, 어떻게 발생하고 해결할 수 있나요? (클로저에서의 순환 참조 포함)
    • 클로저에서 [weak self] vs [unowned self] 선택 기준은 무엇인가요?
    • self가 nil이 될 수 있는 상황과 될 수 없는 상황을 어떻게 구분하나요?
    • guard let self = self 패턴의 장단점은 무엇인가요?

답변:

순환 참조(Retain Cycle)는 두 개 이상의 객체가 서로를 강하게 참조하면서, 어느 한쪽도 메모리에서 해제되지 못하는 현상을 말합니다. 이 경우 참조 카운트가 0이 되지 않아 메모리 누수가 발생합니다. 순환 참조는 어느 한쪽을 약한 참조 또는 미소유 참조로 변경함으로써 해결할 수 있습니다.

클로저에서도 순환 참조가 발생할 수 있습니다. 클로저는 참조 타입이기 때문에, 클래스 인스턴스가 클로저를 소유하고, 그 클로저가 내부에서 다시 self​를 강하게 참조하면 순환 참조가 일어납니다. 이를 방지하기 위해 캡처 리스트에서 [weak self]​나 [unowned self]​를 사용합니다.

[weak self]​는 self​가 먼저 해제될 가능성이 있는 경우 사용합니다. 예를 들어, 애니메이션 완료 핸들러처럼 클로저가 실행될 시점에 ViewController​가 이미 해제되었을 수 있는 경우에 적합합니다.

[unowned self]​는 self​가 먼저 해제될 가능성이 없는 경우 사용합니다. 클로저가 실행될 때 self​가 반드시 존재함이 확실한 경우에 제한적으로 사용합니다.

guard let self = self 패턴은 weak self​를 안전하게 언래핑해 옵셔널 체이닝(self?.)없이 사용할 수 있다는 장점이 있습니다. 하지만, guard let 이후로 self​를 다시 강하게 참조하기 때문에, 클로저의 실행이 끝날 때까지 _self_의 해제를 지연시킨다는 단점이 있습니다.

  • Garbage Collection과의 차이는 무엇인가요?
    • ARC 방식이 GC 방식에 비해 갖는 장점과 단점은 무엇이라고 생각하시나요?

답변:

ARC는 참조 카운트는 컴파일 시점에 ratain과 release 코드를 자동으로 삽입해 메모리를 관리합니다. 반면, 가비지 컬렉션(Garbage Collection)은 런타임 시점에 주기적으로 더 이상 참조되지 않는 객체를 찾아내 해제하는 마크-스윕(Mark-Sweep) 방식으로 메모리를 관리합니다.

ARC의 장점으로 개발자가 메모리 해제 시점을 예측 가능하다는 점이 있습니다. GC처럼 주기적인 정리 과정이 없기 때문에 성능이 더 뛰어나며, 컴파일 단계에서 관리되므로 런타임 오버헤드도 적습니다.

반면 단점으로는, 참조 카운트를 통해 메모리를 해제하기 때문에 순환 참조가 발생하면 객체가 해제되지 않는 메모리 누수가 발생할 수 있습니다.


8. iOS 샌드박스(Sandbox) 개념과 역할, 그리고 앱 간 데이터 공유 방법에 대해 설명해주세요.

답변:

샌드박스 때문에 앱 개발 시 겪을 수 있는 제약사항에는 어떤 것들이 있을까요?

답변:

URL 스킴(URL Scheme)을 이용한 앱 간 통신은 어떻게 이루어지나요?

  • URL 스킴을 사용할 때 보안적으로 고려해야 할 점은 무엇일까요?

답변:

앱 그룹(App Group)을 활용하여 데이터 공유를 하는 방법은 무엇인가요?

  • 앱 그룹을 통한 데이터 공유는 어떤 종류의 데이터에 적합할까요? 대용량 파일 공유에도 적합할까요?
  • 앱 확장(App Extension)과 앱 그룹은 어떤 관계가 있나요?

답변: