스파르타 게임개발종합반(Unity)/TIL - 본캠프 매일 공부 기록

2024.07.25 TIL - 면접 질문지 답변 작성해보기

테크러너 2024. 7. 25.

0. 쿠키런 킹덤 1분 자기소개

안녕하십니까. 저는 이번 쿠키런 킹덤 신입 채용에 지원하게 된 성지윤입니다.

저는 곧 출시 예정인 픽셀몬 키우기라는 게임을 개발한 경험이 있습니다.

해당 게임을 만들면서, 기능 하나를 개발할 때마다 최적화와 개발 효율을 고려하여 적절한 기술을 선택했습니다. 실제로 구글 시트의 데이터를 수동으로 받아오는 작업이 번거로웠기 때문에, 변경사항을 자동으로 실시간 반영되도록 구현했습니다. 또한, 플레이어가 적을 탐색하는 로직을 구현할 때 세 가지 로직을 생각했고, 프로파일링을 통해 지표를 비교 분석하여 가장 성능이 좋았던 로직을 선택했습니다.

쿠키런 킹덤에 입사하게 된다면, 타당한 근거를 바탕으로 기술 결정 의사를 내리고, 최적화를 고려하며, 유저들이 어떻게 하면 게임을 더 재밌고 편하게 즐길 수 있을지 항상 생각하며 개발에 임하겠습니다.

감사합니다.

 

1. `struct`와 `class`의 차이점에 대해 설명해주세요.

`struct`는 값 타입으로, 데이터가 직접 저장되고 변수 간 복사 시 실제 데이터가 복사됩니다. 주로 스택에 저장되며 상속을 지원하지 않습니다. 반면 `class`는 참조 타입으로, 데이터는 힙에 저장되고 변수 간 복사 시 참조가 복사됩니다. 상속을 지원하여 객체 지향 프로그래밍에 사용됩니다.

 

** `C#10`부터 `struct`도 기본 생성자 지원됨.

https://learn.microsoft.com/ko-kr/dotnet/csharp/whats-new/csharp-10

 

2. 가비지 컬렉터가 하는 일과 가비지 컬렉터의 단점을 설명하세요.

가비지 컬렉터는 사용되지 않는 객체를 자동으로 메모리에서 해제하여 메모리 누수를 방지하고, 객체의 생애주기를 관리하여 프로그래머가 명시적으로 메모리를 해제할 필요를 없앱니다. 단점은 가비지 컬렉터가 빈번하게 발생하거나 오래 걸릴 경우 성능에 영향을 미치기 때문에 빈번하게 호출되지 않도록 최적화를 신경써서 프로그래밍해야 합니다.

 

3. 박싱과 언박싱에 대해 설명하세요.

박싱(Boxing)은 값 타입의 데이터를 참조 타입으로 변환하는 과정입니다. 반대로 언박싱은 박싱한 참조타입의 데이터를 값 타입으로 변환하는 과정입니다.

박싱은 힙에 메모리를 할당하고, 언박싱은 힙에서 값을 추출하기 때문에 빈번한 박싱과 언박싱은 성능 저하를 일으킬 수 있습니다.

 

4. 배열과 리스트의 차이에 대해 설명하세요.

배열은 고정된 크기를 가지며 동일한 데이터 타입의 요소를 연속적으로 저장합니다. 배열의 크기는 생성 시에 정의되며 이후로는 변경할 수 없습니다. 반면 리스트는 동적 크기를 가지며 요소를 추가하거나 제거할 수 있습니다. 리스트는 더 유연하지만 메모리 관리 및 성능 측면에서 배열보다 오버헤드가 있을 수 있습니다. 그래서 초기 용량을 미리 정해두면 성능을 최적화할 수 있습니다.

 

5. 빌드를 해봤다면, 최적화를 위해 무엇을 했는지 얘기해보세요.

첫 째로  객체의 생성과 파괴가 빈번하게 발생하여 가비지 컬렉터가 자주 호출되는 현상을 최적화하기 위해 오브젝트 풀링 기법을 사용했습니다.

둘 째로 sprite들은 아틀라스로 묶어서 드로우콜을 크게 줄여 렌더링 성능을 향상시켰습니다.

마지막으로, 플레이어가 적을 탐색하는 여러 가지 로직을 구상하여 프로파일링으로 비교 분석한 후, 성능이 더 좋은 로직을 선택하여 최적화를 진행했습니다.

+ 프로파일링 돌려보기

 

6. 스레드와 코루틴의 차이에 대해 설명하세요.

스레드는 별도의 실행흐름을 가져서 여러 스레드가 동시에 실행될 수 있습니다. 하지만 유니티는 싱글 스레드에서 동작하기 때문에 멀티스레딩을 직접적으로 활용하기 어렵습니다. 대신 유니티에서는 코루틴을 사용하여 비동기 작업을 처리할 수 있습니다. 코루틴은 함수의 일시 중단과 재개를 통해 비동기 작업을 표현합니다.

 

7. adressable이나 assetbundle 중 사용해 본 것에 대해 설명하세요.

Addressable을 사용해본 경험이 있습니다.

리소스를 로드할 때 리소스 매니저를 사용해 최초에는 캐싱하고, 이후에는 캐시된 데이터를 재활용하는 방식으로 효율적으로 관리합니다. 그러나 구글 스토어에 배포할 때 용량 제한 문제가 있습니다. 이를 해결하기 위해 어드레서블을 사용했습니다. 스토어에 유저가 게임을 다운로드할 때는 어드레서블 데이터를 다운받았는지 검사하는 코드만 포함되어 있고, 현재 앱 버전이 어드레서블 버전과 맞지 않다면, 서버에서 어드레서블 데이터를 앱에 다운로드하여 배포 시 용량 제한 문제를 해결할 수 있습니다. 제가 개발 중인 게임은 스토어에 배포할 예정이므로, 에셋 관리와 용량 제한 문제를 해결하기 위해 어드레서블을 사용하고 있습니다.

 

더보기

리소스 로드 로 불러오는건 효율이 안좋음

죽으면 다시 한 번 부를때 리소스 로드를 또 하면 안좋으면

리소스 로드를 하더라도 리소스매니저를 만들어서 최초엔 캐싱, 두 번짼 딕셔너리 검사 그거 재활용 없으면 리소스로드로 불러옴 이러면 어드레서블이나 에셋번들 필요없음

그럼 왜 튀어나왓냐 구글스토어 용량 제한

에셋들 다 빼고 에셋번들로 번들 빌드를 한다음에 aws나 파이어베이스나 서버에 올려둠

그리고 플레이스토어에 올리는 코드에는 데이터를 다운받았는지 검사 데이터 없으면 서버에 ㅈ접근해서 번들을 다운받는 코드만 있음. 유저가 다운받아 실행하면 패치돌아감 그때 에셋번들을 다운한다.

빌드때 용량을 줄일려고 에셋번들이 있음

에셋번들이 불편해서 어드레서블이 나옴

어드레서블을 쓰면  업데이트 재설치 안할 수 있다. 

게임이 인트로씬에 뜸 게임마다 본인 서버가 있음. 서버로 현재 실행되는 버전을 쏨. 어떤 버전으로 들어오네 인식

어드레서블만 패치를 한단계 높여둔 상태 -> 지금 접속한 버전에 어드레서블이 없네? 패치 바뀐거있으니 추가로 받아.

플레이스토어 접근안하고도 어드레서블로 패치진행 새로운 에셋들이 추가되거나 리소스가 바뀌거나 할 수 있다.

문제는 스크립트는 어드레서블로 안묶임 아예새로운 기능이 추가되는건 플ㄹ레ㅔ이 스토어로 가야함.

게임에 쓰이는 모든 소스코드랑 인트로신에서 어드레서블 없으면 서버로 다운받는것들 묶음이 스토어로 올라감

그외에는 어드레서블로 가있는 것.

이미지가 하나 안뜨다가 패치하고 이미지가 뜨는경우가 어드레서블만 패치를 다시 한 것

 

8. 디자인 패턴 중 사용할 수 있는 것이 있나요?

디자인 패턴 중 싱글톤 패턴과 옵저버 패턴을 사용할 수 있습니다. 싱글톤 패턴은 매니저 클래스들에 적용하여 어디서든지 해당 인스턴스에 접근할 수 있도록 했습니다. 옵저버 패턴은 액션 및 이벤트를 통해 객체의 상태 변화를 알리는 용도로 사용했습니다.

 

9. 비동기 처리에 대해 아는대로 설명해 주세요.

 

 

10. 확장 메서드가 뭔지 설명하고 어떻게 활용했는지 알려주세요.

확장 메서드는 C#의 기존 클래스에 새로운 메서드를 추가하는 방법입니다. 해당 클래스에 들어가서 수정하지 않고도 메서드를 추가할 수 있습니다.

제가 활용했던 사례는 펫 등급의 영문 이름을 enum으로 정의해놓은 것을 string형의 한국어로 반환해주는 메서드를 추가했던적이 있습니다. 클래스와 메서드에 static 키워들 붙이고, 매개변수로 enum타입을 받으며 this 키워드를 붙였습니다.

 

11. Reflection이 뭔지, 사용을 해봤다면 어떤 이유에서 사용했는지 설명해주세요.

Reflection을 사용하면 클래스의 메타정보를 가져올 수 있습니다. Reflection을 사용하면 클래스의 메타정보를 가져올 수 있습니다. Reflection을 사용한 경험으로는 클래스의 타입을 GetType() 메서드를 통해 가져와서 사용해봤습니다. 또한, 멤버 변수를 가져올 때는 GetFields() 메서드를, 멤버 프로퍼티를 가져올 때는 GetProperties() 메서드를, 멤버 함수를 가져올 때는 GetMethods() 메서드로 불러올 수 있습니다.

반응형

댓글