복습 프로세스, 장기적인 일정 관리 프로세스, 개발 성장을 위한 프로세스, 데일리 프로세스 등 나의 꾸준한 성장을 위해 많은 프로세스를 구축해왔다. 이러한 프로세스 덕분에 길을 잃지 않고 꾸준히, 지속적으로 성장해올 수 있었다. 일정 관리 프로세스와 데일리 프로세스를 통해 나만의 루틴이 만들어져서 게임, 친구, 유튜브, 인스타그램 등의 유혹을 이겨낼 수 있었다. 개발 성장을 위한 프로세스를 통해 체계적인 학습과 정리를 할 수 있었다.
지난 복습 시스템을 돌아보며
지난 글 새로운 시스템 : 노션 캘린더, 복습 시스템 에서 새로운 복습 프로세스를 소개했고, 지난 한 주 동안 실행해본 결과를 이야기하면 매우 성공적이었다.

물론 하루도 빠짐없이 진행했으며, 이번에 본 효과는 더욱 컸다.
그날 개발한 것들에 대해 돌아보고자 기록을 했다. 평소처럼 Claude에게 피드백을 요청했는데, 뜻밖의 솔루션을 제공해주었다. 다크모드를 구현한 기록이었는데, window.matchMedia라는 메서드를 이용해 사용자 시스템에 맞는 초기 테마 모드 지원, aria를 이용한 접근성 향상 등 다양한 솔루션을 제공해주었다.
단순히 내가 공부한 것들뿐 아니라, 내가 개발한 것들에 대해 이야기하며 솔루션을 듣고 앞으로의 방향성에 대해 함께 고민할 수도 있겠구나, 그리고 나의 개발 멘토가 되어줄 수 있겠구나 싶었다. 인공지능의 더 큰 확장성을 보았다.
나만의 알고리즘 문제 프로세스
복습 프로세스에 대해 이야기를 마쳤고, 이제 이번 주 새로 만든 디버깅 프로세스에 대해 이야기하고자 한다.
이번 주 월요일, 확장 프로그램을 개발하다가 특정 이슈가 해결되지 않아 할리스 카페에서 3시간 동안 그 문제만 파고들었다. 카페를 나올 때 무언가 허전하고 답답한 느낌이 들었다. '나는 그 3시간 동안 무엇을 얻었는가?'라는 생각이 들었다.
그 후 하루 종일 고민했다. 운동을 하면서, 밥을 먹으면서, 유튜브를 보면서 계속 생각했다. 그러던 중, 나만의 '디버깅 프로세스'가 없다는 것을 깨달았다.
나는 1년 전부터 알고리즘 문제를 풀기 시작했다. 당시에는 문제가 풀리지 않으면 '왜 안 풀리지?', '뭐가 문제지?' 하며 속으로 짜증을 내고, 여러 가지 시도를 체계 없이 반복했다. 하지만 이러한 풀이법은 지난 한 달 전쯤 크게 바뀌었다. 알고리즘 스터디 팀원이 인자, 리턴값, 전제 조건, 분석 등 체계적으로 문제에 접근하는 법을 알려주었다. 이 템플릿을 바로 실천에 옮겼다. 그 이후로 문제 정답률이 극적으로 올랐고, '문제를 해결한다'는 기분을 처음으로 느꼈다. 문제에서 주어진 인자가 무엇이고, 내가 구해야 할 리턴값은 무엇인지, 문제에서 주어진 전제 조건들은 무엇인지, 이를 통해 무엇을 유추할 수 있는지, 어떤 알고리즘을 활용하면 좋을지, 그리고 시간 복잡도와 예외 케이스 등 우려해야 할 요소들은 무엇인지 체계적으로 작성해 나갔다. 이를 통해 다양한 접근 방식을 시도해볼 수 있었고, 더 멀리서 문제를 볼 수 있었다. 이전 생각의 흐름과 시도했던 접근 방식도 돌아볼 수 있어 같은 실수를 반복하지 않을 수 있었다.
이러한 알고리즘 문제 풀이 접근 방식을 디버깅에도 적용할 수 있지 않을까 생각했다. 그래서 나만의 '디버깅 시스템'을 만들기로 결심했다.
나만의 디버깅 프로세스
여기서 핵심은 에러를 마주쳤을 때의 마인드이다. 이 에러를 마치 알고리즘 문제를 처음 풀기 시작할 때의 설레는 마음으로 대하는 것이다. 실제로, 디버깅은 알고리즘 문제 푸는 것과 유사하다. 주어진 조건과 현재 상황을 바탕으로 문제의 핵심을 파악하여 해결하는 것이다. 나는 속으로 ‘아싸, 에러다~!’ 외친다. 외치기만 했을 뿐인데, 벌써 기분이 좋지 않은가?
그 다음, 디버깅 일지에 이 에러를 기록한다. 현재 해결해야할 문제와 상황을 차근차근 기록한다. 이러한 '기록'만으로도 큰 효과가 있다. 기록을 쌓으면서 디버깅이 허튼 시간이 되지 않을 것이라는 확신이 들고, 앞으로 이런 기록은 큰 시너지를 발휘할 것이다. 동일한 에러를 다시 겪었을 때 해결하는 시간 복잡도가 O(1)에 수렴하게 된다. 또한, 유사한 에러를 겪었을 때 어떤 방식으로 접근하면 되는지 알게 된다. 이러한 기록을 찾아볼 뿐 아니라, 복습 시스템과 결합하여 장기기억으로 만들 수 있다. 해결하며 처음 보고, 기록하며 두 번 보고, 그날 저녁에 정리하며 정리하며 습에서 세 번 보고, 2차 복습 때 네 번 보고, 3차 복습 때 다섯 번 보게 된다. 그렇게 되면 나의 장기 기억에 안착하여 비로소 '나의 것'이 된다. 디버깅 일지는 단순히 기록과 기억에만 도움을 줄 뿐 아니라, 당시 문제를 해결하는 데도 큰 도움을 준다. 아래에서 더 자세히 이야기하겠지만, 체계적으로 접근할 수 있게 해준다.
디버깅 일지에 기록을 하며, 처음 1시간 동안은 에러 메시지를 절대로 검색하지 않는다. 에러 메시지를 검색하는 것은 마치 알고리즘 문제를 풀 때 답지를 가장 먼저 보는 것과 같다. 최대한 주어진 조건과 현재 상황만을 바탕으로 원인을 추정하고, 그 원인을 해결하기 위해 노력하는 것이다. 가장 먼저 공식 문서를 최대한 찾아보며 그 상황에 대한 판단뿐 아니라, 더 넓은 시야에서 바라보려 노력한다. 그 속에서 내가 알지 못한 기술의 새로운 포인트를 찾고 더 나아가 문제의 근본적인 원인을 파악할 수 있을 것이다. 그럼에도 해결이 되지 않는다면 원인으로 추정되는 것을 구글에 검색하는 것은 허용한다.
그렇게 1시간 타이머 시간동안 해결되지 않는다면, 이제 멘토의 도움을 받을 차례이다. 이 멘토는 바로 AI이다. AI에게 내가 지금까지 디버깅 일지에 기록한 내용을 보여주고 솔루션을 요청한다. 아직은 에러 메시지를 보여주지 않는다. 그리고, AI가 알려준 방법대로 시도해보며 원인을 파악하고 해결해본다. 이 때 주어지는 시간은 40분이다.
그럼에도 해결이 되지 않는다면 최후의 보루로 에러 메시지를 검색한다. 이 때 주어지는 시간은 30분이다.
그럼에도 해결이 되지 않으면, 다음을 기약한다. 관련된 기술을 공부해서 한 층 더 성장한 내가 해결하도록 지금 당장의 미련은 버리도록 하자. 지금 당장에는 현재 상황에만 집중하여 편협된 사고를 할 수밖에 없다. 나의 무의식 속에서 솔루션을 찾을 수도 있고, 리프레쉬를 통해 다음 번에 더 빠르고 새로운 접근을 할 수 있는 것이다. 그 ‘다음’은 다음 날을 의미하고, 너무 늦으면 디버깅에 대한 열정이 사그러져 좋지 않을 것이라 생각한다. 그리고, 중요한 건 그 ‘다음’과 현재 사이에 ‘학습’이 있어야 한다는 것이다. 원인으로 파악되는 기술의 공식 문서를 읽어 깊이 있게 공부하고, 블로그를 검색하며 비슷한 이슈를 겪은 사람이 있는지 찾아본다. 이는 ‘학습 프로세스’에 해당하며 나만의 학습 프로세스는 더 확립한 후 다음에 이야기하도록 하겠다.
직관과 경험
지난 날을 돌이켜보면, 에러를 마주치면 즉시 에러 메시지를 구글에 검색했다. '디버깅'을 '알고리즘 문제 풀이'에 빗대어 생각해보니, 이 행위는 마치 알고리즘 문제를 보자마자 구글에 검색하는 것과 같다는 충격적인 생각이 들었다.
그렇다. 문제를 보자마자 구글을 검색하면 안 된다. 실력이 늘지 않는다. 그 이유는 kcter.so님의 디버깅 원칙을 읽고 또 한번 크게 느길 수 있었다.
디버깅을 통한 문제 해결은 보통 개발자의 직관에서 나온다. 그리고 그 직관은 지난 경험들과 내 지식을 연결하는 과정에서 나온다.
경험이 중요한 이유가 여기에서 나온다. 경험은 나의 직관을 만들어낸다.
개발자는 에러를 해결해나가는 것이 숙명이다. 프로젝트를 만들 때 에러를 계속해서 마주하고, 계속해서 해결해야 한다. 이러한 에러를 빠르고 정확하게 해결하거나, 에러 없이 만들기 위해서는 '직관'이 필수적으로 필요하다. 이러한 직관은 나의 지난 경험들과 지식을 통해 만들어지는 것이다. 그렇기 때문에 우리는 경험을 쌓아야 한다.
디버깅 일지
그리고 나는, 앞으로 이전보다 더 많고, 깊은 경험을 쌓아야 겠다고 결심했다. 그리고 이러한 경험을 축적하기 위해서는 반드시 기록이 필요하다고 느꼈다. 사실, 나는 전부터 작성해오던 개발 위키의 ‘문제해결’ 카테고리가 있다.

이 개발 위키의 ‘문제해결’ 카테고리를 언제부턴가 쓰기가 꺼려졌다. 문제가 정말 해결하기 어려운 문제여야 할 것만 같고, 글 하나하나 공들여서 써야 할 것 같은 느낌 때문이다. 다른 개발 위키의 글들이 ‘완성도 있게 쓰자’라는 주의의 글이 많아서 이러한 느낌을 받은 것 같다. 그리고, 이렇게 제목과 날짜만으로는 어떤 정보도 알 수 없다. 그저 ‘어떤 에러를 몇 월 며칠에 마주했구나’ 정도만 알 수 있다.
이러한 한 페이지의 완성도에 대한 부담감과 한눈에 알 수 없는 문제 해결의 과정이 근본적인 문제라고 생각하여 ‘디버깅 일지’를 만들었다. 위 두 가지 문제점을 해결하기 위해 기존 데이터베이스와 분리된 새로운 데이터베이스를 만들었으며, 속성도 디버깅 이슈 해결에 맞는 속성들로 구성하였다.
지난 이틀 간 8개의 디버깅 이슈를 작성했다.
가장 놀라웠던 것은 어제였다. 어젯밤, 잠이 안 와서 토이 프로젝트를 개발하고자 했다. 그런데 이 프로젝트는 특정 이슈로 인해 진행이 멈춰 있던 상태였다. 이 이슈는 사실 위에서 이야기한 나의 '디버깅 프로세스'를 만들게 한 원인이었다. 이 이슈를 먼저 디버깅 일지에 기록했다. 내가 만든 템플릿대로 어떤 에러를 맞닥뜨렸는지, 현재 상황이 무엇인지, 추정되는 원인이 무엇인지 체계적으로 작성하였다.

이렇게 작성하고 나니, 가장 먼저 봐야 할 것이 무엇인지 떠올릴 수 있었다. 바로 '공식 문서'였다. 공식 문서를 전에 읽어서 '당연히 그대로 잘 작성했겠지'라고 생각했지만, 1:1로 비교해 보았을 때 무엇이 원인인지 알 수 있었다. 바로 async를 함수 앞에 붙였던 것이다. async를 함수 앞에 붙이면 해당 함수는 Promise를 반환하게 된다. 이전에는 Promise를 기본적으로 지원해주는 라이브러리를 사용해왔기에 문제가 발생하지 않았다. 하지만 크롬 익스텐션의 chrome.runtime.sendMessage는 Promise를 반환하지 않기 때문에 async를 사용하면 안 된다. async를 제거하여 해결되었고, Promise 래퍼로 감싸서 await 문을 사용할 수 있는 형태로 변경하였다. 현재 내 지식으로는 async를 붙인 것이 원인이 된 이유가 이러하고, 어젯밤에는 시간이 없어 찾아보지 못했지만 이 async의 근본적인 원인에 대해 좀 더 찾아보고자 한다.
그렇게 해결하지 못하던 이슈를 바로 해결했고, 그 다음에도 이슈를 바로 해결할 수 있었다. Could not establish connection. Receiving end does not exist.가 바로 그 이슈이다.
이렇게 어제의 이슈에 대해 길게 설명하는 이유는 그것이 그만큼 획기적이라고 느꼈기 때문이다.
나는 디버깅 일지를 기록하면서 이제는 디버깅이 짜증나고 재미없고, 빨리 해결하고 다음 단계로 넘어가고 싶은 그런 이슈가 아니라는 것을 느꼈다. 이제는 알고리즘 문제를 처음 맞닥뜨릴 때처럼 설렌다. 무엇이 문제이고, 무엇이 원인이고, 어떻게 해결하면 될지를 구상하고, 설계하고, 행동하는 이러한 '문제 해결'의 재미를 이제는 디버깅에서도 느낄 수 있게 된 것이다.
아직 적용한 지 3일밖에 안 되었지만, 지난 복습 프로세스처럼 이러한 디버깅 프로세스는 나를 한층, 아니 지속적으로 한층 한층 더 성장시킬 수 있는 밑거름이 될 것이라 확신한다.
내 방향은 더 많은 경험과 깊은 경험을 쌓고, 즉 많은 에러와 깊은 에러를 맞닥뜨리며, 많은 디버깅과 깊은 디버깅을 통해 '경험이 풍부한' 개발자가 되는 것이다. 그러면 나의 지금까지의 경험과 탄탄한 지식으로 직관이 뛰어난, 문제를 잘 해결할 수 있는 개발자가 되어 있을 것이다. 그것이 바로 잘하는 개발자가 아닐까.