여러분은 야심찬 프로젝트를 시작했다가 어느 순간 흥미를 잃고 포기한 경험이 있나요? 처음 며칠은 설렘으로 가득하지만, 시간이 지나면서 점점 멀어지는 그 프로젝트 말입니다. Mitchell Hashimoto가 공유한 대규모 기술 프로젝트 완주 전략은 바로 이 문제의 핵심을 파고듭니다.
프로젝트 실패의 진짜 이유: 보이지 않는 진전
대부분의 프로젝트가 중도에 좌초하는 이유는 능력 부족이 아닙니다. 문제는 눈에 보이는 진전을 느끼지 못한다는 것입니다.
터미널 에뮬레이터를 만든다고 가정해보겠습니다. VT 파싱, 셸 프로세스 관리, 폰트 렌더링, 그리드 렌더링, 입력 처리… 수백 개의 거대한 서브 프로젝트가 눈앞에 펼쳐집니다. 이 모든 것을 한꺼번에 바라보는 순간, 우리는 압도당합니다.
초기 목표를 “Neovim을 실행할 수 있는 터미널 만들기”로 설정한다면? 너무 막연합니다. GUI 렌더링도, 프로세스 실행도, 터미널 파싱도 모두 필요하죠. 이런 목표는 직관적으로 ‘너무 크다’고 느껴지고, 한두 달 후면 흥미를 잃기 십상입니다.
첫 단추 끼우기: 어디서 시작할 것인가
경험 많은 엔지니어와 초보자의 차이는 여기서 드러납니다. 숙련된 개발자는 프로젝트의 대략적인 윤곽과 서브컴포넌트를 더 정확하게 파악합니다. 하지만 경험이 부족하거나 낯선 영역이라면? 최선의 추측으로 시작하되, 작업을 버릴 가능성이 높다는 것을 받아들여야 합니다.
핵심은 가장 빠르게 결과를 볼 수 있는 작은 단위를 찾는 것입니다. 터미널 에뮬레이터 예시에서는 이런 선택지가 가능합니다:
- VT 파싱: 터미널 이스케이프 시퀀스 해석하기
- 빈 윈도우 렌더링: 창을 열고 빈 캔버스 그리기
- 자식 프로세스 실행: bash나 zsh 같은 셸을 실행하고 TTY를 설정해 초기 프롬프트 읽기
이 단계에서 모든 서브 프로젝트를 나열할 필요는 없습니다. 프로젝트의 대략적인 모습을 그리고, 독립적으로 구축하면서 실제 결과를 물리적으로 확인할 수 있는 것 하나를 선택하면 됩니다.
초기 단계의 함정: 보이지 않는 작업들
초기 작업은 본질적으로 가시성이 낮습니다. VT 파싱을 선택했다면, UI 없이는 작동하는 모습을 볼 수 없습니다. 데이터베이스 스키마와 최소 API를 만들었다면, 클라이언트나 CLI, GUI 없이는 확인이 불가능하죠.
여기서 자동화된 테스트가 구원자가 됩니다. 유닛 테스트는 코드를 실행하고 작동하는 모습을 확인할 수 있게 해주며, 동시에 좋은 개발 습관을 만들어줍니다.
터미널 프로젝트에서 VT 파싱을 먼저 선택한 이유도 여기 있습니다. 입력 문자열을 주고 파싱된 액션이나 이벤트를 출력으로 기대하는 방식으로 매우 쉽게 테스트할 수 있기 때문입니다.
“1개 테스트 통과”, “4개 테스트 통과”, “13개 테스트 통과”… 이런 진행 상황을 보는 것만으로도 엄청난 흥분을 느낄 수 있습니다. 내가 작성한 코드가 실제로 작동하고 있고, 더 큰 프로젝트의 핵심 서브컴포넌트에서 진전을 이루고 있다는 것을 확인하는 순간입니다.
데모까지 전력질주: 완벽함은 진전의 적
초기 서브 프로젝트의 목표는 완성된 컴포넌트가 아니라 데모를 만들기에 충분한 컴포넌트입니다. 이것이 핵심입니다.
미래에 데이터베이스가 필요하다는 것을 알고 있나요? 고급 자료구조가 필요할까요? 스트리밍 데이터 지원이 있어야 할까요? 지금은 잊으세요. 초기 단계에서는 메모리 내 컨텐츠, 딕셔너리 같은 기본 자료구조, 모든 입출력을 미리 준비하는 방식으로 충분합니다.
완벽함이 진전의 적이 되게 하지 마세요. 더 나아가, 미래에 필요한 개선 사항을 알고 있다고 해서 다음 단계로 넘어가는 것을 멈추지 마세요. 목표는 데모에 도달하는 것입니다.
어떤 작업을 하든 일주일에 한두 번 데모를 만드는 것을 목표로 합니다. 이전 섹션에서 설명한 자동화된 테스트 피드백과 섞어서 말이죠.
데모를 만드는 것은 귀중한 제품 피드백도 제공합니다. 완전히 기능적이지 않더라도 무언가가 좋은 느낌인지 아닌지 빠르게 직관적으로 판단할 수 있습니다. 이것들은 “최소 기능 제품”이 아닙니다. 실제로 사용 가능하지 않으니까요. 하지만 엔지니어에게 가치 있는 자기 성찰을 제공하기에는 충분합니다.
흥미롭게도, 이 부분에서는 경험이 오히려 해가 될 수 있습니다. 현장에서 일하다 보면 시니어 엔지니어들이 완벽한 것을 만들려다 늪에 빠지는 모습을 많이 보게 됩니다. 데모를 만들 때쯤이면 제품이나 기능 자체가 형편없다는 것을 깨닫죠. 구현이 나쁜 게 아니라, 제품 자체가 별로인 겁니다.
나를 위한 소프트웨어 만들기
이 섹션은 개인 프로젝트에 특히 해당됩니다. 다른 사람을 위한 소프트웨어를 출시하고자 하더라도, 내가 필요한 것만 만들고 가능한 한 빨리 내 소프트웨어를 사용하기 시작하세요.
내가 직접 경험하는 문제를 해결할 때 항상 더 동기부여가 됩니다. 그리고 나를 위해 설계된 제품이 나에게 잘 작동하지 않는다면, 다른 사람에게도 잘 작동하지 않을 가능성이 높습니다.
터미널 프로젝트라면 우선 내 셸 설정(fish)을 로드하고 Neovim을 실행할 수 있는 것을 목표로 삼으세요. 그리고 필요한 기능만 바로 구현합니다. 즉, 해당 프로그램들이 사용하는 이스케이프 시퀀스만, 내가 매일 사용하는 폰트 렌더링만. 처음에는 스크롤, 마우스 선택, 검색, 탭/분할 등의 기능은 생략해도 됩니다.
그런 다음 터미널을 일상적으로 사용하기 시작합니다. 이 단계는 보통 몇 번의 시행착오를 거칩니다. 그리고 생략했거나 잊어버린 기능이 실제로 필요하다는 것을 깨닫게 됩니다. 실제로 Mitchell Hashimoto도 처음 터미널을 실행했을 때, 방향키가 작동하지 않는다는 것을 깨달았다고 합니다. 미묘하지만 작업 흐름을 방해하는 렌더링 버그도 있었죠. 그래서 사용을 중단하고 다음에 작업할 구체적인 작업에 대한 아이디어를 떠올릴 수 있었다고 합니다.
게다가, 가장 중요한 것은 내가 작성한 코드로 만든 소프트웨어를 사용하는 것에서 항상 큰 자부심을 느낄 수 있다는 것이죠. 이것이 계속 작업하도록 동기를 부여하는 데 도움이 됩니다.
완주의 공식: 작은 승리의 누적
대규모 프로젝트를 완주하는 방법을 요약하면 다음과 같습니다:
- 1. 문제를 작은 조각으로 분해하세요.
- 각 작은 문제는 작업 결과를 명확하게 볼 수 있는 방법이 있어야 합니다.
- 2. 데모에 필요한 수준까지만 해결하세요.
- 작은 문제를 완벽하게 해결하려 하지 말고, 데모를 진행하기에 충분한 정도로만 해결한 후 다음 문제로 넘어가세요.
- 3. 최대한 빨리 실행 가능한 데모를 만드세요.
- 그리고 반복적으로 기능을 추가합니다. 가능한 한 자주 데모를 만드세요.
- 4. 자신에게 의미 있는 기능을 우선순위로 두세요.
- 해당되는 경우(개인 프로젝트, 실제로 겪고 있는 문제를 해결하는 업무 프로젝트 등), 자신의 소프트웨어를 채택할 수 있게 하는 기능을 우선시하세요. 그런 다음 자신의 문제를 먼저 계속 해결하세요.
- 5. 필요에 따라 반복하세요.
- 미래 개선을 위해 필요에 따라 각 컴포넌트를 다시 반복하며, 이 과정을 필요한 만큼 반복합니다.
여러분만의 동기부여 시스템을 찾으세요
이 방법은 개인 프로젝트, 그룹 프로젝트, 업무 프로젝트, 학교 프로젝트 등에서 효과적으로 작동합니다. 하지만 중요한 것은 이것이 매우 개인적인 프로세스라는 점입니다.
Mitchell Hashimoto가 배포에 대해 언급하지 않았다는 것을 눈치채셨나요? 많은 사람들이 출시를 동기부여 요인으로 삼습니다. 하지만 프로젝트가 성공하기 위해 반드시 출시가 필요한 것은 아닙니다. 그리고 Mitchell Hashimoto는 개인적으로 출시는 장기적인 동기부여를 위해서는 너무 큰 이벤트라고 합니다. 또 툴링(Git 워크플로우, CI 등)에 대해서도 언급하지 않았습니다. Mitchell Hashimoto는 여러 직장에서 이 프로세스를 사용했고, 기존에 확립된 프로세스에 맞춰 적용했습니다.
모든 사람은 건강한 방식으로 동기를 강화할 수 있는 프로세스를 찾아야 합니다. Mitchell Hashimoto는 결과를 보는 것이 저를 정말 강하게 동기부여한다는 것을 깨달았고, 그에 맞춰 작업 스타일을 구축했으며, 지금까지 잘 작동하고 있다고 합니다.
여러분은 어떤 순간에 가장 큰 동기를 느끼시나요? 완성된 제품을 출시할 때인가요, 아니면 작은 기능 하나가 처음으로 작동하는 순간인가요?
참고 자료: Mitchell Hashimoto, “My Approach to Building Large Technical Projects”