Part 1 · 자료구조10 분 읽기

자료구조: 앱의 속도를 결정하는 데이터 그릇

배열, 리스트, 해시맵, 스택, 큐, 트리, 그래프를 앱의 속도와 유지보수성을 결정하는 데이터 그릇으로 이해하는 실전 가이드입니다.

게시일: 2026년 6월 24일최종 업데이트: 2026년 6월 26일

프로그램은 결국 데이터를 다룹니다. 이름, 가격, 예약, 메시지, 사용자 ID, 문서, 파일, 권한, 관계.

자료구조는 이 데이터를 담는 그릇입니다.

그릇이 중요한 이유는 단순합니다. 어떤 일은 쉬워지고, 어떤 일은 느려지고, 어떤 일은 나중에 발목을 잡습니다.

주방을 떠올려 보세요. 모든 양념을 박스 하나에 던져 넣을 수도 있고, 라벨 붙은 작은 통에 나눠 담을 수도 있습니다. 둘 다 "보관"이지만 "소금 어디 있어?"라는 질문 앞에서는 두 번째 주방이 압도적으로 빠릅니다.

그게 자료구조입니다.

실전 질문

"어떤 자료구조를 외워야 하지?"로 시작하지 마세요.

대신 이렇게 물어보세요.

  • 특정 항목 하나를 빨리 찾아야 하나?
  • 순서가 중요하나?
  • 중간에 자주 넣거나 빼야 하나?
  • 계층 구조를 표현해야 하나?
  • 복잡한 연결 관계를 표현해야 하나?

답이 그릇을 가리킵니다.

0123
배열
번호 매긴 사물함
위치로 바로 열 수 있음
리스트
줄 선 사람들
중간 삽입이 자연스러움
keyvalue
해시맵
이름표 달린 사물함
이름만 알면 즉시 찾음
스택
쌓아둔 책
마지막 것부터 꺼냄 (LIFO)
카페 줄
먼저 온 것부터 처리 (FIFO)
트리
폴더 구조
부모-자식 계층 표현
그래프
지하철 노선도
복잡한 연결 관계 표현

배열과 리스트: 줄 세우기

실무에서 "배열"과 "리스트"는 자주 섞여 쓰입니다. JavaScript의 Array, Python의 list, Java의 ArrayList는 이름은 List지만 내부적으로는 **동적 배열(dynamic array)**입니다. 반면 CS 교과서에서 말하는 "리스트"는 흔히 **연결 리스트(Linked List)**를 의미합니다.

CS에서의 차이

**배열(Array)**은 번호가 붙은 연속된 사물함입니다.

  • 23번 사물함이 필요하면 바로 열 수 있습니다. 인덱스 접근이 O(1)입니다.
  • 중간에 뭔가를 끼워 넣으면 뒤의 것들을 한 칸씩 밀어야 합니다.
  • 크기가 고정인 경우가 많습니다.

**연결 리스트(List)**는 손을 잡고 줄 선 사람들입니다.

  • 중간에 사람을 끼우려면 양옆 사람의 손만 바꾸면 됩니다. 삽입/삭제는 O(1)이지만, 위치를 찾는 데는 O(n)이 걸립니다.
  • 23번째 사람을 찾으려면 앞에서부터 한 명씩 세어야 합니다.
  • 크기는 자유롭게 늘어납니다.
관점배열연결 리스트
메모리 구조연속된 공간흩어진 노드 + 포인터
인덱스 접근O(1), 바로 열기O(n), 앞에서부터 세기
중간 삽입/삭제O(n), 뒤를 밀어야 함O(1), 양옆 연결만 바꿈
크기보통 고정자유롭게 늘어남
메모리 사용적고 예측 가능포인터 저장으로 추가 메모리

실무 언어에서는?

언어이름실제로는
JavaScriptArray동적 배열
Pythonlist동적 배열
JavaArrayList동적 배열
JavaLinkedList연결 리스트
C++std::vector동적 배열
C++std::list연결 리스트

언제 무엇을 쓰나요?

배열/동적 배열을 쓰는 경우

  • 인덱스로 빠르게 접근해야 할 때.
  • 데이터를 끝에 자주 추가/삭제할 때.
  • 메모리를 연속적으로 쓰고 싶을 때.
  • 예: 검색 결과, 상품 목록, 테이블 행, 정렬된 데이터.

연결 리스트를 쓰는 경우

  • 중간 삽입/삭제가 매우 잦을 때.
  • 인덱스 접근보다 순회가 많을 때.
  • 크기를 미리 알 수 없고 자주 변할 때.
  • 예: 큐/스택 구현, 실행 취소 기록, 메모리 블록 연결.

앱에서는 이런 형태로 자주 만납니다.

  • 상품 목록.
  • 검색 결과.
  • 채팅 메시지.
  • 테이블 행.
  • 워크플로 단계.

해시맵: 이름표 달린 사물함

**해시맵(Hash Map)**은 실무에서 가장 자주 사랑받는 자료구조 중 하나입니다.

번호 대신 이름표가 붙은 사물함을 떠올리면 됩니다.

  • user_123
  • cart_total
  • appointment_2026_06_25
  • feature_flag_checkout

이름표를 알고 있으면 거의 바로 값을 찾을 수 있습니다.

해시맵은 거의 모든 곳에 나옵니다.

  • 사용자 ID로 정보 찾기.
  • API(앱끼리 요청과 응답을 주고받는 약속) 응답 캐싱.
  • 단어가 몇 번 나왔는지 세기.
  • 설정값을 이름으로 저장.
  • 상태별로 레코드 묶기.

스택과 큐: 쌓을까, 줄 세울까

**스택(Stack)**은 책상 위에 쌓은 책입니다. 마지막에 올린 책을 가장 먼저 뺍니다.

이 방식을 LIFO, 즉 마지막에 들어온 것이 먼저 나가는 방식이라고 합니다.

스택은 이런 곳에 나옵니다.

  • 브라우저 뒤로 가기.
  • 실행 취소(Undo).
  • 함수 호출.
  • 중첩 구조 해석.

**큐(Queue)**는 카페 줄입니다. 먼저 온 사람이 먼저 주문합니다.

이 방식을 FIFO, 즉 먼저 들어온 것이 먼저 나가는 방식이라고 합니다.

큐는 이런 곳에 나옵니다.

  • 이메일 발송.
  • 백그라운드 작업.
  • 프린트 대기열.
  • 메시지 처리.
  • 처리 대기 중인 AI 작업.

트리와 그래프: 가지와 네트워크

**트리(Tree)**는 계층입니다.

폴더 안의 폴더. 댓글의 답글. 회사 조직도. 서브메뉴가 있는 메뉴.

트리는 각 항목에 부모와 자식이 있을 때 유용합니다.

**그래프(Graph)**는 네트워크입니다.

SNS 친구 관계. 지하철역. 서로 링크된 웹페이지. 서로 관련된 상품.

그래프는 관계가 단순히 위에서 아래로 흐르지 않을 때 유용합니다. 하나가 여러 방향으로 여러 것과 연결될 수 있습니다.

한눈에 비교

자료구조일상 비유잘하는 일약한 일앱에서 쓰이는 곳
배열번호 매겨진 사물함위치로 빠르게 접근중간 삽입/삭제정렬된 목록, 테이블 행
리스트줄 선 사람들유연한 증가/변경위치 직접 접근자주 바뀌는 순서
해시맵이름표 달린 사물함키로 빠른 조회순서 보장사용자 조회, 캐시, 설정
스택쌓아둔 책마지막 것 먼저 처리중간 접근Undo, 뒤로 가기
카페 줄먼저 온 것 먼저 처리중간 접근작업, 메시지, 대기열
트리폴더 구조계층 표현교차 연결메뉴, 댓글, 파일
그래프지하철 노선도복잡한 연결탐색 비용SNS, 길찾기, 추천

AI가 만든 앱에서 자주 보이는 문제

AI는 프롬프트 안의 작은 예시 데이터에는 맞는 코드를 잘 씁니다. 문제는 예시 데이터가 보통 아주 작다는 것입니다.

주의할 패턴:

  1. 배열을 모든 곳에 사용 빠른 검색, 중복 제거, 포함 여부 확인이 필요한데도 전부 배열로 처리합니다.

  2. array.find() 반복 ID로 자주 찾는 데이터를 매번 목록에서 선형 검색합니다. Map(키로 바로 찾는 구조)이나 객체 딕셔너리가 더 적합한데 쓰지 않습니다.

  3. 중복 확인을 목록으로 처리 이미 존재하는 값인지 확인할 때 includes()를 반복합니다. Set(중복 없는 집합)을 쓰면 더 단순하고 빠릅니다.

  4. 관계형 데이터를 중첩 객체로만 저장 user → posts → comments → likes처럼 깊게 중첩해서 저장해 업데이트와 조회가 복잡해집니다.

  5. 정규화되지 않은 상태 같은 데이터가 여러 곳에 복사되어 있고, 하나를 수정하면 다른 곳에는 오래된 데이터가 남습니다.

  6. 트리 구조를 목록처럼 처리 카테고리, 메뉴, 조직도, 댓글 스레드 같은 계층 데이터를 매번 전체 순회로 찾습니다.

  7. 그래프 문제를 트리처럼 처리 친구 관계, 추천, 의존 관계, 작업 흐름처럼 순환이 가능한 구조에 방문 기록 없이 재귀를 돌립니다.

  8. 큐가 필요한 곳에 array.shift() 사용 작업 대기열, 알림, 백그라운드 작업을 array.shift()로 처리해서 데이터가 커질수록 느려집니다.

  9. 스택/큐 개념 없이 재귀 남용 깊은 트리나 작업 흐름을 재귀로만 처리해 스택 오버플로 위험이 생깁니다.

  10. 우선순위 큐가 필요한 곳에 매번 정렬 가장 중요한 작업, 최신 이벤트, 최고 점수 항목을 찾기 위해 전체 목록을 매번 정렬합니다.

  11. LRU/캐시 구조 없이 단순 객체 캐시 사용 캐시 크기 제한, 만료, 제거 정책 없이 데이터를 계속 쌓습니다.

  12. 인덱스 역할을 하는 자료구조 부재 검색, 필터, groupBy, count를 매번 원본 목록에서 다시 계산합니다.

  13. 중첩 객체 직접 수정 깊은 객체를 직접 바꿔서 React 상태 변경 감지, 실행 취소/다시 실행, 변경 비교가 꼬입니다.

  14. 대용량 데이터를 하나의 거대한 객체로 관리 부분 업데이트가 어려워지고, 작은 변경에도 전체 구조를 복사하거나 다시 렌더링합니다.

  15. 데이터 접근 방식과 자료구조가 맞지 않음 읽기가 많은지, 쓰기가 많은지, 순서가 중요한지, 빠른 검색이 중요한지 고려하지 않고 기본 목록/객체만 사용합니다.

자주 묻는 질문

자료구조란 무엇인가요?

자료구조는 프로그램이 정보를 효율적으로 저장, 검색, 변경, 연결할 수 있도록 만드는 정보의 모양입니다.

배열과 리스트 중 무엇을 써야 하나요?

인덱스로 빠르게 접근하고 주로 끝에서 추가/삭제해야 할 때는 배열이나 동적 배열을 씁니다. 중간 삽입/삭제가 매우 잦아 병목이 될 때만 연결 리스트를 고려하세요.

해시맵은 언제 쓰나요?

고유한 key로 값을 거의 즉시 찾아야 할 때 씁니다. 사용자 ID로 프로필 찾기, API 응답 캐싱, 이름으로 설정값 찾기 등이 예시입니다.

스택과 큐의 차이는 무엇인가요?

스택은 마지막에 넣은 것을 먼저 꺼내는 last-in-first-out 구조입니다. 큐는 먼저 온 것을 먼저 처리하는 first-in-first-out 구조입니다.

트리는 언제 리스트 대신 쓰나요?

데이터에 부모와 자식이 있는 계층 구조가 있을 때 씁니다. 폴다 구조, 댓글과 답글, 조직도 등이 예시입니다.

핵심 정리

자료구조는 시험용 지식이 아닙니다. 제품의 기억이 어떤 모양을 갖는지 결정합니다.

맞는 그릇을 고르면 코드가 자연스러워집니다. 틀린 그릇을 고르면 모든 기능이 싸움이 됩니다.

저자 소개

송재희

송재희

포춘 500대 기업을 위한 데이터 시스템을 구축한 20년 이상의 경력을 가진 엔터프라이즈 데이터 플랫폼 아키텍트. 바이브 코딩과 AI 개발을 수백 명의 학생에게 가르친 AI 개발 교육자. 한국 기술 스타트업이 미국 시장을 navigating하도록 돕는 Seattle Partners의 창립자.

AI 개발 가이드 저자