프로그래밍주니어 iOS 개발자

스위프트에서 컬렉션의 종류는 무엇이며, 내부 구현에 따라 어떻게 다르고 어떤 경우에 어떤 컬렉션을 사용해야 하나요?

Hintsage AI 어시스턴트로 면접 통과

답변.

스위프트에는 세 가지 기본 표준 컬렉션이 있습니다: Array, Set 및 Dictionary. 각 컬렉션은 서로 다른 인터페이스를 구현하며, 내부 구조가 다르고 서로 다른 작업을 위해 설계되었습니다.

문제의 배경:

스위프트에서는 컬렉션이 타입 안전성(type safety) 및 성능을 염두에 두고 설계되었으며, Arrays/Set/Dictionary에 대해 Copy-on-Write 원칙에 따른 값 의미론(value semantics) 및 복사가 포함됩니다.

문제:

초보 개발자는 종종 Array만 사용하여 Set 또는 Dictionary를 사용해야 하는 상황에서도 이를 사용하는 경향이 있어 메모리 낭비 및 접근/검색 속도 저하로 이어집니다. 차이를 이해해야 합니다.

해결책:

Array

인덱스를 통한 접근이 가능한 순서가 있는 요소의 컬렉션으로, 중복이 가능합니다. 일반적으로 동적 버퍼를 통해 구현됩니다.

Set

유일한 요소(훌륭한 해시 가능 타입)의 순서가 없는 컬렉션입니다. 해시를 통한 접근이 매우 빠르며 중복을 허용하지 않습니다.

Dictionary

키-값 쌍의 컬렉션입니다. 키는 해시 가능해야 합니다. 해시 테이블을 통해 키로 값을 접근할 수 있습니다.

코드 예시:

var arr: [Int] = [1, 2, 3, 4] var set: Set<Int> = [1, 2, 2, 3] var dict: [String: Int] = ["a": 1, "b": 2] // set == [1, 2, 3] — 중복이 제거됨

주요 특징:

  • Array는 인덱스 접근이 효율적이며, 순서를 유지하지만 값으로의 접근은 선형적입니다.
  • Set은 요소의 존재 여부를 빠르게 확인할 수 있으며, 유일한 해시 가능 값을 저장합니다.
  • Dictionary는 키를 통한 검색에 최적화되어 있으며(해시 가능), 순서를 유지하지 않지만 값을 빠르게 검색하고 변경할 수 있습니다.

속임수 질문.

Set이나 Dictionary에서 non-Hashable 타입을 사용할 수 있나요?

아니요. Set/Dictionary에 저장하려면 요소가 해시 가능해야 합니다(고유한 해시 식별자를 가져야 함). 그렇지 않으면 컴파일러가 컬렉션 생성을 허용하지 않습니다.

struct Point {} // Set<Point>는 오류를 발생시킵니다, 왜냐하면 Point는 해시 가능하지 않기 때문입니다.

Set의 요소 저장 순서가 추가한 순서와 같습니까?

아니요. Set는 순서를 보장하지 않으며, 반복(iteration)은 아무 순서로 실행될 수 있습니다. 순서가 필요하다면 Array를 사용하십시오.

존재하지 않는 키에 접근하려고 할 때 Dictionary에서 무슨 일이 발생합니까?

Dictionary는 Optional을 반환합니다. 주의하십시오 — 존재하지 않는 키로 접근하려고 하면 nil을 반환하고 오류를 발생시키지 않습니다.

let val = dict["not exist"] // val은 nil

일반적인 오류 및 안티 패턴

  • 고유한 값을 찾기 위해 Array를 사용 (Set이 더 나음)
  • 키로 검색할 필요 없이 값을 저장하기 위해 Dictionary를 사용
  • 키/값으로 non-Hashable 타입을 사용하려는 시도

실제 사례

부정적인 사례

개발자가 고유 사용자 목록을 위해 Array를 사용하고 contains를 통해 고유성을 검사합니다. 큰 목록에서는 많은 검사가 필요하여 시간이 많이 소요됩니다.

장점:

  • 구현의 용이함

단점:

  • 선형 복잡도의 검색, 중복 저장의 과다, 메모리 부담 증가

긍정적인 사례

같은 목록이 Set으로 구현됩니다. 존재 여부 확인이 즉각적이며, 고유한 값이 보장됩니다.

장점:

  • 빠른 접근, 메모리 절약, 중복 배제

단점:

  • 요소 순서 보장을 받을 수 없음