구글 엔지니어는 이렇게 일한다

구글 엔지니어는 이렇게 일한다

궁금한게 있을때 크롬브라우저로 검색하고 유튜브 영상링크를 공유하고 Keep 으로 메모하고 google Docs, jamboard 까지 구글의 여러 제품을 일상속에서 매일 사용중입니다.

구글은 이런 여러 제품들을 어떻게 성공적으로 개발했고, 구글 개발자는 어떻게 일하고 있을까? 이 책은 궁금한 것들을 상세히 알려주는 거대한 엔지니어링 보고서와 같습니다.

책을 읽으면서 밑줄친 부분들을 정리해봅니다.

간단히 책의 문구를 정리해서 sns에 올렸는데 놀랍게도 번역자분이 직접 만든 슬라이드를 공유해주셨습니다. 책의 내용이 워낙 방대하다 보니 슬라이드로 전체 내용을 한번 훑고 원문을 읽어보는 것도 좋은 방법인 것 같습니다.

구글 엔지니어는 이렇게 일한다- 슬라이드


Part 1 전제

CHAPTER1. 소프트웨어 엔지니어링이란?

  • 프로그래밍과 소프트웨어 엔지니어링의 가장 큰 차이는 시간, (규모) 확장, 실전에서의 트레이드오프, 이렇게 세 가지
  • 구글에서는 이따금 ‘소프트웨어 엔지니어링은 흐르는 시간 위에서 순간순간의 프로그래밍을 모두 합산한 것이다’ 라고 말하곤 한다
  • 프로그래밍은 코드를 생산하는 즉각적인 행위입니다. 소프트웨어 엔지니어링은 활용 가치가 남아 있는 한 오랫동안 코드를 유용하게 관리하고 팀 간 협업을 가능하게 하는 정책, 관례, 도구 모두를 아우르는 종합적인 개념입니다.

Part 2 문화

CHAPTER3. 지식 공유

‘무언가를 옮기거나 바꾸려면 그게 왜 그 자리에 있는지부터 이해하자’ 라고 말하는 체스터슨의 울타리 원칙을 떠올려보세요.

파괴적인 변경과 구분하여 무언가를 좋은 방향으로 변경하는 문제에는 한 가지 분명하고 단순한 원칙이 있습니다. 아마도 역설이라고 불릴 법한 원칙이죠. 어떤 제도나 법률에 이런 예가 숨어 있을 수 있습니다. 쉽게 설명하기 위해 도로를 가로지르는 울타리가 있다고 해보죠. 전통에 크게 신경 쓰지 않는 유형의 개혁가는 ‘무슨 용도로 울타리를 이렇게 설치했는지 모르겠군요. 깔끔히 밀어버립시다’라고 말할 것입니다. 반면 더 현명한 유형의 개혁가는 ‘용도를 모르겠다면 그냥 밀어버리게 둘 순 없죠. 가서 더 생각해봅시다. 용도를 알아내면 그때 철거할지 결정하자고요’라고 말할 것입니다.

CHAPTER5. 팀 이끌기

관리자는 사람을 이끌고 테크 리드는 기술과 관련한 책임을 집니다. 책임지는 대상면에서는 차이가 크지만 두 역할에 필요한 기술은 꽤나 비슷합니다.

신생 팀이라면 관리자와 테크 리드 역할을 한 사람이 맡습니다. 이를 테크 리드 매니저, 줄여서 TLM이라 하지요. 규모가 더 큰 팀에서는 사람을 관리해본 경험이 많은 이가 관리자 역할을, 기술을 잘 아는 선임 엔지니어가 테크 리드 역할을 맡습니다.

구글에서는 규모가 크고 잘 조직된 팀이라면 테크 리드와 엔지니어링 매니저를 각 1명씩, 총 두 명이 이끄는 것이 통례입니다. 완전히 번아웃 되지 않고서 두 역할을 동시에 수행하기란 너무도 어렵기 떄문이죠. 그래서 각각에 집중하는 전문가를 독립적으로 두는 편이 낫습니다.

사람들이 관리자가 되기 싫어하는 이유가 몇 가지 더 있습니다. 소프트웨어 개발 분야에서 가장 큰 이유는 바로 코딩할 시간이 크게 줄어든다는 점입니다.

‘자신의 무능력이 드러나는 직급’까지 승진하는 경향이 있습니다. 구글은 이 법칙을 피하기 위해 다음 직급으로 승진시키기 전에 현 수준 이상의 일을 일정 기간 맡겨봅니다.

리더로서 여러분이 해야 할 가장 중요한 일은 팀을 떠받드는 것입니다.

팀원이 혼자서 제거할 수 없는 관료적 장애물을 치워주고, 팀이 합의에 이르도록 도와주고, 누군가 늦게까지 야근할 때는 저녁을 사주는 일이 될 수도 있습니다.

  • 오늘날의 엔지니어링 관리자

전통적인 관리자는 일을 ‘어떻게how’ 처리할지를 고민하는 반면, 훌륭한 관리자는 ‘무슨what’ 일을 처리할지를 고민합니다 (그리고 어떻게는 팀을 믿고 맡깁니다).

‘불가능한 목표에 도전하면 실패할 가능성은 그만큼 크다. 하지만 불가능에 도전해 실패하면 성공이 확실하리라 생각한 일을 성취했을 때보나 십중팔구 훨씬 크 것을 얻는다.

여러분보다 똑똑한 사람들로 주변을 채우면 자신의 전문성을 확장하는 데도 훨씬 유리합니다.

‘희망은 전략이 아니다’ 구글의 사이트 신뢰성 엔지니어링 (SRE) 팀의 좌우명입니다.

저성과자를 지도하는 효과적인 방법에는 .. 기간을 정하고 (가령 두 달 정도) 아주 구체적인 목표를 제시하세요.

적합한 사람을 찾는 데 드는 비용(리크루터 수당, 채용 광고 비용, 신중을 기하기 위한 레퍼런스 확인 등)은 애초에 뽑지 말았어야 할 직원을 관리하는 비용에 비하면 아무것도 아닙니다.

그럼에도 평균 이하의 엔지니어들이 팀에 배속된다면 어쩌면 직장을 옮겨야 할 때 일지도 모릅니다.

리더는 항상 무대 위에 있다고 생각하는 방법도 좋습니다.

아무리 사소한 것이라도 여러분이 내비치는 거의 모든 것이 무의식적으로 알려지고 팀에 전염됩니다.

조언을 구하는 사람은 보통 ‘여러분이 나서서’해결해주길 원하는 게 아닙니다. 스스로 문제를 해결하는 걸 도와주길 바라는 거죠. 스스로 해결하도록 이끄는 가장 쉬운 방법은 바로 ‘질문하기’ 입니다.

일이 신속하게 진행되길 원하는 팀은 자발적으로 몇가지 권한과 방향 정하기를 리더에게 전적으로 맡기기도 합니다.

멘토가 되는 데 기본적으로 다음 세 가지를 요구합니다.

팀의 프로세스와 체계에 대한 경험, 다른 이에게 무언가를 설명해주는 능력, 마지막으로 멘티에게 도움이 얼마나 필요한지를 측정하는 능력입니다.

여러분의 목표가 명확하다면 우선순위를 명확히 설정해놓고, 구체적으로 무엇을 택하고 무엇을 버려야 할지는 팀이 스스로 정하도록 적시에 도와야 합니다.

리더로서 팀의 생산서을 장기적으로 끌어올리려면 팀원들이 행복해하는지를 확인하는 데도 시간을 써야 합니다.

수시로 팀원들의 복지를 챙기고, 그들이 하는 일을 인정해주고, 일에 만족하는 확인

‘뭐 필요한 거 업어요?’ 라고 묻는 것입니다.

이 질문을 일대일 면담 때마다 빼놓지 않고 던진다면 팀원들은 머릿속에 담아둘 것입니다.

다음은 리더들에게 구글이 권장하는 그 외의 조언와 요령입니다

위임하되, 곤란한 일은 직접 처리하자

여러분을 대신할 사람을 찾자

우리는 수많은 회사가 가장 뛰어난 엔지니어를 (본인의 의사에 반하더라도) 관리직으로 내모는 모습에 어이없어하곤 합니다. 팀 최고의 엔지니어를 내쫓고 평균 이하의 관리자를 채용하는 것과 같은 행위니까요.

파도를 일으켜야 할 타이밍을 알자

혼란으로부터 팀을 보호하자

회사를 원래부터 혼란스러웠다고. 다만 전임 관리자가 팀원들을 혼란으로부터 보호해주고 있었을 뿐이라고 말이죠

팀에 공중 엄호를 해주자

가능한 한 많은 정보를 팀과 공유하되 팀에 실제로 영향을 줄 가능성이 거의 없는 조직 차원의 광기로 팀 업무가 방해받지 않도록 해주세요.

팀이 잘하고 있으면 칭찬하자

실패해도 쉽게 되돌릴 수 있는 일에는 ‘해보세요’라고 말하자

진짜로 훌륭한 리더는 어떤 일은 되돌릴 수 있고 어떤 일은 되돌리기가 생각만큼 쉽지 않은지를 판단해내는 감각이 뛰어납니다.

CHAPTER6. 성장하는 조직 이끌기

늘 결정하라

리더인 여러분은 팀이 매주 무엇을 해야 하는지 결정해야 합니다.

‘이 결정대로 시도해보고 어떻게 되는지 지켜보죠. 상황을 봐서 다음 달에 변경 사항을 취소하고 다른 결정을 내릴 수도 있습니다’라며 위험을 낮추고 긴장을 줄여주세요.

코드 옐로는 ‘중대한 문제를 해결하기 위한 긴급 해커톤’을 뜻하는 구글 용어입니다. 관련 팀들은 모두 하던 일을 멈추고, 선언된 긴급 상황이 해제될 때까지 문제 해결에 100% 전력투구해야합니다.

구글은 품질, 지연시간, 용량 변화가 적절한 균형을 이루는지를 매월 반복해 돌아보면서 ‘늘 결정’하고 있습니다.

늘 떠나라

리더 스스로가 단일 장애점(SPOF) 이 되는 상황. 구글에서는 이를 버스 지수 (몇 명의 팀원이 버스에 치어서 일을 할 수 없게 될 때 프로젝트가 망하게 되는지를 나타내는 지수)라고 합니다.

  • 하위 문제를 다른 리더에게 위임하기

이 문제를 처리할 수 있는 살마이 정말 나뿐일까? 라는 질문을 스스로에게 던져보세요. 일을 처리할 수는 있지만 여러분보다는 훨씬 오래 걸릴 누군가에게 말이죠. 업무 크리티컬 패스 상에서 여러분의 이름이 사라지게 해야 합니다.

매일 아침 출근하면 자신에게 ‘우리 팀원 중 아무도 할 수 없는 일 중에서 내가 할 수 있는 일은 무엇이 있을까?’ 라는 질문을 던져보세요.

  • 조율하고 반복하기

관찰과 경청 95%, 절묘하고 시의적절한 개입 5%, 이것이 좋은 관리입니다.

  • 팀 정체성 설정 시 주의점

팀에는 일반적인 ‘문제’를 맡겨야 합니다. 그런데 우리는 특정 ‘제품’을 맡겨버리는 실수를 자주 범합니다.

늘 확장하라

리더로서 여러분에게 주어진 가장 값진 자원은 ‘자신의 제한된 시간, 집중력, 에너지’ 입니다.

새로운 문제를 받아왔는데 (보통은) 인력 충원은 없습니다. 맡겨진 문제가 두 개가 되어버렸습니다. 원래의 문제도 여전히 관리가 필요하니 ‘절반’의 인력과 ‘절반’의 시간을 할애합니다.

새로운 문제를 정복하고 압축하는 방법을 찾아낸 다음 또 다른 문제를 배정받아 반복하는 식으로 말입니다.

리더로서 여러분은 ‘나만이 할 수 있는 일’을 처리해야 함을 잊지 마세요.

  • 공 떨어뜨리기

소지품들을 3층 선반에 정리한다고 생각해보세요. 가장 아래 칸에는 쓸모없는 20%를

곤도는 ‘진짜’ 정리는 아래 칸 20%가 아니라 위 칸 20%에 무엇을 둘지를 골라내는 것이라고 주장합니다. 정말 중요한 물건만 추리고 나머지 80%를 버려야 합니다.

상위 20% 즉 여러분만이 할 수 있는 중요한 일들을 신중하게 골라낸 다음 오직 그 일들에만 집중하는 것입니다. 나머지 80%를 버릴 권한을 자신에게 부여하세요.

  • 에너지 관리하기

    • 진짜 휴가 떠나기

      잠시나마 심리적으로 멀리 떠나와서 얻은 이점이 모두 날아가버립니다. 휴가로 재충전하려면 일과 단절하는 훈련이 필요합니다.

    • 일과 쉽게 단절하기

      일에서 신경을 끄려거든 어붐용 랩톱은 회사에 두고 떠나세요. 휴대폰에 업무용 앱이 깔려 있다면 지우세요.

    • 진짜 주말 보내기

      금요일 저녁에 미련 없이 퇴근한 후 주말에는 오롯이 자신이 좋아하는 일만 하세요.

    • 매일매일 휴식하기 자연적으로 인간의 뇌는 90분 주기로 운용. 90분마다 돌아오는 이 기회를 의자에서 이러나 사무실 주변을 돌거나 10분 정도 산책하는 데 써보세요. 스트레스를 크게 낮춰줘서 그다음 두 시간은 완전히 다른 기분으로 일할 수 있습니다.

CHAPTER7. 엔지니어링 생산성을 측정하는 이유

엔지니어링 생산서을 측정하는 이유

조직이 두 배 커지면 소통 비용은 제곱으로 늘어납니다. 그래서 조직 덩치에 비례하게 사업을 키워갈 수는 없습니다.

소프트웨어 엔지니어링 생산선 개선과 더불어 개선 업무 자체의 효율까지 높이는 게 구글의 목표였습니다.

GSM 프레임워크: 목표와 신호를 뒷받침하는 의미 있는 지표 선정하기

  • 목표는 측정자가 원하는 최종 결과입니다. 측정을 통해 이해하고 싶은 내용을 고차원의 어휘로 표현하되 특정한 측정 방식을 명시해서는 안 됩니다
  • 신호는 원하는 최종 결과를 이루었는지 판단하는 방법입니다. 우리가 측정하고 싶어 하는 것이지만 신호 자체는 측정하지 못할 수도 있습니다.
  • 지표는 신호를 대변합니다. 우리가 실제로 측정하는 대상이죠. 이상적인 측정법은 아닐 수 있으나 충분히 가깝다고 믿는 것이어야 합니다.

Part 3 프로세스

CHAPTER8. 스타일 가이드와 규칙

스타일 가이드는 구글의 코드를 지배하는 종합적인 규약 모음집입니다.

구글은 코딩할 때 따라야 하는 혹은 하지 말아야 하는 규칙을 모아서 프로그래밍 스타일 가이드로 정리해 표준으로 삼았습니다.

규칙은 일상의 개발 패턴을 조직이 원하는 방향으로 슬쩍 밀어주는 역할로 폭넓게 활용됩니다.

규칙 모음을 정의할 때 반드시 던져야 하는 질문은 ‘무슨 규칙이 필요하지?’ 가 아니라 ‘어떤 목표를 이루려 하지?’ 입니다.

규칙의 양을 최소화한다

읽는 사람에게 맞춘다

구글은 ‘쓰기에 간편한’보다 ‘읽기에 간단한’ 쪽에 가치를 둡니다

일관되어야 합니다

오류가 나기 쉽거나 예상치 모한 동작을 유발하는 구조를 피합니다

꼭 필요하다면 실용성을 생각해 예외를 허용합니다

스타일 중재자

구글의 스타일 가이드들은 언어별로 소유자가 따로 있어서 최종 결정과 승인을 책임집니다. 이 소유자들을 스타일 중재자 style arbiter 라고 부릅니다. 프로그래밍 언어별로 경험 많은 전문가 그룹이 스타일 가이드를 소유하고 결정궈자 역할을 합니다.

CHAPTER9. 코드 리뷰

코드는 작성되는 횟수보다 읽히는 횟수가 몇 배는 많으므로 이해하기 쉽게 작성하는 게 매우 중요합니다.

원작자와 당시 리뷰어들에 그치지 않고 시간을 뛰어넘어 훨씬 많은 엔지니어에까지 지혜를 전달해줍니다.

리뷰어는 최소한으로

리뷰어를 추가해서 얻는 가치보다 비용이 훨씬 빠르게 증가하여 금세 역전됩니다.

코드 리뷰는 지식을 조직 전체에 공유하는 데도 중요한 역할을 합니다

코드 리뷰 프로세스를 확장하려면 자동화가 아주 중요합니다

코드 리뷰 자체가 변경 이력이 되어줍니다.

CHAPTER10. 문서자료

구글에서 문서자료를 개선하고자 해본 시도 중 가장 성공적이었던 방법은 문서자료를 코드처럼 취급하여 엔지니어링 워크플로에 통합하는 것이었습니다.

글쓰기는 소프트웨어 엔지니어링에 반드시 필요한 기술입니다

만약 다른 이에게 두 번 이상 똑같은 설명을 하고 있는 자신을 발견한다면 그 내용을 문서화하는 게 좋습니다.

구글의 성장과 반대로 문서자료의 품질으 점점 나빠졌고 개발자 설문에서 개발자들의 가장 큰 불만으로 꼽히기에 이르렀습니다.

중요한 문서자료를 소스 코드와 똑같이 변경을 추적하도록 한 것입니다. 문서자료들에 소유자를 지정하고, 소스 트리상의 위치도 표준으로 정하고, 오류를 식별하고 수정하는 프로세스도 확립했습니다.

테크니컬 라이터는 도메인에 익숙하지 않은 사람을 더 잘 대변할 수 있습니다. 그래서 테크니컬 라이터의 핵심 역할 하나가 바로 프로젝트가 어디에 유용한가에 관한 팀 내 가정에 의문을 품어보는 것입니다.

CHAPTER11. 테스트 개요

최악의 상황을 겪은 제품은 바로 구글 웹 서버(GWS).

GWS의 테크 리드(TL)는 엔지니어 주도의 자동 테스트를 정책 차원에서 도입하기로 했습니다. 이 정책의 일환으로 모든 코드 변경에는 지속해서 실행할 수 있는 테스트가 반드시 딸려 있어야 했습니다.

테스트의 크기를 가늠하는 기준은 코드줄 수가 아닙니다. 대신 어떻게 동작하고, 무엇을 하고, 얼마나 많은 자원을 소비하는지로 평가합니다.

작은 테스트는 프로세스 하나에서 동작하고, 중간 크기 테스트는 기기 하나에서, 큰 테스트는 자원을 원하는 만큼 사용해 동작합니다.

구글은 큰 테스트를 작은 테스트나 중간 크기 테스트와 분리하여, 빌드나 릴리스 때만 수행되도록 하여 개발 워크플로에 영향을 주지 않도록 합니다.

어떤 행위나 속성을 테스트해야 하냐는 질문 → 간단한 대답은 깨뜨려보고 싶은 모든 것을 테스트하라

코드 커버리지는 테스트되지 않은 코드가 어디인지는 알려줄 수 있지만, 시스템이 얼마나 제대로 테스트되었느냐를 판가름하는 지표로는 적합하지 않습니다.

CHAPTER12. 단위 테스트

  • 커버리지가 높다면 엔지니어들은 기존 동작을 망가뜨리지 않으리라는 확신 속에서 코드를 변경할 수 있습니다.
  • 깨지기 쉬운 테스트란 실제로는 버그가 없음에도, 심지어 검증 대상 코드와는 관련조차 없는 변경 때문에 실패하는 테스트를 말합니다.
  • 구글에서는 개개인의 엔지니어가 하루에 수천 개의 테스트를 돌리는 게 일상.
  • 기존 테스트를 수정해야 하는 경우는 시스템의 해우이가 달라지는 파괴적인 변경이 일어날 때뿐입니다.
  • 상호 작용이 아니라 상태를 테스트하자
    • 시스템이 기대한 대로 동작하는지 검증하는 방법은 크게 두 가지
    • 첫 번째는 상태 테스트로, 메서드 호출 후 시스템 자체를 관찰
    • 두 번째는 상호작용 테스트로, 호출을 처리하는 과정에서 시스템이 다른 모듈(시스템)들과 협력하여 기대한 일련의 동작을 수행하는지를 확인, 많은 테스트가 상태와 상호작요 검증을 혼용
  • 모든 행위는 given, when, then 이라는 세 요소로 구성됨
    • given 요소에는 시스템의 설정을 정의, when 요소에는 시스템이 수행할 작업을 정의, 마지막 then 요소에는 결과를 검증

CHAPTER13. 테스트 대역

  • 테스트를 작성하기는 쉬웠지만 버그는 잘 찾아내지 못했고 끊임없이 보수해야했음. 그래서 방향을 틀었고 오늘날에는 많은 엔지니어가 모의 객체 프레임워크를 피하고 실제에 더 가까운 테스트를 작성
  • 실제 구현을 사용할지 결정하는데 고려요소에는 실행 시간이 있고 빌드 도구인 Bazel은 변경되지 않은 코드는 이전 빌드 결과를 캐시해주는데, 이처럼 확장성이 뛰어난 빌드 시스템을 이용하면 도움이 된다.
  • 테스트에서 데이터베이스를 사용할 수 없다면 데이터 베이스 API를 호출하는 클래스 각각이 아니라 데이터베이스 API 자체만 가짜 객체로 만드는 식
  • 상호작용 테스트의 가장 큰 문제는 대상 시스템이 특정 함수가 호출되었지만 알려줄 뿐, 올바르게 작동하는지는 말해주지 못한다는 점

CHAPTER15. 폐기

  • 이주를 순차적으로 진행하여 궁극적으로는 낡은 시스템을 완전히 걷어내는 과정을 폐기 라 합니다
  • 코드 자체는 가치를 창출하지 않습니다. 가치를 만들어내는 건 바로 ‘기능’ 입니다. 사용자의 요구에 부합하는 기능은 자산
  • 회사에서 기대 수명 동안 제대로 지원하지 못할 것 같은 프로젝트는 시작하지 마십시오.
  • 폐기팀을 관리할 때도 측정할 수 있고 고객에게 가치를 전달해주는 명확하고 점진적인 마일스톤들을 세워야 합니다

CHAPTER16. 버전관리와 브랜치 관리

  • 버전 관리는 엔지니어가 소스 코드와 시간의 상호작용을 관리하는 핵심 도구
  • VCS(파일 이름, 작성 시각, 브랜치 이름) → 파일 내용
  • 개발이란 본질적으로 분기하고 병합하여 전진하는 프로세스이며, 분기와 병합은 여러 개발자 사이에서 이루어지는 혹은 한 명의 개발자가 여러 시간대에서 수행하는 작업들을 체계적으로 관리해주는 핵심 개념
  • 트렁크 기반 개발, 테스트와 CI를 적극 화용하여 모든 빌드와 테스트가 항상 성공하도록 관리, 완벽하지 않거나 테스트되지 않은 기능은 비활성화
  • 원 - 버전 규칙
  • 개발자가 ‘이 구성요소는 어떤 버전을 사용해야 하죠?’ 라고 묻는 상황을 만들지 않아야 한다
    • 의존성을 새로 추가할 때 선택할 수 있는 버전을 제한한다
  • Code Search는 구글이 이용하는 코드 브라우징 및 검색 도구
  • 다음과 같은 질문들에 한두 번으로 답해주는 수준
    • 이 심볼은 어디에 정의되어 있나요?
    • 이건 어디서 사용되죠?
    • 이 심볼은 어떻게 인클루드하죠?
    • 이 코드는 언제 코드베이스에 추가된 거죠?
    • 전체적으로 CPU 사이클을 얼마나 소모하나요?
  • 구글은 어떻게 구현했나?
    • 검색 인덱스
    • 초기에는 트라이그램 기반, 이후 커스텀한 접미사 배열 기반 방식 도입, 현재는 희소 n- 그램 방식까지 진화