본문 바로가기

이론(면접)

LINQ

#define EXAPLE_TYPE_LINQ
//#define EXAPLE_TYPE_THREAD
//#define EXAPLE_TYPE_YUPE_FILE_SYSTYEM


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
using System.Linq;
using System.IO;
//파일과 데이터 스트림에 대한 읽기 및 쓰기를 사용하기 위함
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;

#region
/*
  



* 유니티 면접 질문
1. 코루틴 => 무조건 물어봐
2. 태스크
3. 회전(오일러, 쿼터니언까지 들어가면 피곤해져..)
4. 내부 구조(C#)
5. 문자열 시리즈



* 링크
링크?(Languafe Intergrated Query)는 언어에 통합된 쿼리문을 의미하는 것.
링크를 사용하면 컬렉션을 대상으로 데이터 베이스에 요청하는 것처럼 쿼리문을 실행 가능.
ㄴ 즉, 링크를 활용하면 데이터의 필터와 작업을 더 수월하기 하는 것이 가능



* C# 언어 링크의 특징
링크는 언어에 내장된 쿼리문이기 떄문에 간단한 쿼리문 작성을 통해 쉽게 필터링하는 것이 가능
데이터의 탐색에 대한 효월성이 극대화된다.

링크는 항상 from 키워드를 통해 시작되면 select 키워드를 통해 최종적인 데이터를 필터링하는 것이 가능.
링크는 group 키워드를 통해 특정 데이터를 두 가지로 그룹화시키는 것이 가능하다.



* 스레드란? (면접 질문)
운영체제가 CPU 시간을 할당하는 기본 단위로서 프로세스는 반드시 하나 이상의 스레드를 지니고 있다.
즉 스레드가 CPU 시간을 할당 받아서 동작하기 때문에 스레드가 정지된다면 해당 프로그램은 더 이상 동작하지 안흔ㄴ다.



* C#언어 스레드의 특징
C# 언어의 스레드를 활용하면 병렬 처리 로직을 구성하는 것이 가능하다.
병렬 처리: 동시에 여러 작업을 수행하는 것
C#언어는 lock 키워드를 통해 '크리티컬 섹션'을 처리하는 것이 가능하다.
C# 언어의 스레드는 내부적으로 '라이프 사이클'이 존재한다.




* 프로세스란?
실행 중인 프로그램을 의미한다.
프로그램이란 단순히 CPU가 처리할 수 있는 명령어의 집합인 파일을 의미하며 이 명령어를 CPU가 처리할 수 있게 메모리 상에 적재되어 있을 경우 이것을 프로세스라 한다.



* 스레드와 프로세스를 통한 병렬 처리 로직의 차이점
스레드: 하나의 프로세스에서 병렬처리가 됨
프로세스: 새로운 프로세스를 생성해서 병렬 처리를 수행하는 것이 가능하다.
둘이 차이가 있다!!
=> 스레드를 통한 병렬처리는 내부적으로 데이터를 간단하게 공유할 수 있는 반면 프로세스는 일반적인 방식으로는 데이터를 공유하는 것이 불가능하다.
=> 스레드는 간편하게 데이터를 공유할 수 있지만 CPU의 구조적인 특징과 프로그래머의 실수로 인해 잘못된 결과를 만들어 낼 여지가 다분하다.



* 게임에서 스레드가 필요한 순간
1. 로딩(네트워크 통신 포함)

결론: 일반적으로 하나의 프로세스는 하나의 스레드를 가지고 작업을 수행한다.



* 태스크?(Task)
요약: C#의 대표적인 멀티스레드를 지원하는 클래스
멀티스레드를 지원하기 위해 추가된 클래스로 멀티스레드에서 비동기 작업을 수행한다.
멀티스레드란?: 하나의 프로세스에서 둘 이상의 스레드가 동시에 작업을 수행하는 것을 의미한다.

동기 프로그래밍: 프로그램이 실행되는 도중 어떤 작업을 요청하면 그 작업이 종료될 때까지 기다렸다가 다음 작업을 하는 것.
                동기 방식은 요청과 결과가 동시에 일어나기 때문에 설계가 간단하고 직관적이지만 작업이 완료될 때까지 프로그램이 대기해야 한다.

비동기 프로그래밍: 프로그램이 실행되는 도중 어떤 행위를 요청한 뒤 그 결과는 기다리지 않고 다음 동작을 하는 것.
                 비동기 프로그래밍은 설계 단계에서 동기보다 복잡하고, 요청한 작업이 완료될 때는 별도로 확인을 해야 하지만, 요청한 자료가 오래 걸린다고 하더라도 다른 작업을 수행할 수 있기 때문에 자원을 보다 효율적으로 사용하는 것이 가능하다.



*파일 시스템이란?

*/
#endregion



public class Example_04 : MonoBehaviour
{


    public void Awake()
    {
#if EXAPLE_TYPE_LINQ

        var oCharacterList = new List<STCharacter>();

        oCharacterList.Add(new STCharacter(1, 100, 15));
        oCharacterList.Add(new STCharacter(2, 150, 25));
        oCharacterList.Add(new STCharacter(3, 250, 35));
        oCharacterList.Add(new STCharacter(4, 350, 45));
        oCharacterList.Add(new STCharacter(5, 450, 55));



        /*
        링크 기본 형태 부가 설명


        from : 모든 쿼리식은 from으로 시작해야 한다.
        ex) from 범위 변수 in 데이터 변수
        

        where: 데이터의 원본으로부터 차례대로 요소를 가져오고 그 요소가 범위 변수에 들어가게 되면 조건식을 통해 걸러내는 역할
               만약 요소에 대해 조건식 거짓이면 요소를 반환하지 않고 참이면 요소를 반환한다.
               필터와 같은 역할이라 생각하면 편하다!
        ex) where 조건식
         
        
        orderby: 데이터의 정렬을 수행하고 오름차순 혹은 내림차순으로 정렬된 결과를 출력하겠다.
                 기본적으로 링크는 오름차순 정렬을 하며 ","(콤마)를 통해 둘 이상의 데이터를 한꺼번에 정렬시킬 수 있다.
                 오름차순일 경우 ascending 키워드를 뒤에 붙이며 내림차순일 경우 descending 키워드를 뒤에 붙인다.


        select: 앞에 있는 모든 절과 select 절을 거쳐서 나오는 최종 결과를 뽑아낸다.
                기억해야 될 부분은 LINQ 쿼리식은 from으로 시작했으면 select절 또는 group으로 끝나야만 한다.



        group: 분류 기준에 따라 데이터를 ㅂㄴ류하고 그룹화하여 그룹 개체를 반환한다.
               우리가 모양에 따라, 색깔에 따라, 맛 등의 기준에 따라 나누듯 LINQ 쿼리식에서도 group절을 이용하여 데이터를 분류할 수 있다.


        join: 직접 관계가 없는 두 개의 데이터 원본을 연결할 때 사용한다.
        
         */


        //링크 기본 형태 ㄱ
        var oResult = (from STCharacter in oCharacterList
                       where STCharacter.m_nHP >= 250 || STCharacter.m_nLevel >= 20
                       orderby STCharacter.m_nLevel ascending
                       select STCharacter).ToList();

        for (int i= 0; i < oResult.Count; i++)
        {
            var stCharacter = oResult[i];

            Debug.LogFormat("캐릭터 정보: {0}, {1}, {2}", stCharacter.m_nID, stCharacter.m_nHP, stCharacter.m_nLevel);
        }


        //추가적으로 쿼리 작업을 수행하려면 into 키워드를 사용해야 한다.
        //그렇지 않은 경우에는 into와 그룹 변수를 쓰지 않아도 된다.
        var oGroupResult = (from stCharacter in oCharacterList
                            where stCharacter.m_nHP >= 250 || stCharacter.m_nLevel >= 20
                            orderby stCharacter.m_nLevel ascending
                            group stCharacter by stCharacter.m_nHP >= 250 into oGroup
                            select new
                            {
                                GroupKey = oGroup.Key,
                                Characters = oGroup
                            }).ToList();


        for(int i=0; i< oGroupResult.Count; i++)
        {
            var oGroup = oGroupResult[i];
            var oCharacters = oGroup.Characters.ToList();

            for(int j=0; j< oCharacters.Count; i++)
            {
                var stCharacter = oCharacters[j];
                Debug.LogFormat("Key: {0}, Character: {1}, {2}, {3}", oGroup.GroupKey,
                    stCharacter.m_nID, stCharacter.m_nHP, stCharacter.m_nLevel);
            }
        }

#elif EXAPLE_TYPE_THREAD
#else 
#endif
    }


#if EXAPLE_TYPE_LINQ
    
    struct STCharacter
    {
        public int m_nID;
        public int m_nHP;
        public int m_nLevel;

        public STCharacter(int a_nID, int a_nHP, int a_nLevel)
        {
            m_nID = a_nID;
            m_nHP = a_nHP;
            m_nLevel = a_nLevel;
        }
    }





#elif EXAPLE_TYPE_THREAD
#else
#endif

}

'이론(면접)' 카테고리의 다른 글

Framework  (0) 2022.07.05
Attribute  (0) 2022.07.01
SendMessage (ray)  (0) 2022.07.01
변수 표기법  (0) 2022.06.30
배열 / 정적 클래스 / 확장메서드  (0) 2022.06.29