구글 엔지니어는 이렇게 일한다 — 쉽게 이해하기
Titus Winters · Tom Manshreck · Hyrum Wright 편, Software Engineering at Google (2020, O'Reilly. 한국어판 "구글 엔지니어는 이렇게 일한다") 를 파인만 학습법으로 풀어쓴 재구성 해설 노트입니다.
원서의 요약이 아니라, 핵심 개념을 한국어 비유와 설명으로 다시 짠 것. 정확한 인용·세부 구현·통계는 원서를 직접 보세요.
⚠️ 특히 이 책은 구글이라는 단일 환경의 사례 가 데이터의 대부분입니다. 다른 회사에 그대로 옮기면 어디가 깨지는지는 마지막 10장에서 따로 다룹니다.
0. 이 문서를 읽는 법
- 1장 → 2장의 두 정의가 전부의 골격입니다. 시간 없으면 1·2장만.
- 그 뒤는 문화 → 프로세스 → 도구 의 순서로, 같은 골격이 각 영역에서 어떻게 적용되는지 보는 구조.
- 각 장 끝의 "한 줄 요약" 으로 복습.
- 모르는 게 나오면 멈추고 자기 말로 다시 설명 해 보세요. 안 되면 그 장만 다시.
앞의 세 권과의 결
| 다루는 것 | |
|---|---|
| 달리오 | 결정·조직의 원칙 |
| 메도즈 | 시스템 의 일반 법칙 |
| 그로브 | 매니저의 일상 실무 |
| 이 책 | 소프트웨어 엔지니어 의 일상 실무 — 단, 시간·규모 라는 두 축으로 일관되게 본 것 |
이 책의 핵심 기여는 엔지니어링이 프로그래밍과 어떻게 다른가 를 두 단어로 정의한 것입니다 — 시간 과 규모. 1장에서 시작합니다.
1. 정의: 프로그래밍 ≠ 소프트웨어 엔지니어링
책의 모든 내용은 이 한 문장에서 파생됩니다.
Software engineering is programming integrated over time. (소프트웨어 엔지니어링은 시간에 대해 적분된 프로그래밍이다.)
1-1. 무슨 뜻인가
프로그래밍은 지금 동작하는 코드를 짜는 일. 소프트웨어 엔지니어링은 그 코드가 시간이 흐르는 동안 살아 있게 만드는 일. 사이의 차이를 책은 세 축으로 정리합니다.
| 축 | 프로그래밍 | 엔지니어링 |
|---|---|---|
| 시간 (Time) | 지금 돈다 | 5년 뒤에도 돌고, 그동안 변경 가능 |
| 규모 (Scale) | 한 명이 한 번 짠다 | 수십·수백·수천 명이 동시에 바꾼다 |
| 트레이드오프 (Trade-offs) | "이게 되나?" | "이게 어떤 비용으로 되나?" |
1-2. 직관 잡기 — "내 코드, 5년 뒤"
자기 프로젝트의 코드를 떠올려 보세요. 5년 뒤 그 코드를 다시 본다고 가정합니다. 그동안 일어날 일들:
- 의존하는 라이브러리가 메이저 버전 업데이트 (
v2 → v3). - 컴파일러·런타임·OS 가 한두 번 큰 변화를 겪음.
- 회사 정책 (보안·로깅·지표) 이 두세 번 바뀜.
- 처음 짠 본인은 이미 다른 팀이거나 회사를 떠남.
- 새로 들어온 동료가 그 코드를 바꿔야 함.
이 모든 게 예외 가 아니라 기본 입니다. 책의 정의는 이걸 처음부터 가정하라는 뜻.
1-3. 트레이드오프 — "정답은 없다, 비용만 있다"
엔지니어링의 거의 모든 결정은 트레이드오프입니다.
- 빠른 코드 vs 읽기 쉬운 코드
- DRY 한 코드 vs 복사된 코드 (각각 비용이 있음)
- 강한 타입 vs 빠른 프로토타이핑
- 일찍 추상화 vs 늦게 추상화
책의 입장: "이게 답이다" 라고 가르치는 원칙 은 위험하다. 어떤 상황에서 어떤 비용을 받아들이고 어떤 비용을 거부할지 를 의식적으로 선택할 수 있어야 한다.
1장 한 줄 요약: 소프트웨어 엔지니어링 = 프로그래밍 + 시간 + 규모 + 트레이드오프. 5년 뒤에도 그 코드가 살아 있어야 한다는 사실이 모든 결정의 배경이다.
2. 히럼의 법칙 (Hyrum's Law)
이 책의 공동저자 중 한 명인 Hyrum Wright 가 이 책 출간 전부터 업계에 퍼뜨린 법칙으로, 이 책에서 체계적으로 정리되었습니다 (출처는 hyrumslaw.com 의 한 줄에 있음). 한 문장:
With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviors of your system will be depended on by somebody.
충분히 많은 사용자가 있는 API 라면, 계약서에 무엇을 약속했는지는 중요하지 않다: 관찰 가능한 모든 동작 은 누군가의 의존성이 된다.
2-1. 무엇이 충격적인가
소프트웨어를 만들 때 우리는 공식 API 문서 에 "이건 보장한다, 이건 보장 안 한다" 를 적습니다. 그러나 사용자는 실제로 관찰되는 동작 에 의존합니다. 문서가 아니라.
구체적 예 (책에 나오는 패턴):
sort()함수는 순서가 보장된 정렬 만 약속. 같은 키를 가진 원소들의 순서는 문서상 비결정적.- 사용자가 실제로는 안정 정렬이라는 것을 발견. 그 동작에 의존하는 코드를 쓰기 시작.
- 5년 뒤 성능 향상을 위해 비안정 정렬 로 바꾼다 → 수많은 사용자 코드가 깨짐. 계약서상 잘못 없음, 그래도 깨짐.
2-2. 메도즈와의 연결 (혹시 앞 책을 봤다면)
메도즈 시스템 사고에서 "관찰되는 행동은 구조의 산물 " 이라는 명제와 같은 결입니다. 다만 여기는 기술적 시스템 에 적용됨. 공식 인터페이스 라는 추상화는 실제로 흐르는 정보 의 부분집합일 뿐이고, 시스템은 흐르는 정보 전체 에 반응합니다.
2-3. 그래서 어떻게 하나
책의 두 가지 처방:
- 숨길 수 있는 것은 모두 숨겨라. Python 의
_private, Java 의private같은 가시성 제어 뿐만 아니라, 행동 자체 를 일부러 비결정화할 수도 있음. 예: Go 의 map iteration order 는 의도적으로 매번 다른 순서로 나옵니다 — 사용자가 순서에 의존하는 걸 시작 단계에서 막기 위해. - 변경할 때 문서가 아니라 사용자 를 본다. 자기 API 를 누가 어떻게 쓰고 있는지 실제로 측정. 구글의 답은 모노레포 + 자동화 로 바꾸기 전에 영향 받는 모든 호출자를 찾아 같이 바꾸는 것. (8장 Large-Scale Change 에서 다시.)
2-4. 작은 규모에서는?
10명 사용하는 라이브러리에서는 히럼의 법칙이 약하게 작동합니다. 그러나 충분히 의 임계점은 생각보다 낮다는 게 책의 관찰입니다 (구체적 숫자 없음 — 팀이 여러 개 의존하기 시작하는 순간 정도). 본인이 오픈소스를 만들거나, 사내 공통 라이브러리를 만들거나, 팀이 여러 개 의존하는 모듈을 만든다면 이미 적용 대상.
2장 한 줄 요약: 충분히 많은 사용자가 있으면 문서가 무엇을 약속했는지 와 무관하게 관찰 가능한 모든 동작 이 의존성이 된다. 인터페이스를 좁히고, 변경 시 사용자를 직접 보라.
3. 문화 — "천재" 가 아니라 "팀"
책의 2부 (문화) 의 핵심은 단순합니다.
소프트웨어는 천재가 만드는 것이 아니라 팀이 만든다. 천재 신화를 깨야 좋은 엔지니어링 문화가 시작된다.
3-1. "천재 신화" 가 무엇인가
대중 매체가 그리는 프로그래머의 이미지 — 한밤중에 혼자 콜라 마시며 천재적인 코드를 짜는 사람. 이 이미지가 만드는 행동 양식:
- 자기 코드를 끝까지 혼자 들고 감.
- 미완성을 부끄러워 함 → 동료에게 안 보여줌.
- 모르는 것을 질문하지 못함 → 검색·추측으로 때움.
- 코드 리뷰 받는 것을 지적당하는 일 로 받아들임.
책의 진단: 이 모든 게 팀의 산출 을 떨어뜨립니다. 천재 신화는 개인의 자존심을 보호 하지만 조직의 학습 을 막습니다.
3-2. 처방 — "HRT" 와 심리적 안전
책은 HRT 라는 약자를 씁니다.
- Humility (겸손) — 내가 우주의 중심이 아님을 안다.
- Respect (존중) — 동료를 문제가 있는 사람 이 아니라 함께 일하는 사람 으로 본다.
- Trust (신뢰) — 내가 결정한 일을 동료가 알아서 잘할 거라 믿는다.
이 셋이 받쳐줄 때 심리적 안전 (psychological safety) 이 생기고, 그래야:
- 사람들이 미완성 코드 를 일찍 공유함.
- 모른다 를 빨리 말함.
- 틀린 결정 을 일찍 발견함.
말로는 추상적이니 행동 으로 봅니다. 같은 상황 — 동료의 PR 에서 명백한 실수를 발견:
- HRT 없음: "이거 왜 이렇게 했어요? 이렇게 하면 X 가 깨지는데" (사람 vs 사람).
- HRT 있음: "여기 X 케이스에서 깨질 것 같은데, 제가 잘못 본 건지 한번 봐주실래요?" (문제 vs 두 사람).
후자는 연약함 이 아니라 내가 틀렸을 가능성을 항상 끼워 두는 강함 입니다. 결과적으로 동료가 방어 자세를 풀어서 진짜 답이 더 빨리 나옵니다.
3-3. 그러나 — "겸손" 의 함정
여기서 책이 미묘하게 다루는 점이 있습니다. 겸손 을 잘못 쓰면 다음 패턴이 됨:
- 자기 의견을 너무 약하게 표현 해서 결정이 안 됨.
- 과도한 겸손 이 과소한 권위 와 같은 효과를 냄.
- 모든 의견에 같은 무게 를 주려다 전문성의 차이 가 사라짐.
책의 입장: HRT 는 의견을 약하게 말하라 는 뜻이 아니라 틀릴 가능성을 인정하면서 강하게 말하라 는 뜻. 달리오의 "단호하되 열린 마음" 과 같은 결.
3-2 의 PR 예시도 이 관점에서 다시 보세요. "제가 잘못 본 건지 봐주실래요" 는 의견을 약하게 말하는 게 아니라, 지적 자체는 분명하게 하되 ("X 케이스에서 깨질 것 같다") 자기 판단의 가능성을 함께 표기 하는 것입니다. 핵심은 "X 가 깨진다" 라는 명제 가 사라지지 않는다는 것. 사라지면 그건 겸손이 아니라 회피.
3-4. 지식 공유 — 비공식부터 공식까지
3부에 있는 한 장(지식 공유) 의 핵심 도구들:
- 튜터링·멘토링 (1:1, 비공식)
- 코드 리뷰 (다음 장에서 자세히)
- 문서화 (회사 위키, 디자인 문서)
- 회사 내 강의·발표
- "go/" 단축 링크 — 구글 내부의 명물.
go/foo라고 치면 그 회사 자원에 갈 수 있는 모든 사람이 만들고 수정할 수 있는 짧은 링크 디렉터리.
핵심: 지식 공유는 기본값이 공유 이어야 합니다. 누가 물어봐서 공유하는 게 아니라, 기본값을 거꾸로 뒤집어 — 공유 안 하는 데 이유가 필요한 구조.
3장 한 줄 요약: 소프트웨어는 팀이 만든다. 천재 신화·자존심 보호는 팀의 학습을 막는다. HRT (겸손·존중·신뢰) 가 받쳐주는 심리적 안전이 있어야 미완성·모르는 것·실패가 빨리 표면화된다.
4. 코드 리뷰 — 진짜 목적
대부분의 회사가 코드 리뷰를 합니다. 그러나 왜 하는지 에 대해 책은 흔한 답들을 부분만 맞는다 고 봅니다.
4-1. 코드 리뷰의 "맞지만 부족한" 답들
| 흔한 답 | 책의 평가 |
|---|---|
| "버그 잡으려고" | 부분적으로 맞음. 리뷰가 버그를 잡기도 하지만, 반복 가능한 버그는 테스트로 잡는 게 더 효율적. 리뷰는 테스트로 잡기 어려운 종류의 결함 (설계·가독성 문제) 에 더 강함. |
| "코드 품질 보장하려고" | 맞음. 그러나 품질의 정의가 흐릿함. |
| "스타일 통일하려고" | 작은 부분. 자동화 (linter, formatter) 로 대체 가능. |
4-2. 책이 강조하는 진짜 목적
- 지식 공유. 코드를 한 명만 아는 상태 = bus factor 가 1 (그 사람이 버스에 치이면 끝). 리뷰는 최소 두 명이 그 코드를 안다 를 보장.
- 일관성. 한 사람의 스타일이 아니라 팀·회사의 공통 스타일 로 수렴.
- 인간이 읽을 수 있는 코드인지의 마지막 검증. 자기 코드는 자기 머릿속 모델로 읽혀버립니다. 다른 사람이 처음 보고 이해되는지가 유일한 객관적 측정.
4-3. 운영 원칙
- 리뷰는 빨라야 한다. 책의 데이터로는 작은 리뷰는 시간 단위 로 응답이 옴 (큰 리뷰는 더 오래). 리뷰 응답 지연은 PR 작성자의 맥락 손실 로 이어짐 (다음 일로 넘어가 버림).
- 작은 변경. 큰 PR 은 리뷰가 형식화됨. 책은 구체적 줄 수 대신 "한 번에 하나의 논리적 변경" 을 권장.
- LGTM (Looks Good To Me) 의 무게. "괜찮아 보임" 이 내 검토 책임을 다했음 의 서명. 가볍게 누르면 시스템이 무너짐.
- 저자가 리뷰어를 고른다. 자동 할당이 아니라 저자가 가장 적절한 사람을 지명. 부담을 주는 게 아니라 지식 공유의 방향을 저자가 설계 하는 것.
4-4. 리뷰에서 지적하지 말아야 할 것
- 내 취향 이라서 다른 것. (객관적 근거 없는 스타일 의견)
- 방향이 통째로 다른 큰 그림. (이건 디자인 문서 단계에서 끝났어야 함. 코드 리뷰는 늦음.)
리뷰의 적정 단위 는 디자인이 합의된 후의 구현 선택지 입니다. 디자인 자체를 코드 리뷰에서 뒤집으려 하면 충돌·재작업 비용이 큼.
4장 한 줄 요약: 코드 리뷰의 진짜 목적은 버그 잡기 가 아니라 지식 공유 + 일관성 + 가독성의 마지막 검증. 빠르게, 작게, 디자인이 정해진 후에.
5. 스타일 가이드와 규칙 — 읽는 사람 을 위해
5-1. "내가 짠 코드" 보다 "남이 읽을 코드"
핵심 원칙 하나만 기억하면 됩니다.
코드는 짜는 시간 보다 읽히는 시간 이 훨씬 많다. 그러니 스타일은 작성자의 편의 가 아니라 읽는 자의 편의 에 맞춘다.
이 원칙이 많은 결정을 단순화합니다.
- 변수명을 짧게 vs 길게? → 읽는 사람이 처음 봐도 무슨 뜻인지 알아야 하므로 길게.
- 함수를 한 줄짜리도 따로 빼기 vs 인라인? → 이름이 있는 게 더 잘 읽히면 빼고, 그냥 보이는 게 더 잘 읽히면 두기.
- 약어를 써도 되나? → 팀 외부 사람이 모를 가능성이 있으면 풀어 쓰기.
5-2. 규칙의 수준
책은 규칙을 세 종류로 나눕니다.
| 종류 | 예시 | 결정자 |
|---|---|---|
| 언어 규칙 (Style guide) | 들여쓰기, 명명 규약, import 순서 | 회사·언어 단위 |
| 사용 규칙 (Best practice) | "이 함수를 어떻게 쓰는가" | 라이브러리·팀 단위 |
| 취향 | "while vs for", "한 줄 if 허용 여부" | 합의 후 일관성만 유지 |
위로 갈수록 모두에게 강제, 아래로 갈수록 팀 자율. 모든 것을 회사 수준에서 정하려 하면 팀 자율 이 죽고, 모든 것을 팀 수준에서 정하면 회사 일관성 이 죽음.
5-3. 자동화의 역할
스타일 규칙은 최대한 자동화 해야 합니다.
- 사람이 PR 에서 "들여쓰기 4칸으로 바꿔주세요" 라고 적는 건 시간 낭비.
- formatter (
gofmt,prettier,clang-format) 가 커밋 시점에 자동 적용. - 사람의 리뷰는 자동화가 못 잡는 것 에만 집중.
5-4. 반례 의 인정
책은 "규칙을 어겨도 되는 경우 를 명시하라" 고 합니다. 모든 규칙에는 깨야 정답인 상황 이 있습니다. 그 경우에 주석으로 이유 를 남기면 됨.
5장 한 줄 요약: 코드는 짜는 시간보다 읽히는 시간이 많다. 스타일은 읽는 자 를 위해 정한다. 자동화 가능한 건 자동화하고, 사람 리뷰는 자동화가 못 잡는 것에만 집중. 규칙을 깨도 되는 경우는 주석으로 이유를 남겨라.
6. 문서화 — 코드의 "두 번째 진실"
6-1. 왜 코드만으로 부족한가
"코드가 곧 문서다" 라는 말은 부분만 맞습니다. 코드는 무엇을 하는가 는 보여주지만:
- 왜 그렇게 했는가 — 코드에 없음.
- 어떤 대안을 검토했는가 — 코드에 없음.
- 어떤 가정을 깔고 있는가 — 코드에 없음.
- 언제·어떤 상황에 이걸 써야 하는가 — 코드에 없음.
이 모든 것은 문서 의 영역입니다. 코드는 현재의 진실, 문서는 그 진실의 배경.
6-2. 문서의 종류
책이 정리한 분류:
| 종류 | 답하는 질문 | 예시 |
|---|---|---|
| 참고 문서 (Reference) | "이 함수의 시그니처는?" | API 문서, 함수별 docstring |
| 사용자 가이드 (User guide) | "이걸로 무엇을 어떻게 하나?" | 튜토리얼, How-To |
| 개념 문서 (Conceptual) | "이게 왜 이렇게 설계되었나?" | 디자인 문서, 아키텍처 문서 |
| 랜딩 페이지 (Landing) | "어디서 시작하나?" | README, "Getting Started" |
대부분의 회사가 참고 문서 만 갖고 있고 개념 문서 가 부족합니다. 왜 이렇게 만들었는가 는 시간이 흐르면 아무도 모름 — 그 결정을 한 사람이 떠나면 사라짐. 책의 강한 처방: 디자인 문서를 결정 전에 쓰고, 영구히 보관 하라.
6-3. 문서의 수명
문서는 코드보다 더 빨리 썩습니다. 코드는 안 돌면 바로 표가 나는데, 문서는 틀려도 표가 안 남. 그래서:
- 문서를 코드 옆에 두어야 함 (
/docs/가 같은 리포에). - 문서 변경도 리뷰 받아야 함.
- 오래된 문서 를 주기적으로 삭제 하는 작업이 필요. 틀린 문서는 없는 문서보다 나쁨.
6-4. 문서는 제품 이다
좋은 문서는 제품 처럼 다뤄야 합니다.
- 대상 독자 를 명시.
- 완전성 보다 시작 가능성 우선 (긴 완벽한 문서 > 짧은 시작 가능한 문서 — 후자가 나음).
- 피드백 채널 이 있음. ("이 문서 도움 됐나요?" 같은 가벼운 신호도 OK.)
6장 한 줄 요약: 코드는 현재의 진실, 문서는 그 진실의 배경. 특히 왜 그렇게 만들었나 는 코드에 없고, 시간이 흐르면 사라진다. 디자인 문서를 결정 전 에 쓰고, 코드 옆에 두고, 오래된 건 삭제하라.
7. 테스트 — 변화에 대한 자신감
이 책의 테스트 챕터들은 산업 평균보다 훨씬 깊습니다. 핵심 메시지 하나만 잡으면 됩니다.
테스트의 목적은 지금 코드가 맞는지 가 아니라 바꿔도 깨지지 않는지 다.
7-1. "맞다" 가 아니라 "바꿀 수 있다"
처음 보면 미묘한 차이입니다. 풀어 보면:
- 맞는 코드 는 지금 동작 함.
- 바꿀 수 있는 코드 는 내가 안 보는 동안 누가 바꿔도 망가지지 않거나, 망가지면 즉시 표시 됨.
이 차이가 5년 뒤 의 코드 운명을 결정합니다. 테스트 없는 코드는 시간이 흐를수록 손대기 무서워지고, 결국 손 못 대는 거대 덩어리 가 됨. (이 Legacy code = 테스트 없는 코드 라는 정의는 Michael Feathers 의 Working Effectively with Legacy Code 에서 온 것이고, 이 책도 같은 결로 다룹니다.)
7-2. Beyoncé 룰
책에서 가장 인용되는 농담:
"If you liked it, you should have put a CI test on it." (좋아했다면 CI 테스트를 걸어뒀어야지.)
비욘세 가사 "If you liked it, then you shoulda put a ring on it" 패러디. 의미:
내 코드의 동작이 깨지면 안 되는 거라면, 그 동작에 대한 자동 테스트가 CI 에 있어야 한다. 없으면 누군가 모르고 깨뜨릴 거고, 그건 깬 사람 잘못이 아니라 보호하지 않은 너의 잘못이다.
이건 책임의 위치 를 바꾸는 룰입니다. 내 코드를 깬 사람 을 탓하는 문화 → 깨질 수 있게 둔 나 를 보는 문화. (메도즈의 "사람이 아니라 구조" 와 같은 결.)
7-3. 테스트 사이즈
책은 unit/integration/E2E 라는 흔한 분류 대신 size 라는 축을 강조합니다.
| Size | 시간·자원 | 무엇을 테스트 |
|---|---|---|
| Small | ms 단위, 단일 프로세스 | 함수·메서드의 순수한 로직 |
| Medium | 초 단위, 단일 머신 | 모듈 통합, 가짜 외부 의존성 |
| Large | 분 단위, 여러 머신 | 시스템 전체, 실제 외부 의존성 가능 |
이 분류의 장점: 통합/단위 가 아니라 비용/이득 의 축으로 본다는 것.
- Small 은 빠르고 안정 — 많이 둠.
- Large 는 비싸고 불안정 — 꼭 필요한 곳만.
구체 예 — 결제 처리 한 기능을 세 사이즈에서 어떻게 테스트하나:
| Size | 무엇을 보나 | 외부 의존성 |
|---|---|---|
| Small | "할인율 계산 함수에 10% 를 넣으면 결과가 맞는가" | 전부 가짜 (메모리 안에서 함수 호출) |
| Medium | "주문 모듈이 결제 모듈을 부르면 상태가 맞게 바뀌는가" | 가짜 결제 서버 를 같은 머신에 띄움 |
| Large | "실제 카드사 테스트 환경에 1원 결제가 통과하는가" | 진짜 외부 시스템 |
Small 은 수천 개 두어도 1분 안에 돌고, Large 는 몇 개 만 둬도 30분이 가는 식. 사이즈를 의식해야 어디에 몇 개를 둘지 가 결정됩니다.
7-4. DAMP > DRY (테스트에 한해서)
일반 코드의 미덕은 DRY (Don't Repeat Yourself) — 중복 제거. 그러나 테스트 코드 에서는 책이 DAMP (Descriptive And Meaningful Phrases) 를 더 우선합니다.
이유: 테스트가 깨졌을 때 왜 깨졌는지 가 빨리 보여야 함. 공통 함수로 묶으면 어떤 입력으로 어떤 결과가 기대됐는지 가 코드를 따라가야 함 — 디버깅이 어려워짐. 약간의 중복 이 읽기의 즉시성 을 줌.
이건 책의 트레이드오프 의식 의 좋은 예: "DRY 가 항상 답이 아니다, 맥락에 따라 다르다."
7-5. Flaky 테스트의 함정
가끔 통과·가끔 실패하는 테스트 (= flaky test). 이게 무서운 이유:
- 무서워지면 재실행 함 → 통과 → 그냥 넘어감.
- 다음에 또 깨짐 → 또 재실행 → 또 통과 → 또 넘어감.
- 그러는 동안 진짜 버그 가 그 테스트로 위장 → 안 보임.
처방: flaky 테스트는 고치거나, 지워라. 살려두지 마라. 살려둔 flaky 테스트는 전체 테스트 신뢰도 를 갉아먹음.
7장 한 줄 요약: 테스트의 목적은 지금 맞는가 가 아니라 바꿔도 안 깨지는가. Beyoncé 룰: 깨지면 안 되는 동작은 CI 에 테스트가 있어야 한다. 테스트 사이즈로 비용·이득을 본다. 테스트 코드에는 DRY 보다 DAMP. Flaky 테스트는 고치거나 지워라.
8. Deprecation — 지우는 일도 엔지니어링이다
8-1. 거의 잊혀진 작업
대부분의 회사·프로젝트가 추가 하는 데에는 능숙하지만 지우는 데에는 서툽니다. 결과:
- 사용되지 않는 API 가 영원히 남음.
- 두 가지 버전 (구·신) 이 공존 하다 → 누가 어디 쓰는지 모름.
- 결국 둘 다 유지 해야 함 → 비용 두 배.
책의 입장: deprecation 은 별도의 엔지니어링 활동입니다. 짜는 만큼이나 지우는 데에도 명시적 노력 이 필요.
8-2. 두 종류의 deprecation
- Advisory deprecation ("권고") — "이거 안 쓰는 게 좋습니다" 라고 말만 함. 결과: 거의 아무도 안 옮김. 사용량이 줄지 않음.
- Compulsory deprecation ("강제") — "이 날짜 후에는 작동 안 합니다, 그러니 옮기세요" 라고 마감일을 박음. 결과: 옮김.
책의 솔직한 관찰: advisory deprecation 은 거의 작동하지 않는다. 옮기게 하려면 마감일 과 제거 의지 가 있어야 함.
8-3. 옮기는 일은 제공자가 책임진다
이건 책의 다소 논쟁적인 입장 입니다.
deprecation 의 비용은 옮기는 사용자 가 아니라 유지하는 제공자 가 가능한 한 떠안아야 한다.
이유: 사용자에게 맡기면 안 옮김. 작업 자체가 그들에게 우선순위가 낮음. 제공자가 옮기는 도구·자동화·심지어 직접 PR 을 보내는 것 까지 해야 함. 구글의 모노레포에서는 Large-Scale Change (LSC) 라는 도구로 자동화.
이 입장이 작동하는 전제 조건 이 있습니다: ① 사용자 코드에 제공자가 접근 가능 (모노레포 안에 다 있음), ② 대규모 자동 리팩터링 도구 가 갖춰져 있음 (구글의 LSC). 둘 중 하나라도 빠지면 이 정책은 무너집니다. 오픈소스 나 외부 사용자가 있는 라이브러리 에는 그래서 그대로 적용 안 됨 — advisory + semver + 긴 deprecation 기간 이 현실적.
8장 한 줄 요약: 지우는 것도 짜는 것만큼 노력이 필요한 엔지니어링이다. Advisory deprecation 은 거의 안 옮겨준다 — 마감일·강제·도구가 있어야 옮긴다. 옮기는 비용은 가능하면 제공자가 떠안아야 한다.
9. 트렁크 기반 개발과 브랜치는 적이다
9-1. 모노레포 + 트렁크 기반
구글은 전사 단일 리포지토리 (monorepo) + trunk-based development 를 씁니다.
- Monorepo: 모든 코드가 한 리포에 있음. (책 출간 시점 기준 수십억 줄 / 수백만 파일 규모. 수만 명의 엔지니어가 동시에 작업.)
- Trunk-based: 거의 모든 사람이 main 브랜치에서 직접 작업. 짧은 feature branch 는 있지만 며칠 안에 머지.
대안 (다른 회사에서 흔한 방식):
- Multi-repo + long-lived branches: 리포 여러 개, 큰 기능은 몇 주짜리 브랜치.
9-2. 브랜치는 왜 적 인가
긴 브랜치 (long-lived feature branch) 의 문제:
- 통합 이 나중 으로 미뤄짐 → 충돌이 몇 주치 쌓임.
- 브랜치마다 다른 상태의 시스템 → 테스트 결과 신뢰 불가.
- 머지할 때 큰 충돌 → 빨리 해결 하느라 질 떨어짐.
책의 강한 입장: 장기 feature 브랜치는 비용을 미래로 미루는 부채. 통합 비용을 지금 작게 치르고 자주 치르는 게 낫다.
(단, 모든 브랜치를 적으로 보는 건 아닙니다. release branch — 출시한 버전의 핫픽스를 위한 단기 분기 — 같은 정당한 용도는 책도 인정합니다. 적은 몇 주짜리 feature branch 입니다.)
9-3. 트렁크 기반이 작동하려면
그냥 "main 에 푸시" 가 아닙니다. 받쳐주는 것:
- 빠르고 강한 CI — 모든 푸시 전에 자동 테스트. 깨지면 못 들어감.
- Feature flag — 기능이 코드에는 있지만 비활성화 된 상태로 머지. 사용자에게는 플래그가 켜졌을 때만 보임.
- 빠른 롤백 — 들어간 게 잘못된 줄 알면 되돌리기 쉬워야 함.
이 인프라가 없으면 트렁크 기반은 재앙 입니다. 인프라가 있으면 장기 브랜치보다 훨씬 부드러움.
(그래서 이 장의 권고는 조건부 입니다 — CI·feature flag·롤백 인프라가 먼저 있어야 트렁크 기반이 답입니다. 인프라가 없다면 그것부터. 11-1 에서 "구글 규모는 당신의 규모가 아니다" 와 같은 주의가 여기도 적용됩니다.)
9-4. 작은 팀에도 적용되나
책은 구글 규모 의 사례입니다. 그러나 트렁크 기반의 핵심 통찰 은 규모를 안 탑니다:
- 통합을 미루지 마라.
- 미루지 않으려면 작은 단위로 자주 커밋.
- 그러려면 CI 와 feature flag 가 있어야.
이건 10명짜리 팀에도 작동합니다.
9장 한 줄 요약: 장기 브랜치는 통합 비용을 미루는 부채다. 트렁크 기반 + 강한 CI + feature flag 가 더 부드럽다. 작은 단위로 자주 통합하라.
10. CI/CD — 빠른 피드백 > 완전한 검증
10-1. 핵심 트레이드오프
CI (Continuous Integration) 와 CD (Continuous Delivery) 의 근본적 트레이드오프 하나 (아래 5분·1시간은 책의 데이터가 아니라 트레이드오프를 설명하기 위한 예시 수치):
전체 테스트를 완전히 돌리면 1시간 걸린다 vs 대표 테스트 만 돌리면 5분 걸린다. 어느 쪽?
흔한 답: "안전이 우선이니 1시간." 책의 답: 5분. 이유:
- 1시간 피드백은 실질적으로 비동기. 개발자는 다른 일로 맥락 전환 함. 결과가 나와도 돌아오는 비용 이 큼.
- 5분 피드백은 동기. 지금 그 작업 안에서 결과를 보고 지금 고침.
- 매번 대표 테스트만 돌고, 전체 테스트는 후속 으로 비동기 로 돔. 후속에서 깨지면 그제야 알람.
10-2. 비용을 어디로 옮기는가
이건 비용 제거 가 아니라 비용 이동 입니다.
| 전통적 (1시간 동기) | 책의 권장 (5분 동기 + 1시간 비동기) |
|---|---|
| 모든 결함을 머지 전에 잡으려 함 | 일부 결함은 머지 후에 잡힘 |
| 개발자가 기다림 | 개발자가 진행 + 후속 알람 |
| 머지 후 안전 함 (이론상) | 머지 후 가끔 롤백 필요 |
핵심 가정: 롤백이 싸야 한다. 롤백이 비싸면 (예: DB 마이그레이션) 이 트레이드오프가 무너짐. 그래서 CD 와 롤백 가능한 배포 설계 가 함께 가야 함.
10-3. CD — Continuous Delivery vs Deployment
용어가 헷갈리는데 책의 구분:
- Continuous Delivery — 언제든 배포 가능한 상태 를 항상 유지. 누르면 나감.
- Continuous Deployment — 자동으로 나감. (의미상 더 강함.)
대부분의 회사가 Delivery 까지는 목표하지만 Deployment 는 아닙니다 (사람의 판단을 넣고 싶음). 구글 내에서도 서비스마다 다르고 — 많은 서비스가 Deployment 쪽으로 이동 한다는 게 책의 톤입니다 ("모두" 가 아님).
10-4. 점진적 배포
배포는 전체에 한 번에 가지 않습니다. 책이 권장하는 패턴:
1% 사용자 → 5% → 25% → 50% → 100%각 단계에서 지표를 측정. 이상이 있으면 진행 멈춤 또는 롤백. 이게 카나리 (canary) 배포의 의미.
10장 한 줄 요약: CI/CD 의 핵심은 빠른 피드백 > 완전한 검증. 머지 전에는 5분짜리 대표 테스트, 머지 후에 1시간짜리 전체. 단, 롤백이 싸야 이 트레이드오프가 성립. 배포는 점진적 으로 (카나리).
11. 정직한 비판 — 이 책의 한계
이 책은 산업의 현대 표준 교과서 에 가까운 위치이지만, 무비판적으로 받으면 안 됩니다. 세 가지로 정리합니다.
11-1. 구글 규모는 당신의 규모가 아니다
이 책의 가장 큰 한계입니다.
- 모노레포 + 자동화 는 구글이 인프라에 막대한 투자를 한 결과. 10명짜리 회사가 그대로 옮기면 유지 비용 만 큼.
- Large-Scale Change (LSC) — 수백·수천 개 호출자를 한 번에 옮기는 도구 — 는 구글급 자동화 없이는 불가능.
- 제공자가 옮기는 비용 을 떠안는 deprecation 정책 — 구글 모노레포에서는 자연스럽지만 외부 라이브러리 에는 적용 불가.
- 5분 CI — 구글급 분산 빌드 인프라 (Bazel 의 원형인 Blaze) 없이는 작은 회사에서는 사치.
책은 이 점을 부분적으로 인정 하지만 (각 장의 끝에 "당신의 환경에 맞춰라" 라는 메모), 실제로 어떻게 스케일 다운하는지 의 처방은 약합니다.
11-2. 단일 회사 사례 → 일반화 위험
이 책은 구글의 사례 가 데이터의 거의 전부입니다.
- 다른 회사의 반례 가 거의 없음. (애플의 폐쇄성, 마이크로소프트의 윈도우 호환성, 페이스북의 빠른 출시 등 다른 트레이드오프 패턴 이 가능.)
- 구글의 성공이 이 책의 방법론 덕분인지, 구글이 다른 강점을 갖고도 이 방법론을 했기 때문인지 분리되어 있지 않음. (생존 편향.)
요컨대 이 책은 "구글에서 어떻게 했는지" 의 보고서 이지 "이게 보편적 정답이라는 증명" 은 아닙니다.
11-3. 문화 챕터의 톤
3·4·5장 (문화·지식 공유·리더십) 은 이상적 톤 이 강합니다. 실제 구글의 문화도 완벽하지 않다는 내부 증언들이 누적되어 있습니다 — 번아웃, 정치, 일부 팀의 폐쇄성, 다양성 문제 등. 이 책은 공식 입장 에 가깝고 내부 갈등 은 약하게 다룹니다.
11-4. 그럼에도 살아남는 부분
이 한계들이 있다고 책의 가치가 없는 건 아닙니다. 환경 의존도가 낮고 일반화 가능한 핵심:
- 시간·규모·트레이드오프 라는 정의 (1장).
- 히럼의 법칙 (2장) — 규모와 상관없이 작동.
- 테스트의 목적 = 변화 가능성 (7장).
- deprecation 은 별도의 일 (8장).
- 빠른 피드백 > 완전 검증 (10장).
어떻게 구현하느냐 는 환경마다 다르지만 원칙 은 환경을 거의 안 탑니다.
11-5. 다음 단계로 갈 사람에게
이 책을 다 읽고 나면 다음 셋을 같이 보면 균형이 잡힙니다:
- 반대 환경의 책 — 작은 팀·스타트업 의 엔지니어링 실무를 다룬 책 (예: "The Pragmatic Programmer", "A Philosophy of Software Design"). 구글 규모와 반대편 의 트레이드오프를 봅니다.
- 다른 회사의 사례 — Microsoft, Amazon, Netflix 의 엔지니어링 블로그·책. 다른 트레이드오프 가 있다는 것을 확인.
- 본인 환경의 실제 적용 — 책의 권장을 자기 팀 한 곳에 작게 시험. 거기서 얻은 데이터가 책보다 더 가치 있습니다.
닫는 글
이 책에서 도구 (모노레포·Blaze·LSC) 를 빼면 한 문장이 남습니다 — 프로그래밍에 시간 축을 더하라. 도구는 그 축에 맞춰 만들어진 기계이고, 회사마다 다릅니다. 사고 방식은 회사마다 다르지 않습니다.
끝.