| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- 추상 팩토리 패턴
- Visual Studio Installer
- event bus
- Unity 기술면접
- 구글 스프레드 시트
- New Input System
- 구글플레이콘솔
- 게임 디자인 패턴
- 기술면접
- Render Mode
- 개발
- 데이터 형식
- 오브젝트 풀
- github desktop
- 상태 패턴
- 테이블 데이터
- 프로젝트 생성
- Di
- 콘솔 앱
- Canvas Scaler
- Dependency Injection
- 이벤트 버스
- unity
- C#
- Object Pool
- 의존성 주입
- MVP 패턴
- Abstract Factory Pattern
- 스타일 지침
- 유니티
- Today
- Total
DevDino
[Unity 기술면접] C# 컬렉션 비교: Array, List, ArrayList, LinkedList 본문
"Array와 List의 차이는 무엇인가요?"
C# 컬렉션 비교: Array, List, ArrayList, LinkedList
Array(배열)
- 고정 길이의 자료구조로, 선언 시 크기가 정해지며 이후에는 크기를 변경할 수 없습니다.
- 연속된 메모리를 사용하여 캐시 적중률(Cache Hit)이 높고, 인덱스를 통한 접근 속도가 가장 빠릅니다.
- 데이터의 개수가 변하지 않으며, 순차적이고 빠른 접근이 필요한 경우에 적합합니다.
int[] arr = new int[3] {1, 2, 3};
List(제네릭 동적 배열)
- 가변 길이를 지원하며 현재 C#과 유니티에서 가장 표준적으로 사용되는 자료구조입니다.
- 내부적으로는 Array를 사용합니다. 데이터가 꽉 차면 기존 크기의 2배인 새로운 배열을 할당하고 기존 데이터를 복사하는 방식(동적 확장)으로 작동합니다.
- 확장이 일어날 때 메모리 할당(GC 발생)과 복사 비용이 발생하므로, 예상되는 데이터의 최대 개수를 안다면 생성 시점에 Capacity를 미리 지정해 주는 것이 유니티 최적화에 유리합니다.
// 초기 Capacity를 지정하여 불필요한 배열 재할당 방지
List<int> list = new List<int>(10);
list.Add(1);
list.Add(2);
ArrayList
- List가 등장하기 전(C# 1.0 시절)에 사용되던 비제네릭(Non-generic) 동적 배열입니다.
- 모든 요소를 object 타입으로 저장합니다.
- 값 타입(int, float 등)을 넣고 뺄 때 박싱(Boxing)과 언박싱(Unboxing) 과정이 발생합니다. 이는 힙(Heap) 영역에 가비지(Garbage)를 대량으로 생성하여 유니티의 가비지 컬렉터(GC) 스파이크를 유발하고 프레임 드랍의 원인이 됩니다. 현재는 사용을 지양해야 하는 레거시 구조입니다.
ArrayList arr = new ArrayList();
arr.Add(10); // Boxing 발생 (int -> object)
int n = (int)arr[0]; // Unboxing 발생(object -> int)
LinkedList(이중 연결 리스트)
- 노드(Node) 기반의 구조로, 각 요소가 데이터와 다음/이전 노드의 참조(주소) 정보를 함께 저장합니다.
- 메모리가 연속적으로 배치되지 않으며, 노드의 참조만 연결/해제하면 되므로 중간 삽입과 삭제의 처리 속도가 빠릅니다.
- 특정 인덱스 요소에 접근하려면 처음부터 노드를 타고 이동해야 하므로 접근 속도가 매우 느립니다.
LinkedList<string> linked = new LinkedList<string>();
linked.AddLast("A");
linked.AddLast("B");
자료구조 성능 요약
| 자료구조 | 데이터 접근(인덱싱) | 데이터 삽입/삭제(중간) | 데이터 삽입(끝) | 특징 및 주의사항 |
| Array | O(1) | 크기 변경 불가 | 크기 변경 불가 | 메모리 캐시 효율 최고, 크기 고정 |
| List | O(1) | O(n) (데이터 밀기/당기기) | O(1) (단, 확장 시 O(n)) | 가장 범용적, 초기 Capacity 설정 권장 |
| ArrayList | O(1) | O(n) | O(1) | 박싱/언박싱으로 인한 GC 스파이크 유발. 사용 지양 |
| LinkedList | O(n) | O(1) (단, 위치를 알 때만) | O(1) | 인덱스 접근 불가, 노드 객체 생성 비용 존재 |
요약
- 데이터의 개수가 고정되어 있고 빠른 접근이 필요하다면 Array를 사용합니다.
- 데이터의 추가/삭제가 필요하면서도 범용적인 상황이라면 List를 사용하되, 가급적 초기 용량을 할당하여 GC를 줄입니다.
- ArrayList는 타입 안전성이 없고 박싱/언박싱 오버헤드가 크기 때문에 유니티에서는 사용하지 않습니다.
- 잦은 중간 삽입/삭제가 필요하다면 LinkedList를 고려할 수 있으나, 탐색 시간과 노드 생성으로 인한 힙 메모리 할당을 염두에 두어야 합니다.
'Unity > 기술면접' 카테고리의 다른 글
| [Unity 기술면접] Unity Quaternion과 Gimbal Lock (0) | 2026.01.07 |
|---|---|
| [Unity 기술면접] Dictionary vs Hashtable (0) | 2026.01.06 |
| [Unity 기술면접] C# string은 왜 불변(Immutable) 객체일까? (0) | 2026.01.02 |
| [Unity 기술면접] C# Garbage Collector (0) | 2026.01.01 |
| [Unity 기술면접] C# vs C++ 메모리 관리 (0) | 2025.12.29 |