면접 예상 질문 목록 정리


C#


  • 인터페이스와 추상, 가상함수

    • Virtual (가상 키워드)

      virtual 키워드는 메서드,속성, 인덱서 또는 이벤트 선언을 한정하는데 사용됩니다.파생 클래스에서 필요에 따라서 재정의(override) 할 수 있지만  필수적으로 재정의 할 필요는 없습니다.Virtual 한정자를 사용한 클래스는 완벽한 기능을 제공할 수 있습니다.


    • Abstract (추상 키워드)

      abstract 키워드를 사용하면 불완전하여 파생 클래스에서 구현해야하는 클래스 및 클래스 멤버를 만들수 있습니다.추상클래스의 사용 목적은 여러개의 파생 클래스에서 공유할 기본 클래스의 공통적인 정의를 제공하는 것입니다. 추상 클래스는 인스턴스화할 수 없습니다.


    • Interface (인터페이스)

      인터페이스는 abstract와 비슷하지만 멤버필드(변수)를 사용할 수 없습니다. 대신에 프로퍼티는 사용이 가능합니다.인터페이스는 보통 여러클래스에 공통적인 기능을 추가하기 위해서 사용합니다.


  • 구조체와 클래스 (구조체 필드의 합이 16byte를 넘는다고 힙 할당 되지 않습니다!)

    구조체와 클래스는 코드 상으로는 전체적으로 비슷하지만, 구조체는 상속을 할 수 없고 클래스는 상속이 가능합니다. 그리고 클래스 객체는 힙에 할당되지만 구조체 객체는 스택에 할당됩니다. 하지만 구조체로 선언하였어도 힙에 할당되는 경우가 있는데, 모든 필드의 합이 16바이트가 넘을 때와 구조체 안에 클래스 타입의 필드를 가질 경우입니다.

  • 상속(Inheritance)과 다형성

    사람을 예를 들어 설명하자면, human이라는 클래스를 만든다고 할때 이 안에 예를 들어 박지성, 류현진, 송강호 등 다양한 직업을 모두 표현하기 위해 새로운 클래스를 만들어 설정하지 않고, human이라는 객체를 기반으로 하고,이를 상속 받아 soccerplayer나 baseballplayer 또는 actor라는 클래스에 각각의 부가 기능을 추가하고 재정의하면 됩니다. 이러한 객체를 사용하므로써 각각의 객체가 아니라 human이라는 객체로 간주하여, 형변환을 통해 사람이라는 기반 클래스로 파생클래스 전부를 컨트롤 할 수 있습니다.


  • 유니티와 C#의 관계 C#으로 작성되어 엔진 속도가 느릴 것이라는 것과는 다르게 유니티 개발진은 유니티는 C++로 작성되고 .NET API를 노출시켜서 에디터에서 C#으로도 프로그래밍할 수 있게 한 것입니다.


  • 배열과 리스트

둘의 차이점은 일단 배열은 동적으로 할당이 불가능하고 리스트는 가능한 것입니다. 배열의 장점은 연속된 메모리 공간으로 이루어져 있어 인덱스로 접근 시 빠르게 해당 값을 찾을 수 있습니다. 리스트는 포인터를 사용하여, 다음 데이터의 주소 값을 가지고 있기에 데이터 추가/삭제가 용이합니다. 그 말은 즉슨 데이터 크기를 동적으로 할당할 수 있다는 것입니다.


  • namespace, partial

namespace 키워드는 관련 개체 집합을 포함하는 범위를 선언하는 데 사용됩니다. 네임스페이스를 사용하여 코드 요소를 구성하고 전역적으로 고유한 형식을 만들 수 있습니다. 이 안에는 클래스 또는 인터페이스 구조체 또는 enum 등 다양한 형식을 선언할 수 있습니다. paticial 클래스는 대규모 프로젝트를 진행하는 경우 스크립트를 분할하는 역할을 합니다.


  • 객체지향(추상화, 캡슐화, 상속성, 다형성)
    • 추상화

      공통의 속성이나 기능을 묶어 이름을 붙이는 것입니다.

    • 캡슐화

      데이터 구조와 데이터를 다루는 방법들을 결합시켜 묶는 것입니다.(변수화 함수)

    • 상속성(재사용)

      상위 개념의 특징을 하위 개념이 물려받는 것입니다.

    • 다형성

      부모클래스에서 물려받은 가상 함수를 자식 클래스 내에서 오버라이딩되는 것입니다.


  • 지역변수와 전역변수

    지역 변수는 함수 내에서 선언되고 함수 내에서 작동합니다. 전역 변수는 함수 밖에서 선언되고 프로그램 전체에서 작동합니다. 지역 변수는 기능 블럭이 입력되고 종료될 때 파괴되지만 전역 변수는 프로그램이 실행되는 동안 존재됩니다. 저장은 지역 변수는 지정하지 않으면 스택, 전역 변수는 컴파일러가 결정한 고정 위치에 저장됩니다.


  • delegate와 event 차이

    가장 큰 차이점은 이벤트는 인터페이스 내부에 선언할 수 있지만 델리게이트는 선언할 수 없다는 점입니다. 델리게이트는 반드시 메서드를 참조 시켜야하고, 정의한 형식에 맞아야 합니다. 이벤트는 델리게이트를 통하여 구현하고, 하나의 이벤트는 여러개의 작업들을 추가 될 수 있어야 합니다. 이벤트는 델리게이트를 캡슐화시킨 것과 비슷합니다.


메모리


  • 힙 할당 되는 케이스와 아닌 케이스

    C# 기준으로는 new로 할당되는 모든 참조형 객체는 힙에 할당됩니다. 그 외의 지역 변수 매개 변수 저장은 스택이 합니다. (스택 정적 할당 , 힙 정적 할당)


  • C# 박싱과 언박싱

    박싱은 값 타입의 객체를 참조 타입으로 변환하는 작업이고 반대로 언박싱은 참조 타입 객체를 값 타입으로 변환하는 작업입니다.


  • 오브젝트 타입에 밸류 타입을 대입하면 생기는 일

    벨류를 레퍼런스타입으로 박싱한다. 스택에 있던 벨류를 힙으로 복사 후 주소값을 할당합니다.


  • 가비지에 대하여

    가비지 콜렉터는 사용하지 않는 메모리를 힙의 메모리가 가득차면 자동적으로 회수합니다.


  • C#에서 Struct는 가비지컬렉터가 도는지?

    값 타입이기 때문에 스택 영역에 메모리가 할당되고, 힙 영역에 생성되는 것이 아니기에 가비지 콜렉터는 돌지 않습니다.


  • LOH, SOH (라지 오브젝트 힙, 스몰 오브젝트 힙)

    가비지 콜렉션 방식으로 85KB 기준으로 작으면 SOH 크면 LOH가 관리합니다. SOH는 가비지 콜렉션이 발생하면 해제된 메모리 공간들에 사용중인 메모리들로 재배치하지만 LOH는 메모히 해제를 해도 해제된 공간은 그대로 둡니다. SOH는 0~3세대로 나눠서 메모리를 관리하고 LOH는 2세대밖에 존재하지 않습니다. 그래서 2세대 가비지 콜렉션이 일어날 때에만 사용하지 않는 메모리를 해제시킵니다.


유니티에 대한 이해


  • 코루틴과 Invoke

    어떠한 작업을 처리할 때 필요에 따라 시간 간격을 두고 작업을 처리할 수 있도록 도와주는 함수입니다. 메인 루틴과 함께 호출되어 실행한다. (IEnumerator, yield return)


  • 게임루프와 델타 타임에 대한 이해

    게임 루프는 게임이 시작되고 나면 update와 render가 반복적으로 도는 것입니다. update에는 update input, actor states, graphics states, physics, networking, user interface, audio, coroutines 등 다양한 기능들이 있습니다. 델타 타임은 유니티에서 update 함수가 매 프레임 도는데, 한 프레임 당 실행하는 시간을 뜻합니다. 성능이 좋을수록 델타타입이 짧고 않좋을수록 깁니다.


  • CLR 과 CIL

    Common Language Runtime, 공통 언어 런타임로 CIL CODE를 NATIVE CODE로 컴파일해주는 가상 머신입니다. CILD은 공통 중간 언어로 닷넷 고유의 객체지향 어셈블리 언어 입니다. 닷넷 환경에서 타켓 플랫폼에 관계 없이 자유롭게 개발할 수 있도록 도와주는 기능을 합니다.


  • Mono와 IL2CPP

    MONO와 IL2CPP는 CIL CODE를 NATIVE CODE로 컴파일해주는 스크립팅 백엔드입니다. 닷넷 프레임워크에서 CLR이 수행하는 역할을 유니티에서 해주는 기능을 합니다. MONO는 CIL CODE를 NATICE CODE로 변환해주고, IL2CPP는 CIL CODE를 .NET NATIVE CODE로 변환해줍니다. 이 중에서 IL2CPP는 유니티 자체 개발입니다. MONO가 IL2CPP보다는 빠르고 성능과 보안성은 IL2CPP가 MONO보다 좋습니다.


  • Update, FixedUpdate, LateUpdate, Awake, Start, OnEnable, OnDisable, OnDestroy

    유니티 LIFE CYCLE에 대해서 알아야되는데 먼저 AWAKE - START(시작) - ONENABLED(객체가 활성화 될 때 호출하는 함수) - 1회 호출되는 함수(초기화) - FIXEDUPDATE(고정된 프레임 주기로 실행) - ON TRIGGER - ONCOLLISION - UPDATE(매 프레임마다 실행) - LATEUPDATE(업데이트 다음) - ONDISABLE - ONDESTROY - ONAPPLICATIONQUIT(종료)


최적화


  • 배칭

    배칭은 여러 개의 batch를 하나로 묶는 최적화 기법인데, 크게 두가지 정도로 정적/동적 배칭으로 나뉩니다. 여기서 정적 배칭은 런타임에 움직이지 않는 메시들에 대해서만 가능합니다. 여러 개의 메시를 하나로 통합하고, 메시를 통합한 만큼, 하나의 배치로 그려줄 수 있습니다. 사용 방법은 인스펙터에서 batching static 플래그를 설정하면 됩니다. 장점은 static batching이 되더라도 컬링 연산은 원래의 메시 기준으로 이루어진다는 장점이 있습니다. 동적 배칭은 유니티에 의해 내부적으로 자동으로 수행되고, 플레이어 설정에서 dynamic batching 옵션을 켜주면 됩니다. 실제로는 제약이 너무 많아 최적화를 기대하기는 힘들고 버텍스가 300개 이상의 메시에 대해서는 적용되지 않습니다.


  • 유니티에서의 세대별 가비지 컬렉션

    세대별 가비지 컬렉션은 메모리를 세대별로 나누어 상대적으로 오래 잔재하는 메모리에 대해 적은 빈도의 추적을 수행하게 됩니다. 0~2세대로 나뉘고 메모리를 할당하는 시점에 새로운 세대로 이를 배치하게 되며, 여러 번의 가비지 컬렉션에도 해제되지 않았을 땐 뒷 세대로 이동하게 됩니다.


  • 드로우 콜과 배치

    드로우 콜은 오브젝트가 실제 화면에 렌더링 되려면 cpu가 가지고 있는 정보들이 gpu에 전달 되어야하므로 이러한 정보들을 전달한 뒤, cpu가 gpu에 렌더링하라고 명령을 보내는 것입니다. 배치는 dp 콜과 setpass 콜을 합친 것으로 render state changes가 아니라 set pass를 포함하고 있기에 드로우 콜보다는 좁은 의미를 가집니다. 배치는 메시 변경을 포함하지 않습니다. 메시가 달라도 메테리얼이 같으면 하나의 배치로 통합할 수 있습니다.


  • 스크립팅 최적화

    • SendMessage 와 BroadcastMessage 함수 사용자제

    • Find 관련 함수 사용자제

    • 자식이 많은 오브젝트 transform 변경시 많은 비용 발생

    • Update , LateUpdate 등 함수가 비어있으면 지워라 , 빈 Update 종류 함수는 비용발생

    • Vector2 및 Vector3 연산을 줄여라

    • Camera.main 의 결과를 캐싱 하거나 사용하지 않고 수동으로 카메라에 대한 참조를 관리해라


  • 가비지 컬렉터(힙 메모리) 최적화

    • 캐싱 사용

      우리 코드가 힙 할당으로 이어지는 함수를 반복적으로 호출하고 결과를 폐기하면 불필요한 쓰레기가 생성됩니다. 대신, 우리는 이러한 객체에 대한 참조를 저장하고 재사용하는 기술을 캐싱이라고 합니다.

    • 자주 호출되는 함수에는 힙메모리 할당을 하지 않는다.

    • 오브젝트 풀링 사용

    • 문자열 관련

    1) 필요한 문자열 생성을 줄여야합니다. 동일한 문자열 값을 두 번 이상 사용하는 경우 문자열을 한 번 만들고 값을 캐시해야합니다.

    2) 우리는 불필요한 문자열 조작을 줄여야합니다. 예를 들어 자주 업데이트되고 연결된 문자열이 포함 된 텍스트 구성 요소가있는 경우 두 개의 텍스트 구성 요소로 구분할 수 있습니다.

    3) 런타임에 문자열을 작성해야 한다면 StringBuilder 클래스를 사용해야 합니다.

    4) 디버깅을 위해 더 이상 필요하지 않게 되면 Debug.Log ()에 대한 호출을 제거해야 합니다.

    • 함수 관련

    1) GameObject.tag 대신 GameObject.CompareTag 사용하기

    2) Input.GetTouch 와 Input.touchCount 대신 Input.touches 사용하기

    3) Physics.SphereCastNonAlloc 대신 Physics.SphereCastAll 사용하기

    • 박싱으로 이어지는 함수 호출 제거

    • 코루틴 함수 관련

    1) StartCoroutine 을 사용할때 약간의 가비지가 발생한다.

    2) yield new return 에서 new 를 할때마다 가비지가 생성 된다.

    • foreach 문 자제

    • 수동으로 가비지컬렉터 실행 자제


  • 그래픽 관련 최적화

    • CPU의 작업량을 줄이는 방법

      1. 가까이에 있는 오브젝트를 수동이나 Unity의 드로우 콜 배칭을 활용해 결합합니다.

      2. 큰 텍스처 아틀라스에 개별적 텍스처를 넣는 등의 방법으로 오브젝트의 머터리얼 수를 줄입니다.

      3. 오브젝트가 여러 번 렌더링되는 요소(반사, 그림자, 픽셀 별 광원 등)를 덜 사용합니다.

    • GPU 모델 지오메트리 최적화

      1. 필요 이상으로 삼각형을 사용하지 않습니다.

      2. UV 매핑의 경계 부분과 하드 에지의 수를 가능한 적게 유지합니다.

    • 조명 퍼포먼스

      1. 전역 조명을 베이크라고 라이트 매퍼를 사용
    • GPU : 텍스처 압축과 밉맵

      1. 3D 씬에서 사용되는 텍스처에 항상 밉맵 생성을 활성화
    • 실시간 섀도우

      1. 실시간 섀도우 사용을 줄인다.


  • 기타 최적화 방법

    프로파일링을 통해 어디서 과부하가 생기는지 확인

    • 에셋 관련

      • 텍스처

        1. Read/Write enabled 플래그 비활성화 (기본 비활성화)

        2. 밉맵(하지만 그래픽적인 차이가 좀 있음 그러므로 상황봐서)

        3. 모든 텍스처를 압축

      • 모델

        1. Read/Write enabled 플래그 비활성화(기본 활성화)

        2. 애니메이션화되지 않는 모델의 리그를 비활성화

        3. 애니메이션화되는 모델에 게임 오브젝트 최적화 옵션 활성화

        4. Optimize Game Objects 활성화

        5. 가능한 한 메시 압축 사용

    • 힙 메모리 관련

      1. 오브젝트 풀링 사용

      2. 박싱을 최대한 피해야 한다.

        ex) - enum 타입을 Dictionary 의 키로 사용하면 박싱이 발생한다.

      3. Foreach 루프문 사용시 루프가 종료되는 시점마다 박싱이 발생했었다.(몇번 반복하든 foreach 문 하나당 한번씩)

        버전 업그레이드를 하면서 Foreach문의 박싱은 사라졌지만 CPU 성능에 차이가 있다.(결론은 아무튼 자제 하는게 좋다.)

      4. 배열 기반 Unity API

    • Resources 폴더사용 하지 말고 AssetBundle 을 사용하자.

    • 기타

      1. 부동 소수점보다 정수 연산의 속도가 빠르며, 부동 소수점 연산의 속도가 벡터, 매트릭스 또는 쿼터니언 연산보다 빠르다

      2. Object.Find와 Object.FindObjectOfType의 사용을 모두 제거하는 것이 일반적으로 가장 좋다.(싱글톤은 예외)

      3. 일차원 배열 사용, 다차원 배열이 필요한 경우 다차원 배열 말고 가변 배열을 사용

      4. 적은 콜백 함수 사용 (Update, FixedUpdate, LateUpdate 같은)

      5. 델리게이트 사용시 추가 제거가 자주 일어난다면 다른 데이터 구조 사용을 고려


    • 게임을 더 빠르게 만드는 체크리스트

      1. PC 용으로 빌드할 때(타겟 GPU 에 따라) 버텍스 수를 프레임당 200K 및 3M 아래로 유지합니다.

      2. 빌트인 셰이더를 사용하는 경우 Mobile 이나 Unlit 의 카테고리에서 선택합니다.

      3. 비모바일 플랫폼에서도 작동은 하지만 복잡한 셰이더를 단순화시키고 비슷하게 만듭니다.

      4. 씬 별로 서로 다른 머티리얼의 수를 적게 유지하고 다른 오브젝트 간에 최대한 많은 머티리얼을 공유합니다.

      5. 움직이지 않는 오브젝트에는 Static 프로퍼티를 설정하여, 정적 배칭과 같은 내부 최적화가 가능하도록 해야 합니다.

      6. 다수 보다는 단일(가능하다면 방향성) pixel light 만 지오메트리에 영향을 주도록 해야 합니다.

      7. 동적 조명을 사용하기보다 조명을 베이크해야 합니다.

      8. 가능하면 압축 텍스처 사용하고 32 비트보다는 16 비트를 사용해야 합니다.

      9. 가능하면 안개의 사용을 피해야 합니다.

      10. 오클루전 컬링을 사용하여 오클루전이 많아 복잡한 정적 씬에서 드로우 콜과 가시적 지오메트리를 줄이는 데 활용합니다.

      11. 오클루전 컬링을 염두에 두고 레벨을 디자인합니다.

      12. 스카이박스를 써서 멀리 있는 지오메트리를 “진짜처럼 보이게” 합니다.

      13. 멀티 패스 접근 방식 대신 픽셀 셰이더나 텍스처 컴바이너를 활용해 여러 텍스처를 혼합합니다.

      14. 가능하면 half 정밀도 변수를 사용합니다.

      15. 픽셀 셰이더에서 pow, sin, cos 등 복잡한 수학 연산의 사용을 최소화합니다.

      16. 프래그먼트 별 텍스처 사용을 줄입니다.


컴퓨터 구조


  • 프로세스와 스레드

    프로세스와 스레드는 개념의 범위부터 다릅니다. 스레드는 프로세스 안에 포함되어 있기 때문입니다. OS가 프로세스에게 CODE/DATA/STACK/HEAP 메모리 영역을 할당해 주고 최소 작업 단위로 삼는 반면, 스레드는 프로세스 내에서 STACK 메모리 영역을 제외한 다른 메모리 영역을 같은 프로세스 내 다른 스레드와 공유합니다. 프로세스는 다른 프로세스와 정보를 공유하려면 IPC를 사용하는 등의 번거로운 과정을 거쳐야 하지만, 스레드는 기본 구조 자체가 메모리를 공유하는 구조이기 때문에 다른 스레드와 정보를 공유하기 쉽습니다. 다만 스레드의 스케줄링은 OS가 처리하지 않기 때문에 프로그래머가 직접 동기화 문제에 대응할 수 있어야 합니다.


  • API란?

    API는 애플리케이션 프로그래밍 인터페이스의 약자로, 운영체제가 응용프로그램 개발 또는 동작을 위해 제공하는 함수의 집합이라고 할 수 있습니다. 다시 말하면, API는 어플리케이션을 만들기 위한 하위 함수, 프로토콜, 도구들의 집합을 말합니다. 좋은 API는 프로그래머들이 쉽게 소프트웨어를 개발할 수 있도록 도와주며, 운영체제, 데이터베이스, 하드웨어,소프트웨어 라이브러리나 웹 기반 시스템 등 다양한 곳에서 만들어집니다.


  • 값 형식과 참조 형식

    값 형식은 변수가 값을 담는 데이터 형식이고, 참조 형식은 변수가 값 대신 값이 있는 곳의 위치를 담는 데이터 형식입니다. 값 형식의 변수는 모두 스택에 저장되고 참조형식은 힙에 저장됩니다.


  • 메모리구조 (코드영역, 데이터영역, 힙 영역, 스택 영역)

    메모리 구조에는 네 가지 영역이 있는데, 코드, 데이터, 힙, 스택 영역이 있습니다. 코드 영역은 코드를 실행하기 위해 제어문, 함수, 상수 등 명력문들이 저장되어 있는 영역입니다. 데이터 영역은 작성한 코드에서 전역변수, 정적변수 등이 저장되는 영역입니다. 이들의 특징을 보면 메인 함수 전에 선언되어 프로그램이 끝날 때까지 메모리에 남아있는 변수들이라는 특징이 있습니다. 힙 영역은 사용자에 의해 관리되는 영역입니다. 동적으로 할당 할 변수들이 여기에 저장됩니다. 자바나 C++에서 NEW 연산자로 생성하는 경우 또는 클래스나 참조 변수들고 HEAP 영역에 차지하게 됩니다. 스택 영역은 함수를 호출할 때 지역변수, 매개변수들이 저장되는 공간입니다. 메인 함수안에서 변수들도 포함됩니다. 함수가 종료되면 해당 함수에 할당된 변수들을 메모리에서 해제시킵니다.


  • 리스트, 딕셔너리, 큐, 스택, SortedList, LinkedList

    자료구조에서 선형구조입니다. 선형 구조는 자료 뒤에 하나의 자료가 존재하는 것으로 자료들 같의 앞뒤 관계는 1:1 선형 관계 입니다. 반대로 비선형 구조도 있는데 트리, 그래프가 있습니다.


  • AOT와 JIT, 인터프리터

    AOT와 JIT은 컴파일러이다. 고급 프로그래밍 언어를 사용하면서 어셈블리로 번역해주는 작업을 하는 방식에는 두 가지가 있는데 하나는 컴파일러고 하나는 인터프리터입니다. 컴파일러는 프로그램 전체를 스캔하여 모두 기계어로 번역하고, 인터프리터는 프로그램 실행 시 한 번에 한 문장씩 번역합니다. AOT는 AHEAD OG TIME의 약자로 코드 실행 전에 바이트 코드를 기계어 코드로 바꾸는 컴파일러입니다. JIT는 JUST IN TIME의 약자로 코드를 런타임에 기계어로 번역합니다. 인터프리터와 비슷하지만 JIT가 컴파일 하는 대상은 소스 코드가 아니라 최적화를 거친 바이트 언어입니다.


  • 컴퓨터 구조에서 캐시 히트와 캐시 미스

    일단 캐시는 프로그램이 수행될 때 나타나는 지역성을 이용하여 메모리나 디스크에서 사용되었던 내용을 빠르게 접근할 수 있는 곳에 보관하고 관리하여서 이 내용을 다시 필요할 때 빠르게 불러올 수 있습니다. 이때 CPU가 참조하고자 하는 메모리가 캐시에 존재할 때 캐시 히트이고 존재하지 않는다면 캐시 미스입니다.


  • L1, L2, L3 캐시

    L1은 코어에 제일 가까이 있으며, 데이터 입출력 속도가 가장 빠릅니다. L2 캐시는 L1 캐시보다는 코어에서 멀리 존재하지만 그래도 메모리보다는 빠릅니다. L3 캐시는 L2 캐시보다는 멀리 있지만 메모리보다는 빠릅니다. L3가 없는 cpu도 많습니다. L1은 SRAM , L2와 L3는 DRAM을 사용합니다. DRAM과 ERAM을 사용하는 L4 캐시도 존재하기는 합니다.


  • 컨텍스트 스위칭

    컨텍스트 스위칭이란 스케줄러가 멀티프로세스 환경에서 CPU가 어떤 하나의 프로세스를 진행하고 있을 상태에서 인터럽트 요청에 의해 다음 우선 순위의 프로세스가 실행되어야 할 때 기존의 프로세스의 상태 또는 레지스터 값을 저장하고 CPU가 다음 프로세스를 수행하도록 새로운 프로세스의 상태 또는 레지스터 값을 교체하는 작업입니다. 입출력을 요청할 때, CPU 사용시간이 만료되었을 때, 자식 프로세스를 만들 때, 인터럽트 처리를 기다릴 때 등 다양한 경우에 일어납니다.


  • 콜스택

    콜스택은 프로그램에서 현재 실행 중인 서브루틴에 관한 정보를 저장하는 스택 자료구조입니다.


보안


  • PE구조

    윈도우에서 실행파일의 구조를 말한다. 종류는 실행파일, 라이브러리, 드라이브, 오브젝트 파일 계열이 있습니다. PE구조는 PE HEADER와 SECTION으로 나뉩니다.


  • 커널모드와 유저모드

    일단 커널은 운영체제의 핵심 부분으로 자원을 효율적으로 이용하기 위해서 CPU 스케줄링, 메모리관리, 입출력 관리, 파일 시스템 관리 등의 업무를 수행합니다. 이러한 커널에서 중요한 자원을 관리하기 때문에 사용자가 그 중요한 자원에 접근하지 못하도록 모드를 두가지로 나눕니다. 유저모드는 우리가 여기서 코드를 작성하거나 프로세스를 실행하는 등의 행동을 할 수 있고, 커널모드에서는 모든 자원에 접근, 명령을 할 수 있습니다. 두 모드간의 전환은 SYSTEM CALL로 전환할 수 있습니다.


  • IOCTL

    I/0 컨트롤의 줄임말로 디바이스 드라이버들과 통신하기 위해 사용됩니다. IOCTL이 디바이스를 위한 시스템 콜을 호출하여 디바이스를 동작시킵니다.


  • 드라이버

    운영체제와 디바이스가 통신할 수 있는 소프트웨어 구성 요소입니다.


  • 프로세스와 모듈, 스레드

    프로세스는 CPU에 의해 처리되는 프로그램으로 실행중인 프로그램을 의미하고, 스레드는 프로세스 내에서 실행하는 여러 흐름의 단위입니다. 한 프로세스 안에 존재하는 스레드들은 프로세스의 상태를 공유합니다. 모듈은 독립되어 있는 하나의 소프트웨어 또는 하드웨어의 단위를 지칭합니다.


그래픽스


  • 버텍스 셰이더와 픽셀 셰이더

    셰이더의 종류로 3가지의 셰이더가 있습니다. 버텍스 셰이더는 물체의 정점 정보에 수학적인 연산을 함으로써 물체에 특별한 효과를 주는데 사용합니다. 정점의 정보값들을 변화시켜 물체를 옮기거나 텍스처를 바꾸거나 색깔을 바꾸는 등의 작업을 수행하고 기존의 정점은 삭제하거나 추가 할 수는 없습니다. 픽셀 셰이더는 렌더링 될 각각의 픽셀들의 색을 계산하는 방식입니다. 오직 픽셀만을 연산하므로 주변의 픽셀이나 그리는 도형에 대한 정보를 알 수 없습니다. 마지막으로 지오메트리 셰이더가 있습니다. 버텍스 셰이더가 수행된 후, 수행됩니다. 버텍스 쉐이더를 거쳐온 도형 정보를 입력받아 출력합니다. 버텍스 셰이더가 할 수 없는 점이나 선 , 삼각형 등의 도형을 생성할 수 있습니다. 지오메트리 셰이더는 테셀레이션이나 그림자 효과, 큐브 맵을 한번의 처리로 렌더링 하는 데 주로 사용됩니다.


  • 포워드와 디퍼드 렌더링

    포워드 렌더링은 3d 공간에 존재하는 폴리곤을 픽셀화하여, 그 픽셀마다 쉐이딩과 라이팅 연산을 더하는 방식으로 묘사한합니다. 디퍼드 렌더링은 한화면에 수많은 라이팅 효과를 넣고 싶어 만든 기법으로 구현 방식은 픽셀화하여 포토샵의 레이어처럼 정보를 나누어 비디오 메모리에 저장합니다. 여기에서 각종 쉐이더와 라이팅 효과를 거쳐 화면에 보여줍니다.


  • 디더링

    디더링은 저해상도에서 컴퓨터 도형 처리의 사실감을 높이고 매끄럽지 못하고 계단 모양으로 울툴불퉁한 윤곽선이나 대각선을 눈에 띄지 않게 하기 위해 사용한다. 사용자 눈에 보이지 않는 작은, 인접한 여러 점에 다른 색을 섞어서 사용자 눈에 보이는 색깔을 만들어 사용자가 좀 더 사실감 있는 영상을 볼 수 있게 해줍니다.


  • 랜더링 파이프라인

    파이프라인의 모든 단계는 Direct3D api로 사용하여 구성할 수 있으며, HLSL 언어를 사용하는 프로그래밍이 가능하다. 일반적으로 Vertex Shader 단계와 Pixel Shader 단계에서 사용된다.


    • 입력 어셈블러(input assembler)

      메모리에 사용자가 채워놓은 기본데이터(삼각형, 선, 점)를 다른 파이프라인 단계에서 사용하기 위한 기본 형식으로 조립하는 단계


    • 꼭지점 셰이더 (Vertex Shader)

      변환(Transformation), 스키닝(Skinning), 조명(Vertex Lighting) 등의 작업을 수행한다. 이중 변환 작업 과정에 대해 설명하자면,
      [오브젝트 공간] -> 월드 변환 -> [월드 공간] -> 뷰 변환 -> [카메라 공간] -> 투영 변환 -> [클립 공간] 순으로 최종적인 정점을 생성한다.


      • 오브젝트 공간

        오브젝트 공간은 아직 변환이 되지 않은 폴리곤 메쉬들이 존재하는 공간을 말한다. 오브젝트 공간은 로컬 공간(Local Space)이라고도 한다.

      • 월드 변환

        월드 변환은 확대축소(scaling), 회전(rotation), 이동(translation)을 이용하여 정점을 변환한다. 행렬을 통해 계산되어 최종적으로 월드 공간의 정보로 변환하게 된다.

      • 월드 공간

        오브젝트 공간에서 월드 변환을 통해 월드 공간으로 변환된다. 월드 공간은 여러 메쉬들이 하나의 공간, 즉 하나의 좌표계에 모이는 곳이다.

      • 뷰 변환

        월드 공간으로 변환된 정점들을 특정 시점에서 보기 위해 뷰 변환을 통해서 카메라 공간으로 이동시켜야 한다. 뷰 변환은 카메라 변환이라고도 한다. 카메라 공간은 EYE(카메라 위치), UP(카메라의 윗 방향), AT(카메라가 바라보는 뱡향) 정보를 토대로 카메라 공간으로 변환한다.

      • 카메라 공간

        카메라 공간은 뷰 공간(View Space)라고도 한다. 카메라 공간은 카메라가 보는 시점에서의 상대적인 좌표들이다.

      • 투영 변환

        최종적으로 화면에 보여야 할 물체들만 존재하는 클립 공간으로 변환하는 작업이다. 카메라가 볼수 있는 시야(가시 영역)를 뷰 볼륨이라고 한다. 뷰 볼륨은 fovy(시야각), aspect(종횡비)에 의해 결정되고, n(근평면), f(횡평면)에 의해 절단되어 절두체(View Frustum)의 영역으로 다시 정의된다. 절두체 영역 밖에 그릴 필요가 없는 물체를 제거하게 되고, 이를 컬링(Culling)이라 한다. 다음으로 절두체 영역에 의해 메쉬가 잘리는 경우가 있는데 이를 클리핑(clipping)이라 한다.


  • 덮개 셰이더(Hull Shader)

    이 다음 단계인 테셀레이션 단계를 위한 준비 단계이다. 모델의 단일 표면을 여러개의 삼각형으로 분할하고, 각 입력 패치에 해당하는 도형 패치를 생성하고 계산한다.


  • 테셀레이터(Tessellator)

    주어진 메쉬의 삼각형들을 더 잘게 쪼개서 새로운 삼각형을 만드는 과정이다. 카메라에 가까운 삼각형들은 테셀레이션을 적용하여 세부도를 높이고 먼 삼각형들에게는 테셀레이션을 적용하지 않는 방식으로 구현 할 수 있다. 이는 메모리를 절약할 수 있고, 계산량을 줄일 수 있다.(Level - Of - Detail,LOD)


  • 도메인 셰이더(Domain Shader)

    테셀레이션의 세번째 단계로 출력 패치에서 세분화된 꼭지점 위치를 계산한다.


  • 기하 셰이더(Geometry Shader)

    입력받은 정점 데이터에 정보를 추가하거나 삭제하여 입력받은 기본 도형을 다른 도형들로 확장하거나 출력하지 않도록 버릴 수도 있다. 가장 흔한 용도는 하나의 점이나 선분을 하나의 사각형으로 확장하는 것이다.


  • 래스터라이저(Rasterize)

    투영된 3차원의 삼각형으로 부터 픽셀의 색상들을 계산한다.

    1. 클리핑 (Clipping)
    2. 원근 나누기 (Perspective Division)
    3. 뒷면 제거 (Back-face Culling)
    4. 뷰포트 변환 (View-port Transform)
    5. 스캔 변환 (Scan Transform)


    • 클리핑 (Clipping)

      클리핑은 투영변환 이후에 클립 공간 볼륨 바깥에 놓인 폴리곤들을 잘라내는 작업이다.

    • 원근 나누기 (Perspective Division)

      투영 변환을 통해 원근법이 적용된 3차원의 물체들을 2차원 공간으로 변환 시키는 작업. z좌표로 모든 성분을 나누어 버린다. 이 좌표 공간을 NDC(Normalized Device Coordinates) 공간이라 부른다.

    • 뒷면 제거 (Back-face Culling)

      카메라에 등을 돌리고 있어 보이지 않는 폴리곤을 제거하는 작업 폴리곤의 법선 벡터와 시선 벡터를 통해 이 두개의 벡터가 예각인지 둔각인지에 따라 뒷면을 판별

    • 뷰표트 변환 (View-port Transform)

      NDC 공간의 물체들을 스크린 공간으로 이전시키는 변환

    • 스캔 변환 (Scan Transform)

      삼각형 하나가 내부에 차지하는 프래그먼트를 생성하는 과정.


  • 픽셀 셰이더(Pixel Shader)

    각 픽셀의 데이터를 생성하는 단계. 조명을 계산하거나 텍스쳐를 입혀서 프래그먼트를 색칠하는 단계


  • 출력 병합(Output Merge)

    픽셀 셰이더가 생성한 데이터들을 입력받아 최종적으로 픽셀의 색상을 생성하여 렌더 타겟으로 출력하는 단계. 후면 버퍼에 기록한다.