TOC
참고
본 내용은 구글 엔지니어는 이렇게 일한다(링크)를 읽고 정리한 내용입니다.
책의 내용과 함께 개인적인 의견과 생각, 학습을 담아 작성하였습니다.
코드 리뷰의 이점
- 구글은 대부분 엔지니어들의 자유를 보장하지만, 코드리뷰만큼은 정말 철저하게 한다.
- 코드리뷰의 강제적 규제는 비용을 유발하고 엔지니어링 속도에도 영향을 준다.
- 그럼에도 왜 구글은 이 프로세스를 강제하는 걸까. 왜 장기적으로 이득이라 믿을까.
- 구글이 생각하는 코드리뷰의 이점
- 코드가 정확한지 확인해준다.
- 변경된 코드를 다른 엔지니어도 잘 이해한다.
- 코드베이스가 일관되게 관리된다.
- 팀이 소유권(주인의식)을 더 강하게 느낀다.
- 지식이 공유된다.
- 코드 리뷰 자체의 기록이 남는다.
- 소프트웨어 조직이 오래 존속되는 데 필요하며, 한편으로는 리뷰어들에게도 도움이 된다.
구글이 말하는 코드리뷰의 이점은 대부분 일반적이지만, 지식이 공유된다는 점이 코드 리뷰의 큰 장점이라고 생각합니다. 리뷰어에게도, 작성자에게도 코드 레벨에서 각자의 생각이 부딪히거나 잘못된 지식을 바로잡거나, 몰랐던 더 나은 방법을 알게 되는 계기가 되는 거죠.
코드 정확성
- 코드 리뷰가 주는 가장 확실한 이점
- 코드 리뷰 프로세스는 가벼워야 한다. 쉽게 유지되고 확장되어야 지속 가능하다.
- 정확성 평가는 주관적이면 안 된다. 일반적으로 작성자가 선택한 방식을 존중한다.
- 코드가 '완벽하다'가 기준이 아닌, '개선됐다'가 기준이 된다. 코드 리뷰의 속도를 높이는 수단.
리뷰 속도를 위해 코드가 개선만 되었다면 코드 리뷰를 승인한다는 방식은 좋은 것 같습니다만, 더 좋은 방식을 알고 있음에도 LGTM을 날려야 하는 입장에서는 조금은 답답함을 느낄 수도 있겠네요.
코드 이해 용이성
- 코드 리뷰는 작성자의 관점에 치우치지 않은 피드백을 제공할 수 있다.
- 변경이 수많은 다른 사람에게도 쉽게 이해되는지를 평가하는 시험대
일단 되는 코드를 작성하는 방법론에서는 코드 리뷰를 어떻게 하는지 궁금합니다. 되는 코드는 리팩토링 이전에는 가독성이 그리 좋지 않을테니까요. 리팩토링까지 한 뒤에 PR을 올리는 걸까요? PR 단위가 커지진 않을까요? 아니면 개발-리팩토링-PR의 단위 자체를 작게 하는 걸까요? 이렇게 된다면 일단 되는 코드를 작성한다는 취지에 맞는 걸까요?
코드 일관성
-
규모가 커짐에 따라 내 코드는 다른 사람이, 다른 사람의 코드는 내가 읽고 이해하게 된다.
-
따라서 코드는 일정한 표준을 따라야 한다.
-
복잡해져서는 안 된다. 코드가 단순해야 다른 이들이 이해하고 유지보수하기 쉽다.
-
그래서 코드 리뷰에
가독성 승인
이 필요한 이유이다.- 해당 프로그래밍 언어의 모범 사례들을 잘 따라야 한다.
- 구글 코드 레포지토리에서 같은 언어로 작성된 다른 코드들과 일관되어야 한다.
- 필요 이상으로 복잡하지 않아야 한다.
-
때로는 일관성을 위해 기능성을 희생해야 할 때도 있다.
심리적, 문화적 이점
- 코드리뷰는 코드가 '자신의 것'이 아닌, '조직의 공동 소유물', '협업의 산물'이라는 인식을 남긴다.
- 자신의 취향을 덜 녹이고, 더 큰 조직의 이익을 위해 타협하도록 이끈다.
- 코드 리뷰는 중립적인 방향으로 비판적이어야 한다. 사람과 제도를 분리하여 제도로써 갖추었기에 감정적인 논쟁으로 번지지 않게 한다.
- 코드 리뷰에서는 '나쁜 경찰'이 되도록 제안하기에, 리뷰어 자체는 '좋은 경찰'로 남을 수 있다.
- 코드 리뷰가 없다면 다수가 절차를 무시하려고 들 것이다. 코드 리뷰를 필수라고 못박으면 작성자들에게 자신의 코드를 한번 더 들여다보게 하는 효과가 있다.
자신의 취향을 덜 녹이고 조직을 위한다는 문화적 이점이라는 관점이 좋게 와닿았습니다.
그리고 코드 리뷰가 자신을 돌아보는 장치가 된다고 하는데, 저는 회사에서 팀 없이 혼자 작업을 하고 있기 때문에 리뷰어가 있다고 생각하고 열심히 PR 과정을 밟고 혼자서 돌아보려고 하고 있습니다.
지식 공유
- 많은 코드 리뷰에서 양방향 정보 교환이 이루어진다.
- FYI: for your information(참고로) - 작성자에게 지식 공유 차원에서 가볍게 남길 수 있는 주석
- 새로운 패턴을 알리는 자리로도 활용된다.
- 시간과 공간을 넘어 이력을 남기는 용도로도 활용된다.
코드 리뷰 모범 사례
- 코드 리뷰로부터 투자한 시간만큼의 가치를 뽑아내려면 모범 사례를 알고 적용해야 한다.
- 대다수 모범 사례는 코드 리뷰에 무리가 없을만큼 프로세스를 날렵하게 유지하는 게 중요하다고 강조
공손하고 전문가답게
- 코드 리뷰를 통과하면 코드 베이스의 변경 사항이 반영되므로 피드백과 비평은 전문가답게 건네는 것이 중요하다. 모든 논평은 철저하게 전문적이어야 한다.
- 리뷰어는 작성자의 방식에 대해 성급히 결론짓지 않도록 주의한다.
- 방식이 잘못되었다고 가정하기 전에 그렇게 처리하게 된 이유가 무엇인지 묻는 것이 좋다.
- 신속하게 피드백하되, 너무 단편적인 피드백은 자제한다.
- 작성자에게도 전문가다움이 요구된다. '나'는 '나의 코드'와 다르다. 코드는 팀의 소유이다.
- 코드 리뷰 과정에서 리뷰어가 단 댓글은 모두
TODO
취급해야 한다. 모두 수용할 필요는 없지만 고민은 해봐야 한다. - 리뷰어의 의견과 다를 때에는 대안을 제시하고 한 번 더 살펴봐달라고 부탁하라.
- 의견 충돌은 감정 싸움과 다르다. 정중하고 존중을 가지고 의견을 교환하라.
코드 리뷰라는 감정적 중재 체제 안에서 감정 싸움으로 번지지 않기 위해서 꼭 필요한 자세라고 생각합니다.
작게 변경하기
- 코드 리뷰 프로세스를 날렵하게 가져가기 위한 방법
- 코드 리뷰는 단 하나의 문제만을 다루는 게 가장 이상적
- 리뷰어는 큰 변경에 대해서 거부할 권한이 있다.
혜성님과 함께 하는 프로젝트에서 PR의 크기가 커서 리뷰하기가 어렵다는 피드백을 받았던 기억이 납니다. 이전 회사에서도 PR의 크기를 어느 정도로 작게 해야하는지 갑론을박이 있었고요. 오히려 너무 작은 PR 단위로 인해서 업무 흐름이 끊긴다는 의견도 있었고요. 중용을 택해야 하겠지만 일단 작은 게 맞다는 생각이 듭니다.
- 커다란 기능을 새로 도입할 때는 작은 변경들로 대응하기가 어렵다. 작은 변경 자체는 소화하기 쉽지만 전체 그림 안에서는 종합적 검토가 어렵기 때문
- 큰 단위의 경우 별도 브랜치에서 개발 후 병합하는 방식으로 HEAD 브랜치와의 diff를 기반으로 변경을 관리할 수 있다.
- 프로세스를 작은 변경에 적합하게끔 최적화하는 동시에 가끔 일어나는 큰 변경도 수용할 수 있게 하면 좋다.
어려운 일인 것 같습니다. 책에서 말한 내용은 2depth 브랜치가 아니라, 3depth로 계층적으로 내려가서 2depth에 계속 반영하다가 2depth 브랜치를 1depth에 한 번에 녹여 큰 단위는 유지하는 것이겠죠. 음.. 당장 생각 나는 좋은 방법은 없네요. 좋은 방법이 있다면 공유해주세요.
- '작은' 변경은 200줄 이하의 코드를 의미
- 구글에서 만들어지는 변경의 35%는 파일 하나에서 이루어진다.
- 초기의 작은 리뷰는 잘못된 방향성에 의해 다시 되돌아오는 비용도 크게 낮춰준다.
변경 설명 잘 쓰기
- 변경 설명의 첫 줄은 정말 중요하다. 어떤 종류의 변경인지를 잘 요약해야 한다.
- 올바르게 동작할 지라도 리뷰어가 코드를 잘 이해하지 못한다면 개선해야 하는 코드이다. 구조를 개선하거나 코드 안에도 설명을 달아줘야 한다.
- 코드 리뷰는 지금 당장만이 아니라 후대를 위해 현재 하고 있는 일을 기록하는 행위
그래서 commit convention이 등장한 게 아닐까 싶습니다. 작은 변경사항이더라도 의미를 담기 위해서 말이죠. 저는 commit convention이 없는 환경에서 히스토리 추적이 얼마나 힘든지를 겪어봤어서 스스로 최대한 잘 지켜보려 합니다. 좀 과하지만 레퍼런스를 참고했다면 레퍼런스 링크를, jira나 github issue 번호를 함께 적기도 합니다.
리뷰어는 최소한으로
- 수확 체감(diminishing returns): 첫 번째 LGTM에 비해 두 번째는 크게 신경 쓸 만큼의 가치가 없다.
- 리뷰어가 많으면 얻어지는 가치보다 비용이 훨씬 빠르게 증가한다.
- 때에 따라 여럿이 검토하는 게 나을 때도 있다. 단, 서로 다른 관점에서 바라보도록 역할을 조율하고 진행해야 한다.
이는 구글의 개개인이 일을 올바르게 처리한다는 신뢰에 기반한다고 생각합니다. 만약 직접적인 리뷰어가 인턴이라면 보다 더 코드를 잘 알거나 경험이 있는 누군가가 필요할 수도 있을 겁니다. 어쩌면 아직도 다른 시각을 기대하는 엔지니어의 입장에서 여러 코드 리뷰어를 고집하는 것에 합리화하려는 걸 수도 있겠네요...
가능한 한 자동화하기
- 기계적인 작업을 찾아서 도구에 맡기면 투자한 만큼 거두게 된다.
코드 리뷰 유형
- 코드 리뷰에는 여러 가지가 있고, 유형에 따라 어떤 측면에 집중해야 할지가 달라진다.
- 구글에서는 보통 다음의 4가지 분류로 구분한다.
- 그린필드 리뷰와 새로운 기능 개발
- 동작 변경, 개선, 최적화
- 버그 수정과 롤백
- 리팩터링과 대규모 변경
그린필드 코드 리뷰
- 완전히 새로운 코드를 대상으로 하는 가장 드문 유형의 코드 리뷰
- 대상 코드가 오랜 기간 유지될 수 있는지 판단할 가장 중요한 기회
- 구글에서는 새로운 코드와 프로젝트에서는 설계 리뷰를 강도 높게 진행한다.
- API가 합의된 설계에 부합하는가
- API에 단위 테스트가 존재하는가
- 테스트가 완벽히 이루어졌는가
- 코드의 가정이 달라지면 실패하는가
- 코드를 책임질 소유자가 알맞게 배정되었는가
- 주석이 충분한가
새 땅이라서 GreenField라는 용어를 쓴 것 같은데 적절하다고 생각합니다. 그리고 더 빡빡하게 리뷰해야 한다는 사실도 말이죠. 구글이라 그런지 정말 튼튼한 구조에서 새 땅을 넓혀간다는 생각이 드네요.
동작 변경, 개선, 최적화
- 구글에서는 대부분 기존 코드를 수정한다. API 수정, 기존 구현 개선, 성능 최적화 등
- 이때도 그린필드 리뷰 지침이 그대로 적용된다.
- 죽은 코드나 낡은 코드의 제거는 코드베이스를 건실하게 만드는 멋진 방법이다.
- API 수정에는 관련 테스트도 동반되어야 한다.
- 구현 방식 개선 또는 최적화는 기존 테스트들에 영향을 주지 말아야 한다.
- 최적화는 성능 벤치마크 결과를 리뷰어에게 제시해야 한다.
프로젝트와 조직의 성숙도에 따라 주목하는 상황이 다르다고 생각합니다. 저는 지금까지 사실상 새로운 땅을 계속 만드는 프로젝트에서 일해왔고, 제가 만든 땅만 다시 가꾸는 유지보수만 해왔는데 큰 규모의 회사에서 기존 코드의 수정 프로세스를 맛보고 싶다는 생각도 드네요. 당장은 아니어도 언젠가는 이런 체계를 맛볼 수 있으면 좋겠습니다.
버그 수정과 롤백
- 버그 수정과 함께 다른 문제까지 묶어 처리하고픈 마음을 꾹 눌러라.
- 여러 주제가 섞이면 리뷰할 게 많아지고, 회귀 테스트와 롤백을 훨씬 어렵게 만든다.
- 물론 관련 테스트도 함께 수정하거나 보강해야 한다. 버그가 났다는 건 기존 테스트의 가정이 어긋났거나 충분하지 않았기 때문이다.
- 잠재적으로 롤백을 유발할 수 있는 모든 변경은 가능한 작고 원자적이어야 한다.
목표한 버그만 잡으라는 조언은 저한테 정말 필요한 조언이었습니다. 그동안 롤백할 일이 많지 않았다보니 생겼던 습관인데 commit 단계로만 쪼갤 게 아니라, PR 단계, 혹은 버전이 달라지는 patch 단계까지도 해당 버그에 온전히 독립적이어야 한다는 생각이 듭니다. 따끔한 조언이니 새겨들어야겠네요.
리팩터링과 대규모 변경
- 기계(도구)가 생성한 변경도 리뷰가 필요하다.
- 단, 댓글을 다는 건 지양한다.
- 대규모 변경 프로세스 자체에는 신경 쓰지 않고, 자신의 코드와 관련된 문제만 신경 써라.
- 구글은 자동 변경의 리뷰어들에게 수정 범위를 확대하지 않도록 권장한다. 도구를 개선하는 과정에서 관련 엔지니어가 수백 개의 요청을 받고 동시에 처리해야 할 수 있고, 그러면 의욕이 꺾인다.
마무리
- 코드리뷰는 가장 중요하고 핵심적인 프로세스
- 엔지니어들을 이어주는 매개체
- 거의 모든 다른 프로세스가 엮인 최우선 개발 워크플로우
- 코드 리뷰 프로세스는 확장이 매끄럽게 이루어져야 한다.
- 작은 변경, 빠른 피드백과 반복 등의 모범 사례가 엄격히 지켜져야 한다.
총평
- 초반에는 구글 자체적인 코드 리뷰 구조였기 때문에 '그렇구나' 하면서 따로 적지 않고 가볍게 봤습니다. 수 만 명의 구글러가 한 레파지토리에서 개발을 한다는 사실은 놀라웠지만 말이에요.
- 후반에는 공통적으로 적용할 수 있는 내용들이 많아서 적고 느낀점 쓰기 바빴습니다. 특히 어떻게 해야 코드 리뷰의 생산성을 높이고, 감정 싸움으로 번지지 않게 할 지 고민한 결과들이라는 사실이 느껴져서 좋았습니다.
- 마무리는 보통 정리하는 느낌인데, 이번 챕터는 요약을 잘 해줘서 다시 한 번 요약 느낌으로 정리할 수 있었습니다. 반성한 것도 많고 새로 알게 된 것도 있고, 구글만 해당하는 터라 흠... 하는 것도 있었어요. 유익한 챕터였습니다.