DevDino

[Unity 기술면접] C# 컬렉션 비교: Array, List, ArrayList, LinkedList 본문

Unity/기술면접

[Unity 기술면접] C# 컬렉션 비교: Array, List, ArrayList, LinkedList

데브다이노 2026. 1. 5. 15:26

 

"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를 고려할 수 있으나, 탐색 시간과 노드 생성으로 인한 힙 메모리 할당을 염두에 두어야 합니다.