ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 유니티 클라이언트 면접준비 - 중요하다고 생각되는것들
    면접준비 2024. 1. 29. 07:26
    반응형

    - C# 과 C++ 차이점 -
    1. C++는 개발자가 직접 메모리로 작업할 수 있는 반면, C#은 가비지 컬렉터를 사용하여 메모리 관리를 간소화합니다.
    2. C#은 유형 안전성을 강화하는 강력한 유형 언어인 반면, C++은 보다 유연하게 사용할 수 있는 약한 유형 언어입니다.
    3. C#은 주로 .NET 플랫폼에서 사용되며, C++은 특정 하드웨어 및 운영 체제용으로 컴파일할 수 있는 네이티브 언어입니다.



    - 객체 지향 프로그래밍이란? -
    객체와 상호 작용을 사용하여 응용 프로그램과 컴퓨터 프로그램을 설계하는 프로그래밍 패러다임입니다.
    데이터와 해당 데이터를 조작하는 코드를 포함할 수 있는 "객체" 개념을 기반으로 합니다.



    - 객체 지향 4대 특징 -
    상속 : 상속은 클래스가 다른 클래스의 속성과 메서드를 상속할 수 있도록 하는 객체 지향 프로그래밍의 기본 개념중 하나입니다.
    다형성 : 서로 다른 클래스의 객체를 공통 부모 클래스의 객체로 취급할 수 있도록 합니다.
    캡슐화 : 캡슐화는 클래스의 내부 변수와 메서드를 하나로 패키징 하는것이다.
    추상화 : 불필요한 세부 사항을 숨겨 복잡성을 줄이는 프로세스를 말합니다.



    - 스택(Stack) -
    스택은 함수 호출 및 함수 실행과 관련된 데이터를 저장하는 데 사용되는 프로세스에서 중요한 메모리 영역입니다.
    함수 호출에 사용되는 메모리를 쉽게 관리할 수 있는 후입선출(LIFO) 데이터 구조이지만 제대로 관리하지 않으면 충돌을 일으킬 수 있는 제한된 리소스가 될 수도 있습니다.



    - 큐(Queue) -
    큐는 요소를 선입선출(FIFO) 방식으로 저장하는 데이터 구조의 한 유형입니다.
    즉, 큐에 가장 먼저 추가된 요소가 가장 먼저 제거됩니다. 큐는 일반적으로 작업 스케줄링이나 메시지 전달 시스템과 같이 요소를 수신한 순서대로 처리해야 하는 상황에서 사용됩니다.



    - 맵(Map) -
    맵은 각 키가 고유한 키-값 쌍의 모음을 저장하는 데이터 구조입니다. 연관 배열, 사전 또는 해시 맵이라고도 합니다.
    맵의 기본 아이디어는 고유 키를 사용하여 해당 값을 효율적으로 검색하는 것입니다.
    맵은 일반적으로 구성 설정 저장, 캐시 유지, 컴파일러에 기호 테이블 저장 등과 같은 많은 응용 프로그램에서 널리 사용됩니다.
    맵은 키-값 쌍의 형태로 데이터를 저장하고 싶을 때 사용할 수 있는 효율적인 데이터 구조입니다.



    - 해시 맵(Hash map) -
    해시 맵은 효율적인 조회, 삽입, 삭제를 위해 키를 값에 매핑하는 데이터 구조입니다.
    해시 테이블 또는 Dictionary이라고도 합니다. 해시 맵은 해시 함수를 사용하여 원하는 값을 찾을 수 있는 버킷 또는 슬롯 배열로 인덱스를 계산합니다.
    해시 맵은 게임 오브젝트 관리, 입력 처리, 경로 찾기, 게임 상태 관리등 데이터를 저장하거나 고유 식별자를 부여해 오브젝트를 효율적으로 조회하고 업데이트 할 수 있습니다.



    - 트리(Tree) -
    트리는 컴퓨터 과학 및 소프트웨어 엔지니어링에서 일반적으로 사용되는 비선형 데이터 구조입니다.
    트리는 Ai 경로 찾기 시스템, 충돌감지 등.. 게임 개발에서 다양하게 사용됩니다
    AI 경로 찾기에서는 트리를 사용하여 AI 캐릭터가 게임 환경을 통과할 수 있는 가능한 경로를 나타낼 수 있습니다.
    충돌 감지에서는 트리를 사용하여 게임 월드에서 오브젝트 간의 공간적 관계를 표현함으로써 효율적인 충돌 감지를 수행할 수 있습니다.



    - 자료 구조란? -
    자료 구조는 데이터를 효율적으로 액세스하고 조작할 수 있도록 컴퓨터에서 데이터를 구성하고 저장하는 방법입니다.
    자료 구조에는 여러 가지 유형이 있으며, 각각 고유한 장단점이 있으므로 올바른 데이터 구조를 선택하는 것은 효율적이고
    효과적인 알고리즘이나 프로그램을 설계하는 데 있어 중요한 부분입니다.



    - 리스트 -
    리스트는 배열과 같이 요소들의 집합을 저장하는 데이터 구조입니다. 
    배열과 달리 리스트는 일반적으로 고정된 크기를 갖지 않으며, 필요에 따라 크기가 증가하거나 축소될 수 있습니다.
    리스트는 종종 각 요소가 리스트의 다음 요소에 대한 참조를 포함하는 요소의 선형 컬렉션인 연결된 리스트로 구현됩니다. 

     

    배열 : 메모리 상에 데이터가 연속적으로 저장

    리스트 : 메모리 상에 데이터가 불연속적으로 저장



    - 오버로딩, 오버라이딩 -
    오버로딩은 이름은 같지만 함수의 기능이 다른 메서드를 만들 수 있는 기능입니다.
    오버라이딩(Overriding)은 부모 클래스에서 상속된 메서드의 다른 구현을 제공하는 자식 클래스의 기능입니다.



    - 정렬 알고리즘 -
    정렬은 데이터 요소 모음을 특정 순서로 배열하는 기본적인 알고리즘 문제입니다.



    - 정렬 알고리즘 종류 -
    버블 정렬: 목록을 반복적으로 통과하면서 인접한 요소를 비교하고 순서가 잘못된 경우 교체하는 간단한 정렬 알고리즘입니다.
    선택 정렬: 목록의 정렬되지 않은 부분에서 최소 요소를 반복적으로 찾아서 목록의 시작 부분으로 이동하는 또 다른 간단한 정렬 알고리즘입니다.
    삽입 정렬: 이 알고리즘은 적절한 위치의 각 요소를 앞에 있는 정렬된 하위 배열에 반복적으로 삽입하여 작동하는 또 다른 간단한 정렬 알고리즘입니다.
    퀵 정렬(Quick sort): 피벗 요소를 선택하고 피벗을 중심으로 배열을 분할하여
    피벗보다 작은 요소는 피벗의 왼쪽으로, 피벗보다 큰 요소는 피벗의 오른쪽으로 이동하도록 하는 분할 및 정복 알고리즘입니다.
    병합 정렬(Merge sort): 배열을 두 개의 반으로 나누고 각 반을 재귀적으로 정렬한 다음 정렬된 두 개의 반을 하나의 정렬된 배열로 병합하여 작동하는 또 다른 분할 및 정복 알고리즘입니다.



    - 클래스와 구조체 차이점 -
    구조체는 값 타입이기 때문에 스택 메모리에서 생성되며 속도가 빠릅니다. 구조체는 상속이 불가능합니다. 

    클래스는 참조타입이기 때문에 힙 메모리에 생성되고 상대적으로 느립니다.

    용량이 작고 임시적으로 쓰는 데이터에 구조체를 쓰는 것이 효율적입니다.



    - 디자인 패턴 -
    디자인 패턴은 소프트웨어 개발에서 발생하는 일반적인 디자인 문제에 대한 솔루션입니다. 개발자가 반복되는 문제를 일관되고 효율적인 방식으로 해결할 수 있는 방법을 제공합니다. 



    - 델리게이트 -
    C# 프로그래밍 언어에서 제공하는 타입으로, 메서드에 대한 참조를 저장합니다. 이를 통해 메서드를 변수처럼 전달하고, 저장하며, 호출할 수 있습니다.
    delegate 반환값 변수명(매개변수 타입, 매개변수명);



    - 이벤트 -
    이벤트는 객체의 상태 변화나 사건의 발생을 알리는 용도로 사용이 됩니다.



    - Interface(인터페이스) -
    1. 메서드 선언만 하고 기능 구현을 갖지 않은 형태의 클래스입니다.
    2. 모든 메서드는 추상 메서드로 취급되므로 추상클래스 선언을 사용하지 않아도 됩니다.
    3. 인터페이스를 구현하는 클래스는 인터페이스의 모든 메서드를 반드시 구현해야됩니다.
    4. 다중 상속이 허용되므로, 여러 개의 인터페이스를 한 클래스에서 구현할 수 있습니다.



    - abstract(추상 클래스) -
    1. 일반클래스와 차이로는 추상 메서드를 포함할 수 있습니다.
    2. 추상 메서드는 메서드 선언만 있고, 구현은 하위 클래스에서 이뤄집니다. 추상메서드는 'abstract' 키워드를 선언해서 사용해야 합니다.
    3. 추상 클래스 자체로는 직접 객체를 만들어서 사용할 수 없습니다.
    4. 단일 상속만 허용됩니다.



    - virtual(가상) -
    1. 하나의 기능을 하는 완전한 클래스입니다.
    2. 파생 클래스에서 상속해서 추가적인 기능 추가 및 재정의 가능합니다.



    - 오브젝트 풀링 -
    오브젝트 풀링(object pooling)은 보다 효율적인 방식으로 객체를 관리하고 재사용하는 데 사용되는 소프트웨어 디자인 패턴입니다.
    오브젝트 풀링(object pooling)의 기본 개념은 필요할 때마다 새 객체를 만드는 대신 사용할 준비가 된 객체 풀을 유지 관리하는 것입니다. 
    새 객체를 만드는데 필요한 시간을 줄이고 객체 만들기와 관련된 메모리 오버헤드를 줄임으로써 성능을 향상시킬 수 있습니다.



    - GC(가비지 컬렉터)가 무엇인가? -
    힙 영역에 사용자가 할당한 메모리 중 사용하지 않는 가비지를 자동으로 할당 해제해주는 시스템입니다.



    - GC(가비지 컬렉터) 최적화 -
    가비지를 만들지 않는것이 가장 중요하다고 생각합니다. 
    오브젝트 풀링 사용이 대표적일거 같고, 그 밖에는 string끼리 합칠때 + 기호를 사용하는데,
    이러면 메모리를 조금 더 잡아먹어서 합치는 함수인 Stringbuilder를 사용하는것이 좋다고 생각합니다



    - GC(가비지 컬렉터) 세대 -
    유니티에선 세대가 사용되지 않는 것으로 알고있습니다. 다른 곳에서의 세대를 얘기해보면, 우선 0세대의 메모리들을
    순차적으로 컬렉터가 검사하여 가비지를 골라냅니다. 여기서 걸러지지 않은 메모리들은 1세대로 승급되고, 반복하면 2세대로 승급됩니다.
    세대가 높아질수록 더 중요한 메모리라고 판단되어 컬렉터가 덜 검사하게 됩니다.



    - .Net과 Unity의 GC(가비지 컬렉터)의 차이 -
    내부적으로 GC(가비지 컬렉터)의 알고리즘은 'Mark and Sweep'을 기반으로 하게 되는데 그 이후의 과정이 다르게 됩니다.
    .Net에서는 0~2세대까지 총 3개의 세대를 통해서 관리를 하게 됩니다.
    유니티에서는 'Boehm-Demers-Weiser' 알고리즘을 통해 GC(가비지 컬렉터)작업을 하게 됩니다.
    'Mark and Sweep' 인것은 같으나 세대 구분이 없고 메모리 정렬도 필요없습니다.
    때문에 19 버전 이상에서 제공하게 되는 점진적 GC(가비지 컬렉터) 작업을 활용하거나 오브젝트 풀링 등의 기법을 활용해서 최대한 최적화를 해줘야 할 필요가 있습니다



    - 코루틴 -
    C#과 Unity에서 코루틴은 비동기, 시간 경과에 따라 또는 작은 단계로 실행되는 코드를 생성하는 데 사용할 수 있는 특수한 유형의 반복자 메서드입니다.
    코루틴을 사용하면 복잡한 다단계 작업을 더 작은 코드 조각으로 분할하여 독립적으로 실행하고 보다 제어된 방식으로 실행할 수 있습니다.

     

    정리 : 유니티에서 코루틴이란 작업을 다수의 프레임에 분산하여 작업할 수 있게 만들어주는 메서드 입니다.



    - 싱글톤 패턴이란? -
    오직 한개의 클래스 인스턴스만 갖도록 보장하고, 이에 대한 전역적인 접근점을 제공합니다.
    단 하나만 존재하는 오브젝트를 손쉽게 쓸 수 있는 필요가 있을때 사용합니다.

    단점
    모든 곳에서 접근이 가능하므로 싱글톤 객체의 변경 시점, 변경 주체, 호출 시점을 모두 알기가 어렵습니다.
    하나의 코드를 수정했을때, 싱글톤과 연결된 다양한 곳들에서 문제가 발생합니다.



    - FSM 패턴이란 ? -
    상태를 기반으로 동작을 제어하는 방식을 구현하기위한 디자인 패턴입니다.
    FSM의 핵심은 단 하나의 상태만을 가진다는 점입니다.
    상태를 기준으로 어떤 동작을 수행할지 결정하기 때문에 현재 상태만 알 수 있으면 어떤 동작을 수행하려 하는지 명확히 파악할 수 있고 구현이 쉽다는 장점이 있습니다.

    단점
    상태가 많아지면 각 상태의 전이를 관리해줘야 하기 때문에 코드가 복잡해 질 수 있습니다.
    현재 상태는 하나만 존재하므로 병렬 상태처리가 어렵습니다. 예를들어서 공격하면서 점프와 같이 두상태가 동시에 존재해야하는 경우가 있습니다.


     

    - 직렬화 - 

    직렬화는 특정 객체를 바이트 단위로 변경한 뒤 디스크에 저장하거나 네트워크로 보낼 수 있게 만들어주는 것입니다.

     

    사용 이유 : 직렬화의 경우에는 현재 사용하고 있는 데이터에 대해서 영속성을 부여하기 위해 사용됩니다.

    영속성 : 프로그램을 종료하더라도 사라지지 않는 특성


     

    - 람다식 -

    람다식은 익명 함수를 간결하게 선언하는 방법입니다. 메서드처럼 입력 매개변수를 받고, 실행할 내부 코드를 가지지만 이름은 없습니다.


     

    - 제네릭 -

    제네릭은 데이터 형식을 일반화하여 다양한 형식의 데이터를 처리하는 메서드나 클래스 등을 작성할 수 있는 기능입니다

    재사용성과 유연성을 향상시켜줍니다.

     

    언제 사용 ? : 여러 데이터 형식에 대해 동일한 로직을 적용해야할 때 사용됩니다. 주로 싱글톤 패턴에서 여러 클래스가 상속 받아 사용해야 할 때 적용했습니다.

     

    제약 조건 : 클래스나 메서드가 특정 동작을 수행하거나 특정 타입에 대한 조작을 할 수 있도록 제약을 걸고 Where 키워드를 사용합니다. 


     

    - 힙, 스택 -

    스택

    1. 잠깐 사용하고 삭제하는 데이터를 저장합니다.

    2. 해당 객체가 정의된 블록을 벗어날 때 소멸됩니다.

    3. 힙보다 빠릅니다

    4. 메모리의 끝에서부터 주소를 채워간다.

     

    1. 가비지 컬렉터가 없으면 프로그래머가 직접 관리 해줘야 합니다.

    2. 스택보다 큰 메모리를 할당받기 위해 사용됩니다.

    3. 스택보다 느립니다.

    4. 메모리 앞에서부터 주소를 채워간다.


     - 게임 최적화 방법 -
    문자열 연산을 반복할때 StringBuilder 클래스를 사용합니다.
    string 개체를 변경하면 새로운 String 개체가 생성되는 성질때문에 문자열 연산을 반복적으로 수행하면 메모리 낭비가 심해집니다.
    StringBuilder 클래스는 문자열을 수정할 때 새로운 객체를 생성하지 않고 기존 객체를 변형하기 때문에 문자열 연산을 반복하는 작업에서 StringBuilder를 사용해야합니다.

    Update() 함수를 피해야 합니다. 매 프레임 마다 호출되는 Update 함수보다는 코루틴 함수를 사용해 불필요한 호출을 피해야 합니다.

    나눗셈보다는 곱셈을 사용해야합니다. 나눗셈은 곱셈보다 연산속도가 월등히 느리기 때문입니다.

    오브젝트 풀링 기법을 사용하여 메모리 관리를 해야합니다. 동적 생성 및 해제는 부하가 굉장히 큰 작업이기 때문에 활성화/비활성화로 사용합니다. 

    DrawCall 줄여야 합니다. Batching 시스템을 사용해야 합니다. 서로 다른 메시에서 같은 메터리얼을 쓰는 경우 Unity에서는 해당 Mesh 정보를 하나로 합쳐서 Draw Call 1개로 처리합니다.
    또한 움직이지 않는 정적인 오브젝트의 경우 Static 체크를 통해 하나의 메시로 만들어서 처리합니다.

    Draw Call은 CPU가 GPU에게 무엇을, 어떻게 그릴지 정해주고 그리라고 명령하는 것입니다.
    다시 말해 하나의 mesh와 하나의 material로 하나의 Draw Call이 발생합니다.

     

    텍스쳐 아틀라스를 사용해 이미지를 한 묶음으로 만듭니다.

    텍스쳐들을 하나로 묶어주면 메터리얼들을 일괄적으로 처리 가능하며 Draw Call을 줄일 수 있습니다.

    반응형

    '면접준비' 카테고리의 다른 글

    유니티 클라이언트 면접준비 - 예상 질문  (0) 2024.01.26
Designed by Tistory.