스터디를 진행하며 실시한 모의 면접을 정리한 내용입니다.
겹치는 내용을 고려하지 않고 면접을 실시하기 때문에 일자 별로 겹치는 내용이 많을 수 있습니다.
1. 가비지 컬렉션이란?
참조되지 않는 메모리를 자동으로 해제해주는 시스템입니다. C++에선 지원하지 않는 시스템이지만, 언리얼엔진에선 해당 기능을 제공해주고 있습니다. 메모리를 트리구조로 연결한 뒤, 일정 시간마다 트리를 순회하여 참조가 끊긴 메모리를 해제하는 방식으로 진행됩니다.
2. 가비지 컬렉션의 단점은?
프로그래머가 직접 메모리를 해제하는 경우 메모리 해제 시점을 정확히 예측할 수 있지만, 가비지 컬렉터를 사용하는 경우 그 시점을 예측하기 힘들다는 단점이 있습니다. 또한, 가비지 컬렉션을 실행하기 위한 추가적인 메모리가 필요하며 메모리 컬렉션으로 인한 성능 저하도 발생할 수 있습니다. 또한, 가비지 컬렉션의 구현 방법에 따라 가비지 컬렉션이 실행되는 동안 가비지 컬렉션을 담당하는 스레드를 제외한 모든 스레드의 작업을 멈추는 과정을 거치기도 합니다. 이로 인해, 가비지 컬렉션이 실행되는 동안 성능이 급격히 저하되는 문제를 겪을 수도 있습니다.
3. 힙과 우선순위 큐의 차이는?
힙은 이진 트리의 형식을 활용해 빠르게 최대값과 최소값을 찾는 알고리즘입니다. 반면, 우선순위 큐는 우선순위가 가장 높은 대상이 가장 앞에 위치하도록 구현된 큐입니다. 우선순위 큐를 구현하는 여러 방법 중 힙을 사용하는 것이 가장 대표적이지만 힙이 아닌 다른 방식으로도 우선순위 큐를 구현할 수 있습니다.
4. 클래스, 객체, 인스턴스의 차이는?
구현하고자 하는 대상을 객체라고 하며 코드를 통해 객체의 속성을 구체화한 것을 클래스라고 합니다. 코드로 작성된 클래스가 생성되어 메모리에 적재된 것을 인스턴스라고 합니다.
5. push_back과 emplace_back의 차이는?
push_back은 자료구조에 삽입하고자 하는 값을 인자로 받기 때문에 인자 전달 과정에서 복사가 발생할 수 있습니다. 반면, emplace_back은 생성자의 인자를 함수의 인자로 받아 내부에서 객체를 생성하게 됩니다. 인자 전달 과정에서 복사가 발생하지 않아 상황에 따라 성능상 이점을 노릴 수 있습니다.
6. 코루틴과 멀티스레드의 차이는?
멀티 스레드는 여러 스레드를 활용하여 작업을 물리적으로 병렬 처리하지만 코루틴은 단일 스레드에서 처리되기 때문에 물리적으로는 작업을 순차 처리하게 됩니다. 코루틴은 멀티 스레드에 비해 안전하고 컨텍스트 스위칭이 발생하지 않으며 일반적인 함수 호출에 비해 빠르다는 장점이 있지만 물리적 병렬 작업이 필요한 경우에는 사용할 수 없다는 단점이 있습니다.
7. 앵커란 무엇인가? (언리얼엔진)
UI가 스크린에 렌더링되는 위치의 기준을 잡아주는 기능입니다. 앵커를 활용하면 UI가 다양한 해상도에서 자연스럽게 렌더링될 수 있습니다.
8. 객체 지향이란?
현실에서 사몰을 보는 시각으로 프로그래밍을 하고자 하는 방법론입니다. 코드의 흐름이 직선적이지 않고 객체를 넘나들며 실행되기 때문에, 절차지향적 프로그래밍에 비해 처리 속력이 다소 느리지만 코드를 이해하는 것이 매우 직관적이라는 장점이 있습니다.
9. 메시와 머티리얼에 대해 설명하라.
메시란 대상이 화면에 어느만큼 그려져야 하는지를 결정짓는 데이터입니다. 여러 개의 버텍스로 구성되어 있으며, 버텍스의 위치, 회전, 크기 정보에 따라 렌더링되는 범위가 결정됩니다. 반면, 머티리얼은 메시에 의해 정해진 영역을 어떤 색상으로 그려야 하는지를 결정짓는 데이터입니다. 텍스쳐, 빛 연산 등 색상에 영향을 미치는 모든 요소를 포함하는 개념입니다.
10. 렌더링 파이프라인의 전체적인 과정에 대해 설명하라.
수치로만 가지고 있는 데이터 정보를 화면에 그려질 색상 정보로 변환하는 과정을 렌더링 파이프라인이라고 합니다. 필수 단계로는 인풋 어셈블러, 버텍스 쉐이더, 레스터라이저, 픽셀 쉐이더, 아웃풋 머저 단계가 있습니다.
인풋 어셈블러 단계에선 버텍스 버퍼와 인덱스 버퍼를 참조하여 도형을 조립해 버텍스 쉐이더로 전달하게 됩니다. 또한, CPU에서 전달받은 버텍스 정보와 쉐이더에서 사용할 버텍스 정보를 매칭하기 위해 데이터에 시맨틱스를 부여하는 작업도 거치게 됩니다.
버텍스 쉐이더 단계에선 버텍스의 좌표에 월드 행렬, 뷰 행렬, 프로젝션 행렬을 곱해 원평면에 투영하는 과정을 거칩니다. 해당 과정은 프로그래밍 가능 단계이기 때문에 추가적인 연산이 필요하다면 코드를 작성하여 연산을 추가할 수 있습니다.
레스터 라이저 단계에선 렌더타겟에서 실제로 렌더링 될 위치만 추출하는 과정을 거칩니다. 대상의 후면을 컬링하거나 렌더타겟의 범위 밖으로 넘어가는 부분을 클리핑합니다. 또한, 렌더타겟에서 실제로 렌더링이 될 위치만을 추출하여 픽셀 쉐이더에서 불필요한 연산을 거치지 않도록 도와주는 역할을 합니다. 또한, 버텍스의 데이터를 픽셀 단위로 사용할 수 있도록 보간해주는 역할도 합니다.
픽셀 쉐이더는 레스터라이저 단계에서 렌더링을 하기로 정해진 위치의 색상을 정하는 단계입니다. 프로그래밍 가능 단계이므로 텍스쳐를 사용하여 색상을 결정할 수도 있고, 빛 연산 등의 추가적인 연산을 수행할 수도 있습니다.
아웃풋 머저는 픽셀 쉐이더에 의해 결정된 색상과 기존에 그려져 있던 색상을 어떻게 처리할 지 결정하는 단계입니다. 알파 블렌딩, 뎁스 스텐실 테스트 등을 거쳐 최종적으로 렌더타겟에 저장될 값을 결정짓게 됩니다.
11. 오브젝트 풀링이란?
오브젝트가 필요할 때 마다 동적으로 할당하는 것은 런타임 성능의 저하를 유발할 수 있기 때문에 로드 중에 미리 대량의 메모리를 할당해놓고 필요할 때마다 사용하는 최적화 기법을 오브젝트 풀링이라고 합니다. 오브젝트 풀링은 동적 할당으로 인한 오버헤드를 줄일 수도 있지만 외부 단편화에 강하고 오브젝트의 캐시 적중률을 높일 수 있기 때문에 적절히 사용하면 높은 성능 향상을 기대할 수 있습니다. 다만, 메모리를 할당해놓고 일부밖에 사용하지 않는다면 내부 단편화가 발생할 수 있기 때문에 필요한 만큼만 할당하는 것이 중요합니다.
12. 반투명한 물체를 처리하는 방법은?
반투명 물체의 경우 앞에 있는 물체가 먼저 그려질 경우 뒤에 있는 물체의 일부분이 의도치 않게 클리핑될 수 있습니다. 이를 막기 위해 카메라의 위치를 기준으로 멀리있는 물체부터 정렬하여 렌더링하는 알파 소팅 기법을 사용할 수 있습니다. 하지만, 알파 소팅의 경우에도 완벽하게 문제를 해결하지는 못합니다.
그러한 경우에는 물체가 불투명임을 가정하고 렌더링하여 렌더타겟에 깊이를 저장한 뒤, 해당 깊이 값을 활용해 불투명 물체를 다시 렌더링하여 문제를 해결할 수 있습니다. 하지만, 이 경우 드로우 콜이 2번 발생하기 때문에 반드시 필요한 상황에만 사용해야 합니다.
13. UDP 와 TCP 의 차이에 대해 설명하라.
UDP는 비연결 지향형 프로토콜이며 TCP는 연결 지향형 프로토콜입니다. TCP의 경우 안전한 데이터 송수신을 위해 3 way HandShake로 서로 연결하며 4 Way handShake로 연결을 해제합니다. 또한, 패킷의 송수신 과정에서 흐름제어, 혼잡제어 등의 기법을 사용해 패킷의 신뢰성을 보장하고 있습니다. 반면, UDP의 경우 별도의 처리 없이 목적지로 데이터를 보내기 때문에 데이터의 신뢰성을 보장되어 있지 않습니다. 반면 UDP는 어떠한 처리도 거치지 않는 만큼 송수신 속력이 TCP에 비해 매우 빠르다는 장점이 있습니다. 이러한 특성으로 인해 TCP는 파일 전송 등 신뢰성이 중요한 경우에 사용되며 UDP는 동영상 스트리밍 등 데이터의 신뢰성보다 속력이 중요한 경우에 주로 사용됩니다.
14. 상속을 사용하는 이유는?
상속의 주 목적은 코드의 재사용입니다. 한 클래스에 정의된 내용을 다른 클래스에서도 동일하게 정의해야 한다면 클래스의 상속을 통해 기능을 물려줄 수 있습니다. 또한, 상속을 사용하면 객체지향의 특징인 다형성을 보장할 수 있다는 장점도 있습니다.
15. 템플릿과 오버로딩의 차이는?
템플릿은 동일한 기능이 다양한 자료형에 대해 대응할 수 있도록 사용하는 기능입니다. 동일한 기능을 여러 자료형을 대상으로 여러 개 정의하는 것은 매우 번거로운 일이지만, 템플릿을 활용하면 한 번의 정의를 통해 여러 자료형에 대응할 수 있게 됩니다.
반면 오버로딩은 동일한 이름의 함수를 다양한 파라미터로 사용할 수 있도록 하는 기능입니다. 본질적 기능이 유사한 경우 동일한 이름을 사용하여 작명의 번거로움을 피할 수 있습니다.
16. 오버로딩과 오버라이딩의 차이는?
오버로딩은 이름은 동일하되, 파라미터가 다른 경우에 사용하는 문법입니다. 반면, 오버라이딩은 상속 관계에서 자식클래스가 부모 클래스의 함수를 재정의하여 새롭게 사용하는 문법입니다.
17. 스마트포인터란?
메모리의 할당과 해제를 대신 관리해주는 객체입니다. 메모리를 동적으로 할당하고 해제할 때엔 malloc/free 혹은 new/delete를 사용해야 하지만, 프로그래머의 실수로 인해 메모리의 누수가 발생하거나 댕글링 포인터 문제가 발생할 수 있습니다. 이러한 위험없이 안전하게 메모리를 관리할 수 있도록 C++에서 제공해주는 기능입니다. 동적으로 할당된 메모리 영역을 참조하는 스마트 포인터 객체가 증가할 때마다 참조 카운트를 증가시키고 감소할 때마다 참조 카운트를 감소시키며 참조 카운트가 0이 되었을 때 메모리의 할당을 해제하여, 메모리 누수가 발생하지 않도록 관리해줍니다.
18. 32비트 , 64비트 운영체제 차이
32비트 운영체제는 메모리 주소를 32비트로 저장하며, 64비트 운영체제는 메모리 주소를 62비트로 저장합니다. 32비트로 메모리 주소를 저장하는 경우 표현할 수 있는 주소의 한계로 인해 메인 메모리의 용량이 아무리 크더라도 대략 4GB를 넘어서면 사용할 수 없게 됩니다. 반면, 64비트 운영체제는 표현할 수 있는 주소의 범위가 훨씬 넓기 때문에 메인 메모리의 용량을 최대한으로 사용할 수 있습니다.
19. 유저 영역 vs 커널 영역
유저 영역은 운영체제에서 유저가 사용하고 접근할 수 있는 영역을 의미하며, 커널 영역은 운영체제의 중요한 기능을 담고 있어 유저가 함부로 접근할 수 없도록 제한되어 있는 영역을 의미합니다.
20. 가상메모리란?
SSD, HDD 등 보조 기억 장치의 도움을 받아 메인 메모리의 물리적 용량보다 더 큰 용량을 사용할 수 있게 해주는 기법입니다. 프로세스의 데이터 중 실제로 사용되는 데이터만 메인 메모리에 적재하고 사용되지 않는 데이터는 보조 기억 장치에 적재하는 방식으로 동작합니다.
21. 페이징 기법이란?
가상 메모리를 구현하는 대표적인 방식입니다. 메인 메모리와 프로세스를 동일한 크기의 조각으로 잘게 쪼개놓은 뒤, 프로세스의 조각중 CPU에서 사용되어야 하는 조각을 메인 메모리에 순차적으로 적재하며 동작합니다. CPU에서 프로세스 조각의 물리적 주소에 접근할 수 있도록 운영체제는 페이지 테이블을 생성하여 프로세스의 가상 주소와 물리적 주소를 저장하여 보관합니다.
페이징 기법은 외부 단편화가 발생하지 않는다는 장점이 있지만, 프로세스의 가장 끝에 있는 조각에서 내부 단편화가 발생할 수 있습니다. 또한, CPU에서 메인 메모리에 2번이나 접근해야 하는 상황으로 인해 성능 저하가 발생할 수 있습니다.
23. 변환색인버퍼란?
페이징 기법의 문제를 해결하기 위해 사용하는 하드웨어입니다. 페이징 기법은 CPU가 프로세스 데이터의 물리적 주소에 접근할 수 있도록, 가상 주소 테이블을 메인 메모리에 보관하며 사용합니다. CPU에서 프로세스 데이터의 물리적 주소에 접근하기 위해, 가상 주소 테이블에 접근하여 물리적 주소를 알아낸 뒤 물리적 주소에 접근하게 됩니다. CPU보다 처리 속도가 느린 메인 메모리에 2번이나 접근해야 하는 이유로 병목 현상이 크게 발생할 수 있습니다. 이러한 병목현상 문제를 최소화하기 위해 변환 색인 버퍼라는 캐시 메모리에 가상 주소와 물리적 주소를 캐싱하여 사용하게 됩니다.
22. 세그멘테이션 기법이란?
가상 메모리를 구현하는 기법 중 하나입니다. 프로세스의 데이터를 연관이 있는 것끼리 묶어 여러 세그멘트로 나눈 뒤 세그멘트 별로 메모리에 적재하여 사용하게 됩니다. 세그먼트의 크기가 일정하지 않아, 페이징 기법처럼 순차적으로 메모리에 적재할 수 없어 적재할 때마다 크기만큼 메모리를 할당하는 과정을 거치게 됩니다. 이로 인해, 내부 단편화는 전혀 발생하지 않지만 잦은 메모리 할당과 해제로 인해 외부 단편화가 발생할 수 있습니다. 세그멘테이션 기법도 페이징 기법처럼 가상 주소와 물리 주소를 매핑하는 테이블을 보유하지만 페이지 테이블에 비해 크기가 매우 작아 메인 메모리가 아닌 레지스터에 위치하고 있습니다.
24. 캐시 메모리란?
CPU와 메인 메모리의 작업 처리 속도 차이로 인해, CPU가 메인 메모리에 직접 접근하게 되면 병목 현상이 발생할 수 있습니다. 이러한 병목 현상을 완화하기 위해, 메인 메모리보다 속력이 빠른 캐시 메모리가 CPU와 메인 메모리 사이에 위치하고 있습니다. CPU가 메인 메모리에 접근하게 되면, 접근한 주소와 근접한 데이터를 캐시 메모리에 복사하여 저장합니다. 이후, CPU는 캐시 메모리를 우선적으로 탐색하게 되고 원하는 데이터가 캐시 메모리에 없다면 메인 메모리에 접근하여 다시 데이터를 가져와 캐시 메모리를 갱신하게 됩니다. 이러한 과정을 통, CPU가 메인 메모리에 직접 접근하는 횟수를 줄여 병목 현상으로 인한 성능 저하를 최소화할 수 있습니다.
25. 캐시적중률이란?
캐시 메모리에서 원하는 데이터를 발견할 확률을 의미합니다. CPU에서 필요한 데이터를 캐시 메모리에서 탐색할 때, 데이터를 발견하는 것을 캐시 적중이라고 하며 발견하지 못하는 것을 캐시 미스라고 합니다. 캐시 미스가 발생하게 되면, CPU는 다시 메인 메모리에 접근하여 캐시 메모리를 갱신하게 됩니다. 즉, 캐시 미스가 많이 발생할수록 CPU는 메인 메모리에 자주 접근하게 되고 캐시 적중이 많이 발생할수록 CPU는 메인 메모리에 적은 횟수로 접근하게 됩니다. 캐시 적중이 얼마나 많이 발생하는 가를 캐시 적중률이라고 하며, 성능 저하를 최소화하기 위해선 캐시 적중률을 높이는 방향으로 프로그래밍하는 것이 좋습니다.
26. volatile 키워드란?
volatile 키워드란, 컴파일러의 최적화를 제한하는 키워드입니다. 컴파일러는 프로그램이 최선의 속도로 실행될 수 있도록 프로그래머가 작성한 코드를 일부 변경하여 최적화를 달성하곤 합니다. 하지만, 이러한 최적화로 인해 프로그래머의 의도와 실행결과가 달라지는 경우가 있습니다. 이러한 상황을 방지하기 위해 volatile 키워드를 변수 앞에 붙혀 해당 변수에 대한 컴파일러 최적화를 제한할 수 있으며, 이로 인해 프로그래머의 의도와 실행 결과를 일치시킬 수 있습니다.
27. inline 키워드란?
함수 호출로 인한 오버헤드를 줄이기위해, 컴파일 타임에 함수의 호출 코드를 함수의 내부 코드로 치환하는 키워드입니다.
28. 함수 뒤에 붙는 const 를 설명하라.
함수 뒤에 const를 붙이게 되면 해당 함수 내에서 멤버 변수의 값을 변경할 수 없게 됩니다. 함수 뒤에 const를 붙이게 되면 this 포인터가 가리키는 대상이 상수화되어, 함수 내부에서 멤버변수의 값을 변경할 수 없게 됩니다. 이러한 동작 원리 때문에, 내부에서 전역변수나 다른 클래스의 멤버 변수 값은 얼마든지 변경할 수 있으며 전역 함수의 뒤에는 const를 붙일 수 없습니다.
29. L-Value와 R-Value를 설명하라.
L-Value는 메인 메모리에 존재하며 스코프를 벗어나기 전까지 사라지지 않는 값입니다. 반면, R-Value는 메인 메모리에 존재하지 않으며 호출식 이후에는 사라지는 값입니다.
30. this 콜이란?
멤버 함수를 호출할 때, 함수를 호출하는 인스턴스를 식별하기 위해 첫 번째 인자로 객체의 주소를 대입하는 방식입니다.
31. 멀티 스레드와 멀티 프로세스에 대해 설명하라.
멀티 스레드는 하나의 프로세스에서 여러 스레드를 사용하는 것을 의미하며, 멀티 프로세스는 동시에 여러 프로세스를 실행하는 것을 의미합니다.
프로세스는 각각 별도의 메모리 공간을 보유하고 있기 때문에 하나의 프로세스에 문제가 발생하더라도 다른 프로세스에 영향을 주지 않지만, 스레드는 스택 영역을 제외한 메모리를 모두 공유하기 때문에 하나의 스레드에서 문제가 발생하면 프로세스 전체에 영향을 줄 수 있다는 차이가 있습니다.
또한, 프로세스는 모든 메모리 영역이 독립되어있는 만큼 컨텍스트 스위칭의 비용이 크지만 스택 영역만을 독립적으로 보유하고 있는 스레드의 컨텍스트 스위칭은 상대적으로 가볍다는 차이가 있습니다.
32. 뮤텍스와 세마포어의 차이는?
뮤텍스는 임계 영역에 1개의 스레드에 대해서만 접근을 허용하지만, 세마포어는 여러 개의 스레드가 접근하도록 설정할 수 있습니다. 또한, 뮤텍스는 뮤텍스 객체가 lock과 unlock 권한을 가지고 있지만, 세마포어는 자체적으로 lock과 unlock 권한을 가지고 있지 않습니다.
33. IPC란?
IPC는 프로세스 간의 통신을 의미합니다. 멀티 프로세스 환경에서 각 프로세스는 메모리 영역이 철저히 분리되어 있기 때문에 일반적인 방법으로는 서로 통신할 수 없지만, 커널 영역을 거치면 특수한 방법으로 통신할 수 있게 됩니다.
34. unnamed PIPE vs named PIPE
PIPE란, 멀티 프로세스 환경에서 프로세스 끼리 통신하기 위해 사용되는 기법 중 하나입니다. PIPE라는 공간에 한 프로세스가 쓰기 작업을 하면 다른 프로세스는 쓰여진 값을 읽는 방식으로 통신하게 됩니다. PIPE에 이름이 부여되어 있으면 named PIPE라고 하며 이름이 부여되어 있지 않다면 unnamed PIPE라고 합니다. unnamed PIPE의 경우 PIPE에 이름이 부여되어 있지 않으므로 하나의 PIPE에 프로세스가 연결되어 있어야 합니다. 이러한 문제로 인해, 자식 부모 관계로 얽혀 있는 프로세스 간의 통신에 사용하게 됩니다. 반면 named PIPE는 PIPE에 이름이 부여되어 있어 프로세스가 원하는 PIPE에 직접 접근할 수 있어 관련없는 프로세스 간의 통신에도 사용할 수 있습니다.
35. IP와 MAC 이란?
네트워크에 연결되어 있는 장치들을 식별하기 위해 부여되는 식별 번호입니다. IP는 장치의 Lan Card가 연결되어 있는 회선에 부여되는 주소이며, MAC주소는 Lan Card 자체에 부여되어 있는 주소입니다. IP는 회선에 부여되어 있기 떄문에, 장치가 접속하는 인터넷이 변할 때마다 함께 변하게 됩니다. 반면, MAC주소는 하드웨어에 기록되어 있기 때문에 Lan Card를 교체하지 않는 한 변하지 않는 주소입니다.
36. IPv4 과 IPv6의 차이는?
IPv4의 경우 IP를 8비트의 숫자 4개가 엮인 32비트의 형태로 주소를 표현합니다. 반면, IPv6의 경우 16비트의 숫자 8개가 엮인 128비트의 형태로 주소를 표현합니다. IPv4로 표현할 수 있는 주소 범위 내에선 현대에 사용되는 모든 장치에 고유 주소를 부여하는 것이 어렵기 때문에 보다 넓은 범위로 주소를 표현하기 위해 IPv6 방식이 탄생하였습니다. 하지만, 현대에 사용되고 있는 IPv4 기반의 네트워크 통신을 IPv6 기반으로 변경하는 것은 매우 큰 비용이 발생하기 때문에 IPv6는 매우 제한된 환경에서만 사용되고 있습니다.
37. 포트넘버란?
포트 넘버란, IP, MAC 주소 만으로는 데이터의 도착지를 식별할 수 없는 경우 최종 목적지를 식별하기 위해 추가적으로 사용되는 주소입니다. 데이터가 도착한 PC에서 여러 개의 프로세스가 실행중인 경우 최종적으로 어느 프로세스에 도달해야 할 지 IP, MAC 주소 만으로는 식별할 수 없기 때문에 프로세스에 포트번호를 부여하여 최종적인 목적지를 판별하게 됩니다.
38. 프로세스의 메모리 구조를 설명해라.
프로세스는 코드 영역, 데이터 영역, 힙 영역, 스택 영역으로 분할되어 있습니다. 코드 영역엔 프로세스를 프로그래밍할 때 작성된 코드 전체가 저장되어 있으며, 데이터 영역엔 전역 변수, 문자열 리터럴 등 한 번 메모리에 저장되면 프로세스가 종료될 때 까지 삭제되지 않는 데이터들이 저장되어 있습니다. 힙 영역은 런타임에 동적으로 할당하여 사용할 수 있는 메모리 영역이며, 스택 영역엔 호출된 함수 내부에서 사용되는 로컬 데이터가 저장됩니다.
39. 문자열 리터럴은 L-Value인가 R-Value인가?
문자열 리터럴은 일반적인 상수 리터럴과 다르게 데이터 영역에 저장되어 있으며 그 주소값을 참조할 수 있습니다. 즉, 문자열 리터럴은 L-Value 입니다.
40. 무브 시맨틱이란?
더이상 사용되지 않을 것이 확실한 객체에 대해 깊은 복사가 아닌 얕은 복사를 한 뒤 대상의 데이터를 지워 소유권을 완전히 이전시키는 기법입니다. 깊은 복사가 발생하지 않기 때문에 성능상의 이점이 있으며, 복사되는 객체의 데이터를 지워버림으로써 얕은 복사로 인한 댕글링 포인터 문제도 발생하지 않습니다.
41. 플레이어를 기준으로 몬스터가 어디에 있는지 알아내는 방법
대표적으로 내적과 외적을 사용하는 방법이 있습니다. 플레이어의 위치에서 몬스터를 향하는 벡터와 플레이어의 전방 벡터를 내적하여 몬스터가 앞에 있는지, 뒤에 있는지 구할 수 있습니다.
또한, 플레이어 위치에서 몬스터를 향하는 벡터와 플레이어의 위쪽을 향하는 벡터를 외적하면 몬스터가 좌측에 있는지, 우측에 있는지를 구할 수 있습니다.
42. 행렬연산을 사용하는 이유는 무엇인가?
벡터를 사용해 연산하는 것보다 훨씬 간단하게 연산 결과를 구할 수 있으며, 하나의 행렬에 모든 정보를 누적하여 저장하기 때문에 메모리를 절약할 수 있기 때문입니다. 또한, 4x4 행렬의 경우 SIMD 연산을 통해 추가적인 성능 향상을 기대할 수 있습니다.
43. 노말맵이란?
색상 정보가 아닌 노말 정보를 가지고 있는 텍스쳐를 의미합니다. 주로 픽셀 단위로 빛을 계산하기 위해 사용합니다.
44. 탄젠트 스페이스란?
폴리곤의 법선을 수직축으로 하는 평면공간입니다. 입체 도형의 법선 정보를 월드 좌표계의 값으로 저장하여 사용하게 되면, 오브젝트가 아무리 회전하더라도 법선 값은 변하지 않아 조명 효과가 부자연스럽게 적용됩니다. 반면, 노말 값을 탄젠트 공간의 값으로 저장하게 되면 현재 폴리곤의 접선과 종법선을 활용해 노말값을 동적으로 계산하여 물체의 회전 정보에 따라 자연스럽게 법선을 매핑할 수 있게 됩니다.
하지만, 탄젠트 공간의 노말맵을 사용하게 되면 런타임에 연산이 추가되는 만큼 성능 면에서 손해를 볼 수 있기 때문에, 회전할 가능성이 없는 정적 오브젝트에 대해선 월드 공간의 노말 맵을 사용하는 것이 좋습니다.
45. G버퍼란?
렌더타겟이 지니고 있는 데이터 버퍼를 의미합니다. 해당 버퍼에는 색상 값이 저장될 수도 있고, 노말 값이 저장될 수도 있으며, 깊이 값이 저장될 수도 있습니다.
46. AABB충돌이란? 문제점은?
두 사각형 혹은 정육면체 간의 충돌을 탐지하는 방법입니다. 두 도형의 좌표 차와 길이 합을 비교하여 충돌을 탐지합니다. 연산이 매우 간단하지만 회전한 사각형, 정육면체에 대해서는 올바르게 작동하지 않는다는 문제점이 있습니다.
47. OBB충돌이란?
AABB 충돌로 탐지할 수 없는 회전한 도형의 충돌을 탐지하기 위한 방법입니다.두 도형을 x, y, z 축에 대해 투영한 뒤, 두 도형의 투영 공간이 겹치는 지 여부를 통해 충돌을 탐지합니다. 회전한 도형에 대해서도 충돌을 탐지할 수 있지만 연산량이 많다는 단점이 있습니다.
48. 드로우콜이란?
CPU에서 GPU에 렌더링 연산을 명령하는 것을 의미합니다. GPU가 이해할 수 있는 명령어 형태로 변환하는 과정이 상당히 오래걸리기 때문에 CPU에 병목 현상을 가져올 수 있습니다. 그렇기 때문에, 드로우 콜을 최소화하는 것은 최적화에 있어 매우 중요한 요소입니다.
49. 드로우콜 최적화는 CPU최적화인가 GPU최적화인가
드로우 콜은 CPU 최적화입니다. CPU에서 GPU로 명령을 보내는 작업이기 때문에, 드로우 콜을 줄일수록 CPU는 다른 연산에 시간을 더 투자할 수 있게 됩니다. GPU 최적화 기법은 대표적으로 LOD, 밉맵 등이 있습니다.
50. 쿼터니언이란?
오일러 각을 사용했을 때 발생할 수 있는 짐벌락 현상이나 회전 보간의 비정확성을 해결하기 위해 회전 연산에 사용하는 수학적 개념입니다.
51. 짐벌락이란?
회전 축이 겹침으로써 한 축이 회전 능력을 소실하는 현상입니다..
52. 픽셀충돌을 사용하는 이유는?
복잡한 지형에 대한 충돌 처리를 간단하게 수행할 수 있기 때문입니다.
53. 싱글톤 패턴이란?
객체의 인스턴스가 프로세스 내에 단 1개만 존재하도록 설계하는 디자인 패턴입니다. 생성자와 소멸자를 private 으로 설정하여외부에서 호출되는 것을 막은 뒤, 객체 내부에서 static 변수로 인스턴스를 생성하는 방식으로 구현됩니다.
54. 멀티스레드 환경에서 싱글톤의 문제점
싱글톤 클래스의 인스턴스를 동적 할당하는 방식으로 구현한다면 멀티 스레드 환경에서 객체가 여러개 생성되는 문제가 발생할 수 있습니다. 여러 스레드가 동시에 인스턴스를 반환하는 함수를 호출하게 되면, nullptr 검사 조건문을 여러 스레드가 동시에 통과하게 되어 여러번 동적 할당이 발생하게 됩니다. 이러한 상황을 막기 위해 해당 함수 내부에 lock()과 unlock()을 추가하게 되면 오버헤드로 인해 멀티 스레딩의 능률이 매우 저하될 수 있습니다.
이를 해결하기 위한 대표적인 방법으로 싱글톤 클래스를 지역 static 변수로 생성하는 방법이 있습니다.
55. 전방선언이란 무엇인가? 사용하는 이유는?
전방 선언이란, 헤더파일을 참조하지 않더라도 자료형을 사용할 수 있도록 전방에 미리 선언해주는 기법입니다. 다만, 자료형이 선언만 되어 있는 형태이기 때문에 멤버 함수 등 자료형에 포함된 기능을 사용할 수는 없습니다. 전방 선언을 사용하는 이유는 불필요한 헤더의 참조를 막아 순환 참조를 방지함과 동시에 빌드 시간을 단축시키기 위해서입니다.
56. 네임맹글링이란?
네임 맹글링이란 컴파일러가 함수나 변수의 이름을 변경하는 것을 의미합니다. C++의 경우 함수 오버로딩과 같이 동일한 이름의 함수가 존재할 수 있기 때문에 이를 구별하기 위해 이름을 의도적으로 변환하는 과정을 거치게 됩니다. 하지만, C언어의 경우 네임 맹글링을 사용하기 때문에 C언어 개발 환경에선 C++ 라이브러리를 사용할 수 없게 됩니다. 이를 해결하기 위해, C++ 로 코드를 작성할 때 extern "C" 키워드를 함수 앞에 붙여 함수의 네임 맹글링을 제한할 수 있으며, C언어에서도 C++ 컴파일러에 의해 컴파일된 라이브러리를 사용할 수 있게 됩니다.
57.다중상속의 문제점
상속받은 여러 클래스에 각각 동일한 이름의 함수 혹은 변수가 정의되어 있다면 하위 클래스에선 어떤 클래스의 함수 혹은 변수를 사용해야 할 지 예측할 수 없는 문제가 발생합니다.
58. 라운드 로빈 알고리즘이란?
우선순위에 따라 차등하게 작업을 실행하는 것이 아니라, 모든 작업을 동일한 시간만큼 평등하게 실행하는 알고리즘입니다. 우선순위에 의한 기아 현상은 발생하지 않지만, 중요한 작업과 중요하지 않은 작업이 똑같이 실행되는 만큼 작업이 효율적으로 분배되지 못한다는 단점이 있습니다.
59. 컨텍스트 스위칭이란
CPU에서 작업중인 프로세스, 스레드를 다른 프로세스, 스레드로 교체하는 과정 전체를 의미합니다. 잦은 컨텍스트 스위칭은 오버헤드의 원인이 되기 때문에 멀티 프로세스, 멀티 스레드 프로그래밍에선 컨텍스트 스위칭을 최소화하는 방향으로 설계해야 합니다.
60. 가상 소멸자를 쓰는 이유는 무엇인가?
자식 클래스의 소멸자를 올바르게 호출하기 위해 사용합니다. 자식 클래스가 부모 클래스로 업캐스팅된 상태에서 객체가 소멸하게 되면, 자식 클래스의 소멸자가 아닌 부모 클래스의 소멸자를 호출하게 됩니다. 이러한 상황을 방지하기 위해, 소멸자를 가상화하여 업캐스팅 된 상황에서도 자식 소멸자가 올바르게 호출될 수 있도록 할 수 있습니다.
61. 클래스와 구조체의 차이는?
클래스는 접근 제한 지정자의 디폴트 값이 private이고, 구조체는 public이라는 차이가 있습니다.
62. RTTI란?
런타임에 객체의 실제 타입을 확인할 수 있도록 도와주는 기능입니다. 객체의 가상함수 테이블 가장 앞에 클래스의 정보를 저장하여 사용합니다. 주로, dynamic_cast에 사용됩니다.
63. 람다함수란 무엇인가? 장단점은 무엇이 있는가?
람다 함수란 이름이 없는 함수를 의미합니다. 일반적인 함수처럼 미리 선언 및 정의하여 사용하는 것이 아니라, 필요할 때 즉석으로 정의하여 사용하게 됩니다. 여러 번 사용될 가능성이 없는 기능을 람다 함수로 사용하면 메모리를 절약할 수 있다는 장점이 있지만, 람다 함수를 무분별하게 사용하면 가독성이 크게 저하될 뿐더러 디버깅이 매우 어려워집니다.
64. string과 string_view의 차이
string은 문자열을 저장하는 자료구조입니다. 내부에 배열을 만들어 문자열을 데이터로 보유하고 있습니다. 반면, string_view는 특정 문자열에 대한 포인터만 보유하고 있습니다. string은 실제 문자열을 유연하게 관리하기 위해 사용하는 반면, string_view는 불필요한 문자열의 복사를 방지하기 위해 사용합니다.
65. RTV란?
텍스쳐를 렌더타겟으로 사용하기 위해 필요한 GPU의 자원입니다. 렌더타겟 옵션, 플래그 및 텍스쳐 포멧 정보를 담고있습니다.
'모의 면접' 카테고리의 다른 글
게임 클라이언트 개발자 모의 면접 (2024/08/03) (0) | 2024.08.03 |
---|---|
게임 클라이언트 개발자 모의 면접 (2024/07/31) (0) | 2024.07.31 |
게임 클라이언트 개발자 모의 면접 (2024/07/25) (0) | 2024.07.24 |
게임 클라이언트 개발자 모의 면접 (2024/07/22) (2) | 2024.07.22 |
게임 클라이언트 개발자 모의 면접 (2024/07/15) (0) | 2024.07.15 |