*자료구조와 알고리즘* — *Java 와 Python* 의 *서로 다른 *결*
자료구조 와 *알고리즘 은 언어 *무관 한 *개념 — 이라고 교과서 에 쓰여 있다. 그러나 Java 에서 *짠 *동일 알고리즘 과 Python 에서 *짠 *알고리즘 은 코드 *모양, 성능, 심지어 *생각의 *순서 까지 다르다. 두 언어 의 *서로 다른 *결 을 알면 — 둘 다 *깊이 *써 본 사람 만이 가지는 *시야 가 생긴다.
TL;DR
| 차원 | Java | Python |
|---|---|---|
| 정체성 | 정적 타입 / JIT 컴파일 | 동적 타입 / 인터프리터 (+ CPython) |
| 자료구조 표현 | 명시 적 클래스 (ArrayList, HashMap) | 내장 *문법 ([] / {} / set()) |
| 성능 (Big-O 동일) | 상수 계수 *작음 — 빠름 | 상수 계수 *큼 — 5~50배 느림 |
| 알고리즘 작성 | 명시 적 + 장황 | 간결 + 표현 력 |
| 학습 적합도 | 원리 이해 + 시스템 직관 | 빠른 시도 + 알고리즘 문제 친화 |
| 실 무 | 대형 백엔드 / 엔터프라이즈 | 데이터 / ML / 스크립트 / 자동화 |
핵심 통찰 :
두 언어 는 *서로의 *약점을 *보완 한다. Java 가 *시스템 의 *깊이, Python 이 알고리즘 의 *간결.
1. 두 언어 의 *정체성
Java
1995 출시 (Sun → Oracle)
정적 타입 / 강 한 타입
JVM 위에 동작
JIT 컴파일 → 어셈블리 *직접 실행*
모든 게 *클래스 안* (primitive 외)
→ 대규모 / 장기 운영 시스템 친화. 기업 / 백엔드 / Android 의 기둥.
Python
1991 출시 (Guido van Rossum)
동적 타입 / 강 한 타입
인터프리터 (CPython 표준)
*JIT 는 *PyPy 등 *대안 구현* 만
모든 게 *객체* (int, str, function 까지)
*간결 + 표현 력* 의 *철학*
→ 데이터 / ML / 스크립트 / 빠른 프로토 타입 친화. 과학 계산 + AI 의 *표준 언어.
2. 자료구조 비교 — 같은 개념 의 *다른 *모습
2.1. Array / List
// Java
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
int first = list.get(0);
# Python
list = []
list.append(1)
list.append(2)
first = list[0]
→ Python 은 *문법 자체 가 자료구조 표현. Java 는 *명시 적 *클래스 호출.
| 항목 | Java ArrayList | Python list |
|---|---|---|
| 삽입 (말미) | O(1) amortized | O(1) amortized |
| 임의 접근 | O(1) | O(1) |
| 메모리 효율 | 높음 (primitive 활용 시) | 낮음 (모든 게 객체) |
| 동시성 | 별도 *synchronizedList | GIL — 단일 thread |
2.2. Hash Map / Dictionary
// Java
Map<String, Integer> map = new HashMap<>();
map.put("a", 1);
int v = map.get("a");
# Python
d = {}
d["a"] = 1
v = d["a"]
→ Java 의 HashMap 은 Java 8 부터 *충돌 시 *Tree 변환 (성능 보장). Python 의 dict 는 3.6 부터 *insertion order 유지 — 순서 가 *기본.
2.3. Set
Set<Integer> s = new HashSet<>();
s.add(1);
boolean has = s.contains(1);
s = set()
s.add(1)
has = 1 in s
→ 동작 동일. Python 의 *in 키워드 가 코드 의 *읽힘 *명확.
2.4. Stack / Queue / Deque
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
int top = stack.pop();
Deque<Integer> queue = new ArrayDeque<>();
queue.offer(1);
int head = queue.poll();
from collections import deque
stack = deque()
stack.append(1)
top = stack.pop()
queue = deque()
queue.append(1)
head = queue.popleft()
→ Java 는 *Deque 한 클래스 *모두 활용. Python 은 *collections.deque — 별도 import.
2.5. Tree / TreeMap
// Java — *내장 *TreeMap (Red-Black Tree)*
TreeMap<Integer, String> sorted = new TreeMap<>();
sorted.put(5, "five");
sorted.put(1, "one");
// 자동 *키 정렬*
# Python — *내장 없음*. sortedcontainers 또는 *수동 구현*
from sortedcontainers import SortedDict
sd = SortedDict()
sd[5] = "five"
sd[1] = "one"
→ Java 가 *우위 인 영역. 정렬 된 Map / Set 가 기본 제공. Python 은 *외부 라이브러리 필요.
2.6. Heap / PriorityQueue
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
minHeap.offer(3);
minHeap.offer(1);
int min = minHeap.poll(); // 1
import heapq
heap = []
heapq.heappush(heap, 3)
heapq.heappush(heap, 1)
min = heapq.heappop(heap) # 1
→ Java 의 PriorityQueue 가 *OO 적. Python 의 heapq 가 *함수형 + list 기반 — 익숙해지면 *간결.
3. 알고리즘 *표준 라이브러리
Java — Stream API
List<Integer> nums = List.of(1, 2, 3, 4, 5);
int sum = nums.stream()
.filter(n -> n % 2 == 0)
.mapToInt(Integer::intValue)
.sum();
Python — Comprehension + functools / itertools
nums = [1, 2, 3, 4, 5]
# Comprehension — *가장 *Pythonic*
sum_val = sum(n for n in nums if n % 2 == 0)
# 또는 functools
from functools import reduce
sum_val = reduce(lambda a, b: a + b, [n for n in nums if n % 2 == 0])
→ Python 의 comprehension 이 알고리즘 작성에 *매우 *효과. Java 의 Stream 은 체이닝 + 명시 가 읽기 *명확.
정렬
// Java
List<Integer> sorted = nums.stream().sorted().toList();
// 또는
Collections.sort(nums);
nums.sort(Comparator.naturalOrder());
# Python — *5 가지 방법*
sorted_list = sorted(nums) # 새 리스트 반환
nums.sort() # in-place
sorted(items, key=lambda x: x.name) # key 지정
sorted(items, reverse=True) # 역순
→ Python 의 sorted() 가 알고리즘 문제 *풀이 에 압도적 *친화.
집합 연산
// Java — *Set 연산*
Set<Integer> a = Set.of(1, 2, 3);
Set<Integer> b = Set.of(2, 3, 4);
Set<Integer> intersection = new HashSet<>(a);
intersection.retainAll(b);
# Python — *연산자 *자체*
a = {1, 2, 3}
b = {2, 3, 4}
intersection = a & b
union = a | b
diff = a - b
→ Python 이 수학 *연산자 *직접 지원. 집합 알고리즘 에 압도적 강점.
4. 성능 비교 — 같은 알고리즘 의 *다른 *비용
벤치 마크 (대략적 수치)
같은 *Quicksort* 100 만 정수 :
Java : 150 ~ 200 ms
Python : 3500 ~ 5000 ms (CPython)
PyPy : 300 ~ 500 ms (JIT)
→ 순수 알고리즘 에서 Java 가 *15~30 배 빠름.
왜 이 차이?
- JIT vs Interpreter — Java 의 어셈블리 직접 실행 대 Python 의 바이트코드 해석.
- 타입 정보 — Java 는 컴파일 시 *타입 확정 → 최적화 가능. Python 은 런타임 *타입 *체크 매번.
- 메모리 표현 — Java 의 primitive int = 4 바이트. Python 의 int = 26 바이트 (객체 헤더 + 가비지 컬렉션 정보 + 값).
- GIL (Global Interpreter Lock) — Python 의 멀티 thread 가 *진짜 병렬 안 됨.
그럼에도 Python 이 *빠른 경우
- NumPy / SciPy / pandas — C 로 구현 된 *벡터 연산. Java 보다 빠를 수 도.
- 외부 라이브러리 (TensorFlow, PyTorch) — C++/CUDA 의 *호출 래퍼. Python 은 조립.
→ Python 의 진짜 강점 은 *C 라이브러리 의 *조립 — 순수 Python 만 으론 느림.
5. 알고리즘 학습 *측면
Python 이 학습에 *친화 한 이유
# Tower of Hanoi — 간결
def hanoi(n, src, dst, aux):
if n == 0: return
hanoi(n-1, src, aux, dst)
print(f"Move disk {n} from {src} to {dst}")
hanoi(n-1, aux, dst, src)
hanoi(3, 'A', 'C', 'B')
- 문법 잡음 적음 — 알고리즘 자체에 *집중 가능
- REPL 즉시 시도 — 학습 cycle 짧음
- 제출 환경 (LeetCode, Codeforces) 의 기본 언어
Java 가 학습에 *유리한 이유
- 타입 의 *명시 — 변수 의 *형태 가 *눈에 보임
- OO 의 *직접 표현 — 클래스 + 인터페이스 의 *직 관
- 시스템 SW (DB, Kafka, ES) 의 *내부 구조 가 *Java 에 *가깝다
→ 둘 다 *배우는 게 *최적 — Python 으로 *알고리즘 의 *흐름 익히고, Java 로 *시스템 의 *깊이 익힘.
6. 실 무 *측면
Java 가 적합한 도메인
- 대형 백엔드 (Spring Boot)
- Android 앱
- 대용량 *분산 시스템 (Kafka, Elasticsearch, Cassandra)
- 금융 / 결제 (정확성 + 성능)
- 장기 운영 시스템 (안정성)
Python 이 적합한 도메인
- 데이터 분석 / 시각화 (pandas / matplotlib)
- 머신러닝 / AI (PyTorch, TensorFlow)
- 과학 계산 (NumPy, SciPy)
- 자동화 / 스크립트 (DevOps, CI/CD)
- 빠른 프로토 타입 / MVP
- 교육 / 학생 *입문 언어
둘 다 *쓰는 *흔한 패턴
Java : 백엔드 API + DB + 시스템 통신
Python : 데이터 파이프라인 + ML 모델 + 분석 스크립트
*같은 회사 의 *서로 다른 시스템*
대부분 기술 팀 의 주력 백엔드 + 보조 Python 패턴.
7. 알고리즘 의 *실 무 *순간
Java 의 흔한 알고리즘 *순간
// 상품 목록 *N+1 회피 — *해시 활용*
Map<Long, Category> categoryMap = categoryRepo.findAll().stream()
.collect(Collectors.toMap(Category::getId, c -> c));
for (Product p : products) {
Category c = categoryMap.get(p.getCategoryId()); // O(1)
// ...
}
→ Hash Map 으로 O(n × m) → O(n + m) 개선.
Python 의 흔한 알고리즘 *순간
# 대용량 CSV 의 *집계*
from collections import defaultdict, Counter
import csv
counter = Counter()
with open('data.csv') as f:
for row in csv.DictReader(f):
counter[row['category']] += 1
top10 = counter.most_common(10) # *내장 *우선순위 큐 활용*
→ Python 의 collections 모듈 — Counter / defaultdict / deque — 알고리즘 *간결.
8. 둘의 *함정
Java 의 흔한 함정
- List.contains(o) — O(n). HashSet 이 *대부분 적합.
- Stream + parallel 남용 — 작은 데이터 에선 *오히려 *느림.
- Auto-boxing —
int↔Integer의 암묵 변환 비용. - ConcurrentModificationException — iterating 중 *수정 시.
- equals / hashCode 미구현 — HashSet / HashMap 이 *동작 *예측 불가.
Python 의 흔한 함정
- list 의 *list slicing 비용 — 복사 발생. 큰 list 의 *반복 slice 위험.
- Mutable default *인자 —
def f(x=[])는 공유 됨. for i in range(n): list.append(i)— 대량 데이터 시 *NumPy 활용 권장.- GIL 의 *모르고 *threading — 멀티 thread 가 *병렬 안 됨 (
multiprocessing또는asyncio). - dict.keys() / values() 반복 중 수정 — 예외 발생.
9. 언제 *어느 *언어 인가 — 결정 가이드
*시스템* + *성능* + *안정성* → Java
*데이터* + *ML / AI* + *빠름* → Python
*Android 앱* → Java / Kotlin
*과학 계산* → Python (+ NumPy)
*Scripting / 자동화* → Python
*Big Data 처리* → 둘 다 (Spark : Java + PySpark)
*면접 코딩* → Python (간결)
*시스템 면접* → Java (구조)
→ 둘 다 익혀라 — 각자 의 *영역 이 *명확 하다.
10. 본인 *경험 — Java + Python 의 *7 년
Java 주력 + Python 보조 패턴
본인은 주력 Java (Spring Boot) 인데 Python 도 *매주 *5 시간 *정도 쓴다 :
- DB 데이터 *분석 — pandas
- AWS / GCP / K8s *스크립트 — boto3 / kubectl wrapper
- 간단 한 *데모 / 프로토 타입
- 로그 *파싱 + 알람
- AI 호출 / 임베딩 *처리
이 2 언어 조합 이 서로 보완. Java 가 *시스템 *구축, Python 이 *데이터 + 운영 *유연 성.
알고리즘 학습 의 Python 효과
LeetCode / Codeforces 풀이 *전부 Python. *Java 보다 *2~3 배 빠르게 *작성. 알고리즘 의 *흐름 에 집중 가능.
단 — 실 무 *Java 환경 에선 *그 알고리즘 을 *다시 Java 로 변환. 그 *변환 의 *경험 자체 가 깊이.
11. 마치며
Java 와 Python 은 *서로 의 *약점 을 *보완 한다. 둘 다 *깊이 *써 본 사람 만 이 *볼 수 있는 *시야 가 있다*.
3 줄 요약 :
- Python 으로 *알고리즘 의 *흐름 익히고, Java 로 *시스템 의 *깊이 익혀라.* 둘 다.
- Big-O 가 같아도 *상수 계수 의 *차이 가 5~50 배.* Python 의 NumPy 등 *C 호출 * 활용 이 진짜 강점.
- 언어 선택 보다 *자료구조 + 알고리즘 의 *직 관 이 더 *중요 하다.* 언어 는 *도구, 직관 은 능력.
7 년차 회고 :
“학부 시절 *Java 만 *쓴 게 *후회. Python 의 *간결 표현 이 알고리즘 학습 의 *속도 를 *바꾼다.”*
다음 글 — 알고리즘 의 *직 관 — Big-O 너머 실 무 *비용 지도. 같은 시리즈 로 이어 집니다.
본 글은 7년차 백엔드 *엔지니어 의 *Java + Python 동시 운영 회고. 벤치 마크 수치 는 환경 / 버전 에 따라 다를 수 있다. 원리 + 비율 의 *직 관 에 무게 중심 을 두는 게 오래 가는 지식.