Spark 면접 단골 질문 모음
Apache Spark Structured Streaming 워터마크 공식 문서 및 면접 단골 질문 정리 (웹 리서치, 2026) — Apache Spark 공식 문서(structured-streaming-programming-guide.html) + Databricks 기술 블로그 종합 여러 Spark 인터뷰 준비 자료·기술 블로그에서 공통으로 반복되는 질문을 교차 확인해 정리
이 모듈을 다 읽으면
- 면접에서 반복적으로 나오는 Spark 핵심 질문에 짧고 정확하게 답할 수 있다
- 각 질문의 답이 이 카테고리의 어느 심화 모듈과 연결되는지 알아 필요하면 더 깊이 파고들 수 있다
이 카테고리의 44개 심화 모듈에서 이미 다룬 내용을 전제로, 실제 면접에서 반복적으로 나오는 질문만 뽑아 짧고 정확한 모범답안 형태로 재구성했다.
Q. RDD, DataFrame, Dataset은 어떻게 다른가?
RDD는 타입은 있지만 최적화되지 않은 저수준 분산 객체 컬렉션이다(Catalyst/Tungsten 최적화 대상이 아님). DataFrame은 Row 객체의 컬렉션으로 스키마가 있고 Catalyst 최적화를 받지만 컴파일 타임 타입 안전성은 없다. Dataset은 DataFrame에 컴파일 타임 타입 안전성을 더한 것(Scala/Java에서만 완전히 지원, PySpark의 DataFrame은 사실상 Dataset[Row]다). 실무에서는 최적화 혜택 때문에 DataFrame/Dataset을 우선하고, RDD는 저수준 제어가 꼭 필요할 때만 쓴다(spark-learn-05, 09, 22 참고).
핵심 포인트
- RDD=저수준·최적화 없음, DataFrame=스키마+Catalyst최적화·타입안전성 없음, Dataset=DataFrame+컴파일타임 타입안전성
Q. narrow transformation과 wide transformation은 어떻게 다른가?
narrow transformation(map, filter 등)은 각 입력 파티션이 정확히 하나의 출력 파티션에만 기여해 셔플이 필요 없다. wide transformation(groupByKey, join, repartition 등)은 하나의 출력 파티션을 만들려면 여러 입력 파티션의 데이터가 필요해 셔플(네트워크를 통한 데이터 재분배)이 발생한다. 셔플은 Spark 성능 튜닝에서 가장 자주 다뤄지는 병목 지점이다(spark-learn-24, 33 참고).
핵심 포인트
- narrow: 파티션 간 데이터 이동 없음(셔플 X) / wide: 셔플 발생 — 성능 튜닝의 핵심 관찰 대상
Q. persist()/cache()는 언제 써야 하는가?
같은 DataFrame/RDD를 여러 액션에서 반복적으로 재사용할 때 유리하다 — 캐시하지 않으면 매 액션마다 그 DataFrame을 만드는 전체 연산 체인(지연 평가 특성상)이 처음부터 다시 실행된다. 다만 Execution 메모리가 Storage 메모리보다 우선하므로(spark-learn-40 참고), 무거운 셔플이 뒤따르면 캐시된 블록이 축출돼 재계산이 일어날 수 있다는 점도 함께 알아야 한다.
핵심 포인트
- 같은 데이터를 여러 액션에서 재사용할 때 재계산을 피하는 용도 — 단, Execution 메모리 압박 시 축출될 수 있다
Q. 데이터 스큐(skew)는 어떻게 대응하는가?
조인 키 하나에 데이터가 몰리면 그 파티션을 처리하는 태스크만 오래 걸리는 straggler 현상이 생긴다. Spark 3.0+의 AQE skew join 최적화(spark-learn-24, 41)가 실행 중 통계로 스큐 파티션을 자동으로 쪼개 완화해주며, 수동으로는 조인 키에 무작위 접두사를 붙이는 salting 기법을 쓸 수 있다.
핵심 포인트
- AQE skew join(3.0+)이 우선 고려 대상, 수동 대응은 salting
Q. broadcast join은 언제 쓰이고 무엇을 해결하는가?
조인할 두 테이블 중 한쪽이 충분히 작으면(기본 임계값 10MB) 그 테이블 전체를 모든 executor에 복사해, 셔플 자체를 없애고 각 executor가 로컬에서 조인하게 만든다. 큰 테이블과 작은 차원 테이블(dimension table)을 조인하는 전형적인 스타 스키마 패턴에서 특히 효과적이다(spark-learn-24, 42 참고).
핵심 포인트
- 한쪽이 작을 때(기본 10MB 미만) 셔플을 없애는 조인 전략 — 큰테이블+작은차원테이블 조인에 전형적
Q. Structured Streaming에서 exactly-once는 어떻게 보장하는가?
세 요소가 함께 필요하다: (1) 재현 가능한 소스(Kafka처럼 오프셋으로 되감기 가능), (2) 체크포인트(checkpoint)로 각 마이크로배치의 진행 상황과 상태를 안정적으로 기록, (3) 멱등적(idempotent)이거나 트랜잭션을 지원하는 싱크(sink) — 장애로 같은 배치가 재실행되더라도 결과가 중복 반영되지 않아야 한다. 셋 중 하나라도 빠지면 정확히 한 번 처리를 보장할 수 없다(spark-learn-25 체크포인트 관련 내용 참고).
핵심 포인트
- 재현 가능한 소스 + 체크포인트 + 멱등적/트랜잭션 싱크, 세 가지가 함께 갖춰져야 exactly-once
Q. Python UDF가 성능에 안 좋다고 하는데 왜 그런가?
Python UDF는 Catalyst 옵티마이저가 내부 로직을 들여다볼 수 없는 '블랙박스'로 취급돼 여러 최적화(프레디케이트 푸시다운 등)가 그 지점에서 막힌다. 게다가 JVM(Spark 실행 엔진)과 별도 Python 프로세스 사이에 매 행(또는 배치)마다 데이터를 직렬화/역직렬화해서 주고받아야 하는 오버헤드가 크다. 가능하면 내장 함수(built-in functions)나 pandas UDF(벡터화돼 배치 단위로 직렬화 오버헤드를 줄임)를 우선 검토하는 게 일반적인 조언이다.
핵심 포인트
- Python UDF는 Catalyst 최적화를 못 받는 블랙박스 + JVM-Python 직렬화 오버헤드가 큼
- 가능하면 내장 함수나 벡터화된 pandas UDF를 우선 검토
Q. Structured Streaming에서 늦게 도착하는 데이터는 어떻게 처리되는가?
withWatermark로 지정한 지연 임계값을 넘어서 도착한 데이터는 무시된다. 워터마크는 동시에 '더 이상 안 바뀔 윈도우'의 상태를 정리하는 기준이기도 해서, 무한 스트림에서도 상태 크기를 유한하게 유지하게 해준다(spark-learn-44 참고).
핵심 포인트
- 워터마크 지연 임계값을 넘긴 데이터는 무시됨 + 그 시점 지난 윈도우 상태는 정리됨