- 객체란 무엇인가요? 클래스와 어떤 연관이 있나요? 객체는 클래스를 통해 생성한 인스턴스이다. 객체 안에는 기능과 속성이 존재하고 이 기능과 속성은 클래스 내부에서 메서드랑 변수로 정의되고 있다. 쉽게 말해서 클래스는 설계도라고 할 수 있고 객체는 이 설계도를 통해 만든 실체화 된 물체라고 볼 수 있다 .
- 생성자에 대해 간단하게 설명해주세요. 객체를 초기화 할 때 호출되는 메서드이다. 메서드명이 클래스명과 같고 반환 타입이 없다는 게 특징이다. 이 생성자 메서드는 new 키워드를 통해 실제로 생성이 된다.
- 접근제한자란 무엇이며, 각각 어떤 차이가 있는지 비교해서 설명해주세요. 타입(클래스)과 타입 멤버(변수)를 선언할 때 외부로부터 접근할 수 있는 정도를 설정할 수 있는 키워드이다. 가장 자주 쓰이는 private, public, protected를 비교하자면, private는 클래스 내부에서만 사용이 가능하고, public은 모든 외부에서 접근이 가능하고, protected는 상속을 받은 자식 클래스에서만 접근이 가능하다.
- static 한정자에 대해 설명해주세요. 타입 맴버를 선언할 때 사용되는 한정자로, 스태틱으로 선언된 타입 맴버는 클래스에서 딱 하나만 존재하게 된다. 이때의 인스턴스는 모든 외부에서 객체 생성 없이 클래스명으로만 접근이 가능해 싱글톤 패턴을 사용할 때 자주 쓰이게 된다. 단, 스태틱으로 만든 인스턴스는 프로그램이 실행할 때부터 종료될 때까지 그 메모리를 가지고 있기 때문에 메모리 효율이 좋지 않다는 단점이 있다.
- SOLID 원칙에 대해 설명해주세요. 객체지향 프로그래밍을 할 때 중요시 되는 5가지 원칙의 약자를 써서 솔리드 원칙이라고 부른다. [1] 단일 책임 원칙 : 하나의 클래스는 하나의 책임만 가져야 한다. [2] 개방 폐쇄 원칙 : 확장에는 열려 있어야 하고 코드 변경은 닫혀있어야 한다. [3] 리스코프 치환 원칙 : 자식 클래스는 부모 클래스를 기능을 완벽하게 따름으로써 만약 부모 클래스의 인스턴스가 아닌 자식 클래스의 인스턴스를 사용해도 시스템의 제대로 작동해야 한다. (언제나 교체될 수 있는 상태여야 한다.) [4] 인터페이스 분리 원칙 : 하나의 인터페이스 보다 여러 개의 구체적인 인터페이스를 구현해야 한다. [5] 의존성 역전 원칙 : 구체적인 클래스보다 인터페이스나 추상 클래스에 의존해야 한다. 그래서 모듈 간의 결합도가 낮아진다.
- 객체지향 프로그래밍의 속성 중 하나인 다형성과 이를 활용한 설계의 장점에 대해 설명해주세요. 만약 다른 타입의 두 가지 객체가 하나의 큰 분류로 묶일 때, 인터페이스나 추상 클래스 등을 사용해서 동일한 메서드를 각각 다른 동작으로 작동할 수 있게 하는 설계이다. 다형성을 활용할 경우 코드의 중복을 줄일 수 있다.
- override와 overload에 대해 설명해주세요. override는 부모 클래스를 상속 받은 자식 클래스에서 부모 클래스에서 정의한 메서드를 재정의 해서 사용하는 것이다. 이때 virtual로 선언된 메서드만 override할 수 있는 게 특징이다. overload는 동일한 메서드명을 가진 메서드를 여러 개 만들어 사용하는 방식으로 매개변수를 필수로 가져야 하는 건 아니지만 매개변수의 유무나, 매개변수의 타입, 종류 등으로 메서드 간의 차이를 만들어야 한다.
- 확장 메서드에 대해 설명하고 어떻게 활용했는지 알려주세요. 잘 모름
- 콜백이란 무엇인가요? 콜백을 사용해본 경험이 있을까요? 메서드를 바로 호출하는 게 아니라 대리자가 가지고 있다가 특정 시점에서 호출해주는 형식을 의미한다. 다이얼로그 메세지를 챕터별로 순회하면서 챕터에 진입하고 빠졌을 때 발생하는 UI 이벤트를 호출할 때 콜백을 사용해보았다.
- 델리게이트(delegate; 대리자)란 무엇인가요? 그러니까 변수처럼 메서드를 쓰려고 사용하는데, 델리게이트를 선언하고 델리게이트로 호출할 메서드를 델리게이트의 반환타입 및 매개변수로 맞춰서 정의해준 다음에 직점 그 메서드를 호출하는 게 아니라 델리게이트 그 메서드를 호출해주는 거임. 그래서 대리자라고 불리는 거임. + 인스턴스가 아니라 타입이기 때문에 객체를 만들어서쓰는 거임.
- C#의 event란 무엇인가요? 델리게이트를 기반으로 한 객체인데요. 델리게이트가 타입인 반면 이벤트는 이 델리게이트 타입을 사용해서 객체로 만들어서 저장하고 있습니다. 그래서 객체를 생성할 필요 없이 호출할 시점만 정해주면 되는데 이벤트는 이벤트를 선언한 클래스에서만 호출이 가능해서 접근이 제한된다는 특징이 있습니다.
- Unity에서 사용하는 델리게이트 혹은 이벤트에는 어떤 것이 있나요? Inspector에서 이벤트를 연결하여 사용할 수 있는 유니티 내장 이벤트가 존재한다. 델리게이트 타입에는 Action, Action<T>, Func< T, TResult >가 존재하고, 액션은 반환값이 없고 매개변수를 필요로 하지 않고, 액션<T>는 매개변수만 존재하며, 펑션은 매개변수와 반환값이 둘 다 존재하는 델리게이트 타입이다.
- 참조 형식과 값 형식에 대해 설명해주세요. 참조 형식은 이미 존재하는 데이터의 메모리 주소를 참조해서 사용하는 것이다. 이를 통해서 메모리 주소에 있는 실제 데이터에 접근이 가능하다. 값 형식은 변수에 데이터를 직접 넣어서 사용하는 것처럼 자기 자신이 실제 값을 가지고 있는 것을 말한다
- 메모리에서 스택과 힙의 차이점에 대해 설명해주세요. 메모리 공간은 코드 영역 > 데이터 영역 > 스택 영역 > 힙 순으로 저장이 된다. 스택 영역은 함수 호출과 관계되는 지역 변수와 매개 변수가 저장되고, 함수의 호출과 함께 할당된다. 선입선출의 방식에 따라 동작하게 된다. 변수가 차곡차곡 쌓이는 스택과 달리 힙영역은 임의의 객체가 생성이 된다. 객체를 선언하면 항상 힙 메모리 영역에 생성이 되고 이러한 객체에 대한 참조 정보는 스택 메모리에 저장이 된다. 결론 : 스택은 메모리 할당과 할당 해제가 자동으로 수행되지만 힙은 수동으로 메모리를 할당하고 해제해야 한다. 그래서 스택 메모리가 더 빠르다.
- 1번과 2번 질문의 답안을 기반으로 struct와 class의 차이점에 대해 설명해주세요. class는 어떤 기능을 하는 객체를 만들기 위해 작동하고, struct은 단순한 데이터를 모아두는 집합체처럼 보통 사용이 된다. 클래스는 상속, 다향성 및 캡슐화 같은 객체 지향 기능을 더 잘 제공하고 있다.
1. 얕은 복사와 깊은 복사의 차이점은 무엇인가요? 얕은 복사는 객체의 참조를 복사하는 것이다. 얕은 복사로 복사된 객체는 원본 객체와 일부 데이터(참조 형식 데이터)를 공유한다. 깊은 복사는 객체의 데이터를 새로운 메모리에 복사하는 것이다. 값 형식뿐만 아니라 참조 형식 데이터도 새로운 복사복을 만들기 때문에 원본과 복사본이 독립적인 상태가 된다.
쉬운 설명 : 우리가 데이터를 만들기 위해서는 데이터를 저장할 주소가 필요하다. 만약 A = 6 이라는 데이터가 있다고 했을 때, A는 6이라는 데이터가 들어간 주소값이 된다. 여기서 얕은 복사는 객체를 복사해서 똑같은 A라는 주소값을 사용하게 되는 것이고(같은 집 공유, 그래서 하나를 변경하면 서로 영향 주고 받음), 깊은 복사는 A-1라는 새로운 주소값을 만들어서 사용하게 되는 것(새 집 만들어서 거기 데이터 복사)이다.
2. 박싱과 언박싱이 일어나는 과정을 메모리 관점에서 설명해주세요. 박싱은 값 형식 데이터를 참조 형식으로 변환하는 과정이다. 값 형식 데이터가 힙 메모리에 새로운 객체로 저장되면서 이 객체의 주소(참조)가 생성된다. 그러니까 힙 메모리에 해당 값 형식 데이터의 복사본이 만들어지고, 힙에 저장된 객체의 주소는 스택에 저장된다. 언박싱은 참조 형식 데이터를 다시 값 형식으로 변환하는는 과정이다. 힙 메모리에 있던 값 형식 데이터를 스택 메모리로 복사하게 된다.
3. 클래스를 다른 클래스로 상속하기 위한 방법은 무엇인가요? 클래스는 : 기호를 통해 상속을 받을 수 있다. 기본 클래스를 파생 클래스가 상속받으면, 기본 클래스의 멤버를 사용할 수 있다.
4. 클래스 상속에서 다이아몬드 문제(diamond problem)가 발생하는 이유와 이를 해결하는 방법에 대해 설명해주세요. 다이아몬드 문제는 다중 상속에서 발생할 수 있는 충돌 문제를 말한다. 이는 한 클래스가 여러 부모 클래스를 상속받고, 이 부모들이 공통의 조상을 가질 때 발생한다.
쉬운 설명 : 기본 클래스를 A, B가 상속받고 이 A, B 클래스를 C가 상속받으면 어떤 클래스를 통해 기본 클래스에 접근해야 할지 알 수 없게 된다.
다중 상속 대신 인터페이스를 사용하여 해결이 가능하다. (기본 클래스를 인터페이스로 만들고, A와 B 중 하나의 클래스만 상속받으면 된다.)
5. 인터페이스란 무엇인가요? 인터페이스(Interface)는 서로 다른 객체가 공통적인 기능을 가져야 할 때, 추상화를 하기 위해 사용하는 설계 방식 중 하나이다. 인터페이스 자체에는 구현이 없고, 오직 멤버들의 선언(시그니처)만 포함됩니다.
6. 인터페이스와 추상클래스의 차이는 무엇인가요? 인터페이스는 하나의 클래스에서 여러 개의 인터페이스를 상속 받을 수 있고 상속 받은 자식 클래스에게 모든 멤버의 구현을 강제한다. 반면 추상 클래스는 단일 상속만 가능하며 일반 메서드와 추상 메서드를 별도로 분리해서 만들 수 있다. 자식 클래스는 추상 메서드만의 구현이 강제된다.
7. 가비지 컬렉터란 무엇인가요? 가비지 컬렉터(Garbage Collector, GC)는 .NET과 같은 관리형 언어(C#, Java 등)에서 메모리 관리를 자동으로 처리하는 시스템이다. GC는 더 이상 사용되지 않는 객체(즉, 접근할 수 없는 메모리)를 탐지하고 회수하여, 개발자가 명시적으로 메모리를 해제하지 않아도 되도록 한다.
8. 가비지 컬렉터의 장점과 단점에 대해 설명해주세요.
9. 가비지 컬렉터의 세대 개념에 대해 설명해주세요.
// 가비지 컬렉터 진짜 처음 듣는데 이건 유튜브 봐야 할 듯?
10. 박싱, 언박싱을 사용할 때 주의해야 할 점은 무엇일까요? 메모리 할당과 형 변환을 동반하기 때문에 가능한 최소화 하고, 박싱이 필요한 경우 잘못된 타입으로 변환하면 오류가 나서 타입 변환에 신경 써야 한다.
11. 오브젝트 풀을 사용하면 메모리 관리에 도움이 되는 이유가 무엇일까요? 오브젝트를 생성하고 삭제하는 데 메모리가 상당히 사용되기 때문에 객체가 생성해야 할 오브젝트를 만들어놓고 활성/비활성화로 관리하는 게 메모리가 절감된다.
12. 제네릭이란 무엇인가요? 메서드나 클래스를 작성할 때 데이터 형식을 지정하지 않고 실제 사용하는 시점에서 데이터 형식을 지정할 수 있도록 하는 기능으로 <T> 이렇게 생겼다. (ex. 싱글톤, GetComponent)
13. 람다식(Lambda Expression)이 무엇인지 설명해주세요. 이름이 없는 익명 함수로 별도의 메서드를 정의하지 않고도 함수를 사용할 수 있게 해준다. (=>)
14. LINQ란 무엇인가요?
15. 리플렉션(Reflection)이 뭔지, 사용을 해봤다면 어떤 이유에서 사용했는지 설명해주세요. 런타임에 객체의 메타데이터를 조사하고 동적으로 객체를 생성하거나 메서드를 호출할 수 있게 하는 기능이다. 사용해본 적은 없다.
1. Unity 생명주기(Unity Life Cycle)에 대해서 설명해주세요. 유니티는 사용자가 호출하지 않아도 호출되는 내장 함수가 있는데, 그 함수가 호출되는 순서를 생명주기라고 부른다.
2. MonoBehaviour 클래스의 주요 메서드와 그 기능에 대해 설명해주세요. MonoBehaviour은 게임 오브젝트의 컴포넌트로 사용할 수 클래스이다. 주요 메서드는 Start, Awake, Update, OnEnable 등이 있다.
- MonoBehaviour 클래스에서 Start와 Awake의 차이점은 무엇이며, 이를 적절히 사용하는 방법에 대해 설명해주세요. Awake는 오브젝트가 생성될 때 바로 호출되고, Start는 오브젝트가 활성화 된 후 호출된다. 그래서 Awake가 Start보다 호출 순서가 빠르다는 게 가장 큰 차이점이다. Awake는 데이터를 로드하거나 싱글톤 같은 그 오브젝트에 필요한 요소를 초기화하는 작업에 쓰는 게 좋고, Start는 초기화를 하고 이후 이 초기화 된 작업을 통해 게임 로직을 짤 때 사용하는 게 좋다.
3. Update, FixedUpdate, LateUpdate의 차이점에 대해 설명해주세요.
Update : 매 프레임마다 한 번씩 호출된다. 이때의 프레임은 사용자의 컴퓨터 설정에 따라 차이가 나기 때문에 호출 주기도 차이가 발생할 수 있다.
FixedUpdate : 고정된 간격인 Fixed Timestep에 따라 호출된다. 물리 연산과 같은 규칙적이고 일정한 처리를 필요로 하는 로직에 적합하다.
LatedUpate : Update의 모든 함수가 수행되고 난 뒤에 호출된다.
https://note8918.tistory.com/51
11월 11일 월요일 본 캠프 개발 일지
📌 다양한 유니티 기능을 사용하는 숙련 주차 강의를 다시 한 번 복습하게 되었다. 클래스 구조보다 이론 및 기능과 코드 해석에 초점을 맞춘 TIL이 이어질 것 같다. 학습 내용 1. 물리 엔진
note8918.tistory.com
4. Time.deltaTime이란 무엇이며, 사용하는 이유에 대해 설명해주세요.
5. 코루틴의 동작원리와 사용해본 예시를 함께 설명해주세요. StartCoriutine으로 실행하며, StartCoriutine으로 실행된 IEnumerator 메서드는 yield return을 반환해 구문을 실행한다. / 일정 시간 뒤에 팝업 UI을 띄워고 일정 시간 뒤에 팝업을 자동으로 삭제하는 작업에서 코루틴을 사용했다.
6. Invoke와 코루틴의 차이에 대해 설명해주세요. 둘다 비동기 방식을 구현한다. 하지만 코루틴은 StartCoriutine을 통해 함수를 실행하지만, Invoke는 함수 이름을 찾아서 실행해야 하기 때문에 시간이 보다 느릴 수 있다. Coroutine은 실행한 오브젝트가 비활성화 되면 자동으로 중지되고, Invoke는 오브젝트가 비활성화되어도 중지되지 않는다. 코루틴은 매개변수가 있는 함수까지 실행이 가능하고, Invoke는 void 형만 실행 가능하다.
7. 코루틴과 멀티쓰레딩은 어떤 차이가 있는지 설명해주세요. 코루틴은 프레임 단위로 단일 스레드 위에서 작업의 실행을 분할하여 로직을 처리하고, 멀티 쓰레딩은 작업 도중 다른 작업까지 동시에 작업하는 것으로 CPU 코어를 병렬로 활용한다.
8. 유니티 최적화 기법은 어떤 것들이 있나요?
- 최적화를 해본 적이 있나요? 없다면 어떤 최적화가 있는지 설명해주세요. 최적화를 위해 오브젝트 풀링과 아틀라스를 사용해본 적이 있다.
- 최적화에서 가장 중요한 부분은 무엇인가요? 필요하지 않는 기능을 비활성화 하고, 리소스 용량을 최대한 줄이는 것이라고 생각한다.
- 최적화를 위해서 적용해본 텍스쳐 포맷이 있나요? X.
9. 드로우콜에 대해서 설명하고, 최적화하는 방식에 대해 알고 있는 것이 있으면 설명하세요. 드로우콜은 GPU가 하나의 메쉬를 헨더링하기 위한 명령이고, 최적화 하는 방식은 정적인 오브젝트를 병합하는 Static Batching, 작은 다이나믹 오브젝트를 병합하는 Dynamic Batching가 있다.
10. Find 함수 사용을 자제해야 하는 이유에 대해 설명해주세요. Find는 리스트를 모두 순회하기 때문에 메모리가 많이 사용된다.
11. Update에서 GetComponent와 그 계열의 캐싱을 지양해야하는 이유를 설명하세요. 일단 GetComponent 자체가 게임 오브젝트를 찾고 그 안의 컴포넌트를 다시 검색하는 구조라서 효율이 그렇게 좋지 않은데, Update를 사용해버리면 매프레임마다 GetComponent가 돌아가서 메모리가 낭비된다. 따라서 Awake에서 한번만 호출하고, 호출된 데이터를 변수로 저장해 사용하는 것이 좋다.
12. CSV/JSON 등 데이터 저장 포맷에 대해 설명하고, 활용에 적절한 상황을 설명해주세요. CSV는 텍스트 파일을 , 로 구분해 원하는 데이터를 사용할 수 있는 구조이고 대향의 테이블형 데이터에 적합하다. JSON은 키명-키값을 딕셔너리로 매칭해서 가지고 있는 데이터 구조고 계층 구조를 표현할 때 적합하다.
13. 특정 데이터를 JSON으로 활용하기 위해 해야하는 작업은 무엇인가요? 데이터를 JSON 형식으로 직렬화하고, JSON 파일에서 역직렬화하여 객체로 변환한다.
14. Unity에서 필드를 직렬화하려면 어떻게 해야하는지 설명해주세요. 필드를 직렬화 할 때는 [SerializeField]를 사용하고, 사용자 정의 클래스를 만들때는 [System.Serializable]를 사용한다.
15. Unity에서 멀티스레딩을 구현하기 위한 방법에 대해 설명해주세요. Job System을 활용한다.
16. CPU와 GPU의 작동 방법은 어떤 차이가 있는지 설명해주세요. CPU는 순차적으로 작업을 처리하고, GPU는 병렬로 연산한다.
17. 월드 스페이스 (World Space) 와 로컬 스페이스 (Local Space)의 차이에 대해 설명해주세요. 월드 스페이스는 전역 좌표계, 그러니까 게임 씬을 기준으로 위치와 회전값을 잡는 거고, 로컬 플레이스는 오브젝트의 부모 기준의 좌표를 의미한다.
18. 벡터의 내적과 외적을 어느 상황에 사용할 수 있는지 설명해주세요.
19. 쿼터니언을 사용하는 이유에 대해 설명해주세요. 회전 계산에서 짐벌락을 방지하고, 더 부드럽게 회전하기 위해서.
20. 네트워크 프로토콜 (IP, TCP, UDP)에 대해 설명해주세요.
21. TCP와 UDP의 차이를 설명해주세요.
22. 렌더링 파이프라인에 대해 설명해주세요.
23. 3D 공간에 있는 오브젝트들이 화면에 표현되는 픽셀로 표시되기까지의 과정을 설명해보세요.
24. 셰이더를 활용해본 경험이 있을까요? 어떻게 활용했는지 설명해주세요. 경험을 해본 적이 없다.
1. LinkedList의 특성을 설명해주세요.
노드로 구성된 자료구조, 노드는 데이터와 다음/이전 노드에 대한 참조를 가진다.
LinkedList는 언제 사용하면 좋은 자료구조인가요? 반대로 언제 사용하기 불리할까요? 삽입/삭제가 많은 경우에 좋고 인덱스 기반 접근이 많을 때 불리하다.
LinkedList를 본인의 프로젝트에 적용해본 경험을 말해주세요. X.
2. Stack의 특성을 설명해주세요.
Last in, First Out 구조이다.
Stack은 언제 사용하면 좋은 자료구조인가요? 반대로 언제 사용하기 불리할까요? 재귀 호출, 실행 순서를 저장해야 할 때 좋고 특정 데이터에 접근해야 할 때 불리하다.
Stack을 본인의 프로젝트에 적용해본 경험을 말해주세요.게임에서 UI 팝업을 관리할 때 용이하다.
3. Queue의 특성을 설명해주세요.
First in, First Out 구조이다.
Queue는 언제 사용하면 좋은 자료구조인가요? 반대로 언제 사용하기 불리할까요? 작업 대기열을 만들고 순차적으로 데이터를 처리할 때 좋고, 임의 접근이 필요할 때 불리하다.
Queue를 본인의 프로젝트에 적용해본 경험을 말해주세요. 몬스터 스폰 관리에서 대기열을 구현할 때 사용했다.
4. Tree의 순회(Traversal) 방법에 대해 설명해주세요. 모르겠다.
5. DFS와 BFS에 대해 설명해주세요. DFS는 깊이 우선 탐색으로 재귀/스택을 사용하고, BFS는 너비 우선 탐색으로 큐를 사용한다.
DFS와 BFS를 본인의 프로젝트에 활용한 경험이 있다면 설명해주세요.
6. 행동 트리 (Behaviour Tree) 에 대해 설명해주세요. AI를 위한 계층적 상태 관리 구조로 간단하고 직관적으로 복잡한 행동을 구현할 수 있다.
7. 길찾기 알고리즘에 대해 알고 있는 것이 있나요? DFS, BFS, Dijkstra를 알고 있다.
8. 각 길찾기 알고리즘의 차이점은 무엇인가요? DFS/BFS는 전체 탐색, 최단 경로 보장이 되지 않고 Dijkstra는 가중치 기반 최단 경로를 찾아갈 수 있다.
9. A* 알고리즘에 대해 설명해주세요. 모르겠다.
10. 해당 알고리즘들을 프로젝트에 적용해본 경험이 있나요? 없다.