오늘은 기술 면접을 보았는데, 튜터님께서 해주신 피드백이 중요하다고 생각해서 적는다!
오늘은 게임 클라이언트 프로그래머로 지원하게 된 계기와 가비지 컬렉터에 대한 기술 면접이 있었다.
안녕하십니까? 제 이름은 아무개라고 합니다.
제가 게임 클라이언트 프로그래머를 지원하게 된 계기에 대해 말씀드리겠습니다.저는 평소에 게임하는 것을 좋아하기 때문에, 제가 플레이했던 게임들의 반응들을 살펴보기 위해 리뷰 영상이나 커뮤니티를 자주 확인하는 편입니다.
그럴 때마다 제가 게임을 즐기면서 느꼈던 긍정적인 경험들이 다른 사람들에게서도 똑같이 공유되는 것이 제게는 굉장히 고무적으로 다가왔습니다.그러다 문득, 제가 게임 개발에 참여해서 유저들에게 즐거운 경험을 느끼게 해주고 싶다는 생각이 들었습니다. 저 스스로가 게임을 하면서 즐거운 경험을 했듯이, 다른 유저분들에게 즐거운 경험을 드릴 수 있는 게임을 만드는 것이 제 지원 동기입니다.
단순히 지원 계기만 말하고 끝낼 것이 아니라, 그래서 내가 이걸 위해 어떤 공부를 했고 어떤 준비를 했는지 또한 말을 할 수 있어야 한다고 하셨다. 생각해보니 내 지원 계기가 중요한 것이 아니라 그를 위해 어떤 준비를 했는지 어필하는 것이 더 중요할 것 같다. 예를 들어
이를 위해 저는 게임 개발에 대한 지식, 팀원들과 협업하는 경험을 하기 위해 게임 개발 부트 캠프에 참여하고, 매일 공부한 내용을 TIL로 작성하는 등 준비를 했습니다.
최소한 이 정도는 붙어야 할 것 같다...
동적으로 할당한 메모리를 직접 해제하지 않고, 더 이상 사용이 되지 않을 경우 할당된 메모리를 알아서 해제 시켜주는 기능입니다. 프로그래머가 직접 해제하지 않기 때문에 메모리 관리가 편리하나, 자주 호출될 경우 프로그램 성능에 악영향을 끼칠 수 있습니다.
내가 한 답변은 이러했다. 그러나 튜터님께서는 기술 면접에 필요한 주요 포인트들이 하나도 안 들어가 있다고 말씀하셨다.
예를 들어, 참조 카운트나 메모리 해제 시점과 같은 키워드들이 빠졌다고 하셨다.
→ 가비지 컬렉터의 의미, 작동 방식을 설명하면 괜찮지 않을까 싶다. 내일 튜터님께 피드백 받아봐야 할듯?
가비지 컬렉터는 할당되어 있는 메모리가 더 이상 참조되지 않는다고 판단될 경우 할당된 메모리를 해제해주는 기능으로, 판단 방법으로는 추적 기반 방식과 참조 카운팅 방식이 있습니다. 추적 기반의 경우, GC가 특정 시점에 메모리를 확인하여 더 이상 접근이 불가한 메모리를 쓰레기로 분류, 해제하는 방식입니다. 참조 카운팅의 경우, 어떤 메모리가 다른 메모리에 의해 참조되면 카운트를 더하고, 더 이상 참조되지 않으면 카운트를 빼는 방식으로, 해당 카운트가 0이 되면 쓰레기로 분류, 해제하는 방식입니다. GC는 프로그래머가 직접 메모리를 해제하지 않아도 되기 때문에 메모리 관리에 편리하나, 자주 호출될 경우 프로그램의 성능에 악영향을 끼칠 수 있습니다.
할당된 메모리를 직접 해제하는 방법과, 메모리를 할당할 때 최소한으로 생성하거나 재사용이 가능하게끔 생성하는 방법이 있습니다. 전자의 경우는 GC를 임의로 실행시키거나 Dispose과 같은 메서드를 활용하여 메모리 해제를 할 수 있으며, 후자의 경우 오브젝트 풀링과 같은 최적화 방법을 활용할 수 있습니다.
해당 답변은 그래도 패스를 받았다.
메모리 관리 기법 중 하나로, 메모리에 할당된 객체가 더 이상 참조되지 않을 경우 해당 객체를 메모리에서 해제를 시켜주는 프로세스입니다. 이를 실행하는 주체가 가비지 컬렉터입니다.
나는 단순히 이렇게 대답을 했으나, 튜터님께서 참조 세대에 대한 키워드가 빠졌다고 하셨다.
가비지 컬렉션이란, 메모리 관리 기법 중 하나로, 메모리에 할당된 객체가 더 이상 참조되지 않을 경우 해당 객체를 메모리에서 해제를 시켜주는 프로세스입니다. 이를 위해서 C#에서는 참조 세대를 사용하여 가비지를 분류하는 데, 0, 1, 2세대 총 3개의 세대로 구분을 하며, 세대 구분을 통해 객체의 수명을 분류하여 관리할 수 있습니다. 가비지로 분류되지 않고 남게 되면 다음 세대로 승격을 하게 되며 메모리가 부족하지 않은 한 1 ~ 2세대를 굳이 확인하지 않기 때문에, 확인해야 할 객체들의 양을 줄여 효율적으로 가비지를 회수할 수 있습니다.
이번 프로젝트에서 플레이어의 무기가 몬스터를 공격했을 때, 해당 몬스터의 Layer가 Enemy인지 판별을 한 후에 맞다면 데미지를 가하는 방식으로 코드를 작성했는데, OnTriggerEnter에서 LayerMask를 비교할 때 계속해서 실패를 했었다.
왜인지 찾아보니 문제는 크게 2가지 였다.
충돌하는 두 물체에 Collider가 필요한 것은 알고 있었지만, 둘 중 하나에 반드시 Rigidbody가 필요하다는 사실을 까먹고 있었다.
때문에 기억해두기 위해 작성한다.
LayerMask를 검사할 때, 비트 연산을 통해 비교를 하게 되는데, 해당 방법을 까먹고 단순히 비교 연산자로 비교를 했기 때문에 당연히 비교가 되지 않았다.
위와 같은 방식으로 Layer를 비교하고 있었으니 코드가 당연히 동작을 하지 않았다...
비트 연산을 통해 비교하니 문제를 해결할 수 있었다. 비트 연산을 통해 비교하기 위해서는 목표 LayerMask와 비교 대상 LayerMask를 OR 연산한 뒤에 비교를 해야 한다.