개발에서의 정크 — 정크 코드란 무엇이며, 왜 해롭고 어떻게 제거할까

저자: IT Sectr 게시일: 2026-07-27 읽는 시간: 10 분

정크 코드(junk code)란 프로젝트에 이익을 가져오지 않지만 프로젝트 크기, 빌드 시간, 팀의 인지 부하를 증가시키는 코드와 의존성을 말합니다. 실행되지 않는 데드 코드와 달리 정크는 작동할 수 있지만 비효율적이거나 중복된 방식으로 작동합니다: 중복 라이브러리, 사용되지 않는 임포트, 주석 처리된 블록, 오래된 폴리필, 장식적인 추상화 등입니다. CodeScene Code Health Report (2025)에 따르면, 모바일 프로젝트의 평균 15% 의존성이 직접 사용되지 않고 전이 패키지만 끌어옵니다. 정크 코드는 프로젝트의 “여분의 무게”로, 코드베이스를 더 두껍게 만들지만 더 강하게 만들지는 않습니다. 정기적인 의존성 감사와 중복 추상화 제거는 빌드 속도와 코드 품질을 직접적으로 향상시킵니다.

핵심 요점

  • 정크는 이익 없이 프로젝트 크기를 증가시키는 쓸모없거나 중복된 코드와 의존성입니다.
  • 정크의 유형: 데드 의존성, 중복 라이브러리, 주석 처리된 코드, 빈 추상화.
  • 정크 의존성은 공격 표면을 증가시키고 CI 파이프라인을 느리게 합니다.
  • 감사 도구: Gradle dependencies(Android), SwiftPM audit(iOS), depcheck(Node.js).
  • 정기적인 정크 정리는 새 코드를 작성하는 것만큼 프로젝트 유지보수의 일부입니다.

정크 코드란?

정크(junk code)는 프로젝트에 존재하지만 기능적 가치를 제공하지 않는 코드, 구성 및 의존성에 대한 포괄적 용어입니다. 정크가 반드시 고장났거나 사용되지 않는 것은 아닙니다 — 문제는 그 존재가 적절한 정당성 없이 프로젝트 지표를 악화시킨다는 점입니다.

정크는 네 가지 범주로 나뉩니다. 첫째 — 중복 의존성: 표준 도구로 구현할 수 있는 단일 기능을 위해 추가된 라이브러리. 둘째 — 데드 웨이트: 주석 처리된 블록, 티켓 없는 TODO, 빈 메서드, 스텁 클래스. 셋째 — 중복 솔루션: 같은 일을 하는 두 라이브러리(예: 한 프로젝트에 Gson과 Kotlin Serialization). 넷째 — 오버 엔지니어링: 사용되지 않지만 “만일을 대비해” 유지되는 아키텍처 계층.

Stripe Engineering Productivity (2025) 연구에 따르면, 일반 프로젝트에서 10%의 정크를 제거하면 전체 빌드 시간이 평균 22% 단축됩니다. 이유: 추가 의존성은 빌드 그래프를 증가시키고, 빈 추상화는 이해하는 데 시간이 필요하며, 주석 처리된 블록은 주의를 산만하게 합니다.

정크와의 싸움에서 주요 어려움은 즉각적인 결과의 부재입니다. 정크 코드가 있는 프로젝트는 컴파일되고 작동합니다. 문제는 점진적으로 축적됩니다: 빌드가 느려지고, 전이 의존성 수가 증가하며, 1년 후에는 새 기능을 추가하는 데 필요한 시간의 두 배가 소요됩니다.

정크 의존성과 식별 방법

정크 의존성이란 프로젝트에 추가되었지만 코드에서 직접 사용되지 않거나, 표준 API로 구현하기 더 쉬운 단일 기능에만 사용되는 라이브러리와 패키지입니다.

일반적인 예: 프로젝트가 이미 Kotlin Serialization을 사용하는 경우의 JSON 처리 라이브러리(두 개의 파서는 정크); Kotlin 확장 isNullOrBlank로 대체할 수 있는 단일 StringUtils.isEmpty 호출을 위한 Apache Commons Lang 라이브러리; 10개 모듈 중 1개에서 사용되고 나머지는 수동으로 생성자를 통해 의존성을 받는 DI 라이브러리.

추가 의존성은 단지 바이너리의 추가 코드만이 아닙니다. 취약점에 대한 공격 표면을 증가시킵니다: GitHub Advisory Database(2025)에 따르면, 모바일 프로젝트의 중요 CVE 중 40%가 개발자가 통제할 수 없는 전이 의존성에서 발생합니다. 의존성이 적을수록 공격 표면이 작아집니다.

Android 프로젝트 의존성 분석

groovy
// View Gradle dependency tree
./gradlew app:dependencies --configuration releaseRuntimeClasspath

// Find unused dependencies (Gradle plugin)
plugins {
    id "com.autonomousapps.dependency-analysis" version "2.0.0"
}

// Generate unused library report
./gradlew buildHealth

iOS의 경우 swift package show-dependencies 명령어로 전체 의존성 트리를 확인합니다. Xcode Build Timeline 도구는 각 라이브러리가 빌드에 추가하는 시간을 보여줍니다. 라이브러리가 컴파일 시간의 30%를 차지하지만 단일 화면에서만 사용된다면 제거 또는 교체 대상입니다.

Node.js(React Native)의 경우 depcheck — package.json에서 사용되지 않는 의존성을 찾는 유틸리티, 그리고 npm-check — 추가로 오래된 버전을 표시하는 유틸리티를 사용합니다. “왜 표준 도구를 사용할 수 없는지”에 대한 정당성과 함께 모든 새 의존성이 코드 리뷰를 통과해야 한다는 규칙을 도입하세요.

데드 임포트와 주석 처리된 코드

데드 임포트는 가장 흔한 정크 유형입니다. 런타임에는 영향을 미치지 않지만 컴파일 시간을 증가시킵니다: 컴파일러는 사용되지 않는 것까지 모든 임포트를 처리합니다. 대규모 프로젝트에서 사용되지 않는 임포트를 제거하면 빌드 시간이 5–10% 단축됩니다.

최신 IDE는 사용되지 않는 임포트를 자동으로 회색으로 강조 표시합니다. 파일 저장 시 자동 정리 설정: IntelliJ IDEA에서는 Optimize Imports on the fly, Xcode에서는 Editor > Remove Unused Imports. CI에 확인을 추가: 린터가 사용되지 않는 임포트가 포함된 커밋을 차단하도록 합니다.

주석 처리된 코드는 또 다른 정크 유형입니다. 개발자는 리팩토링 중 기능을 “잃지 않기” 위해 블록을 주석 처리합니다. 그러나 git은 변경의 전체 기록을 저장합니다: 제거된 코드는 한 번의 git revert 또는 git log -S 명령어로 복원할 수 있습니다. master의 주석 처리된 코드는 팀에 대한 무례입니다: 모든 개발자는 “왜 주석 처리되었고 언제 해제해야 하는가?”라는 질문에 정신적 에너지를 소비합니다.

규칙: 저장소에 주석 처리된 코드가 없습니다. 코드가 필요하지 않으면 영구히 삭제하세요. 코드가 필요하지만 일시적으로 비활성화된 경우 티켓과 만료일과 함께 피처 토글을 사용하세요. // TODO: remove after migration 같은 주석 — 마감일 없이 남겨두지 마세요. 날짜를 설정하고 캘린더로 알림을 설정하세요.

중복 추상화와 오버 엔지니어링

오버 엔지니어링은 현재 문제를 해결하지 않지만 유지보수가 필요한 아키텍처 계층을 만드는 것입니다. 이는 가장 까다로운 정크 유형 중 하나입니다. 형식적으로 코드가 “올바르고” SOLID를 따르고 테스트로 커버되며 아키텍처에 부합하기 때문입니다. 문제는 불필요하다는 점입니다.

전형적인 예는 단순히 리포지토리를 호출하는 하나의 invoke 메서드를 가진 추상 UseCase 클래스입니다. UseCase가 로직(캐싱, 재시도, 변환)을 추가하지 않고 호출을 전달만 한다면 불필요한 엔티티입니다. 프로젝트 탐색을 증가시킵니다: 개발자가 UseCase를 열고 invoke → 리포지토리를 보고 닫습니다. 시간 낭비, 이점 없음.

또 다른 예는 과도한 매개변수화입니다. 한 곳에서만 사용되는 여섯 개의 타입 매개변수를 가진 제네릭 인터페이스. 각 타입 매개변수는 인지 부하입니다: 코드를 읽을 때 실제로는 두 개만 사용되는데 여섯 개의 타입을 기억해야 합니다. 추상화가 재사용되지 않으면 중복입니다.

판단 기준: 추상화가 세 가지 다른 맥락에서 재사용되지 않으면 제거하세요. 추상화는 실제로 중복 문제를 해결할 때 정당화되며, 가상의 미래 시나리오를 예측할 때는 정당화되지 않습니다. YAGNI(You Ain’t Gonna Need It)는 오버 엔지니어링을 예방하는 최선의 원칙입니다.

정크 감사 도구

정크 감사는 정적 분석, 의존성 분석, 수동 검토의 조합이 필요합니다. 중복 추상화 탐지를 완전히 자동화하는 것은 불가능하지만, 기술적 정크(데드 임포트, 미사용 라이브러리, 주석 처리된 코드)는 도구로 찾을 수 있습니다.

범주도구확인 내용
미사용 의존성dependency-analysis(Gradle)코드에서 사용되지 않는 라이브러리
미사용 의존성depcheck(Node.js)임포트 없는 package.json 패키지
미사용 의존성swift package --show-dependenciesSwiftPM 의존성 트리
데드 임포트IDE(Optimize Imports)사용되지 않는 import 문
주석 처리된 코드grep -r “//” / rg “^\s*//”코드가 포함된 주석 블록
빈 메서드/클래스SonarQube / CodeClimate본문이 없거나 빈 메서드
중복 라이브러리Gradle lint(duplicate classes)다른 라이브러리의 클래스 충돌

전체 감사를 위해 스프린트당 한 번 buildHealth(Android) 또는 depcheck(Node.js)를 실행하세요. 스프린트별 의존성 수 추세를 보여주는 CI 대시보드를 만드세요. 수는 증가하지만 기능이 비례하여 증가하지 않으면 팀이 정크를 축적하고 있는 것입니다.

중복 클래스에 주의하세요 — 두 라이브러리가 동일한 클래스를 포함할 때 발생하는 오류입니다. 이는 정크일 뿐만 아니라 빌드 충돌의 직접적 원인입니다. Gradle에서 이러한 충돌은 force나 exclude로 해결되지만, 각 해결은 라이브러리 중 하나가 불필요하다는 신호입니다.

정기적인 프로젝트 정리 프로세스

정크 정리는 일회성 작업이 아니라 정기적인 프로세스입니다. 절차가 없으면 정크는 2–3 스프린트 내에 돌아옵니다. 모범 사례는 각 스프린트 용량의 10–15%를 정크 감사를 포함한 기술 정리에 할당하는 것입니다.

프로세스는 네 단계로 구성됩니다. 첫째 — 진단: 도구 실행, 보고서 획득, 우선순위 지정. 높은 우선순위: 알려진 CVE가 있는 의존성과 중복 라이브러리. 중간 우선순위: 데드 임포트와 주석 처리된 코드. 낮은 우선순위: 중복 추상화(수동 분석 필요).

둘째 — 정리: 데드 의존성 제거, 중복 라이브러리를 하나로 교체, 주석 처리된 코드 삭제. 각 변경은 명확한 메시지와 함께 별도 커밋이어야 합니다: “remove unused dependency: gson (replaced by kotlinx.serialization)”, “delete commented code in LoginViewModel.”

셋째 — 검증: 프로젝트 빌드, 테스트 실행, UI 확인. 의존성 제거 후 테스트가 통과하면 의존성은 실제로 불필요했습니다. 테스트가 실패하면 정적 분석기가 감지하지 못한 숨겨진 참조가 어딘가에 남아있습니다.

넷째 — 예방: 코드 리뷰 체크리스트 업데이트, Definition of Done에 “정당성 없는 새 의존성 금지” 규칙 추가, CI에 자동 검사 설정. 예방이 정크 재축적을 막는 유일한 방법입니다.

자주 묻는 질문

정크와 기술 부채의 차이는?

기술 부채는 의식적인 타협(빠르지만 품질이 낮음)으로, 수정이 계획되어 있습니다. 정크는 의식적 결정이 아니라 축적된 쓰레기입니다: 아무도 계획하지 않았고 유지보수하고 싶어하지 않는 여분의 의존성, 주석 처리된 코드, 빈 추상화.

얼마나 자주 정크를 정리해야 하나요?

최적의 리듬은 각 스프린트의 10%를 기술 정리에 할당하는 것입니다. 이렇게 하면 임계 질량을 축적하지 않고 정크를 통제할 수 있습니다. 프로젝트에 정크가 많다면 한 번의 대규모 정리 스프린트로 시작한 후 정기적인 리듬으로 전환하세요.

팀이 정크를 제거하도록 어떻게 설득하나요?

숫자를 측정하고 보여주세요: 3–5개의 불필요한 의존성을 제거하기 전후의 빌드 시간을 측정합니다. 빌드당 15–30초 감소에 하루 빌드 수를 곱하면 팀이 절약한 시간이 몇 시간이 됩니다. 숫자는 추상적인 청결 요구보다 더 잘 설득합니다.

프로젝트가 안정적이어도 의존성에서 정크를 제거해야 하나요?

네, 특히 의존성에 CVE가 있는 경우. 프로젝트가 안정적이어도 전이 의존성의 취약점은 보안 위험입니다. 또한 SDK나 언어를 업데이트할 때 오래된 의존성이 호환되지 않을 수 있으며, 업그레이드 전에 제거하면 마이그레이션 시간을 절약할 수 있습니다.

코드의 TODO는 어떻게 하나요?

티켓 없는 모든 TODO는 정크입니다. 규칙 설정: TODO는 // TODO(PROJECT-1234): fix 형식으로 트래커의 작업에 연결해서만 작성됩니다. 정기적으로 TODO를 확인하고 관련성을 잃은 것은 종료하세요. 만료된 TODO는 제거 — 6개월 동안 문제가 나타나지 않았다면 중요하지 않습니다.

요약

  • 정크는 이익 없이 프로젝트를 증가시키는 쓸모없는 코드, 사용되지 않는 의존성 및 중복 추상화입니다.
  • 네 가지 범주: 중복 의존성, 데드 웨이트, 중복 라이브러리 및 오버 엔지니어링.
  • 모든 추가 의존성은 빌드 시간, 공격 표면 및 인지 부하를 증가시킵니다.
  • 감사 도구: dependency-analysis(Gradle), depcheck(Node.js), SonarQube, 주석 처리된 코드용 grep.
  • 정기적 정리: 스프린트의 10–15%를 기술 작업에, 스프린트당 한 번 의존성 감사.
  • 예방: 새 의존성 확인이 포함된 코드 리뷰, 설계 시 YAGNI, 임포트 자동 정리.
  • 규칙: 정당성 없는 새 의존성 금지, 티켓 없는 TODO 금지, master에 주석 처리된 코드 줄 없음.

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기