Today I Learned - Unity & C# 면접 대비 심화 정리

2025. 4. 22. 20:36카테고리 없음


1. 객체(Object)와 클래스(Class)

객체는 현실 세계의 사물이나 개념을 코드로 표현한 실체입니다. 클래스는 이러한 객체를 생성하기 위한 설계도 역할을 합니다. C#에서는 클래스를 정의한 후, new 키워드를 통해 객체를 생성할 수 있습니다.

객체는 상태(변수)와 동작(메서드)을 포함하며, 클래스는 그 틀을 제공합니다. 예를 들어 '고양이'라는 클래스를 만들고 '나비', '냐옹이'라는 이름을 가진 객체를 만들 수 있습니다. 두 객체는 같은 클래스를 기반으로 하지만 서로 다른 데이터를 가질 수 있습니다.


2. 생성자(Constructor)

생성자는 클래스의 인스턴스를 생성할 때 호출되는 특별한 메서드입니다. 생성자는 클래스 이름과 동일하며 반환형이 없습니다. 기본 생성자, 매개변수를 받는 생성자, 정적 생성자(static constructor) 등이 있습니다.

기본 생성자는 클래스 정의 시 별도로 작성하지 않으면 컴파일러가 자동으로 생성합니다. 생성자 오버로딩을 통해 여러 개의 생성자를 만들 수 있고, this()를 이용해 생성자 간 체이닝도 가능합니다.


3. 접근제한자(Access Modifiers)

접근 제한자는 클래스, 필드, 메서드, 속성 등의 접근 범위를 제어하는 키워드입니다. 코드를 안전하게 보호하고, 외부에서의 잘못된 접근을 방지하며, 캡슐화를 실현하는 데 사용됩니다.

  • public – 모든 곳에서 접근 가능
  • private – 현재 클래스 내부에서만 접근 가능
  • protected – 현재 클래스 및 상속받은 클래스에서 접근 가능
  • internal – 동일 어셈블리 내에서 접근 가능
  • protected internal – 상속 또는 같은 어셈블리 내에서 접근 가능
  • private protected – 상속 관계면서 같은 어셈블리일 때만 접근 가능

4. static 키워드

static은 해당 멤버가 인스턴스가 아닌 클래스 자체에 속함을 의미합니다. static 필드나 메서드는 객체를 생성하지 않고도 클래스 이름으로 접근할 수 있습니다.

static 클래스는 인스턴스를 생성할 수 없으며, 모든 멤버가 static이어야 합니다. 대표적인 예로 Math 클래스의 Mathf.Abs(), Mathf.Pow() 같은 수학 유틸리티 메서드가 있습니다.


5. SOLID 원칙

SOLID는 객체지향 설계의 5가지 핵심 원칙입니다. 유지보수성과 확장성을 높이는 데 중요한 가이드라인 역할을 합니다.

  • Single Responsibility Principle – 클래스는 단 하나의 책임만 가져야 합니다.
  • Open/Closed Principle – 확장에는 열려 있고, 수정에는 닫혀 있어야 합니다.
  • Liskov Substitution Principle – 자식 클래스는 부모 클래스의 기능을 대체할 수 있어야 합니다.
  • Interface Segregation Principle – 불필요한 기능을 강요하지 말고, 작은 인터페이스로 분리해야 합니다.
  • Dependency Inversion Principle – 구현보다는 추상에 의존해야 하며, 의존성은 외부에서 주입받도록 해야 합니다.

6. 다형성(Polymorphism)

다형성이란 동일한 메서드 호출이 상황에 따라 다른 동작을 하는 성질입니다. 대표적으로 오버라이딩(override), 인터페이스 구현을 통해 나타납니다. 예를 들어 Animal.Speak()을 오버라이드한 Dog.Speak()Cat.Speak()는 같은 메서드 호출로 서로 다른 소리를 낼 수 있습니다.


7. Override vs Overload

Override는 부모 클래스의 메서드를 자식 클래스에서 재정의하여 다른 동작을 하게 하는 것이며, 주로 다형성을 위한 수단입니다. 반면 Overload는 같은 이름의 메서드를 매개변수 시그니처가 다르게 여러 개 정의하는 것으로, 호출 시점에 적절한 메서드를 선택합니다.


8. 확장 메서드

확장 메서드는 기존 클래스의 코드를 변경하지 않고 메서드를 추가할 수 있게 해주는 문법입니다. static 클래스 내에서 정의되며 첫 번째 인자는 this 키워드를 통해 확장 대상 타입을 지정합니다.


9. Unity 생명주기

Unity는 MonoBehaviour를 기반으로 하는 스크립트의 생명주기를 통해 게임 오브젝트의 상태 변화를 처리합니다. 호출 순서는 다음과 같습니다:

Awake → OnEnable → Start → Update → LateUpdate → OnDisable → OnDestroy

FixedUpdate는 일정 시간마다 호출되며, 주로 물리 연산에 사용됩니다.


10. MonoBehaviour 주요 메서드

Awake는 오브젝트가 생성될 때 호출되며, 컴포넌트 참조 등에 사용됩니다. Start는 모든 Awake 이후 호출되어 게임 시작 직전에 초기화 작업에 사용됩니다. Update는 매 프레임마다 호출되며, 입력 처리 및 상태 갱신에 적합합니다. FixedUpdate는 일정한 간격으로 호출되어 물리 연산에 최적화되어 있으며, LateUpdate는 모든 Update 이후 호출되어 후처리에 사용됩니다.


11. Update / FixedUpdate / LateUpdate 비교

  • Update: 매 프레임 호출, 입력 처리 및 일반 게임 로직 수행
  • FixedUpdate: 고정된 시간 간격, 물리 기반 처리
  • LateUpdate: 모든 Update 이후, 카메라 추적 등 후처리에 적합

12. Time.deltaTime

Time.deltaTime은 이전 프레임과 현재 프레임 사이의 시간 간격을 초 단위로 반환하는 값입니다. 프레임 속도에 따라 동작 속도가 달라지지 않도록 보정하는 데 사용됩니다. 대표적으로 이동 처리 시 속도 * Time.deltaTime을 곱해줍니다.


13. Coroutine(코루틴)

코루틴은 IEnumerator를 반환하며, 시간 지연, 조건 대기, 프레임 분할 실행 등을 통해 논리적 흐름을 자연스럽게 표현할 수 있습니다. yield return을 통해 중단점과 재개 지점을 설정할 수 있으며, 복잡한 상태 흐름 처리에 유용합니다.


14. Invoke vs Coroutine

Invoke는 지정된 시간 후에 단일 메서드를 실행할 때 유용하며 간단합니다. 반면 Coroutine은 반복 실행, 다단계 처리, 조건 분기 등 유연한 흐름 제어가 가능합니다. 실제 게임에서는 페이드, 스킬 쿨타임, 상태 변화 처리 등에서 Coroutine이 자주 사용됩니다.


15. Coroutine vs Multi-threading

Coroutine은 Unity의 메인 스레드에서 작동하며, Unity API와 안전하게 연동할 수 있습니다. 반면 Multi-threading은 별도의 스레드에서 병렬로 동작하며 CPU 집약적인 연산, 파일 IO, 웹 요청 등에 적합합니다. Unity API는 대부분 메인 스레드에서만 호출 가능하므로, 병렬 처리 후 결과를 메인 스레드로 전달해야 합니다.