[Technical Interview] 게임 클라이언트 면접 복기_1
과거 면접 때, 답변 복기
(중복되는 것들도 있을 수 있음)
- 코드 짤 때 중요사항이 있다면?
4가지 사항을 얘기하고 설명했다.
가독성 : 코드가 얼마나 읽기 쉬운가?, 사용한 이름은 적절한가?, 함수의 길이가 너무 길어서 보기 힘들지는 않는가?
무결성 : 버그가 없는가?, 버그가 예상되는 코드는 없는가?, 방어적으로 코드를 짰는가?
유연성 : 나중에 기획이 변경되었을때 쉽게 변경할 수 있는가?, 동시에 변경해야 하는 부분이 흩어져있지 않는가?
재사용성 : 코드가 잘 설계되어 있는가?, 관계있는 부분끼리 잘 모여있는가?
1. 디자인 패턴
싱글턴 : 이펙트, 사운드 관리, 전체적인게임관리?
> 문제 : 네트워크 동기화 문제 생길 수 있다.
옵저버 : 스타크래프트 ui출력 부분에 사용
> 사용한 이유 : 서로의 객체 직접참조 문제해결을 위해 사용
소멸한 객체를 참조했을 때의 문제해결을 위해 사용
추상팩토리 : 객체들을 다양한 형태로 생성을 위해 사용
컴포넌트 : 플레이어의 움직임, 충돌처리
사용 이유 : 공식같다. 팀원들과 구조적인것에 대해 설명할 때 편하다
2. 깊은 복사 얕은 복사
메모리 공유의 차이
얕은 복사 : 같은 메모리 공유
깊은 복사 : 새로운 동적 할당을 통해 다른 메모리 사용
3. 오버로딩 라이딩
라이딩 서로다른인자를 같은 함수로 사용
4. 스택과 힙의 차이
사용자가 원할 때 할당하고 해제할 수 있는 것
스택 : 지역을 벗어나면 해제가 된다.
5. L - Value 와 R - Value
왼쪽과 오른쪽에서의 대입이 불가능하다.
L - Value
R – Value
예시 ) int a = 1; 1 = a;
7. c++ 과 자바의 차이점
인터페이스의 유무
자바 : 가비지 컬렉터 ( 자동으로 되고, 매 주기마다 실행) , 인터페이스(순수가상함수만)
개발자가 깊은 부분을 관여할 수 없다.
C++ : 쉐어드ptr(스마트포인터) , 추상클래스, 인터페이스라는 개념이 없다.
10. 소멸자에 virtual을 붙여야하는 이유
부모의 소멸자가 먼저불려서 메모리 누수가 일어난다.
자식의 소멸자를 먼저 호출하게 하기위해
부모의 소멸자가 먼저 호출되어서 자식의 소멸자가 불려서 문제가 생기다.
11. 부모자식 생성자 호출 순서, 소멸자 호출 순서
생성자가 불리기 전에 메모리 할당
생성자 : 부 자
소멸자 : 자 부 메모리 해제
12. 다중상속
다이아몬드
같은이름의 함수를 사용하게 되서 모호성이 발생한다.
13. 추상클래스를 포인터형으로 사용가능한가
가능하다. 추상클래스를 객체로써 사용이 불가능할 뿐이지 포인터로는 사용가능하다
15. 애플리케이션에서 함수가 메모리상에서 동작하는 원리
코드 영역을 찾아서 함수에 대하 주소를 가져온 후 함수에 들어가서 함수 안에 있는 로직들을 동작시킨 후 함수 들어오기 전에 있었던 위치를 기록하고 함수가 끝나면 전에 있던 위치로 돌아가다.
16. 인라인함수
.h에서 사용. 전처리기 시점에서 컴파일 될 수 있게 하기 위해 사용했다.
인라인 사용 유무는 컴파일러가 결정하다
17. 인라인과 매크로의 차이
매크로 함수 단순 치환. 디버깅이 힘들다.
인라인 함수 될 수도 안될 수도 있다.
18. 헤더 파일에 썼던 이유
전처리기 시점에서 확인하기 때문에 전처리기 시점에 헤더파일을 읽으며 판단을 내린다.
19. class 와 object의 차이
클래스는 오브젝트를 만드는 툴. 클래스를 인스터싱하여 오브젝트를 만든다.
21. 클래스를 초기화 할 때 멤버변수를 어떤 방식으로 초기화 해주었는지
클래스를 초기화 시 이니셔라이저를 통해서 초기화를 실시.
초기화 할 수 없는 것들은 생성자 내부에서 했다.
위 두개 차이 : 이니셔라이저는 전처리기 시점
생성자는 런타임 시점
Const는 이니셔라이저에서 해주면 가능하다.
선언과 동시에 해주어야하기 때문에 헤더에서 해주던가 이니셔라이저를 통해서 한다.
이니셔라이저와 생성자 두개에서도 초기화 가능하다
리인터프리캐스트로 const를 초기화 할 수 있다.
22. strcmp 동작 원리
자체에서 임시변수를 통해 비교하면서 확인을 한다.
ㅇ임시변수를 만들 필요?
필요없다 두개 문자열이 들어왔으면 한 글자씩 인덱스 접근을 통해 비교하며 임시 변수가 필요없다
반환값 같으면 -1, 다르면 true를 반환
Ø 다르면 0이 아닌값, 값으면 0이 나온다.
23. c와 c++의 다르점
C 절차지향 c++ 객체지향
절차지향 순차적, 순서가 중요 시 된다.
객체지향 객체관의 관계를 중심으로
더 깊고 많지만 이 정도만 미리 얘기.
24. 객체를 배열로 만든다면 메모리는 어떤 식으로 되는가?
각각의 배열마다 초기화 할 수 있는 방법?
Memset을 사용 객체안에 포인터가 없다는 전제하에 사용
생성자를 이용할 수 있는 방법은 없는지?
비효율 적이지만 for문을 돌려서 초기화 생성하는 방식으로 한다.
그런식으로 안하면 복사생성자가 불릴 것이다.
25. 깊이우선, 너비우선
깊이우선 : 하나의 노드를 왼쪽부터 선택하면 자식노드까지 쭉 내려간다.
너비우선 : 바로 옆의 노드를을 참조하면서 내려간다.
위 2개를 구현할 때 한 가지의 자료구조를 쓸 수 있다면 어떤 것을 쓸 것인지?
깊이 : list로 사용한다. 자신의 자식 노드를 탐색하ㅐ야하기 떄문에 다음 자식 노드를 연결해서 연속된데이터로 가능
너비 : 순서 관련 없이 주변 순차적으로 내려가면 될거같아서 map을 사용한다.
26. 랜더링 파이프라인 순서 및 간략 설명
순서에 따라 정의한 걸 말했다.
로컬 : 각 객체들이 가지고 있는 좌펴 개념, 다른 점이 원점이 될 수 있다.
월드 : 월드의 원점을 정해서 각 원점을 통해 움직이는 것
뷰 : 원점에 카메라강 잇고 z값에 양의 방향에 … 공전
후면 : ccw,cw, none을 통해 뒷면 렌더 유무를 확정
조명 : 조명에 대한 연산
클리핑 : 절두체 안에서 객체가 있는지 없는 렌더링 유무 결정
투영 : n차원을 n-1로 변환 과정
부포트 : 모니터 종횡비에 맞게 x축을 늘려준다.
레스터라이트 : 폴리곤을 픽셀 단위로 연산
27. 쉐이더 사용 이유
정점 단위가 아니라 픽셀 단위에서 연산을 해주고 싶었기 때문.
픽셀 쉐이더로 가능한 이유?
펙셀의 개수 만큼 작동하기 때무에 원하는 구역을 픽셀을 넘겨주고 색을 넘겨주면 변경이 되기때문에 가능하다.
29. 개인 3d 충돌은 어떻게 구현했는지
각 공격에 대한 애니메이션 프로그레스 값을 얻어 특정 프로그래스에 구충돌을 통해
콜리션 매니저를 통해 각 객체에 대한 충돌을 통해 했다.
한 프레임을 알 수 있는 방법은?
애니메이션 총 크기를 알 수 있는 변수와 현재 진행도를 비율로 통해서 얻었다.
30. 프로젝트 중 가장 어려웠던 점과 극복을 어찌 했는지.
마지막 팀프로젝트 리소스에 대한 문제가 많았다. 팀원들이 다들 어떻게 해결해야할지 물어봄.
부담감을 느낌 . 구글 시트로 구현 계획을 정함. 리소스 어려움은 각 파트별로 담당하게끔
계획 틀어졌을 때 대책은?
무리를 해서라도 계획을 맞추었다. 물리적으로 불가능 한 것들은 회의를 통해서 정했다.
해결 또는 이후에 할당을 통해 해결했다.
기술적으로 문제를 해결한 것은?
이펙트를 렌더할 때 directx특성상 2048이 최대였는데, 4028을 사용해야해서 처음 순간적인 렌더가 발생. 로딩창에서 한 번 미리 렌더를 해서 문제를 해결 했다.
31. 디버깅을 어떤 식으로 하고 있는지?
디버깅 시 항상 북마크를 사용함. 계속 멈추기 보다는 북마크를 함수 호출 시점으로 하여 문제를 해결함.
중단점, 프레임저하는 성능프로파일링을 통해 과부하 걸리는 부분을 찾아 냈다.
32. 프로세스와 스레드 차이
프로세스 자원을 할당받는 단위. 컨텍스트 스위칭이 일어날 때 코드 데이터 스택 힙이 다 바뀌다.
쓰레드는 모드 공유해서 사용하기 떄문에 컨텍스트 스위칭 없었다.
서로의 장단점은?
-쓰레드
각자의 쓰레드마다 연결 통신이 쉬움 자원공유 떄문에 특수한 자원을 망가트릴 수 있다.
시작되는 시점이 다르기 때무에 싱글턴을 사용하면 동기화가 잘못될 수 있다.
-프로세스
리소스들을 고유하기 않기 때문에 안정적.
컨텍스트 스위칭 떄무에 오버헤드 발생.
cpu에서 컨텍스트 스위칭 일어나는 과정?
Cpu로 자원을 가져옴 메모리 공간에 있는 것을 패치를 통해 버스에 태운 후 디패치를 통해 익시큐트를 통해
34. fsm 구현 방법
Api 기본적인 초기화 업데이트 나감으로 구분해서 사용함
나중에는 3가지로는 부족하다는 판단
초기화 업데이트 레이트업데이트 애니메이션 나갈건지말거지 분기
상태들의 변환은 어떻게 이루어지는지?
업데이트와 레이트업데이트 함수에서 if문을 통해 각자 상태에 맞는 특수 조건을 만들어 상태변화을 했다.
구조는 state라는 클래스를 만들고, 자바에있는 인터페이스 가상함수만 있는 것을 만들어서 결국은 자식에서 오버라이딩을 통해서 패턴들이 호출되게끔 구현했다.
상태들은 각자 자식들이 가지고 있다.
플레이어가 상태가 많아질수록 데이터 늘어난다.