뒤로가기
시스템으로 생각하는 개발자

February 10, 2025

essayproductivity

3년 차 때 새해 목표를 세운 적이 있다. "올해는 오픈소스에 기여하고, 블로그 월 2회 쓰고, 알고리즘 매주 3문제 풀겠다." 노션에 예쁘게 정리하고, 캘린더에 알림도 넣었다. 1월은 꽤 잘했다. 2월도 어찌저찌 했다. 3월부터 알림을 무시하기 시작했고, 4월에는 그 노션 페이지를 열어보지도 않았다.

연말에 돌아보니 목표 달성률 15%. 근데 웃긴 건, 같은 팀의 동기는 새해 목표 같은 거 세운 적도 없는데 1년 동안 꾸준히 성장하고 있었다는 거다. 블로그를 쓰겠다고 선언한 적 없는데 격주로 글이 올라왔고, 알고리즘을 풀겠다고 다짐한 적 없는데 점심시간마다 한 문제씩 풀고 있었다.

차이가 뭘까 한참 생각했다. 나중에 James Clear의 글을 읽으면서 정확히 짚어주는 문장을 만났다.

"You do not rise to the level of your goals. You fall to the level of your systems."

목표의 수준으로 올라가는 게 아니라, 시스템의 수준으로 떨어진다. 이 한 문장이 내 사고방식을 꽤 많이 바꿨다.

목표가 소용없다는 게 아니다#

오해하면 안 되는 게, 목표 자체가 나쁘다는 뜻이 아니다. 방향을 잡는 데는 목표가 필요하다. 문제는 목표만 있고 시스템이 없는 경우다.

Clear가 지적한 네 가지 문제 중 하나가 "승자와 패자가 같은 목표를 가진다"는 거다. 올림픽에 출전한 모든 선수가 금메달을 원한다. 면접 본 모든 개발자가 합격을 원한다. 목표가 같은데 결과가 다르다면, 차이를 만드는 건 목표가 아니라 과정이다. 그 과정을 반복 가능하게 만든 게 시스템이다.

나는 "좋은 코드를 쓰겠다"는 목표가 있었지만, 좋은 코드를 쓰기 위한 시스템은 없었다. 동기는 목표 대신 시스템을 가지고 있었다. 매일 출근하면 15분 동안 어제 작성한 코드를 다시 읽는 습관, PR을 올리기 전에 스스로에게 3가지 질문을 던지는 체크리스트, 주 1회 다른 팀의 코드를 30분간 읽는 루틴. 거창한 게 아니었다. 근데 그게 쌓이니까 1년 뒤에 확연한 차이가 났다.

코드 리뷰의 시스템#

코드 리뷰를 예로 들어보겠다. "꼼꼼하게 코드 리뷰하겠다"는 목표다. 시스템이 아니다.

시스템은 이런 거다.

  1. PR이 올라오면 먼저 전체 diff를 훑어본다. 5분 이내.
  2. 변경된 파일 목록을 보고 "이 PR의 핵심 변경이 뭔지" 한 문장으로 정리한다.
  3. 핵심 변경부터 읽는다. 주변 코드는 나중에.
  4. 코멘트를 달 때 "이건 왜 이렇게 했는지?"가 아니라 "이 부분은 이런 이유로 다르게 하면 어떨까?"로 쓴다.
  5. 리뷰가 끝나면 approve, request changes, 또는 comment 중 하나를 반드시 선택한다. "나중에 다시 볼게"는 금지.

이 다섯 단계를 정해놓으니까 리뷰 품질이 눈에 띄게 올라갔다. 매번 "이번엔 꼼꼼하게 해야지" 하고 의지력을 쓰는 게 아니라, 절차를 따라가면 자동으로 일정 수준 이상의 리뷰가 된다.

더 중요한 건, 시스템이 있으니까 바쁠 때도 리뷰를 건너뛰지 않게 됐다는 거다. "꼼꼼하게 해야지" 같은 목표는 시간 압박 앞에서 쉽게 무너진다. "일단 approve 하고 나중에 볼게"가 된다. 근데 시스템이 있으면 "오늘은 시간이 없으니까 핵심 변경만 5분 안에 본다"는 식으로 최소한의 품질을 유지할 수 있다.

학습의 시스템#

개발자에게 가장 중요한 시스템 중 하나가 학습 시스템이다. 기술이 너무 빠르게 바뀌니까 "따라잡아야지"라는 막연한 목표만으로는 어림도 없다.

나는 한동안 "최신 기술 트렌드를 놓치지 말자"를 목표로 삼았다. 결과는 뻔했다. 트위터 타임라인을 뒤지면서 이것저것 읽다가 아무것도 기억에 남지 않는 상태. 정보는 많이 소비했는데 지식은 늘지 않았다.

Derek Sivers가 "hell yeah or no"라는 개념을 이야기한 적이 있다. 어떤 선택 앞에서 "와, 이거 꼭 해야 해!"가 아니면 하지 말라는 거다. 이걸 학습에 적용해봤다. 모든 새 기술을 따라가려는 대신, 정말 흥미롭거나 당장 업무에 필요한 것만 깊게 파기로 했다.

그리고 시스템을 만들었다.

매일 아침 20분: 하나의 주제만 읽는다. 여러 아티클을 돌아다니는 게 아니라, 한 주에 하나의 주제를 정해서 관련 글만 읽는다. 이번 주에 React Server Components를 공부한다고 정하면, 월요일부터 금요일까지 RSC 관련 글만 읽는다. 공식 문서, 블로그 포스트, GitHub 이슈 순서로.

금요일 오후 30분: 주간 정리. 그 주에 읽은 걸 노션에 세 문장으로 요약한다. 세 문장 이상 쓰지 않는다. 많이 쓰려고 하면 부담이 되어서 안 하게 되니까.

월 1회: 배운 걸 블로그에 쓴다. 글을 쓰려면 제대로 이해해야 하니까, 이게 가장 효과적인 학습 마무리다.

이 시스템이 완벽한 건 아니다. 가끔 놓치는 중요한 기술도 있다. 근데 "모든 걸 따라잡자"는 목표보다 훨씬 낫다. 적어도 한 달에 하나는 확실히 내 것으로 만들 수 있으니까.

"시스템을 만드는 시스템"이 필요하다#

여기서 한 단계 더 나아가면, 시스템 자체를 만드는 습관이 필요하다는 걸 깨닫게 된다.

새로운 업무가 생기면 나는 이렇게 한다.

  1. 첫 번째로 물어볼 질문: "이걸 반복적으로 잘하려면 어떤 절차가 필요한가?"
  2. 대충이라도 절차를 정리한다. 처음엔 3단계 정도.
  3. 두세 번 해보면서 절차를 수정한다.
  4. 안정되면 팀에 공유한다.

배포도 그랬다. 처음에는 매번 수동으로 하다가 실수가 잦았다. 그래서 배포 체크리스트를 만들었다. 체크리스트가 안정되니까 스크립트로 자동화했다. 스크립트가 안정되니까 CI/CD 파이프라인에 넣었다. 시스템이 시스템을 낳는 구조다.

이게 James Clear가 말하는 "시스템은 개인의 수준을 결정한다"는 거랑 연결된다. 좋은 시스템을 만드는 사람은 시간이 지나면 자연스럽게 좋은 결과를 낸다. 반면 매번 목표만 세우는 사람은 의지력이 고갈되면 원래 수준으로 돌아간다.

커리어 시스템#

좀 더 큰 범위로 보면, 커리어 자체에도 시스템이 있을 수 있다.

팀 리드한테 들은 이야기가 인상 깊었다. "나는 5년 뒤 어디 있겠다는 목표가 없어. 대신 매 분기 '내가 이번 분기에 뭘 배웠는가'를 적어. 배운 게 없는 분기가 2번 연속이면 뭔가를 바꿔." 목표가 아니라 신호등 시스템이다. 초록불이면 계속 가고, 빨간불이면 멈추고 점검한다.

나도 비슷한 시스템을 운영한다. 분기마다 세 가지를 적는다.

  • 이번 분기에 새로 할 수 있게 된 것: 기술적 스킬이든, 소프트 스킬이든.
  • 이번 분기에 가장 어려웠던 것: 반복되는 어려움이 있으면 시스템을 바꿔야 한다는 신호.
  • 다음 분기에 실험해볼 것: 크지 않아도 된다. 새 도구 하나 써보기, 새 팀원과 페어 프로그래밍 해보기 같은 작은 것.

이걸 시작한 지 2년이 넘었는데, 돌아보면 방향 설정이 훨씬 명확해졌다. "5년 뒤에 시니어가 되겠다"는 목표보다, "매 분기 뭔가 하나는 새로 할 수 있게 되자"는 시스템이 실제로 더 빠르게 성장시켜줬다.

디버깅의 시스템#

학습 말고 디버깅에서도 시스템이 빛을 발한다.

예전에는 버그가 나오면 "감"으로 찾았다. "여기가 수상한데?" 하면서 코드를 이리저리 뒤적거렸다. 운 좋으면 빨리 찾고, 운 나쁘면 반나절이 날아갔다.

지금은 디버깅 절차가 있다.

  1. 버그를 재현한다. 재현이 안 되면 재현 조건을 먼저 찾는다.
  2. 재현이 되면 "마지막으로 정상 동작한 지점"을 찾는다. git bisect를 쓰기도 하고, 수동으로 확인하기도 한다.
  3. 정상과 비정상 사이의 변경사항을 좁혀나간다.
  4. 원인을 찾으면 수정 전에 테스트를 먼저 작성한다. "이 버그가 재현되는 테스트"를 만들어놓으면 같은 버그가 다시 나올 일이 없다.
  5. 수정 후에 테스트가 통과하는지 확인한다.

이 절차를 따르면 "감"에 의존하지 않아도 된다. 체계적으로 좁혀가니까 시간 예측도 가능해진다. "이 버그는 대략 2시간이면 찾을 수 있겠다"는 감이 생긴다. 감으로 디버깅할 때는 "5분 만에 끝날 수도 있고 하루 종일 걸릴 수도 있고"였는데, 시스템이 생기니까 편차가 줄었다.

Clear가 말한 "점수는 알아서 따라온다(the score takes care of itself)"가 정확히 이거다. 좋은 디버깅 결과를 노리는 게 아니라, 좋은 디버깅 절차를 따르면 결과는 자연스럽게 따라온다.

시스템의 함정#

시스템 만능주의도 경계해야 한다. 시스템에 집착하면 시스템 자체가 목적이 되어버리는 경우가 생긴다.

한때 나는 코드 리뷰 시스템, 학습 시스템, 운동 시스템, 독서 시스템 등등을 동시에 운영하려고 했다. 시스템을 관리하는 게 하루 일과의 절반이 되어버렸다. 본말이 전도된 거다.

Sivers가 강조하는 것처럼, "hell yeah"가 아니면 하지 않는 게 맞다. 시스템도 마찬가지다. 정말 중요한 2-3개의 시스템만 유지하고, 나머지는 과감히 버려야 한다. 나는 지금 코드 리뷰 시스템, 주간 학습 시스템, 분기별 회고 시스템 딱 세 개만 유지한다. 이것만으로 충분하다.

시스템은 나를 자유롭게 해주는 도구이지, 나를 옥죄는 틀이 아니다. 효과가 없는 시스템은 빠르게 버리고, 효과가 있는 시스템은 계속 다듬어가는 것. 그것 자체가 시스템이다.

그래서 결론#

목표를 세우는 건 쉽다. 새해 첫날이면 누구나 원대한 목표를 적는다. 근데 2월이 되면 그 목표를 기억하는 사람이 절반으로 줄고, 6월이면 거의 없다.

시스템은 다르다. 시스템은 의지력에 의존하지 않는다. 시스템은 "잘해야지"가 아니라 "이 절차를 따르면 된다"다. 시스템은 컨디션이 좋든 나쁘든 일정한 결과를 보장한다. 완벽하지는 않아도, 최소한 바닥으로 떨어지진 않게 해준다.

개발자로 일하면서 제일 많이 느끼는 건, 뛰어난 개발자와 보통 개발자의 차이가 재능이 아니라 루틴에 있다는 거다. 매일 15분 코드 리뷰를 꼼꼼히 하는 사람, 주 1회 새 기술을 30분씩 살펴보는 사람, 분기마다 자기 성장을 점검하는 사람. 이런 사람들이 3년 뒤, 5년 뒤에 확연히 다른 자리에 서 있다.

목표의 수준으로 올라가는 게 아니라, 시스템의 수준으로 떨어진다. 그러니까 시스템의 수준을 올려야 한다. 거창할 필요 없다. 작은 절차 하나부터 시작하면 된다. 그게 쌓인다.