# QUIZ
## 주제 고르기
### 최근에 한 주제
- 프로토콜 / SOLID
- View Drawing Cycle / Layout Cycle
- Database / Core Data
- Key Chain
- Understanding Swift Performance
- Cache / NSCache / URLCache
### 원하는 주제
- Initializer
- Swift Performance
- HTTP
## QUIZ 내기
### 종합
0. lldb에서 mirror 형태로 인스턴스의 자세한 설명까지 출력하고자 할 때 사용하는 명령어를 고르시오.
- 보기 : e / po / e print() / e dump()
- 답 : e dump()
- 해설 : e는 expression의 약자로 lldb에서 실행이 멈춰있는 동안 새로운 동작을 실행시킨다. po는 NSObject의 debugDescription을 출력한다. print와 달리 dump는 객체가 nested인 경우 mirror형태로 출력해주기 때문에 하위 구조를 보다 가시적으로 파악하기 쉬워진다.
1.
- 보기 : 나는 방학동안 복습을 한번 이상이라도 했다.
- 답 : True, False
2.
- 보기 : UI 갱신 메서드는 반드시 Main Thread에서 호출되어야 한다.
- 답 : True
- 해설 : 반드시 Main Thread에서 호출되어야한다.
3.
- 보기 : UICollectionViewDiffableDataSource의 변경된 State를 적용하는 apply() 메서드는 Main Thread에서 호출되어야 한다.
- 답 : False
- 해설 : 백그라운드 대기열에서 이 메서드를 안전하게 호출할 수 있지만 앱에서는 일관되게 호출해야 합니다. 항상 기본 대기열이나 백그라운드 대기열에서만 이 메서드를 호출할 수 있습니다. 반드시 Main Thread에서 호출되어야할 필요가 없습니다.
4.
- 보기 : NSData init중 하나인 init(contentsOf:) 메서드는 Network-Based URLs을 요청하는데 사용되어서는 안된다.
- 답 : True
- 해설 : 느린 Network 상황에서는 현재 쓰레드를 수십초동안 block 할 수 있기 때문에 사용자로 하여금 부정경험을 노출하고 앱을 강제로 종료시킬 수 있습니다.
5.
- 보기 : Escaping 클로저에서 self에 접근하게되면 순환참조가 발생하므로 항상 [weak self] 를 붙여줘야한다.
- 답 : False
- 해설 : Escaping 클로저에서 순환참조는 항상 발생하는 것은 아니다. 순환참조가 발생하는 경우에만 붙여줘도 충분하다.
6.
- 보기 : 소스 코드 의존성의 방향은 반드시 제어 흐름을 따르게 된다.
- 답 : False
- 해설 : 인터페이스를 통해 소스 코드 의존성이 제어 흐름과 반대가 될 수 있음. 이는 의존성 역전이라고 불린다.
7. Convenience Initializer는 자신의 모든 프로퍼티를 초기화하기 전에 super class의 Initializer를 호출해야 한다.
- 보기 : True / False
- 답 : False
- 해설 : Convenience Initializer는 프로퍼티에 값을 할당하기 전에 자신의 다른 Initializer를 호출해야 한다.
8. Designated Initializer는 자신의 모든 프로퍼티를 초기화하기 전에 super class의 Initializer를 호출해야 한다.
- 보기 : True / False
- 답 : False
- 해설 : Designated Initializer는 자신의 모든 프로퍼티를 초기화한 후에 다른 작업을 할 수 있다.
9. UIView를 상속받는 서브 클래스에서 designated init을 직접 구현했을 때 이 (메소드)를 필수적으로 구현해야합니다. 이 (메소드)를 서술하시오.
- 보기 : 단답형
- 답 : required init
- 해설 : 슈퍼 클래스에서 충족하고 있는 초기화 요구사항을 모두 충족하지 못하기 때문에 required init을 구현해야 한다.
10. 다음 중 app delegate 객체를 사용하여 처리할 수 있는 작업이 아닌 것은?
- 보기 : 앱의 중앙 데이터 구조 초기화 / 앱의 scenes 구성 / 메모리 부족 경고 등 앱 외부에서 발생하는 알림에 대응 / scene에 필요한 데이터 로드
- 답 : scene에 필요한 데이터 로드
- 해설 : scene에 필요한 데이터 로드는 scene 전환을 사용하여 수행하는 작업이다.
11. 클로저를 변수에 할당하는 것은 그 변수를 클로저에 대한 ()로 설정하는 것이다. ()에 들어갈 알맞은 말은?
- 보기 : (단답형)
- 답 : 참조 / reference
- 해설 : 함수와 클로저는 참조 타입이다.
12. 다음 중 화면을 업데이트하기 위해 직접 호출하면 안 되는 메서드는?
- 보기 : layoutSubviews / setNeedsLayout / layoutIfNeeded / draw
- 답 : layoutSubviews, draw
- 해설 : layoutSubviews를 사용하는 대신 다음 업데이트 사이클에 업데이트 하려면 setNeedsLayout(), 즉시 업데이트 하려면 layoutIfNeeded()를 호출해야 한다. draw를 사용하는 대신 뷰의 일부를 무효화하여 해당 부분을 다시 그리려면 setNeedsDisplay() 또는 setNeedsDisplay(_:)를 호출해야 한다.
13. Heap에 메모리 할당 시 비용을 발생 시키는 요소를 모두 고르시오.
- 보기 : 순차적으로 메모리 할당 / 데이터 구조를 Search하여 적절한 데이터 블록 찾기 / 순차적으로 메모리 할당 해제 / 다중 스레드 접근 제한을 위한 Locking
- 답 : 데이터 구조를 Search하여 적절한 데이터 블록 찾기 / 다중 스레드 접근 제한을 위한 Locking
- 해설 : 순차적으로 메모리 할당 및 해제하는 것은 Heap이 아닌 Stack의 특성이다.
14. Dynamic Dispatch 시 하위 클래스가 클래스 메서드를 호출할 때 참조하는 배열로, 런타임 시 이 배열을 참조하여 실제 호출 함수를 결정하게 된다. 이 배열의 이름을 서술하시오.
- 보기 : (서술형)
- 답 : vtable / vTable / VTable / VTABLE / Virtual Method Table / 브이테이블
- 해설 : Swift는 클래스마다 함수 포인터들의 배열인 vTable을 정적 메모리에 저장하여, 하위 클래스가 메서드를 호출할 때마다 이를 참조하여 실제 호출할 함수를 결정한다.
15. Class의 성능을 향상 시키기위한 방법으로 적절한 것을 모두 고르시오.
- 보기 : 상속 시킬필요 가 없는 class 전체에 final 붙이기 / 특정 프로퍼티, 메서드에 final 붙이기 / private를 붙여 컴파일러가 final을 유추시키기 / 전체 모듈 최적화를 활성화 시키기
- 답 : 전부 다
- 해설 : final을 붙임으로 class가 override되지 않을 것을 명시하여 성능을 향상킬 수 있다. 한편 private을 붙여 선언된 프로퍼티, 메서드의 사용 범위를 한 파일안으로 제한시켜 컴파일러가 override가능한 모든 선언을 찾을 수 있게되어 서브 클래싱을 하지 않을 것이라고 추론이 가능해진다. 이때 컴파일러는 해당 class에 final 키워드를 자동으로 유추 가능해지고 이로서 class의 성능을 향상시킬 수 있게 된다. 전체 모듈 최적화의 경우 swift는 기본적으로 컴파일 할 때 모듈 내의 파일을 하나씩 컴파일하는데, 전체 모듈 최적화를 활성시키면 모든 모듈이 동시에 컴파일 되게 된다. 이로서 컴파일러가 전체 모듈에 대한 추론이 가능해여 override가 없는 internal 선언에 final을 유추가능해지게 된다.
### Zion
1.
- 보기 : setNeedsDisplay와 layoutIfNeeded가 호출 되었을 때 공통적으로 호출되는 함수는 layoutSubviews 이다.
- 답 : False
- 해설 : 공통적으로 호출되는 함수는 없다. SetNeedDisplay는 draw(), layoutIfNeeded는 layoutSubviews() 가 호출된다.
2.
- 보기 : UI 갱신 메서드는 반드시 Main Thread에서 호출되어야 한다.
- 답 : True
- 해설 : 반드시 Main Thread에서 호출되어야한다.
3.
- 보기 : UICollectionViewDiffableDataSource의 변경된 State를 적용하는 apply() 메서드는 반드시 Main Thread에서 호출되어야 한다.
- 답 : False
- 해설 : 백그라운드 대기열에서 이 메서드를 안전하게 호출할 수 있지만 앱에서는 일관되게 호출해야 합니다. 항상 기본 대기열이나 백그라운드 대기열에서만 이 메서드를 호출할 수 있습니다. 반드시 Main Thread에서 호출되어야할 필요가 없습니다.
4.
- 보기 : NSData init중 하나인 init(contentsOf:) 메서드는 Network-Based URLs 을 요청하는데 사용되어서는 안된다.
- 답 : True
- 해설 : 느린 Network 상황에서는 현재 쓰레드를 수십초동안 block 할 수 있기 때문에 사용자로 하여금 부정경험을 노출하고 앱을 강제로 종료시킬 수 있습니다.
5.
- 보기 : Escaping 클로저에서 self에 접근하게되면 순환참조가 발생하므로 항상 [weak self] 를 붙여줘야한다.
- 답 : False
- 해설 : Escaping 클로저에서 순환참조는 항상 발생하는 것은 아니다. 순환참조가 발생하는 경우에만 붙여줘도 충분하다.
6.
- 보기 : 소스 코드 의존성의 방향은 반드시 제어 흐름을 따르게 된다.
- 답 : False
- 해설 : 인터페이스를 통해 소스 코드 의존성이 제어 흐름과 반대가 될 수 있음. 이는 의존성 역전이라고 불린다.
---
### Moon
1. Designated Initializer는 자신의 모든 프로퍼티를 초기화하기 전에 super class의 Initializer를 호출해야 한다.
- 보기 : True / False
- 답 : False
- 해설 : Designated Initializer는 자신의 모든 프로퍼티를 초기화한 후에 다른 작업을 할 수 있다.
2. Convenience Initializer는 자신의 모든 프로퍼티를 초기화하기 전에 super class의 Initializer를 호출해야 한다.
- 보기 : True / False
- 답 : False
- 해설 : Convenience Initializer는 프로퍼티에 값을 할당하기 전에 자신의 다른 Initializer를 호출해야 한다.
<!-- ### 3. Protocol에서 Initializer를 정의할 경우, 이를 채택하는 class는 required init으로 구현해야 한다.
- 보기 : True / False
- 답 : True
- 해설 : 프로토콜에서 이니셜라이저를 정의할 경우, 이를 채택하는 클래스는 상속의 가능성이 있기 때문에 required init으로 구현해야 한다. final 클래스의 경우에는 required를 붙일 필요 없다. struct도 상속의 가능성이 없기 때문에 required를 붙일 필요 없다. -->
3. 슈퍼 클래스에 이미 구현된 initializer가 존재할 경우, 이를 상속받는 서브 클래스에서 designated init을 직접 구현했을 때 이 (메소드)를 필수적으로 구현해야합니다. 이 (메소드)를 서술하시오.
- 보기 : 단답형
- 답 : required init
- 해설 : 슈퍼 클래스에서 충족하고 있는 초기화 요구사항을 모두 충족하지 못하기 때문에 required init을 구현해야 한다.
4. 다음 중 app delegate 객체를 사용하여 처리할 수 있는 작업이 아닌 것은?
- 보기 : 앱의 중앙 데이터 구조 초기화 / 앱의 scenes 구성 / 메모리 부족 경고 등 앱 외부에서 발생하는 알림에 대응 / scene에 필요한 데이터 로드
- 답 : scene에 필요한 데이터 로드
- 해설 : scene에 필요한 데이터 로드는 scene 전환을 사용하여 수행하는 작업이다.
5. 클로저를 변수에 할당하는 것은 그 변수를 클로저에 대한 ()로 설정하는 것이다. ()에 들어갈 알맞은 말은?
- 보기 : (단답형)
- 답 : 참조 / reference
- 해설 : 함수와 클로저는 참조 타입이다.
6. 다음 중 화면을 업데이트하기 위해 직접 호출하면 안 되는 메서드는?
- 보기 : layoutSubviews / setNeedsLayout / layoutIfNeeded / draw
- 답 : layoutSubviews, draw
- 해설 : layoutSubviews를 사용하는 대신 다음 업데이트 사이클에 업데이트 하려면 setNeedsLayout(), 즉시 업데이트 하려면 layoutIfNeeded()를 호출해야 한다. draw를 사용하는 대신 뷰의 일부를 무효화하여 해당 부분을 다시 그리려면 setNeedsDisplay() 또는 setNeedsDisplay(_:)를 호출해야 한다.
---
### Serena
1. 참조 타입만을 활용하여 추상화를 하면 Swift Performance가 하락한다.
- 보기 : True / False
- 답 : True
- 해설 : Performance에 영향을 주는 3가지 요소인 Allocation, Reference Counting, Method Dispatch는 참조 타입을 사용할게 될 시 Heap, More, Dynamic 으로 편향되게 되는데, 이렇게 편향될 수록 Swift Performance가 하락하게 된다.
2. Heap에 메모리 할당 시 비용을 발생 시키는 요소를 모두 고르시오.
- 보기 : 순차적으로 메모리 할당 / 데이터 구조를 Search하여 적절한 데이터 블록 찾기 / 순차적으로 메모리 할당 해제 / 다중 스레드 접근 제한을 위한 Locking
- 답 : 데이터 구조를 Search하여 적절한 데이터 블록 찾기 / 다중 스레드 접근 제한을 위한 Locking
- 해설 : 순차적으로 메모리 할당 및 해제하는 것은 Heap이 아닌 Stack의 특성이다.
5. Dynamic Dispatch 시 하위 클래스가 클래스 메서드를 호출할 때 참조하는 배열로, 런타임 시 이 배열을 참조하여 실제 호출 함수를 결정하게 된다. 이 배열의 이름을 서술하시오.
- 보기 : (서술형)
- 답 : vtable / vTable / VTable / VTABLE / Virtual Method Table / 브이테이블
- 해설 : Swift는 클래스마다 함수 포인터들의 배열인 vTable을 정적 메모리에 저장하여, 하위 클래스가 메서드를 호출할 때마다 이를 참조하여 실제 호출할 함수를 결정한다.
6. Class의 성능을 향상 시키기위한 방법으로 적절한 것을 모두 고르시오.
- 보기 : 상속 시킬필요 가 없는 class 전체에 final 붙이기 / 특정 프로퍼티, 메서드에 final 붙이기 / private를 붙여 컴파일러가 final을 유추시키기 / 전체 모듈 최적화를 활성화 시키기
- 답 : 전부 다
- 해설 : final을 붙임으로 class가 override되지 않을 것을 명시하여 성능을 향상킬 수 있다. 한편 private을 붙여 선언된 프로퍼티, 메서드의 사용 범위를 한 파일안으로 제한시켜 컴파일러가 override가능한 모든 선언을 찾을 수 있게되어 서브 클래싱을 하지 않을 것이라고 추론이 가능해진다. 이때 컴파일러는 해당 class에 final 키워드를 자동으로 유추 가능해지고 이로서 class의 성능을 향상시킬 수 있게 된다. 전체 모듈 최적화의 경우 swift는 기본적으로 컴파일 할 때 모듈 내의 파일을 하나씩 컴파일하는데, 전체 모듈 최적화를 활성시키면 모든 모듈이 동시에 컴파일 되게 된다. 이로서 컴파일러가 전체 모듈에 대한 추론이 가능해여 override가 없는 internal 선언에 final을 유추가능해지게 된다.
7. lldb에서 mirror 형태로 인스턴스의 자세한 설명까지 출력하고자 할 때 사용하는 명령어를 고르시오.
- 보기 : e / po / e print() / e dump()
- 답 : e dump()
- 해설 : e는 expression의 약자로 lldb에서 실행이 멈춰있는 동안 새로운 동작을 실행시킨다. po는 NSObject의 debugDescription을 출력한다. print와 달리 dump는 객체가 nested인 경우 mirror형태로 출력해주기 때문에 하위 구조를 보다 가시적으로 파악하기 쉬워진다.