뒤로가기
남의 코드를 읽는 기술

December 18, 2023

frontendcareer

주니어 때 새 프로젝트에 투입됐다. 팀 리드가 "일단 코드 파악부터 해"라고 했다. 그래서 src 폴더를 열었다. 파일이 200개쯤 있었다. 어디서부터 봐야 할지 감이 안 잡혔다. 아무 파일이나 열어서 읽기 시작했다. utils 폴더의 helper 함수부터 봤다. 3일 동안 열심히 읽었는데 전체 그림은 여전히 안 보였다.

동기한테 물어보니까 반응이 달랐다. "나는 먼저 라우터 설정부터 봤어. 어떤 페이지가 있는지 파악하고, 메인 페이지 컴포넌트 따라가면서 데이터 흐름을 추적했지." 같은 시간 동안 동기는 전체 구조를 파악했고, 나는 유틸 함수 10개의 동작만 파악했다.

그때 깨달았다. 코드를 읽는 것도 기술이고, 아무도 이걸 가르쳐주지 않는다는 것을.

왜 코드 읽기가 중요한가#

개발자의 일상에서 코드를 쓰는 시간보다 읽는 시간이 압도적으로 길다. Robert C. Martin이 "코드를 읽는 시간과 쓰는 시간의 비율이 10:1이다"라고 말한 게 과장이 아니다.

PR 리뷰할 때 읽고, 버그 잡을 때 읽고, 새 기능 추가하기 전에 기존 코드를 읽고, 새 프로젝트에 합류하면 며칠에서 몇 주를 코드 읽기에 쓴다. 근데 대학에서도, 부트캠프에서도, 책에서도 "코드 잘 읽는 법"은 거의 다루지 않는다. 전부 "코드 잘 쓰는 법"만 가르친다.

한재엽이 쓴 글에서 인상적인 관점을 봤다. 문제 해결은 구현보다 "문제를 어떻게 추상화하고 정의하느냐"에서 결정된다는 이야기. 코드를 읽는 것도 마찬가지다. 코드를 읽는 건 단순히 문법을 해석하는 게 아니라, 그 코드가 해결하려는 문제를 이해하는 과정이다.

나의 코드 읽기 방법론#

수년간 시행착오를 거쳐 정리한 방법이다.

1단계: 지도 그리기 (30분)#

새 코드베이스를 처음 보면, 코드를 읽기 전에 먼저 지도를 그린다.

  • package.json (또는 build.gradle, requirements.txt 등)을 본다. 어떤 라이브러리를 쓰는지. 이게 놀랍도록 많은 정보를 준다. react-query가 있으면 서버 상태 관리 방식을 예상할 수 있고, zustand가 있으면 클라이언트 상태 관리 패턴을 짐작할 수 있다.
  • 폴더 구조를 본다. pages/가 있으면 페이지 기반 라우팅이고, features/가 있으면 기능 기반 구조다. 이것만으로도 팀의 설계 철학이 보인다.
  • 엔트리 포인트를 찾는다. 프론트엔드면 App.tsx나 라우터 설정, 백엔드면 main 함수나 서버 초기화 코드.

이 30분 동안 코드를 한 줄도 깊이 읽지 않는다. 전체 윤곽만 파악한다. 이게 중요하다. 처음부터 세부 코드에 들어가면 숲을 못 보고 나무만 보게 된다.

2단계: 핵심 경로 따라가기 (2-3시간)#

지도가 그려지면, 가장 중요한 사용자 플로우 하나를 골라서 따라간다.

예를 들어 이커머스 프로젝트라면 "상품 목록 조회 → 상품 상세 → 장바구니 추가"를 따라간다. 라우터에서 상품 목록 페이지를 찾고, 그 페이지 컴포넌트가 어떤 데이터를 가져오는지 보고, API 호출을 따라가고, 응답 데이터가 어떻게 화면에 렌더링되는지 추적한다.

이 과정에서 핵심은 데이터 흐름을 따라가는 것이다. 데이터가 어디서 시작해서, 어떻게 변환되고, 어디에 도착하는지. 이게 파악되면 코드의 70%는 이해한 거다.

따라가면서 이해 안 되는 부분은 주석으로 표시해둔다. // TODO: 이 변환 로직 이해 안 됨 같은 식으로. 나중에 돌아와서 보거나 팀원한테 물어볼 때 쓴다.

3단계: 패턴 수집 (지속적)#

핵심 경로를 따라가고 나면, 코드베이스 전반에 걸친 패턴이 보이기 시작한다.

  • API 호출은 항상 이런 구조로 하는구나.
  • 에러 처리는 이 레이어에서 하는구나.
  • 상태 업데이트는 이런 컨벤션을 따르는구나.

이 패턴을 노트에 정리해둔다. 나는 프로젝트별로 "코드베이스 가이드"라는 문서를 만들어서 개인적으로 관리한다. 팀 공식 문서가 아니라 내가 이해한 걸 내 언어로 적어놓는 거다. 나중에 비슷한 기능을 구현할 때 "이 프로젝트에서는 이렇게 하면 되겠구나"의 기준이 된다.

코드를 읽을 때 흔한 실수#

모든 줄을 이해하려고 한다#

처음에 내가 그랬다. 파일을 열면 1번 줄부터 끝까지 다 이해하려고 했다. 이건 소설 읽는 방법이지 코드 읽는 방법이 아니다.

코드는 필요한 부분만 깊이 읽고, 나머지는 표면적으로 훑으면 된다. formatDate라는 함수가 있으면 "날짜를 포맷하는 함수겠지"하고 넘어간다. 구현이 궁금하면 나중에 보면 된다. 지금 중요한 건 이 함수가 데이터 흐름에서 어떤 역할을 하는가이다.

혼자서 전부 파악하려고 한다#

자존심 때문에 코드를 혼자 다 읽으려는 사람이 많다. 나도 그랬다. "이것도 이해 못 하면 바보 아닌가" 하는 마음. 근데 코드에는 작성자만 아는 맥락이 있다. 왜 이런 설계를 했는지, 이 예외 처리가 어떤 장애에서 나온 건지. 코드만 봐서는 알 수 없는 것들.

팀원한테 30분 설명 들으면, 혼자 3일 읽어야 알 수 있는 걸 한 번에 파악할 수 있다. 물어보는 건 실력이 부족한 게 아니라 효율적인 거다.

디버거를 안 쓴다#

정적으로 코드를 읽는 것만으로는 한계가 있다. 실제로 돌려보면서 읽어야 한다. 브레이크포인트를 찍고, 변수 값을 확인하고, 호출 스택을 따라가 보면 코드만 보는 것보다 훨씬 빠르게 이해할 수 있다.

특히 비동기 코드나 이벤트 기반 코드는 정적으로 읽으면 실행 순서를 파악하기 어렵다. 돌려보면 한눈에 보인다.

2주간 코드만 읽었던 경험#

입사 후 새 팀에 배정됐을 때, 팀 리드가 의외의 제안을 했다. "첫 2주는 코드만 읽어. 한 줄도 안 써도 돼."

처음엔 불안했다. 빨리 기여해야 한다는 압박감 때문에. 근데 그 2주가 이후 6개월을 편하게 만들어줬다.

첫째 주에는 위에서 말한 방법대로 지도 그리기, 핵심 경로 따라가기를 했다. 둘째 주에는 PR 히스토리를 봤다. 최근 3개월간의 PR을 시간순으로 읽으면서, 이 코드베이스가 어떻게 진화해왔는지 파악했다. 이게 엄청나게 유용했다. 코드의 현재 모습만 보면 "왜 이렇게 되어 있지?"라는 의문이 많은데, PR 히스토리를 보면 "아, 이런 맥락에서 이렇게 된 거구나"가 이해된다.

2주 뒤에 첫 번째 PR을 올렸는데, 팀 리드가 "이미 이 코드베이스에서 일해온 사람처럼 코드를 짜네"라고 했다. 과장이 있었겠지만, 2주간 읽기만 한 투자가 제대로 된 셈이었다.

오픈소스 코드 읽기#

남의 코드를 읽는 기술을 가장 빠르게 기르는 방법 중 하나가 오픈소스 코드를 읽는 거다.

처음부터 React 소스 코드를 읽으라는 게 아니다. 작은 라이브러리부터 시작한다. 내가 추천하는 시작점은 Zustand다. 코어 코드가 수백 줄 정도인데, 상태 관리의 핵심 패턴이 다 들어 있다. createStore 함수 하나를 따라가면 구독 패턴, 불변성 관리, 셀렉터 최적화 같은 개념을 한꺼번에 볼 수 있다.

읽는 순서는 프로젝트 코드와 같다.

  1. package.json에서 의존성 확인 (놀랍게도 의존성이 거의 없는 라이브러리가 많다)
  2. 엔트리 포인트 (index.ts 또는 src/index.ts) 에서 시작
  3. 핵심 export를 따라가며 내부 구현 확인
  4. 테스트 코드를 읽으면서 의도된 사용법 파악

테스트 코드를 읽는 게 특히 좋다. 테스트는 "이 코드가 어떻게 쓰이길 기대하는가"를 보여준다. 구현 코드만 보면 "왜 이렇게 했지?"가 안 풀릴 때, 테스트를 보면 "아, 이런 케이스를 처리하려고 이렇게 한 거구나"가 보인다.

Dan Abramov가 "Things I Don't Know as of 2018"이라는 글에서 "아는 것과 모르는 것을 솔직하게 인정하는 게 실력을 키운다"고 말한 적 있다. 오픈소스 코드를 읽다 보면 내가 뭘 모르는지가 정확하게 드러난다. 구독 패턴을 이해한다고 생각했는데 Zustand의 subscribe 구현을 보고 "아, 이런 방식도 가능하구나"를 깨닫는 식이다. 이게 성장의 시작점이 된다.

코드 읽기를 습관으로#

나는 주 1회, 금요일 오후에 30분 동안 "의도적으로 코드를 읽는" 시간을 갖는다.

세 가지 중 하나를 한다.

  1. 우리 프로젝트에서 내가 안 본 부분 읽기. 주로 다른 팀원이 작업한 영역. 전체 코드를 알 필요는 없지만, 대략적인 감은 있어야 협업이 원활하다.
  2. 오픈소스 라이브러리 코드 읽기. 주로 업무에서 쓰는 라이브러리. 내부 구현을 알면 디버깅이 빨라지고, 더 효율적으로 사용할 수 있다.
  3. 과거에 내가 쓴 코드 읽기. 3개월 전에 쓴 코드를 다시 읽으면, 그때 내가 뭘 이해하고 뭘 이해 못 했는지가 보인다. 성장을 체감하는 가장 확실한 방법이기도 하다.

30분이면 충분하다. 목적은 코드 전체를 파악하는 게 아니라, "읽는 근육"을 꾸준히 단련하는 거다. 코드를 읽는 속도와 이해의 깊이는 확실히 연습으로 늘어난다.

결론#

코드를 잘 쓰는 개발자가 되고 싶으면, 먼저 코드를 잘 읽는 개발자가 되어야 한다. 좋은 글을 쓰는 사람은 예외 없이 많이 읽는 사람이다. 코드도 마찬가지다.

읽는 법은 간단하다. 전체 지도를 먼저 그리고, 핵심 경로를 따라가고, 패턴을 수집한다. 모든 줄을 이해하려 하지 않고, 데이터 흐름에 집중한다. 모르면 물어보고, 가능하면 돌려보면서 읽는다.

거창한 방법론이 아니다. 근데 이걸 의식적으로 하느냐 안 하느냐가 코드 이해 속도에서 큰 차이를 만든다. 파일을 아무거나 열어서 위에서 아래로 읽는 것과, 엔트리 포인트에서 시작해서 데이터 흐름을 따라가며 읽는 것은 같은 시간을 써도 파악하는 양이 전혀 다르다.

코드를 읽는 건 수동적인 행위가 아니다. 적극적으로 질문을 던지고, 가설을 세우고, 확인하는 과정이다. 그리고 그 과정을 통해 남의 경험이 내 것이 된다. 10년차 시니어가 짠 코드를 읽는 건, 그 사람의 10년 경험에서 일부를 흡수하는 거다. 이보다 효율적인 학습 방법이 있을까.