포스트

모의면접

생각해보니 모의 면접 질문에 대해 답을 한다는걸 까먹어서 정리한다.

데일리로 업데이트를 해볼 예정.

애매한건 나중에 적어야할 듯 하다.

<오늘의 질문지=""> 1. Storyboard를 이용해 UI를 구현하는 방법을 설명해주세요. [05.14] - StoryBoard를 사용하여 UI를 구현할때는 Commnad + Shift + L을 눌러서 UIComponent를 추가할 수 있는 창을 띄우고 원하는 Component를 검색 후 드래그하여 추가한다. - 이때 StoryBoard로 추가한 Component는 말그대로 보이기만 하고 아무런 기능이 없기에, 우리가 여기에 기능을 부여하거나, 외적인 부분을 코드로 접근을 하려고 하는 경우엔 VC로 Control을 누른채로 드래그를 해서 IBOutlet / IBAction을 만들어 주어야 한다. 2. UserDefaults로 저장해놓은 데이터를 UICollectionView에 보여주는 방법을 설명해주세요. [05.16] - 우선 UserDefaults는 프로젝트 내에 있는 데이터 저장소 이며, Key, Value로 이루어 진다. - Data를 저장할때는 UserDefaults.standard.set(value, forKey:"") 를 사용한다. - Data를 로드할때는 타입을 알고있다면 다음과 같이 한다. - integer(forKey:) : key값이 존재하면 정수값를 반환하고, 그렇지 않으면 0 반환 - bool(forKey:) : key값이 존재하면 boolean를 반환하고, 그렇지 않으면 false 반환 - float(forKey:) : key값이 존재하면 float을 반환하고, 그렇지 않으면 0.0 반환 - double(forKey:) : key값이 존재하면 double을 반환하고, 그렇지 않으면 0.0 반환 - object(forKey:) : 데이터 타입에 맞게 조건부로 typecast할 수 있도록 Any?를 반환 - object에 대한 예시 `let array = defaults.object(forKey: "SavedArray") as? [String] ?? [string]()` 3. 디자인과 동일한 UI를 구현하는 방법을 설명해주세요. [05.17] - 4. present를 사용해 화면 전환을 구현하는 방법을 설명해주세요. [05.20] - present를 사용해 화면 전환을 구현하는 방법은 3가지가 있다. - 1. VC에서 present 사용 - 2. NavigationController.pushViewController 사용 - 3. segue를 통환 화면 전환 5. 동영상 재생 화면 구현 시, 불러온 이미지 리스트는 어떻게 보여지는지 설명해주세요. [05.21] - 불러온 이미지 리스트는, 컬렉션뷰나, 테이블 뷰의 셀에 보여주면 된다. 6. 두 검색 결과를 datetime 필드를 이용해 정렬하여 출력하는 방법을 설명해주세요. [05.22] - 우선 두 검색 결과를 하나의 배열에 넣어주고, orderby 오름차순, 내림차순으로 정렬해준다. 7. AutoLayout을 사용해 제약조건을 기반으로 반응형 UI를 구현하는 방법을 설명해주세요. [05.23] - 8. Storyboard를 이용한 UI구현과 코드를 이용한 UI구현의 차이를 설명해주세요. [05.27] - StoryBoard로 UI를 구현하게되면 직관적으로 실행시 어떻게 UI가 보여지는지 확인이 가능하다. 그리고, 제약조건을 설정해도 잘못되면 Warning or Error 형식으로 보여지기에, 코드보다는 확실히 직관적인 설정이 가능하지만, 메모리적인 측면에서는 효율적이지 않다(StoryBoard가 보이는것과는 다르게 XML 파일로 되어있어서 해당 파일을 코드로 변환시키는 작업이 별도로 필요하기 떄문). 그리고 Merge시 Conflict가 발생하는 경우 수정하기가 쉽지않다는 단점이 존재. - Codebase로 UI를 구현하게 되면 우선 실행하거나 또는 #Preview를 사용하지(iOS 17 이후부터 가능) 않으면 UI를 확인 할 수 없다, 그리고 VC에 일일이 UIComponent를 할당할경우 VC가 상당히 Massive해지면서 코드가 길어지는 치명적인 단점이 존재한다. 하지만 메모리적인 측면에서는 훨씬 효율적이다. 9. Storyboard를 이용해 내부 reference를 두고, ViewController에 접근하는 방법을 설명해주세요. [05.28] - VC에 접근할때는 크게 2가지 방법으로 정의를 할수가 있다. - a. Storyboard의 InstantiateViewController 메서드를 사용하여 접근 - 메서드는 다음과 같다 `storyboard?.instantiateViewController` - 해당 메서드의 경우 먼저 VC에 일종의 Identifier가 있어야한다. - 다운캐스팅을 반드시 해준다. - b. Segue의 Detination으로 접근 - 메서드 역시 `segue.destination as? VC이름` 으로 한다. - VC의 Destination 타입이 UIViewController 이므로 다운캐스팅을 반드시 해줘야함. 10. UICollectionView의 Scroll 영역을 조절하는 방법을 설명해주세요. [05.29] - 11. ViewController를 기준으로 기능별 관계 및 구조를 설명해 주세요. - 1. UIView - 컨텐츠를 담아 이를 스크린 상에 표시하고 사용자의 입력에 반응 하는 객체 - 필요한 컨텐츠를 채워넣어 스크린에 나타내는 역할을 함 - 2. UIScene - 화면의 컨텐츠를 표현하고 view를 관리 - 한개의 VC당 한개의 UIScene이 필요 12. ViewModel 및 View 바인딩으로 쌍방향 소통에 대해 설명해주세요. [06.03] - 데이터 바인딩으로는 클로저, observable, Combine, RxSwift등 을 사용하여 바인딩을 할 수 있다. - Observer Design Pattern 사용. 13. iOS 메모리 관리는 어떻게 이루어지나 - 1. ARC(Automatic Reference Counting)의 동작 원리를 설명해주세요. - ARC는 Heap 영역의 객체에 대한 Strong Reference(강한 참조) count를 추적하고, 객체가 더 이상 필요하지 않을 때 (참조 count가 없을 때) 해당 객체에 대한 메모리를 자동으로 해제하는 방식으로 메모리를 관리 - 2. 강한 참조(Strong Reference)와 약한 참조(Weak Reference)의 차이점은 무엇인가요? - 기본적으로 Swift에서 변수나 상수는 Strong Reference(강한 참조)를 한다. 객체에 대한 Strong Reference(강한 참조) count가 증가되어 있다면, 해당 객체는 메모리에 유지된다. - 약한 참조는 Strong Reference(강한 참조)와는 달리 객체의 참조 count 증가시키지 않는다. 객체의 생명 주기에 영향을 주지 않으면서 참조를 유지할 수 있다 - 3. 순환 참조(Retain Cycle)가 발생하는 경우와 해결 방법을 설명해주세요. - ARC 작동 방식의 특성상 두 객체가 서로를 강하게 참조하는 경우, 순환참조가 발생. 두 객체 모두 더이상 사용되지 않더라도 두 객체가 서로를 강하게 참조하는 경우, Strong Reference count가 감소하지 않아, 메모리에서 해제되지 못하고 메모리가 누수되는 문제가 발생 - 4. 강한 참조, 약한 참조, 미소유 참조의 차이점을 설명해주세요. - 약한 참조와 달리 자신이 참조하는 인스턴스가 항상 메모리에 존재할 것이라는 전제를 기반으로한다. 즉 해당 인스턴스가 nil이 아닐것이라는 확신을 가지고 미소유 참조를 사용. 메모리에 해제된 인스턴스에 접근하려하면 런타임 에러가 발생하며 강제종료 된다. - 5. iOS 앱의 메모리 사용량 최적화를 위한 방안과 고려 사항에 대해 설명해주세요. - 고려사항 우선 불필요한 객체가 메모리에 남아있는지를 확인하여 그에 맞게 변수를 설정 - instrument나, memory hierarchy를 통해 확인. - 앱의 생명 주기를 고려하여 메모리에서 해제 - NotificationCenter의 경우 메모리에 남아 있을 경우가 있어, 직접 해제하는 방식 14. Task Entity를 생성 후 CoreData에 생성, 읽기, 수정, 삭제 기능을 구현하는 방법을 설명해주세요. - 우선 Coredata는 Container의 viewContext 파일을 통하여 CRUD를 수행한다. - Framework이다. - 1. Create - 보통 entity class를 가져와서 class의 Attribute에 값을 넣고, context.save를 통해 Create한다. - 2. Read - NSFetchRequest타입을 통해 코어데이터를 로드 한다. 보통은 request 변수를 사용 - context.fetch 메서드를 통해 Read한다. - 이때 값을 저장하는 배열의 타입은 Entity명을 그대로 사용. - Entity도 Class 가능하다. - 3. Update - setValue를 통해 조건에 맞는 부분을 업데이트를 한다. - 4. Delete - context.delete를 사용한다. 이때 원하는 내용만 삭제도가능하고, 전체 삭제도 가능하다. 15. 메모리와 View의 생명주기에 따라 데이터의 업데이트 시점과 호출 시점에 따른 데이터 저장 및 불러오기를 구분해서 설명해주세요. [06.07] - 앱의 상태는 여섯가지로 구분이 된다. 1. Not Running - 앱이 실행이 되지 않았거나, 종료되어 더이상 동작하지 않는 상태. - ```swift application(_:willFinishLaunchingWithOptions:) application(_:didFinishLaunchingWithOptions:) ``` 2. Foreground - Inactive - Inactive는 앱이 실행중이지만, 사용자로부터 이벤트를 받을 수 없는 상태 - 멀티 태스킹 윈도우로 진입하거나 앱 실행중 전화, 알림 등에 의해 앱을 사용할 수 없게 되는 경우 이상태로 진입을 하게 됨. - ```swift applicationWillResignActive(_:) ``` 3. Foreground - Active - Active는 앱이 실행중이고 사용자로부터 이벤트를 받아 서로 상호작용을 할 수 있는 상태 - Inactive → Active로 된다. 바로 Active로 활성화는 불가능하다. - ```swift applicationDidBecomeActive(_:) ``` 4. Background - Running - Background는 홈 화면으로 나가거나 다른 앱으로 전환 되어 현재 앱이 더이상 동작을 하지 않는 상태를 말한다. - 백그라운드에서 코드를 실행하는 상태이며, 데이터 저장, 네트워크 작업, 음악 재생등의 작업이 가능하다. - ```swift applicationDidEnterBackground(_:) ``` 5. Background - Suspended - Suspended는 앱을 다시 실행했을 때 최근 작업을 빠르게 로드하기 위해서 메모리에 관련 데이터만 저장되어있는 상태를 말한다. - 백그라운드에서 코드 실행이 없는 상태 - 앱이 Background상태에 진입 했을 때 다른 작업을 하지 않으면 Suspended 상태로 진입을 하게 됨 - Suspended 상태 앱은 시스템이 메모리가 부족해지면 필요에 따라 가장 먼저 메모리에서 해제 된다. - 앱을 종료시킨적이 없어도 다시 실행하려고 하면 처음부터 다시 실행되는 경우가 바로 메모리에서 해제가 되었기 때문. 6. Termination - 앱이 종료된 상태. - ```swift applicationWillTerminate(_:) ``` - 생명주기는 AppDelegate / SceneDelegate로 나뉘어진다. (iOS13부터) - 이전에는 AppDelegate에서 통흡으로 관리했었다. - AppDelegate - Process LifeCycle 관리. - 앱의 중요한 데이터 구조를 초기화 - Scene을 환경설정 - 앱 밖에서 발생하는 알림에 대응 - 특정 Scene, View, VC에 한정되지 않고, 앱 자체를 타겟으로 하는 이벤트에 대응 - 애플 푸시 알림 서비스처럼 실행 시 요구되는 모든 서비스를 등록한다. - VC 생명주기 1. **`LoadView()`** - View를 로드한다 → View를 메모리에 올린다. - 일반적으로 직접 호출하지 않으며, 뷰 계층 구조를 프로그래밍 방식으로 설정할 때 오버라이드된다. - [Apple](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview)에서는 - LoadView는 직접 호출 하면 안되고 iOS Framework가 실행해줘야 한다고 되어있음. 2. **`ViewDidLoad()`** - View가 메모리에 올라온 후 호출 된다. - 메모리에 올라온 후 **한번만** 호출 된다. - 뷰가 메모리에서 해제 된다면 다시 호출 된다 (deinit) - 처음 한번만 실행 되는 코드를 여기서 작성해둔다. - ex) 뷰 요소의 초기 속성 설정, 데이터 모델의 초기화.... - ```swift override func viewDidLoad() { super.viewDidLoad() tableView.dataSource = self tableView.delegate = self } ``` 3. **`ViewWillAppear`** - View가 화면에 나타나기 전에 호풀된다. - ViewDidLoad와달리 화면이 나타날 때마다 호출된다. - 화면 갱신이 필요할떄, 뷰를 업데이트할떄(Table, CollectionView Reload) 사용된다. - ex) 화면이 나타나기 전에 데이터를 갱신하거나 사용자 인터페이스 업데이트 () - ```swift override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tableView.reloadData() } ``` - **`ViewIsAppearing`** - WWDC23에서 새로 추가됨. - ViewWillAppear와 ViewDidAppear사이에서 View가 추가된 후 불리게 된다. - Apple에서는 View를 업데이트할때 사용하라고 권고 - 즉 화면이 전환될 때 실행할 특정 작업이 필요하거나, 화면의 특성과 관계없이 실행할 작업이 있을 때 사용한다. - ex) 화면 전환 시 애니메이션 시작. - ```swift override func viewIsAppearing(_ animated: Bool) { super.viewIsAppearing(animated) startAnimation() } ``` - **`ViewDidAppear`** - 뷰가 화면에 나타난 후 호출된다. - 화면이 나타난 후 필요한 작업을 처리 - ex) 뷰가 나타난 후 애니메이션을 시작하거나 데이터를 가져오는 작업. - ```swift override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) fetchData() } ``` - **`ViewWillDisappear`** - 뷰가 사라지기 직전에 호출 - 애니메이션을 멈추거나, 타이머를 종료시키는 등의 작업을 처리 - ex) 뷰가 사라지기 전에 진행 중인 작업을 정리. - ```swift override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) timer.invalidate() } ``` - **`ViewDidDisappear`** - 뷰가 사라진 후 호출 된다. - 메모리에서 해제 된건 아님. - ex) 화면에서 사라진 후 데이터 정리 또는 상태 저장. - ```swift override func viewDidDisappear(_ animated: Bool) { super.viewDidDisappear(animated) saveCurrentState() } ``` - SceneDelegate - UI LifeCycle 관리 - iOS13 부터 새로 생김 - 앱당 하나의 Window만을 가졌던 과거에 비해 앱당 여러개의 Scene을 가질 수 있게되며 생겨남 - Scene에는 UI의 인스턴스를 나타내는 Windows와 ViewController들이 들어있습니다. - Scene에 해당하는 UIWindowSceneDelegate를 가지고 있어 UIKit과 앱간 상호작용에 사용됨. - Scene들은 같은 메모리와 앱 프로세스 공간을 공유하면서 동시에 실행됨. - 하나의 앱이 여러개의 Scene과 SceneDelegate 객체를 동시에 활성화할 수 있게 도와줌 1. scene(_:willConnectTo:options:) - 새 장면이 생성될 때 호출이 된다. - UI의 초기 상태를 설정하고 장면의 Root ViewController를 설정함. - ``` swift func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) let rootViewController = ViewController() window.rootViewController = rootViewController self.window = window window.makeKeyAndVisible() } ``` 2. sceneDidBecomeActive(_:) - 장면이 활성 상태가 될 때 호출 된다. - 장면이 활성화 될때 해야할 작업을 구현한다 - ```swift func sceneDidBecomeActive(_ scene: UIScene) { DataSyncManager.shared.startSync() NetworkManager.shared.resumeRequests() } ``` 3. sceneWillResignActive(_:) - 장면이 비활성화 되기 직전에 호출 - 애니메이션 중지, 타이머 일시정지 등 비활성화 준비 작업을 할때 사용 - ```swift func sceneWillResignActive(_ scene: UIScene) { AnimationManager.shared.stopAllAnimations() GameStateManager.shared.saveCurrentState() } ``` 4. sceneWillEnterForeground(_:) - 장면이 백그라운드에서 포그라운드로 전환될 때 호출됩니다. 장면이 화면에 나타나기 전에 필요한 준비 작업을 여기에 구현합니다. - ```swift func sceneWillEnterForeground(_ scene: UIScene) { UserInterfaceManager.shared.updateUI() TimerManager.shared.resumeAllTimers() SessionManager.shared.refreshSessionIfNeeded() } ``` 5. sceneDidEnterBackground(_:) - 장면이 포그라운드에서 백그라운드로 전환될 때 호출됩니다. 데이터 저장, 공유 자원 해제 등의 작업을 여기에 구현합니다. - ```swift func sceneDidEnterBackground(_ scene: UIScene) { DataManager.shared.saveImportantData() NetworkManager.shared.pauseRequests() ResourceManager.shared.releaseSharedResources() BackgroundTaskManager.shared. startBackgroundTasks() } ``` 16. UserDefaults와 CoreData의 차이점에 대해 설명해주세요. [06.10] - UserDefaults - UserDefaults는 보통 Key와 Value로 이루어져 있다. - 데이터도 보통은 간단한 정보값을 영구적으로 저장한다. - plist파일에 xml형식으로 저장이됨. - JSON Encoder를 통해 Encoding 후 데이터 저장함. - 스레드 안전성을 지님. - Notification을 사용하여 특정 기본값에 대한 업데이트 알림을 받을 수 있다. - Coredata - FrameWork이며, UserDefaults와 달리 크고 복잡한 데이터를 영구적으로 저장한다. - 데이터 작업이 백그라운드 단위에서 이루어 진다. - 테이블, 컬렉션 뷰에 대한 데이터 소스 제공으로 뷰와 데이터 동기화를 유지하는데 도움이 됨 17. 데이터 모델링을 기반으로 각 Entity, Attribute, Relationship의 역할을 설명해주세요. [06.11] - Database에서 Entity는 Table의 역할을 하고, Attribute는 Field의 역할을 한다. RelationShip은 각 Entity 간의 관계를 설정할때 사용하는데, ParentRelationShip / ChildRelationShip으로 나뉜다 18. MVC, MVVM 각 아키텍쳐의 장단점과, MVC to MVVM으로의 리팩토링시 고려해야 할 점을 설명해주세요. [06.12] - MVC와 MVVM의 궁극적인 목적은 비즈니스 로직과 뷰를 분리 하는 것이다. - MVC - View: 사용자 인터페이스를 담당, 모델의 데이터를 보여주고, 사용자 입력을 받아 Model에 전달 - Controller: 모델과 뷰를 연결하고, 어플리케이션 흐름을 제어, 뷰에서 입력을 받아 모델에 전달하거나, 모델에서 변경된 데이터를 가져와 뷰에 반영 - Model: 어플리케이션의 데이터와 비즈니스 로직을 담당, 데이터를 가져오고 변경하는 메서드를 가지고 있음. - MVVM - View: 사용자 인터페이스를 담당, 모델의 데이터를 보여주고, 사용자 입력을 받아 Model에 전달 - Model: 어플리케이션의 데이터와 비즈니스 로직을 담당, 데이터를 가져오고 변경하는 메서드를 가지고 있음. - ViewModel: 모델의 데이터를 뷰에서 필요한 형태로 가공후 컨트롤러에 제공 - 장,단점 - MVC - 장점: 간단한 패턴으로, 구조파악과 확장이 쉽게 가능 - 단점: 뷰와 모델의 분리가 어려우며, 컨트롤러가 뷰와 모델을 모두 알고 있어야 한다. 즉 코드가 많아지면서 가독성이 떨어지며 이에따라 유지 보수가 어려움 - MVVM - 장점: 뷰와 비즈니스로직의 분리가 분명하여, 유지 보수에 용이함, 서로가 독립적이다. - 단점: 진입장벽이 높다, 데이터 바인딩이 반드시 필요함. 이에따라 불필요한 코드가 발생 하게 된다. --- ## 튜터님 모의면접 이후 피드백 1. 두 검색 결과를 datetime 필드를 이용해 정렬하여 출력할때 sorted 만 사용해서 소팅이 된다면? - Data 다 Equatable 프로토콜 준수할때, Sorted()가 가능. 2. VC 설명 - viewcontroller 에서 항상 나오는 내용 : ⭐️⭐️view의 lifecycle 을 관리. viewisappearing 최근에 추가(ios 13부터, 애니메이션 사용하기 위한 라이프 사이클.). 라이프 사이클 순서. 3. ViewModel에 대해 좀 더 디테일하게 설명 4. 총평 - 먼저 키워드를 이야기해서 정의를하고 설명. 두괄식으로. - 애매하면 역질문을 통해 어떤것에 대한 대답을 원하는지? - 같이 일하기 힘든 사람. -> 소통의 부재...
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.