Rain Lag

투 컬럼 코딩 레저: 시도한 것 vs 실제로 먹힌 것을 남기는 가장 간단한 방법

간단한 두 칸짜리 노트 패턴만으로 디버깅 세션을 ‘무엇을 시도했고, 실제로 무엇이 먹혔으며, 왜 그런지’를 남기는 명확하고 재사용 가능한 기록으로 바꾸는 방법을 소개합니다.

소개

대부분의 개발자는 이런 상황을 한 번쯤 겪어 봤을 겁니다.

세 시간 동안 악성 버그를 디버깅합니다. 이것저것 열두 가지는 해 본 것 같습니다. 결국 어떻게든 해결은 됩니다. 그런데 일주일 뒤, 비슷한 버그가 다시 나타났을 때—지난번에 뭘 했는지 전혀 기억이 나지 않습니다.

로그를 grep으로 뒤졌다든가, 설정을 바꿨다든가, print 로그를 여기저기 넣었다는 기억은 어렴풋이 나는데, 정확히 어떤 순서로 무엇을 시도했는지는 통째로 사라져 있죠.

이건 단순히 기억력의 문제가 아닙니다. 우리 대부분에게는 무엇을 시도했는지 vs 실제로 무엇이 효과가 있었는지를 간단하고 반복 가능하게 기록하는 방법이 없기 때문입니다. 노트를 적더라도, 그나마 있는 기록은 되돌려 보기 괴로운 스트림-오브-컨셔스니스식 메모, 산만한 Slack 대화, 반쯤 쓰다 만 TODO 정도에 그칩니다.

여기서 등장하는 게 바로 **투 컬럼 코딩 레저(Two-Column Coding Ledger)**입니다.

이건 마찰이 거의 없는 간단한 노트 패턴인데, 다음을 도와줍니다.

  • 행동/시도결과/인사이트를 분리해서 적기
  • 각 디버깅/코딩 세션을 작은 미니 버그 리포트처럼 다루기
  • 간결하면서도 재사용 가능한 작업 기록 쌓기
  • 쓸데없는 반복과 비생산적인 시행착오 줄이기

**코넬식 필기(Cornell note-taking method)**를 써 본 적 있다면 익숙하게 느껴질 겁니다. 다만 소프트웨어 엔지니어링에 맞게 살짝 변형한 버전이라고 보면 됩니다.


투 컬럼 코딩 레저란 무엇인가?

투 컬럼 코딩 레저의 핵심은, 코딩이나 디버깅을 할 때 유지하는 구조화된 노트 레이아웃입니다.

한 페이지(또는 디지털 노트)를 세로로 두 구역으로 나눕니다.

  • 왼쪽 컬럼: 시도 / 액션 – 무엇을 했는지, 어떤 변경을 가했는지
  • 오른쪽 컬럼: 결과 / 인사이트 – 무슨 일이 일어났는지, 무엇을 배웠는지, 무엇을 결정했는지

Markdown으로 적으면 대략 이런 모양입니다.

| Attempt / Action | Outcome / Insight | |-------------------------------------------|---------------------------------------------------| | Restarted service with debug logging on. | Logs show repeated 500 errors from auth service. | | Disabled new feature flag `X_BETA_LOGIN`. | Errors stop; bug tied to new login flow feature. | | Reviewed recent auth PR #1234. | Found missing null check on user profile object. |

혹은 좀 더 풀어서 이렇게 적을 수도 있습니다.

  • Attempt: Restarted service with debug logging on.
    Outcome: Logs show repeated 500 errors from auth service.

  • Attempt: Disabled new feature flag X_BETA_LOGIN.
    Outcome: Errors stop; bug tied to new login flow feature.

중요한 점은, 이걸 나중에 기억을 더듬어서 채우는 게 아니라 진행하면서 바로바로 적는다는 겁니다. 이 노트는 세션이 끝난 뒤 재구성한 이야기체 기록이 아니라, 세션과 함께 살아 움직이는 “레저(ledger, 장부)”에 가깝습니다.


왜 두 개의 컬럼이 그렇게 잘 먹히는가

형태는 단순하지만, 이 패턴이 만들어 내는 효과는 꽤 강력합니다.

1. 과정과 결과를 명확하게 분리

대부분의 날것 그대로의 디버깅 메모는 이런 식으로 한데 뒤엉겨 있습니다.

"Tried X. Then Y. Then restarted. Then changed env var. Still broken. Maybe it’s the cache?"

두 컬럼으로 나누면, 다음을 강제로 구분해서 적게 됩니다.

  • 정확히 무엇을 했는지
  • 그로 인해 정확히 무엇이 일어났는지

이 구분만으로도 훨씬 쉽게 다음을 파악할 수 있습니다.

  • 어떤 행동은 완전한 노이즈였는지
  • 어떤 단계가 실제로 문제 해결에 가까워지게 만들었는지
  • 나중에 원인–결과의 흐름을 다시 복원하는 일

2. 코넬식 필기와 비슷한 정신

코넬식 필기는 이렇게 구조화된 레이아웃을 씁니다.

  • 메인 노트 영역
  • 왼쪽의 키워드/질문용 컬럼
  • 아래쪽 요약 섹션

핵심 철학은 동일합니다. 구조가 있으면 압축이 쉬워진다는 거죠.

투 컬럼 코딩 레저에서는:

  • 왼쪽 컬럼이 시간 순서대로 적는 시도/액션 스트림이고
  • 오른쪽 컬럼이 거기서 뽑아낸 해석/인사이트입니다.

이 내장된 구조 덕분에, 로그를 그대로 덤프하듯 쓰기보다는, 진행하면서 생각을 조금씩 요약하고 정제하도록 자연스럽게 유도됩니다.

3. 개인용 디버깅 블랙박스 레코더

두 컬럼 레저를 쓰면 각 세션이 작은 미니 버그 리포트로 변합니다.

  • 무엇을 의심했는지(시도들에 암묵적으로 드러납니다)
  • 무엇을 왜 시도했는지
  • 그 다음에 무슨 일이 일어났는지
  • 마지막에 무엇이 통했는지

나중에 본인이나 팀원이 다음이 필요할 때:

  • 동일한 문제를 재현해야 하거나
  • 근본 원인을 이해해야 하거나
  • 수정 사항을 문서화하거나 포스트모템을 써야 할 때

이미 간결하고 시간 순으로 정리된 조사 기록을 갖고 있는 셈입니다.


디버깅 세션에서 레저 사용하는 방법

별도의 툴 세팅 없이도 바로 시작할 수 있습니다. 기본적인 워크플로우는 이렇습니다.

1단계: 짧은 문제 설명으로 시작하기

노트 맨 위에 다음을 적습니다.

  • Problem: 한 줄짜리 문제 설명
  • Context: 환경, 브랜치, 관련 조건 등

예시:

Problem: API returns 500 on `POST /login` in staging. Context: Staging, build 1.4.2, feature flag X_BETA_LOGIN enabled.

이렇게 적어 두면 이후의 모든 시도가 어디를 향해 있는지 기준점이 됩니다.

2단계: 의미 있는 시도마다 바로 기록하기

의미 있는 행동을 할 때마다 한 줄(또는 한 행)을 추가합니다.

  • Attempt: 무엇을 했는지 (명령, 코드 변경, 확인한 것 등)
  • Optional Why: (간단한 가설 메모)
  • Outcome: 무엇을 관찰했는지 (로그, 동작, 지표 등)

예시:

| Attempt / Why | Outcome / Insight | |---------------------------------------------------------|-------------------------------------------------------| | Checked Nginx logs for /login requests. | No errors; upstream is returning 500s. | | Inspected app logs around request timestamp. | Stack trace shows `NullPointerException` in AuthSvc. | | Hypothesis: missing field in JWT claims. | | | Logged decoded JWT in AuthSvc. | All expected fields present; hypothesis incorrect. |

여기서 틀린 가설도 여전히 유용한 정보입니다. 나중에 보면 “이건 원인이 아니라는 걸 확인했다”는 근거가 되기 때문입니다.

3단계: 실제로 먹힌 지점을 눈에 띄게 표시하기

해결책이나 중요한 인사이트에 도달했을 때는 눈에 잘 띄게 만들어 둡니다.

  • 텍스트에 FIX: 같은 라벨을 붙이거나
  • Outcome을 굵게(bold) 처리하거나
  • 맨 아래에 짧은 "결론" 섹션을 추가합니다.

예시:

| Attempt / Why | Outcome / Insight | |------------------------------------------------------|--------------------------------------------------------| | Added null check on `user.profile` in AuthSvc. | **✔ Login succeeds; 500 errors disappear.** | | Deployed fix to staging and reran regression tests. | **All tests passing; no new errors detected.** |

그리고 이렇게 한 줄로 정리합니다.

Conclusion: 500 errors on /login were caused by missing null check on `user.profile` in AuthSvc. Triggered only when beta login feature flag was enabled.

이렇게 정리된 레저는 바로 이슈 티켓 코멘트, 인시던트 리포트, 사내 위키 문서로 옮기기 좋은 형태가 됩니다.


집중력을 높이고 시행착오를 줄이는 이유

각 시도와 그 결과를 적다 보면, 다음과 같은 변화가 생깁니다.

  • 같은 아이디어를 빙빙 돌며 반복하고 있다는 걸 실시간으로 인지하게 되고
  • “왜 이걸 해보는지”에 대해 좀 더 의식적으로 생각하게 되며
  • “혹시 아직 다 안 껐다 켜 본 게 남았나…” 식의 막연한 시도를 덜 하게 됩니다.

과정을 머릿속이 아니라 바깥으로 꺼내 적기 때문에, 다음과 같은 일을 덜 하게 됩니다.

  • 같은 명령을 결과를 기대하며 10번이나 반복 실행한다든가
  • 코드–로그–대시보드를 아무 생각 없이 왔다 갔다 한다든가
  • 이미 바꿔 본 설정/플래그를 또 건드렸다가 헷갈리는 일

두 컬럼 포맷은 자연스럽게 이런 루프를 만들도록 도와줍니다.

가설 → 시도 → 관찰 → 인사이트

…무계획한 난사식 트라이얼앤에러 대신에 말이죠.


장기적인 이점: 개인용 QA이자 학습 도구

이 레저를 꾸준히 사용하다 보면, 세션별 메모를 넘어 개인용 품질 보증 및 학습 시스템에 가까운 자산이 됩니다.

1. 나 자신의 실수 패턴이 보이기 시작

몇 주 혹은 몇 달 치 레저를 돌아보면서 다음을 살펴보세요.

  • 반복적으로 나오는 버그 유형 (off-by-one, null 처리 누락, 레이스 컨디션, env var 설정 오류 등)
  • 자주 틀리는 전제나 가정
  • 자꾸 문제를 일으키는 코드베이스 영역

이 정보는 곧바로 다음을 향해 이어집니다.

  • 어떤 부분에 테스트가 부족한지
  • 어떤 부분의 문서가 불명확한지
  • 어떤 모듈이 리팩터링이나 추가적인 보호 장치를 필요로 하는지

2. 나에게 가장 잘 먹히는 디버깅 기술 찾기

반대로, 어느 시도들이 자주 성과를 내는지도 보일 겁니다.

  • 특정 위치에 로그를 추가하는 방식
  • 최소 재현 케이스(minimal reproduction)를 테스트로 바로 만드는 습관
  • 특정 프로파일러나 트레이싱 툴을 활용하는 방식

시간이 지나면 “남들이 좋다더라”는 일반론이 아니라, 실제로 나에게 잘 맞았던 방법들을 바탕으로 개인용 디버깅 플레이북을 다듬을 수 있습니다.

3. 팀 커뮤니케이션 개선

레저는 공유하기도 쉽습니다.

  • Jira 같은 이슈 트래커 코멘트에 붙여 넣거나
  • Slack 스레드에 통으로 공유하거나
  • 인시던트 리포트에 첨부하거나

“대충 이것저것 보다가 고쳤어요”라는 말 대신, 다음을 제공할 수 있습니다.

  • 어떤 시도들이 있었는지에 대한 명확한 히스토리
  • 근본 원인을 뒷받침하는 증거
  • 포스트모템에 바로 가져다 쓸 수 있는 서사 구조

이건 팀 내 신뢰를 높여 주고, 다른 사람들이 다음을 더 쉽게 할 수 있게 해 줍니다.

  • 문제를 재현하고
  • 당신의 접근 방식을 배우고
  • 이미 실패한 시도를 반복하지 않도록 하는 것

레저는 어디에 적어 두면 좋을까?

특별한 툴이 필요하지 않습니다. 본인 워크플로우에 맞는 걸 쓰면 됩니다.

  • 이슈별로 레포 안에 Markdown 파일 하나씩 만들기
  • Notion, Obsidian, Evernote 등에 "Debug Log" 노트를 만들어 누적하기
  • 프로젝트 디렉터리에 간단한 텍스트 파일로 두기
  • 종이 노트에 세로로 선 하나 긋고 왼쪽/오른쪽으로 나누어 쓰기

단, 다음 세 가지는 꼭 만족해야 합니다.

  • 디버깅을 시작할 때 바로 열 수 있을 만큼 빠를 것
  • 작업하면서 즉시 덧붙이기 편할 것
  • 나중에 검색하거나 훑어보기 쉬울 것

결론

투 컬럼 코딩 레저는 아주 작은 습관이지만 효과는 제법 큽니다.

  • 무엇을 시도했는지실제로 무엇이 먹혔는지를 분리해 주고
  • 각 디버깅 세션을 작은 미니 버그 리포트로 바꿔 주며
  • 나의 실수, 인사이트, 효과적인 전략의 역사 전체를 남겨 줍니다.

새로운 툴이나 거창한 템플릿이 필요하지도 않습니다. 다음 디버깅 세션을 시작할 때 이렇게 두 가지 헤딩만 적어 두세요.

Attempt / Action | Outcome / Insight

그리고 진행하면서 그 아래를 채워 나가면 됩니다. 몇 주만 지나도, 같은 실수를 반복하는 일과 불필요한 시행착오가 줄어들 뿐 아니라, 실제로 스스로 문제를 어떻게 해결해 나가는지에 대한 풍부하고 검색 가능한 로그가 쌓여 있을 겁니다.

다음에 ‘이상하게 안 되는’ 버그가 다시 나타나더라도, 이제는 완전히 맨바닥에서 다시 시작할 필요가 없습니다. 대신, 당신만의 레저를 펼쳐 볼 수 있을 겁니다.

투 컬럼 코딩 레저: 시도한 것 vs 실제로 먹힌 것을 남기는 가장 간단한 방법 | Rain Lag