모던지 / 컴퓨터과학 / 프로그래밍의 세계 4강. 코드는 쓰기보다 읽는 시간이 깁니다

프로그래밍의 세계 4강. 코드는 쓰기보다 읽는 시간이 깁니다

소프트웨어의 진짜 비용은 처음 만드는 데 들지 않습니다. 만든 다음 10년 동안 계속 고치는 데 듭니다.

풀고 시작

문제 1. 늦어지는 프로젝트에 인력을 더 투입하면 더 늦어진다는 브룩스의 법칙, 그 이유는 무엇일까요?
인원이 n명이면 서로를 잇는 경로는 n 곱하기 n 빼기 1을 2로 나눈 수만큼 늘어나 조율 비용이 인원보다 빠르게 커지고, 게다가 새 사람을 가르치는 일은 가장 사정을 잘 아는 기존 인력이 맡게 됩니다. 실력이나 예산 문제가 아니라 구조적인 산술의 문제입니다.

다 만들고 나서가 시작입니다

건물은 준공되면 끝나지만 소프트웨어는 배포되면 시작입니다. 이름에 들어 있는 소프트라는 말 자체가 고칠 수 있다는 약속이었고, 그 약속 때문에 요구사항은 반드시 변합니다. 사용자가 처음에 원한다고 말한 것과 실제로 필요한 것이 다르다는 사실은 대개 물건이 나온 뒤에야 드러나고, 시장도 법규도 함께 쓰는 다른 시스템도 그동안 가만히 있지 않습니다. 그래서 소프트웨어 공학의 질문은 어떻게 하면 한 번에 잘 만들까가 아니라, 계속 바뀔 것을 알면서 어떻게 무너지지 않게 만들까입니다. 코드를 쓰는 시간보다 읽는 시간이 훨씬 길다는 오래된 관찰도 같은 자리에서 나옵니다. 우리가 코드를 읽는 이유는 감상하기 위해서가 아니라 고치기 전에 무엇이 깨질지 알아내기 위해서입니다.

폭포수와 애자일, 각자의 조건

여기 재미있는 오해가 하나 있습니다. 1970년 윈스턴 로이스가 쓴 논문은 흔히 폭포수 모형의 원전으로 인용되지만, 정작 그 논문은 단선적인 진행이 위험하다고 경고하면서 시제품을 만들고 되돌아가는 반복을 권했습니다. 앞부분의 단순한 그림만 널리 퍼지고 뒤의 경고는 덜 읽힌 셈이죠. 그럼에도 폭포수가 오래 쓰인 데는 이유가 있습니다. 요구사항이 계약으로 고정되고 결함의 대가가 치명적인 영역, 예컨대 항공 전자나 의료기기나 규제 산업에서는 설계와 검증 문서를 앞에 두껍게 쌓는 편이 합리적입니다. 반대로 사용자 반응을 빨리 받을 수 있고 배포를 되돌리기 쉬운 영역에서는 짧은 주기로 만들고 보여 주고 고치는 편이 유리하며, 2001년 애자일 선언문이 정리한 것이 이 태도입니다. 다만 애자일은 계획을 하지 않는다는 뜻이 아니라, 계획을 자주 다시 세운다는 뜻입니다.

안전망이 있어야 과감해집니다

빠르게 고치려면 고쳐도 괜찮다는 확신이 필요하고, 그 확신을 만드는 것이 테스트입니다. 함수 하나를 검사하는 단위 테스트, 여러 부분을 붙여 보는 통합 테스트, 예전에 고친 결함이 되살아났는지 확인하는 회귀 테스트가 층을 이룹니다. 이 테스트들을 코드가 올라올 때마다 자동으로 돌리는 것이 지속적 통합이고, 사람이 기억에 의존하지 않아도 되도록 만드는 장치입니다. 다만 정직하게 짚을 것이 있습니다. 다익스트라의 말대로 테스트는 결함이 있음을 보여 줄 수는 있어도 없음을 증명하지는 못합니다. 커버리지 수치가 높다는 것은 그만큼의 코드가 실행되었다는 뜻이지 그 코드가 옳다는 뜻이 아니고, 검사하지 않은 조건을 지나가기만 해도 숫자는 올라갑니다. 테스트는 증명이 아니라 그물이며, 그물의 값어치는 촘촘함이 아니라 무엇을 잡으려고 쳤는지에 달려 있습니다.

되돌릴 수 있어야 도전할 수 있습니다

버전 관리 시스템은 코드의 모든 상태를 기록해 두었다가 언제든 특정 시점으로 되돌아가게 해 줍니다. 깃(Git)은 변경 이력을 커밋의 연결로 남기고 브랜치를 통해 여러 갈래의 작업을 나란히 진행하게 하는데, 여기서 얻는 심리적 효과가 기술적 효과 못지않습니다. 언제든 되돌릴 수 있다는 사실이 사람을 과감하게 만들기 때문입니다. 여기에 코드 리뷰가 붙습니다. 리뷰의 목적은 결함을 찾는 것만이 아닙니다. 한 사람만 아는 코드가 생기지 않게 지식을 퍼뜨리고, 이 코드는 우리 모두의 것이라는 상태를 유지하는 일이 그만큼 중요합니다. 실제로 담당자 한 명이 떠나면 아무도 손대지 못하는 영역이 생기는 것은 흔한 실패 방식이고, 리뷰는 그 위험에 대한 보험입니다.

부채와 은탄환

워드 커닝햄은 급한 일정 때문에 남긴 미완성 설계를 빚에 비유했습니다. 지금 아는 만큼 만들어 빨리 내보내고 배운 것을 반영해 갚아 나가는 것이 원래 의미였고, 갚지 않으면 이자가 붙어 새 기능을 넣는 속도가 점점 느려집니다. 여기서 주의할 점은 이 비유가 엉망인 코드를 정당화하는 말이 아니라는 것입니다. 빌린 줄 알고 빌려야 부채이고, 모르고 저지른 것은 그냥 사고입니다. 그러면 사람을 더 붙여서 빨리 갚으면 되지 않을까요. 프레더릭 브룩스는 1975년 책 맨먼스 미신(The Mythical Man-Month)에서 늦어지는 프로젝트에 인력을 더 넣으면 오히려 더 늦어진다고 적었습니다. 인원이 n명이면 서로를 잇는 의사소통 경로가 n 곱하기 n 빼기 1을 2로 나눈 수로 불어나고, 새로 온 사람을 가르치는 일마저 사정을 가장 잘 아는 기존 인력의 몫이 되기 때문입니다. 브룩스는 1986년 글에서 더 근본적인 진단을 내놓습니다. 소프트웨어의 복잡함에는 문제 자체에서 오는 본질적 복잡성과 도구와 환경 때문에 생기는 우발적 복잡성이 있는데, 도구가 아무리 좋아져도 앞의 것은 남기 때문에 생산성을 단숨에 몇 배로 올려 줄 단일 기법, 즉 은탄환은 없다는 것이죠. 최근의 AI 코딩 도구도 이 틀로 보는 편이 정확합니다. 반복적인 코드 작성이나 문법 확인 같은 우발적 복잡성을 덜어 주는 데는 분명한 도움이 되지만, 무엇을 만들어야 하는지 정하고 모순되는 요구를 조정하는 본질적 복잡성은 그대로 남습니다. 도구가 코드를 생성한다는 말과 도구가 요구사항을 이해한다는 말은 전혀 다른 주장이며, 뒤쪽은 아직 조심스럽게 다루어야 할 표현입니다. 다음 과목에서는 이런 시스템들이 서로 연결되는 세계, 네트워크로 넘어갑니다.

인출 문제

문제 1. 로이스의 1970년 논문과 폭포수 모형의 관계로 옳은 것은 무엇일까요?
그 논문은 시제품을 만들고 되돌아가는 반복을 권하면서 단선적 진행이 위험하다고 지적했는데, 초반의 단순한 단계 그림만 인용되며 폭포수의 원전으로 굳었습니다. 애자일 선언문은 2001년으로 30년 뒤의 문서이고, 규제 산업 한정이라는 단서는 후대의 해석입니다.
문제 2. 테스트 커버리지 수치가 높다는 사실이 보장해 주지 못하는 것은 무엇일까요?
커버리지는 실행된 코드의 비율일 뿐이라서, 결과를 제대로 검사하지 않고 지나가기만 해도 숫자는 올라갑니다. 테스트는 결함의 존재를 보여 줄 수 있어도 부재를 증명하지 못한다는 다익스트라의 지적이 여기에 그대로 적용됩니다.
문제 3. 코드 리뷰가 결함 발견 말고도 노리는 효과는 무엇일까요?
리뷰는 코드에 대한 이해를 여러 사람에게 나눠 담당자 한 명이 떠나면 아무도 손대지 못하는 상황을 막습니다. 소유를 개인에게 몰아 주거나 성과를 측정하는 장치로 쓰면 리뷰가 방어적으로 변해 원래 효과를 잃습니다.
문제 4. 브룩스가 은탄환은 없다고 말한 근거는 무엇일까요?
브룩스는 복잡성을 본질적인 것과 우발적인 것으로 나누고, 도구와 언어는 뒤쪽만 줄일 수 있으므로 생산성을 단숨에 몇 배로 올릴 단일 기법은 없다고 보았습니다. 이 구분은 오늘의 AI 코딩 도구를 평가할 때도 그대로 쓸 수 있습니다.

생각해볼 질문 (정답 없음)

  • 코드 작성의 우발적 복잡성이 계속 줄어든다면, 남는 본질적 복잡성을 다루는 일은 여전히 프로그래밍이라고 불릴까요, 아니면 다른 이름을 얻게 될까요.

이전: 프로그래밍의 세계 3강 · 다음: 네트워크와 인터넷 1강

모던지 · 궁금하면 모던지 GitHub · 2026-09-10