백엔드 개발에서 많이 사용하는 자료구조는 List라고 생각합니다
주로 게시글 목록,조회 결과,API 응답 데이터 등 여러 데이터를 순서대로 다뤄야 하는 상황에서 사용됩니다
여기서 List를 왜 사용하고 어떤 구현체를 통해 구현했는지에 대해 알아보고자 합니다
Spring 기반 프로젝트에서 List를 어떤 기준으로 사용했는지에 대해서 작성합니다
1. 백엔드에서 List를 사용하는 상황
프로젝트에서 List 자료구조는 다음과 같은 상황에서 주로 사용한다
- DB 조회 결과 저장
- REST API 응답 데이터 구성
List<Post> posts = postRepository.findAll();
해당 상황에 대한 공통점은 데이터가 여러 개이며 순서가 중요하고 중복을 허용하는 데이터인 경우가 많았다
이 조건을 만족하는 자료구조는 List가 적합하다고 생각합니다
2. List의 구현체는 어떤 걸 사용해야 좋을까?
List의 대표적인 구현체로는 ArrayList와 LinkedList가 있다
이 중 대부분의 상황에서 ArrayList를 기본적으로 사용했다 구현체의 특징을 살펴보면 그 이유를 알 수 있다
2-1. ArrayList 특징
- ArrayList는 내부적으로 배열(Array) 기반으로 동작한다
- 연속적인 데이터의 리스트가 메모리 공간에 저장됨
- 배열 기반이기 때문에 인덱스를 통한 접근이 빠르다
- 조회가 많은 백엔드 환경에서 읽기 성능 뛰어나다
- 리스트의 중간에 데이터를 삽입/삭제하는 경우 요소들을 한 칸씩 이동해야 하기 때문에 성능 비용이 발생
Post post = posts.get(0);
2-2. LinkedList 특징
- LinkedList는 각 요소가 노드(Node) 형태로 구성되며 노드들이 이전/다음 노드를 가리키는 포인터로 연결된 구조
- 배열처럼 연속된 메모리 공간을 사용하지 않고 비순차적으로 저장된다
- 포인터로 연결된 구조로 공간의 제약이 없으며 삽입/삭제 성능이 뛰어나다
- 특정 인덱스의 요소에 접근하기 위해 처음부터 순차적으로 탐색해야 하는 순차 탐색으로 이루어져 조회 성능이 떨어진다
- 각 노드는 데이터 + 포인터 정보를 함께 저장하기 때문에 ArrayList에 비해 추가적인 메모리 공간이 필요하다
| 구분 | ArrayList | LinkedList |
| 내부 구조 | 배열 기반 | 노드 연결 구조 |
| 메모리 | 연속적 | 비연속적 |
| 조회 성능 | 빠름 (O(1)) | 느림 (O(n)) |
| 중간 삽입/삭제 | 느림 | 상대적으로 유리 |
| 메모리 사용 | 적음 | 상대적으로 많음 |
| 백엔드 사용 빈도 | 높음 | 낮음 |
2-3. 백엔드에서는 "조회"를 주로 사용하기 때문에 ArrayList를 선택한다
백엔드 API 개발에서 List는 대부분 조회된 데이터를 DTO로 감싸 반환하는 용도로 사용된다
List<PostResponse> responses = postService.findAll();
이러한 사용 패턴은 다음과 같다
- 리스트 생성 이후 데이터를 추가하는 작업은 거의 한 번
- 이후에는 조회와 순회가 대부분
- 중간에 데이터를 삽입하거나 삭제하는 경우는 드물다 (주로 DB에서 작업)
쓰기보다 읽기가 더 많은 구조를 가지고 있기 때문에 인덱스를 통한 접근이 빠른 ArrayList가 자연스러운 선택이 된다
물론 리스트의 중간에 삽입/삭제가 빈번히 일어나는 구조라면 LinkedList의 구조적 장점으로 사용될 수 있을 것 같다
실제 백엔드 환경에서는 데이터를 DB에 저장하고 삽입/삭제/변경 등을 DB에서 처리하기 때문에 애플리케이션에서 List는 조회용으로 사용하는 경우다 대부분이다 그렇다 보니 ArrayList를 사용하는 경우가 많다고 생각이 드네요