컴포넌트 패턴 기술면접 문제집

omniAI·2025년 10월 14일
0

Design-Pattern

목록 보기
10/11

사용법

  1. 각 질문을 2분 안에 답변
  2. 정의 + 예시 + 실무 적용 포함
  3. 70% 이상 정답 시 합격

파트 1: 기본 개념 (10문제)

Q1. 컴포넌트 패턴이 무엇인가요?


Q2. 상속과 조합의 차이는 무엇인가요?


Q3. Unity에서 컴포넌트 패턴이 어떻게 적용되나요?


Q4. 컴포넌트 패턴의 장점 3가지는?


Q5. 인터페이스를 왜 사용하나요?


Q6. 이벤트를 왜 사용하나요?


Q7. GetComponent vs TryGetComponent 차이는?


Q8. 컴포넌트 간 통신 방법 3가지는?


Q9. God Component가 무엇인가요?


Q10. 순환 참조가 무엇이고 어떻게 해결하나요?


파트 2: SOLID 원칙 (5문제)

Q11. S - 단일 책임 원칙(SRP)을 설명하세요.


Q12. O - 개방-폐쇄 원칙(OCP)을 설명하세요.


Q13. L - 리스코프 치환 원칙(LSP)을 설명하세요.


Q14. I - 인터페이스 분리 원칙(ISP)을 설명하세요.


Q15. D - 의존성 역전 원칙(DIP)을 설명하세요.


파트 3: 실무 적용 (5문제)

Q16. Update에서 GetComponent를 호출하면 안 되는 이유는?


Q17. 컴포넌트 설계 시 주의사항 4가지는?


Q18. 성능 최적화를 위한 방법 4가지는?


Q19. 언제 ECS로 전환해야 하나요?


Q20. 실무에서 가장 많이 쓰는 디자인 패턴 5가지는?


파트 4: 코드 리뷰 (5문제)

Q21. 다음 코드의 문제점을 찾으세요.

public class Player : MonoBehaviour
{
    void Update()
    {
        GetComponent<Health>().Regen();
    }
}

Q22. 다음 코드의 문제점을 찾으세요.

public class PlayerController : MonoBehaviour
{
    void Move() { }
    void Attack() { }
    void Jump() { }
    void Heal() { }
    void OpenInventory() { }
    void SaveGame() { }
    void UpdateUI() { }
}

Q23. 다음 코드의 문제점을 찾으세요.

public class A : MonoBehaviour
{
    [SerializeField] B b;
}

public class B : MonoBehaviour
{
    [SerializeField] A a;
}

Q24. 다음 코드를 개선하세요.

void OnTriggerEnter(Collider other)
{
    TankHealth health = other.GetComponent<TankHealth>();
    if (health != null)
    {
        health.TakeDamage(10);
    }
}

Q25. 다음 코드를 개선하세요.

public class Health : MonoBehaviour
{
    [SerializeField] UIManager ui;
    
    void TakeDamage(int damage)
    {
        hp -= damage;
        ui.UpdateHealthBar(hp);
    }
}

👀 컴포넌트 패턴 기술

면접 정답지

파트 1: 기본 개념 (10문제)

A1. 컴포넌트 패턴이 무엇인가요?

정의:
기능을 독립된 블록으로 나눠서 조립하는 설계 방식입니다.

핵심:

  • 상속 대신 조합 사용
  • GameObject에 필요한 기능만 붙임
  • Unity의 기본 구조

예시:

상속: Player → Character (코드 수정)
컴포넌트: GameObject + Move + Attack (조립)

실무:
Unity는 이미 컴포넌트 패턴 엔진이므로 자연스럽게 적용됩니다.


A2. 상속과 조합의 차이는 무엇인가요?

상속 (Inheritance):

  • IS-A 관계 (플레이어는 캐릭터다)
  • 계층 구조로 확장
  • 기능 추가 시 클래스 수정 필요
  • 경직된 구조

조합 (Composition):

  • HAS-A 관계 (플레이어는 이동 기능을 가진다)
  • 필요한 컴포넌트만 조립
  • 기능 추가 시 컴포넌트만 붙임
  • 유연한 구조

실무:
컴포넌트 패턴(조합)이 확장/재사용에 유리합니다.


A3. Unity에서 컴포넌트 패턴이 어떻게 적용되나요?

Unity = 컴포넌트 패턴 엔진

매핑:

  • GameObject = 빈 컨테이너
  • MonoBehaviour = 컴포넌트
  • AddComponent = 조립

실무:
Transform, Rigidbody, Collider 모두 컴포넌트입니다.


A4. 컴포넌트 패턴의 장점 3가지는?

1. 재사용성

  • 같은 컴포넌트를 여러 GameObject에 사용
  • Move 컴포넌트를 플레이어/적/NPC 모두에게

2. 확장성

  • 새 기능 추가 시 기존 코드 수정 불필요
  • AddComponent만 하면 끝

3. 유지보수성

  • 컴포넌트 단위로 독립적 수정
  • 버그 격리 용이
  • 테스트 간편

실무:
팀 협업 시 서로 다른 컴포넌트 작업 → 충돌 최소화


A5. 인터페이스를 왜 사용하나요?

이유:
확장성과 결합도 감소

효과:

  • TankHealth든 Shield든 Building이든 상관없이 동작
  • 코드 수정 없이 새 타입 추가 가능
  • 다형성 활용

실무:
인터페이스로 추상화하면 확장이 무한대로 가능합니다.


A6. 이벤트를 왜 사용하나요?

이유:
직접 참조를 끊기 위해

효과:

  • HealthComponent는 누가 구독하는지 몰라도 됨
  • UI 추가해도 HealthComponent 수정 불필요
  • Observer 패턴 구현

실무:
이벤트로 발행자-구독자를 완전 분리합니다.


A7. GetComponent vs TryGetComponent 차이는?

성능:
TryGetComponent가 약 2배 빠름

차이점:

  • TryGetComponent: 검색 + null 체크 동시 처리
  • 코드 간결
  • 안전성 증가

실무:
충돌/트리거 처리는 90% TryGetComponent 사용


A8. 컴포넌트 간 통신 방법 3가지는?

1. 직접 참조 (단방향)
필수 의존성에 사용

2. 이벤트 (느슨한 결합)
알림/브로드캐스트에 사용

3. 인터페이스 (추상화)
확장 가능한 타입에 사용

실무:

  • 필수 의존: 직접 참조
  • 알림: 이벤트
  • 확장: 인터페이스

A9. God Component가 무엇인가요?

정의:
너무 많은 일을 하는 컴포넌트 (안티패턴)

문제:

  • 단일 책임 원칙 위반
  • 수정 이유 10가지 이상
  • 재사용 불가
  • 테스트 어려움

해결:
MoveComponent, CombatComponent, HealthComponent로 분리

판별:
100줄 넘거나 책임 3개 이상이면 분리


A10. 순환 참조가 무엇이고 어떻게 해결하나요?

정의:
A가 B를 참조하고, B가 A를 참조

문제:
둘 다 독립 사용 불가

해결 1: 이벤트
A는 이벤트 발행만, B는 구독만

해결 2: 인터페이스
추상에 의존하여 단방향으로 만들기

실무:
이벤트/인터페이스로 단방향 의존으로 만듭니다.


파트 2: SOLID 원칙 (5문제)

A11. S - 단일 책임 원칙(SRP)을 설명하세요.

정의:
한 클래스는 하나의 책임만

변경 이유:
1개 클래스 = 1개 변경 이유

예시:
MoveComponent - 이동만
ShootComponent - 공격만
HealthComponent - 체력만

효과:

  • 한 기능 수정 시 다른 기능 안전
  • 재사용 쉬움
  • 테스트 간편

실무:
컴포넌트 하나는 한 가지만 하게 합니다.


A12. O - 개방-폐쇄 원칙(OCP)을 설명하세요.

정의:
확장에는 열림, 수정에는 닫힘

의미:
새 기능 추가 시 기존 코드 수정 불필요

예시:
인터페이스로 새 타입 추가해도 기존 코드 수정 안 함
Shield, Building 등 IDamageable 구현만 하면 자동 지원

효과:

  • 기존 코드 안전
  • 무한 확장 가능
  • 버그 위험 감소

실무:
인터페이스로 확장 지점을 만듭니다.


A13. L - 리스코프 치환 원칙(LSP)을 설명하세요.

정의:
부모 타입을 자식 타입으로 바꿀 수 있어야 함

방향:
부모 → 자식 교체 가능

예시:
IDamageable 타입 변수에 TankHealth, Shield, Building 모두 할당 가능
target.TakeDamage(10) 모두 동작

효과:

  • 구현체 자유롭게 교체
  • 다형성 활용
  • 유연한 설계

실무:
인터페이스 구현체는 언제든 교체 가능해야 합니다.


A14. I - 인터페이스 분리 원칙(ISP)을 설명하세요.

정의:
인터페이스를 작게 분리

의미:
필요 없는 메서드 구현 강제 금지

예시:
IDamageable - TakeDamage만
IHealable - Heal만
각각 필요한 것만 구현

반례:
큰 인터페이스 IEntity에 TakeDamage, Heal, Stun 모두 있으면
건물은 Heal 필요 없는데 강제 구현

실무:
인터페이스는 1-3개 메서드만


A15. D - 의존성 역전 원칙(DIP)을 설명하세요.

정의:
구체가 아닌 추상에 의존

의미:
구체 클래스 대신 인터페이스 참조

예시:
TankHealth 대신 IDamageable 타입으로 참조

효과:

  • 느슨한 결합
  • 테스트 용이 (Mock)
  • 확장/유지보수 쉬움

실무:
TryGetComponent<인터페이스> 패턴 사용


파트 3: 실무 적용 (5문제)

A16. Update에서 GetComponent를 호출하면 안 되는 이유는?

이유:
매 프레임 검색 → 성능 낭비

문제:
60fps면 초당 60번 검색

해결:
Awake/Start에서 캐싱 후 재사용

실무:
Awake/Start에서 캐싱 필수


A17. 컴포넌트 설계 시 주의사항 4가지는?

1. Update에서 GetComponent 금지
Awake에서 캐싱

2. God Component 방지
100줄 넘으면 분리, 1컴포넌트 = 1책임

3. 순환 참조 방지
A ↔ B 금지, 이벤트/인터페이스로 절단

4. RequireComponent 활용
필수 의존성 명시

실무:
이 4가지만 지켜도 80% 깔끔


A18. 성능 최적화를 위한 방법 4가지는?

1. 참조 캐싱
Awake에서 GetComponent 1회만

2. Update 최소화
이벤트/코루틴으로 대체, 매 프레임 계산 피하기

3. 오브젝트 풀링
총알/이펙트는 생성/파괴 대신 재사용

4. FixedUpdate 사용
Rigidbody 물리 처리는 FixedUpdate

실무:
캐싱 + 풀링이 가장 효과 큼


A19. 언제 ECS로 전환해야 하나요?

기준:
수천 개 이상 오브젝트에서 성능 병목

컴포넌트 패턴:

  • 개발 빠름
  • 직관적
  • Unity 친화적
  • 수백~수천 개 OK

ECS (DOTS):

  • 학습 곡선 존재
  • 성능 최고
  • 수만 개 처리
  • 에디터 제한적

권장:
대부분 게임은 컴포넌트 패턴으로 충분
병목 보이는 핵심 루프만 ECS 혼용

실무:
먼저 컴포넌트로 만들고, 필요시 ECS 전환


A20. 실무에서 가장 많이 쓰는 디자인 패턴 5가지는?

1. 컴포넌트 (90%)
Unity 기본 구조

2. 오브젝트 풀링 (80%)
메모리 관리 필수

3. 싱글톤 (70%)
전역 접근 (남용 주의)

4. 옵저버/이벤트 (65%)
통신

5. 스테이트 FSM (60%)
AI, 캐릭터 상태

참고:
GoF 23개 중 실제로는 7~8개만 씀


파트 4: 코드 리뷰 (5문제)

A21. Update에서 GetComponent 문제

문제:
매 프레임 검색 → 성능 낭비

개선:
Awake에서 캐싱 후 Update에서 재사용


A22. God Component 문제

문제:

  • 너무 많은 책임 (7가지)
  • 단일 책임 원칙 위반
  • 재사용 불가

개선:
MoveComponent, CombatComponent, JumpComponent, HealthComponent, InventoryComponent, SaveComponent, UIComponent로 분리


A23. 순환 참조 문제

문제:
A → B, B → A
둘 다 독립 사용 불가

개선 1: 이벤트
A는 이벤트 발행만, B는 구독만

개선 2: 단방향
A → B (B만 A를 앎)


A24. 구체 타입 의존 문제

문제:
구체 타입에 의존 → 확장 어려움

개선:
인터페이스 의존으로 변경
IDamageable 사용하면 Shield, Building 등 자동 지원


A25. 직접 참조 문제

문제:
직접 참조 → 높은 결합도

개선:
이벤트 사용
Health는 OnHealthChanged 발행만
UIManager는 구독해서 처리


평가 기준

점수 계산

25문제 중:

  • 23개 이상: S등급 ⭐⭐⭐⭐⭐ (92%)
  • 21-22개: A등급 ⭐⭐⭐⭐ (84-88%)
  • 18-20개: B등급 ⭐⭐⭐ (72-80%)
  • 15-17개: C등급 ⭐⭐ (60-68%) - 재시험
  • 14개 이하: 재학습 필요

답변 필수 요소

각 답변마다 포함해야 할 것:

  • ✅ 정의/개념 명확히
  • ✅ 코드 예시 (좋은 예 + 나쁜 예)
  • ✅ 실무 적용 방법

시간 관리

  • 총 50분 (질문당 2분)
  • 2분 초과 시 다음 문제로
  • 모르는 문제는 건너뛰고 나중에

합격 후 학습 로드맵

다음 단계

  1. 과제 3: ScriptableObject 데이터 분리
  2. 최종 과제: 타워 디펜스 미니 게임
  3. 포트폴리오: GitHub에 정리

추가 학습 주제

  • 오브젝트 풀링 구현
  • 스테이트 패턴 (FSM)
  • 커맨드 패턴
  • 옵저버 패턴 심화

작성일: 2025-10-14
난이도: 미들 레벨
목표: 컴포넌트 패턴 마스터

profile
킵러닝

0개의 댓글