Swift 100문 100답

Swift 100문 100답

Swift에 대한 100개의 문제와 그에 대한 답변해보기

Table of contents

나도 면접에서 만족스러운 답변에 추가 질문 해보고 싶다. 😢

그래서 100문 100답을 꼬꼬무 형식으로 채워가고자 함

100문 100답을 채울 때 까지 화이팅! 😄

1. Swift의 Extension은 어떻게 사용되나요?

Extension은

  • 클래스

  • 구조체

  • 열거형

에서 사용이 가능합니다.

저장 프로퍼티는 사용이 불가능하고 연산 프로퍼티는 사용이 가능하다.

단 Extension에서는 메소드 추가 작성이 가능하나, override는 되지 않는다.

생성자 또한 만들 수 없으면 convienece init만 사용이 가능하다.

convienece init

  • 보조 생성자로 동일 클래스의 생성자를 반드시 호출해야한다.

연산 프로퍼티

  • get / set 을 이용하여 프로퍼티를 이용한다. 단, property Observer(willSet, didSet)과 동시에 사용이 불가능하다.

2. Swift의 upcasting과 downcasting의 차이에 대해서 설명해보세요.

  • upcasting

    • 자식 클래스 -> 부모 클래스 로 변환 작업

    • 컴파일 타임에 결정한다

=> as 로 사용

  • downcasting

    • 부모 클래스 -> 자식 클래스로 변환 작업

    • 런타임시간에 결정한다.

=> as? as! 로 사용이 가능하다.

3. Dispatch Queue의 Serial Queue에 대해서 설명해보세요.

이건 글이 길 것 같으므로 따로 글 작성!

4.function과 method의 차이를 말해보세요.

  • function: 재사용 가능한 코드 블럭

  • method: 클래스, 구조체, 열거형에 포함되는 function을 의미

5. mutaing 키워드의 의미를 설명해보세요.

  • struct에서 프로퍼티 변경이 있는 메소드에 내리는 명령어

  • struct는 값 타입이기에 변경이 원래는 불가능하다. (불변성)

  • 새로운 struct를 만들고 재 배당하는 로직을 거친다.

*스위프트에서 값 타입 프로퍼티는 인스턴스 메소드에 의해 수정될 수 없다.

6. 프로토콜과 클래스의 차이를 설명해보세요.

  • 프로토콜: 함수 선언만 포함되며 함수 내용은 들어가지 않는다.

    • 단! Extension을 통해서 함수 내용이 포함된 함수를 구현할 수 있다.
  • 클래스: 함수 선언과 함수 내용이 포함되어 있어야한다.

7. Enum에서 raw value와 associated value에 대해 설명해보세요.

  • raw value: 원시 값으로 1개의 값만 가질 수 있다.

  • associated value: 튜플을 통해서 case 마다 다른 값을 가질 수 있고 named tuple도 사용 가능하다.

// associated values - named tuple
enum Fruits {
    case apple(origin: String, cost: Double)
    case grape(origin: String, cost: Double, size: Double)
    case orange(color: String)
}

let apple: Fruits = .apple(origin: "Korea", cost: 1000)
let grape: Fruits = .grape(origin: "Korea", cost: 100, size: 10)
let orange: Fruits = .orange(color: "Orange")

if case let .apple(origin, cost) = apple {
    print("apple \(origin) \(cost)")
}

// raw values
enum Numbers: Int {
case one = 1
case two, three, four
}

print(Numbers.one.rawValue)   // 1
print(Numbers.two.rawValue)   // 2
print(Numbers.three.rawValue) // 3

8. 연산 프로퍼티와 클로저를 가지는 저장 프로퍼티의 차이를 설명해보세요.

  • 연산 프로퍼티: 참조 할 때 마다 클로저를 생성하고 실행한다.

  • 저장 프로퍼티: 프로퍼티 생성 시점에 클로저를 생성하고 결과값을 저장한다.

9. Class와 Struct의 공통점과 차이점을 설명해보세요.

  • 공통점

    • 프로퍼티를 저장하고 인스턴스 생성이 가능하다.

    • 프로토콜 채택이 가능하다.

  • 차이점

    • Class는 참조 타입, Struct는 값 타입

    • Class는 상속 가능, Struct는 상속이 불가능

10 . 강한 참조는 무엇이고 왜 필요한가요?

  • 강한 참조는 ARC를 +1 증가시킵니다.

  • ARC가 0이 되면 메모리에서 해제되기에 강한 참조로 ARC를 증가시켜야 합니다.

11. strong, weak, unowned reference는 각각 언제 사용할까요?

  • Strong

    • 단방향 참조 일 때 안전합니다.

    • 메모리위에 유지하기 위해서 사용됩니다.

  • weak

    • ARC를 증가시키지 않습니다.

    • weak는 Optional, var 이여야 합니다. 참조되는 인스턴스가 중간에 해제될 수 있기 때문입니다.

  • unowned

    • weak과 마찬가지로 ARC를 증가시키지 않습니다.

    • 단, 반드시 메모리에 있다고 런타임이 인지하기에 Null Point Exception 에러가 발생 할 수 있습니다.

    • 값이 존재 하지 않으면 앱이 문제가 되어서 반드시 에러처리를 해야하는 곳에 사용한다.

    • weak 보다 unowned를 사용하는 이유는 오버헤드가 덜 들기 때문이다.

      *오버헤드: 어떤 코드가 실행되는데 걸리는 시간

12. Array, Set, Dictionary의 차이점이 뭘까요?

  • Array

    • random access가 가능해 인덱스로 요소 접근이 가능하다.
  • Set

    • Hashable을 채택하는 값을 저장한다.

    • 중복, 순서 보장 둘 다 안된다.

    • 탐색, 삭제, 삽입에 모두 O(1) 시간이 든다. 삽입 삭제 잦다면 Set이 최적이다.

  • Dictionary

    • Key-Value 형태로 데이터 관리하는 컬렉션

    • key는 Hashable을 채택하고 있다.

13. required 키워드에 대해서 설명해보세요.

required키워드가 붙은 생성자는 자식 클래스에서 반드시 구현해야 한다.
* override가 required에 포함되어 생략이 가능하다.

class A {
    required init() {
        print("HELLO")
    }
}

class B: A {
    required init() {
        super.init()
        print("B IS WELCOME")
    }
}

let b = B()
// HELLO
// B IS WELCOME

14. Self와 self의 차이가 뭘까요?

  • Self: 사용된 타입

  • self: 현재 인스턴스

15. Trailing Closure에 대해서 설명해보세요.

  • 함수의 파라미터로 들어가는 클로저

16. objc는 언제 사용하나요?

  • 런타임 시간에 Objective-C코드를 사용하기 위해서 사용됩니다.

17. DispatchQueue.main.async 와 DispatchQueue.main.sync 의 차이를 설명해보세요.

  • 두 방법 모두 Main Thread에서 작동합니다.

  • Main Thread는 Serial Queue입니다.

    • 무슨 소리인지 모르겠다면? 링크에서 더 자세하게 설명합니다!
  • async

    • 작업을 요청하고 결과는 천천히 받습니다.
  • sync

    • 작업을 요청하고 결과를 받을 때까지 기다립니다.

    • Main Thread는 UI Interative하기에 Dead Lock에 걸릴 수 있습니다.

18. defer에 대해 설명해보세요.

  • 함수가 종료되고 실행되는 클로저
func tobyBolg() {
    defer {
        print("LAST")
    }
    print("FIRST")
}

tobyBolg() 
// FIRST
// LAST

19. open과 public 키워드의 차이를 설명해보세요.

  • 공통점

    • 외부 모듈에서 접근을 허용합니다.
  • 차이점

    • open

      • 클래스에서만 사용 가능합니다.

      • 외부에서 상속 및 overrider가 가능합니다.

    • public

      • 외부에서 상속 및 override가 불가능합니다.

20. fileprivate을 설명하고 언제 사용하면 좋을지 이야기해보세요.

  • 같은 파일 내에서만 인스턴스 혹은 프로퍼티를 사용해야 할 때 사용합니다.

21. static 와 class 의 차이를 설명해보세요.

  • 공통점

    • 모두 Type method 혹은 Type property이기에 인스턴스 생성없이 접근이 가능하다.
  • 차이점

    • class은 override를 허용합니다.

    • static은 override를 불허합니다.

* Type method 혹은 Type property

  • 인스턴스가 아닌 타입 자체에 속하는 프로퍼티 혹은 메소드
class A {
    class func printHello() {
        print("안녕하세요!")
    }
}

class B: A {
    override class func printHello() {
        print("새로운 안녕입니다!")
    }
}

A.printHello() // 안녕하세요!
B.printHello() // 새로운 안녕입니다!

23. function 과 closure의 차이를 설명하시오.

  • closure는 function을 포함하는 더 큰 개념이다. 이름있는 closure가 function 이다.

  • closure: 실행 가능한 코드 블럭

24. 프로토콜과 클래스 상속에 대해서 설명해보세요.

  • 프로토콜은 추상 메소드로 이뤄진 구현 방법이다.

    • Extension을 통해서 일반 메소드도 구현이 가능하다.

    • 프로토콜은 다중 상속이 가능하다.

  • 클래스 상속

    • 클래스 상속은 단 1개 밖에 불가능하다.

    • 클래스 상속이 깊어진다면 부모 클래스 변경에 의해서 하위 클래스에 큰 영향을 끼칠 수 있다.(의존성이 깊어진다.)

25. Any와 AnyObject의 차이를 설명해보세요.

  • Any

    • Any는 모든 타입을 포함 할 수 있다.
  • AnyObject

    • 모든 클래스 타입만 포함 할 수 있다.

26. 언제 클래스 대신 구조체를 사용하면 좋을까요?

  1. Objective-C 코드를 런타임에 사용할 때 ( ex. NSCache )

  2. 클래스의 고유성을 유지하고 싶을 때

    • 고유성: 객체가 생성되면 객체의 유일성을 나타내는 값 (값이 복사되는 것이 아닌 주소가 복사된다.)

27. Swift의 Copy-on-Write에 대해서 설명해보세요.

  • COW = Copy on Write

    • 값 타입이 복사 될 때 COW에 의해서 프로그래밍 상에서는 값이 2개지만 메모리 상에서는 1개이다.

    • 복사가 일어난 2개의 값 중 어느 하나가 변경될 때 메모리 상에서도 분리가 된다.

    • 이로 인해서 Swift 메모리 사용 최적화, 오버헤드 감소를 꿰할 수 있다.

28. ARC와 GC는 어떤 차이점이 있나요?

  • ARC

    • Automatic Reference Count

    • 참조 카운트를 세면서 0이 되는 인스턴스를 메모리 해제함

    • 순환 참조가 된다면 해결 방법이 없다.

  • GC

    • Garbage Collector

    • Mark and Swipe방식을 Root로 부터 시작하여 참조되지 않는 인스턴스를 조사해 인스턴스를 메모리에서 해제한다.

    • 보라색 -> 참조되고 있는 인스턴스

    • 빨간색 -> 참조되고 있지 않는 인스턴스

    • 이런 경우 빨간색 인스턴스는 메모리에서 해제된다.

  • 순환 참조를 해결할 수 있을까?

    • ARC: ARC에서는 순환 참조를 해결 할 수 없다.

    • GC: 만약 순환참조하는 두 객체가 Root로 부터 참조 받고 있지 않는다면 GC는 메모리를 해제 할 수 있다.

    • 단, GC는 ARC만큼 빠르게 작동할 수 없다. 오버헤드가 GC가 더 크기 때문에!

29. autoclosure attribute에 대해서 설명해보세요.

autoclosure는 클로저가 아닌 코드를 함수의 인자로 받을 때 이 코드를 클로저로 만들어주는 키워드입니다.

func normalPrint(_ closure: () -> Void) {
    closure()
}
normalPrint({ print("I'm Normal Expression") })

func autoClosurePrint(_ closure: @autoclosure () -> Void) {
    closure()
}
autoClosurePrint(print("I'm AutoClosure Expression"))

30. GCD의 QoS에 대해서 설명해보세요.

  • Thread 우선순위

    1. userInteractive - UI 작업

    2. userInitiated - 문서 열람, 인터페이스 제스쳐

    3. default

    4. utility - 데이터 다운로드

    5. background - 사용자가 인지 못하는 영역

31. Hashable 프로토콜에 대해서 설명해보세요.

  • Hashable프로토콜을 채택하는 타입은 해시값(정수)로 표현 가능해야 한다.

  • 커스텀 타입의 저장 프로퍼티가 모두 Hashable하다면 커스텁 타입도 Hashable하다.

  • 그렇지 않다면 ==메소드를 만들고 hash(into:) 구현해서 해시값을 생성하는데 필요한 프로퍼티를 지정해줘야 한다.

Hashable을 채택하는 기본 타입

  1. 문자열

  2. 숫자 관련

  3. Bool

  4. Set

  • Hashable을 채택하는 커스텀 타입이 Equatable도 채택해야 하는 이유는?

    • Hash하다는 것은 유일한 값이어야 한다. 만약 해시 값이 간다면 해시충돌을 일으켜야 한다. 그렇기에 Equatable을 채택하여 동일 값인지 비교해야 한다.

32. init?()과 init()은 어떤 차이가 있나요?

  • init()은 반드시 인스턴스 생성에 성공하여 인스턴스를 반환하지만

  • init()?은 인스턴스 생성에 실패하여 nil을 반환할 수 있다.

33. Never 반환 타입에 대해 설명해보세요.

  • Never는 do-catch throw를 통해서 잡을 수 없는 에러로 비정상적인 종료에 사용된다.

34. DispatchGroup에 대해서 설명해보세요.

35. DispatchWorkItem의 장점이 무엇인가요?

  • DispatchWorkItem을 사용하면 DispatchQueue에 등록할 작업을 캡슐화 할 수 있다.

  • cancle, wait등 제공되는 메소드를 사용할 수 있다.

36. @ escaping에 대해서 설명해보세요.

  • 탈출클로저로써 함수가 종료된 뒤에 실행될 수 있도록 만듭니다.

37. @ objc와 dynamic의 차이에 대해서 설명해보세요.

38. RunLoop에 대해서 설명해보세요.