스터디를 진행하며 실시한 모의 면접을 정리한 내용입니다.
겹치는 내용을 고려하지 않고 면접을 실시하기 때문에 일자 별로 겹치는 내용이 많을 수 있습니다.

1. 메모리 풀링이란?

더보기

런타임에 객체를 계속 생성하고 파괴하는 것이 오버헤드를 유발할 뿐만 아니라 외부 단편화의 원인이 될 수 있기 때문에 이를 방지하기 위해 미리 메모리를 크게 할당해놓고 사용하는 기법을 메모리 풀링이라고 합니다. 

2. 외부단편화란?

더보기

메모리의 할당과 해제가 반복되면 할당된 메모리 사이에 틈이 발생하게 됩니다. 이러한 틈이 많아지면 실제 메모리에 공간이 충분함에도 불구하고 메모리를 할당하지 못하거나 비효율적으로 할당해야 하는 상황이 발생할 수 있습니다. 이를 외부단편화라고 합니다.

3. 가상 메모리란?

더보기

HDD, SDD등의 보조 기억장치의 도움을 받아 메인 메모리의 물리적 용량보다 더 큰 범위의 용량을 사용하는 기법을 가상 메모리라고 합니다.  

4. 사용해본 경험이 있는 디자인 패턴있는가?

더보기

싱글톤 패턴을 사용해보았습니다. 플레이어의 스탯 혹은 보유한 아이템 정보 등을 보관하기 위해선 레벨과 무관하게 존재하는 클래스가 필요했고, 이를 전역 클래스로 구현하였습니다. 하지만, 이 클래스의 인스턴스가 여러개 생성되면 데이터가 안정적으로 보관되지 못할 가능성이 있기 때문에 하나의 인스턴스만 존재함을 보장해야했습니다. 이를 위해 싱글톤 패턴을 활용하였습니다.

5. (C++) 캐스팅 종류는 무엇이 있는가?

더보기

static_cast, dynamic_cast, reinterpret_cast, const_cast가 있습니다. static_cast는 컴파일 타임에 타입 캐스팅이 이루어지기 때문에 성능에 큰 영향을 주지 않는다는 장점이 있지만, 타입 캐스팅의 성공 여부를 반환하지 않아 안전하지 않다는 단점이 있습니다. 반면, dynamic_cast는 런타임에 타입 캐스팅이 이루어집니다. 타입 캐스팅이 실패시 nullptr을 반환하기 때문에 안전하게 사용할 수 있다는 장점이 있지만 성능에 영향을 줄 수 있다는 단점이 있습니다. 

reinterpret_cast는 가장 넓은 범위의 캐스팅을 지원하는 키워드입니다. static_cast는 값을 유지하기 위해 자료형에 따라 비트에 저장된 값을 변경하지만 reinterpret_cast는 비트에 저장된 값을 유지하는 방식의 캐스팅입니다. 다양한 형태의 타입 캐스팅을 지원하지만 자료형에 따라 값을 해석하는 것이 달라지기 때문에 안전하지 못하다는 단점이 있습니다. const_cast는 포인터 변수의 상수성을 일시적으로 제거해주는 타입 캐스팅입니다. 상수화 되어있는 포인터 변수가 다른 대상을 가리키게 하고 싶을 때 사용할 수 있습니다.

6. (C#) ref키워드에 대해 설명하라.

더보기

대상을 참조 타입으로 사용하기 위한 키워드입니다. C#에서 객체는 모두 참조 타입으로 사용되지만 구조체와 string을 제외한 기본 자료형 등은 기본적으로 참조 타입이 아니기 때문에 ref 한정자를 통해 참조 타입으로 사용할 수 있습니다.   

7. (C#) class와 struct의 차이는?

더보기

class는 new를 통해서만 생성할 수 있기 때문에 참조 형식으로만 사용할 수 있습니다. 반면, struct는 new 키워드 없이도 생성할 수 있어 값 타입으로 사용할 수 있습니다. struct는 일반적으로 stack영역에 위치하기 때문에 heap 영역에 위치하는 class보다 성능적인 부분에서 우위에 있지만, class와 달리 상속이 불가능하다는 단점이 있습니다. 

8. 동시성과 병렬성이란?

더보기

여러 작업이 동시에 실행되는 것처럼 보이지만 물리적으로는 동시에 실행되지 않는 것을 동시성이라 하며, 물리적으로 동시에 실행되고 있는 것을 병렬성이라고 합니다.

9. 유저영역과 커널영역이란?

더보기

운영체제에서 사용자가 마음껏 접근할 수 있는 영역을 유저영역이라 하며, 함부로 접근할 수 없도록 제한되어 있는 영역을 커널 영역이라고 합니다. 운영체제는 메모리 관리, 하드웨어 상호작용 등 저수준의 작업을 처리하는 역할을 합니다. 사용자가 이를 함부로 수정하게 되면 기기에 큰 문제를 발생시킬 수 있기 때문에 일부 영역에 대해선 접근할 수 없도록 막아두고 있으며, 이 영역을 커널 영역이라고 합니다. 반면, 문제가 발생하더라도 쉽게 해결할 수 있거나 국소적인 문제만 발생할 수 있는 영역에 대해선 자유로운 접근을 허용하고 있으며 이를 유저 영역이라고 합니다.

11. 외부단편화를 해결하는 방법은 무엇이 있나?

더보기

대표적으로 메모리 풀링 기법이 있습니다. 외부 단편화는 잦은 메모리의 할당과 해제로 인해 발생하기 때문에, 미리 메모리 블록을 할당해놓은 뒤 이를 재사용하는 메모리 풀링 기법을 활용하면 외부 단편화 문제를 최소화할 수 있습니다.

12. 네임스페이스란?

더보기

클래스, 구조체 등을 분류하기 위해 사용하는 문법입니다. 네임스페이스 안에 존재하는 클래스, 구조체 등은 네임스페이스를 통해 사용해야 하기 때문에 역할이나 사용처 등을 쉽게 알아볼 수 있다는 장점이 있습니다. 하지만, 매번 네임 스페이스를 통해 사용하는 것이 다소 불편하기 때문에 using 문법을 활용하여 이를 생략할 수도 있습니다. 

13. (C++) 가상 소멸자를 사용하는 이유는?

더보기

자식 클래스의 소멸자가 호출되는 것을 보장하기 위해 사용합니다. 특정 클래스가 부모 클래스로 업캐스팅되어있는 상태에서 소멸하게 되면, 자식 함수의 소멸자가 호출되지 않을 수 있습니다. 소멸자에서 메모리 해제 등의 중요한 작업이 이루어지는 경우 문제가 발생할 수 있기 때문에 소멸자를 가상화하여 반드시 호출되도록 할 수 있습니다.

14. 캐시 메모리란?

더보기

CPU와 메인 메모리의 작업 처리 속도 차이로 인해, CPU에서 메인 메모리에 접근하는 경우 CPU에 병목 현상이 발생할 수 있습니다. 현대의 컴퓨터는 이러한 병목현상을 완화하기 위해, CPU가 메인 메모리에 접근했을 때 일정량의 데이터를 캐시 메모리로 복사한 뒤 CPU가 캐시 메모리의 데이터를 먼저 탐색하도록 설계되어 있습니다. 캐시 메모리는 메인 메모리에 비해 매우 빠른 작업 처리 속도를 보유하고 있기 때문에 높은 성능 향상을 기대할 수 있습니다.

15. 캐시 적중률이란?

더보기

원하는 데이터가 캐시 메모리에서 발견될 확률을 캐시 적중률이라고 합니다. 캐시 메모리에 원하는 데이터가 없을 경우 CPU는 메인 메모리에 접근하여 데이터를 다시 캐시로 옮겨오는 작업을 실행하게 됩니다. 원하는 데이터를 캐시 메모리에서 많이 발견할 수 있다면 CPU가 메인 메모리에 접근하는 횟수가 적어지기 때문에 캐시 적중률이 높을수록 높은 성능을 기대할 수 있습니다.

16. (C++) 접근 제한 지정자란 무엇인가? 종류는 무엇이 있는가?

더보기

접근 제한 지정자란, 외부의 접근을 허용하는 정도를 설정하는 키워드 입니다. 접근 제한 지정자는 public, protected, private 총 3개의 종류가 있습니다. public는 모든 곳에서 접근을 허용하는 키워드이며, protected는 상속 관계에서만 접근을 허용하는 키워드입니다. private는 어느 곳에서도 접근을 허용하지 않는 키워드입니다.

17. 초기화 리스트와 리터럴 초기화의 차이는?

더보기

리터럴 초기화는 변수가 생성되는 동시에 값을 초기화 하지만, 초기화 리스트는 생성자가 호출될 때 초기화를 실행하기 때문에 리터럴 초기화보다 늦은 시기에 실행되게 됩니다.

18. TCP와 UDP의 차이를 설명하라.

더보기

TCP는 연결 지향형 통신 프로토콜입니다. 소켓을 이용해 서로를 1:1로 연결하여 통신하기 때문에 안전하게 통신할 수 있습니다. 하지만, 안정성을 위해 패킷 송수신에 부가적인 작업을 많이 하는 만큼 반응성은 다소 느리다는 단점이 있습니다.

 

UDP는 비연결 지향형 통신입니다. 서로 연결되어 있지 않고 데이터 검증, 보호 등의 작업을 수행하지 않기 때문에 데이터의 신뢰성이 TCP에 비해 낮다는 단점이 있지만 매우 빠르게 통신할 수 있다는 장점이 있습니다.

 

이러한 특징으로 인해 TCP는 파일의 전송 등 데이터의 신뢰성이 중요한 작업에 자주 이용되며, UDP는 실시간 게임이나 동영상 스트리밍처럼 데이터의 신뢰성보다 속도에 중점을 둬야하는 경우 자주 사용하게 됩니다.

19. (C#) abstract와 interface에 대해 설명하라.

더보기

abstract는 대상을 추상화하는 키워드입니다. abstract 키워드에 의해 추상화 된 대상은 독립적으로 존재할 수 없게 되므로 자식 클래스에서 대상을 구체화해야만 정상적으로 사용이 가능합니다.

interface는 추상화된 객체에 몇가지 제약을 더해 외부에서 편하고 안전하고 기능을 사용할 수 있도록 도와주는 키워드입니다. interface는 C#에서 유일하게 다중상속이 허락된 객체이지만, 다중상속의 위험성을 방지하기 위해 부모 클래스는 가지는 것이 불가능하고 멤버 변수를 가질 수 없습니다. 또한, 내부에 선언된 메서드는 모두 자식 클래스에서 재정의되어야만 합니다. 

20. 객체지향의 4가지 특징에 대해 설명하라.

더보기

객체 지향의 4가지 특징은 상속, 캡슐화, 추상화, 다형성입니다. 상속은 한 클래스 내부에서 선언, 정의한 것을 다른 클래스가 물려받는 것을 의미합니다. 이는 객체의 성질을 표현하는 것에도 도움이 되지만 코드의 재사용성을 높이는 것에도 도움이 됩니다.

 

캡슐화는 연관이 있는 특성을 묶어 내부에서 구현한 뒤, 구체적인 구현부는 외부에 공개하지 않고 기능 사용에 관련된 인터페이스만 공개하는 것을 의미합니다. 캡슐화가 잘 된 객체의 경우 외부에서 객체의 성질을 함부로 변형할 수 없지만, 필요에 따라 객체에서 제공하는 기능은 사용할 수 있기 때문에 안정성, 유지보수성 등을 높일 수 있습니다. 

 

추상화는 클래스를 상속받을 대상의 공통적인 속성을 추려내는 것을 의미합니다. 자식 클래스들이 모두 공통적인 속성을 보유하고 있다면, 해당 속성과 관련된 메서드, 멤버 변수 등을 부모 클래스에서 선언한 뒤 자식 클래스에서 이를 정의하는 방향으로 설계할 수 있습니다. 이러한 과정을 거치면 다양한 자식 클래스가 통일성 있게 작동할 수 있습니다.

 

다형성이란 대상이 다양한 모습으로 표현되고 사용될 수 있는 것을 의미합니다. 상속 관계에 있는 클래스가 부모 클래스로도 표현될 수 있고 자식 클래스로도 표현될 수 있는 것이 다형성의 대표적인 예시입니다.

 

이러한 객체지향의 특징을 살리는 방향으로 코드를 설계한다면 안전하고 유지보수가 용이하며 사용이 편리하고 가독성이 높은 코드를 설계할 수 있습니다.

21. LOD와 밉맵에 대해 설명하라.

더보기

LOD는 특정 기준에 따라 버텍스의 수를 조절하여 매쉬의 디테일 수준을 조절하는 기법입니다. 멀리 있는 대상 혹은 작게 그려지는 대상을 디테일하게 렌더링하는 것은 연산의 낭비로 이어질 수 있기 때문에, 거리, 투영면적 등의 기준에 따라 LOD단계를 조절하여 최적화를 달성할 수 있습니다.

 

밉맵은 LOD와 동일한 기술을 텍스쳐에 적용하는 기술입니다. 디테일하게 렌더링 될 필요가 없는 대상의 텍스쳐 해상도를 낮춰 연산 낭비를 줄이는 기법입니다.

 

두 기술 모두 속도 측면에선 최적화에 큰 도움이 되지만, 단계별 리소스를 별도로 저장해야 하기 때문에 메모리를 많이 사용하게 된다는 단점이 있습니다.

22. 렌더링 파이프라인을 요약해서 설명하라.

더보기

렌더링 파이프라인이란, 데이터로만 존재하는 오브젝트를 모니터에 출력하기 위해 거치는 일련의 과정을 의미합니다. 렌더링 파이프라인은 3D공간에 있는 물체에 WVP 행렬을 곱하여 2D 평면에 투영한 뒤, 뷰포트 행렬을 통해 대상이 그려질 픽셀을 건져내고 쉐이더 등을 통해 최종적인 색상을 결정하는 과정으로 진행됩니다.

23. C#의 static 키워드에 대해 설명하라.

더보기

멤버 변수나 메서드가 인스턴스에 종속되지 않고 클래스에 종속되도록 만들어주는 키워드입니다.

 

static으로 생성된 멤버 변수는 프로세스가 생성되고 초기화되는 과정에서 메모리에 저장되기 때문에 인스턴스가 생성되지 않은 시점에서도 대상을 사용할 수 있게 됩니다. static 멤버 변수는 데이터 영역에 위치하는 만큼, 멤버 변수가 인스턴스별로 생성되는 것이 아니라 모든 인스턴스가 하나의 변수를 공유하여 사용하게 됩니다. 여러 인스턴스가 하나의 변수를 공유하는 만큼 static 멤버 변수의 데이터의 안전성을 보장할 수 있는 방향으로 설계해야 합니다.

 

static 메서드의 경우는 함수를 호출하는데 this가 필요하지 않기 때문에 인스턴스가 없어도 독립적으로 사용할 수 있게 됩니다. 다만, 이러한 이유 때문에 함수 내부에서 this가 필요한 작업은 수행할 수 없다는 단점이 있습니다.

24. (C# )컬렉션이란?

더보기

컬렉션이란, 닷넴 프레임워크에서 지원해주는 데이터 관리용 클래스를 의미합니다.

25. (C#) List와 ArrayList의 차이를 설명하라.

더보기

List는 generic을 기반으로 데이터를 보관하는 자료구조이고, ArrayList는 object를 기반으로 데이터를 보관하는 자료구조 입니다.

 

List는 generic을 사용하는 만큼 선언할 때 명시한 자료형에 해당하는 데이터만 저장할 수 있지만, ArrayList는 C#의 모든 객체가 공통으로 상속받고 있는 object 자료형으로 데이터를 저장하기 때문에 모든 자료형의 데이터를 저장할 수 있습니다.

 

List는 자료형이 한정되어 있는 만큼 ArrayList에 비해 활용성이 다소 제한되어 있지만, 그만큼 안정성이 높으며 boxing, unboxing과정을 거치지 않아 성능 부분에서도 우위에 있다는 장점이 있습니다. 반대로 ArrayList는 안정성이 낮고 boxing, unboxing 과정으로 인해 느린 속도를 보인다는 단점이 있지만 활용성이 매우 넓다는 장점이 있습니다. 

26. BFS와 DFS에 대해 설명하라.

더보기

두 알고리즘 모두 그래프를 완전탐색하는 알고리즘입니다. BFS는 너비우선탐색으로 시작 노드와 가까이에 있는 노드를 우선적으로 탐색하는 알고리즘입니다. 반면, DFS는 노드의 자식노드를 재귀적으로 순회하며 탐색하는 알고리즘입니다. BFS는 가까이에 있는 대상을 DFS보다 먼저 탐색할 확률이 높지만, DFS는 반대로 멀리 있는 대상을 BFS보다 먼저 탐색할 확률이 높다는 차이가 있습니다.

27. 메모리 정렬이란? 

더보기

모든 데이터는 차지하는 메모리 크기의 배수에 해당하는 메모리 주소에 위치해야 합니다. 구조체처럼 메모리에 연속적으로 위치해야 하는 데이터들이 메모리 주소에 올바르게 위치하려면 데이터 사이에 패딩 데이터를 추가하여 데이터가 위치하는 메모리 주소를 맞춰주어야 합니다. 이를 메모리 정렬이라고 합니다. 

28. 내부단편화란?

더보기

메모리 풀링 등을 사용하여 미리 할당한 메모리영역 내에서 메모리가 비효율적으로 사용되는 것을 의미합니다. 실제 필요한 메모리 공간에 비해 불필요하게 많은 메모리를 할당하는 경우 내부 단편화가 발생할 수 있습니다.

29. (유니티) ILtoCPP란?

더보기

프로그래머가 유니티 엔진을 사용할 때는 C#을 사용해 코드를 작성하게 됩니다. 닷넴 프레임워크에서 작동되는 C#은 컴파일 타임에 IL이라는 중간언어로 번역되고  IL이 런타임에 기계어로 변환되는 과정을 거치지만, 유니티 엔진은 그러한 과정을 거치지 않고 IL을 다시 C++로 디컴파일 한 뒤 다시 기계어로 컴파일하는 과정을 거칩니다. 이 작업을 통해 실제로 실행되는 게임은 C++ 코드로 실행되며 닷넴 프레임워크에 의해 실행될 때에 비해 높은 성능을 가지게 됩니다. 

30. 내적과 외적에 대해 설명하라.

더보기

내적은 두 벡터의 방향이 얼마나 일치하는지를 구하는 수학적 개념입니다. 두 벡터를 내적하게 되면 두 벡터의 길이와 사잇각의 코사인 값을 곱한 스칼라 값을 얻을 수 있습니다. 두 벡터의 길이를 안다면 두 벡터의 사잇각을 구할 수 있기 때문에, 게임 프로그래밍에선 두 오브젝트의 위치 관계를 구하는데 사용할 수 있습니다.

 

외적은 두 벡터가 속한 평면의 법선 벡터를 구하는 수학적 개념입니다. 두 벡터를 외적하게 되면, 두 벡터에 모두 수직인 벡터를 구할 수 있습니다. 이를 활용하여 두 오브젝트의 위치 관계를 구하는데 사용할 수 있습니다.

 

내적의 경우, 대상이 나의 앞에 있나 뒤에 있나를 구할 수 있지만 왼편에 있는지 오른편에 있는지는 구할 수 없기 때문에 외적을 추가적으로 사용하여 나의 왼편에 있는지 오른편에 있는지를 구할 수 있습니다.

31. 프로세스 스케줄링이란?

더보기

CPU의 코어는 동시에 여러 작업을 수행할 수 없습니다. 하지만, 실제 컴퓨터에선 여러 작업이 동시에 수행되어야 하기 때문에 CPU는 프로세스를 작은 작업으로 쪼갠 뒤 이를 고속으로 번갈아 수행하며 여러 프로세스가 동시에 실행되는 것처럼 보이게 해줍니다. 

 

이처럼 여러 프로세스가 번갈아가며 수행될 때 효율성을 높이기 위해선 프로세스를 어떤 순서로 얼만큼씩 작업하는가를 구체적으로 설정할 필요가 있습니다. 이를 구체적으로 설정하는 작업을 프로세스 스케줄링이라 하며 이는 운영체제에 의해 수행됩니다.

32. 스케줄링의 선점형, 비선점형에 대해 설명하라.

더보기

선점형 스케줄링이란 한 작업이 실행되고 있을 때 다른 작업을 수행하기 위해 현재 작업이 중단될 가능성이 있는 스케줄링을 의미합니다. 

 

비선점형 스케줄링이란 현재 실행중인 작업이 완료되기 전까진 다른 작업을 수행하지 않는 스케줄링을 의미합니다.

33. 소켓 통신이란?

더보기

소켓 통신이란, 소켓을 사용하는 통신 방법을 의미합니다. 소켓을 사용하여 서버와 클라이언트가 특정 포트번호를 통해 양방향으로 통신하는 방식으로, TCP 프로토콜의 통신 방법입니다.

34. 무브 시맨틱이란?

더보기

깊은 복사의 단점인 성능 저하를 최소화하기 위해, 다시는 사용되지 않을 것이 확신한 객체를 복사할 때 얕은 복사를 응용한 이동 연산을 사용하는 최적화 기법입니다.

35. auto 키워드

더보기

자료형을 프로그래머가 명시하지 않고 컴파일러의 추론에 맡기는 키워드 입니다. 자료형이 길고 복잡하거나 프로그래머가 추론하기 힘든 상황에 편리하게 사용할 수 있지만, 자료형을 한 눈에 알아볼 수 없기 때문에 가독성이 저하될 수 있다는 단점이 있습니다.

 

+ Recent posts