/ DEVOPS

왜 Code Review를 해야 하는가

DevOps 관련 포스팅

※ 이 글은 4월 우아한테크세미나 영상을 첨부된 발표 자료와 함께 정리한 것입니다. 원본 영상은 4월 우아한테크세미나를 참고하시기 바랍니다.

발표자: 11번가 백명석 님

1. 왜 코드 리뷰를 해야 하나?

1-1. 우리가 살고 있는 시대

image

오프라인 업체를 온라인 업체가 대체하고 있음

image

4차 산업 혁명의 키워드 중 하나, VUCA

  • 변동성(V)으로 인해 점점 기존의 방식으로는 문제를 해결할 수 없게 됨
  • 혼자가 아니라 여러 명이 협력해 문제를 해결하는 것의 가치가 높아지고 있으며,
    코드 리뷰는 변동성을 해결하는 데 도움을 주는 방법이 됨

image

  • 전체 산업에서 IT 비율이 10년만에 2배로 성장, 90%는 Digital Transformation (DT) 중
  • 미국은 보다 원활한 서비스를 공급하기 위해서는 3배(2020년 당시) 더 많은 개발자가 필요하다고 함
  • 우리 나라의 경우, 미국의 1/4 수준의 개발자를 보유하고 있으므로 현 시점보다 12배 많은 개발자가 필요함

image

시장은 VUCA하고, 비즈니스는 빠른 혁신이 필요하므로,
개발에 있어서 SW를 더 자주 안정적으로 출시(DRFR)해야 함

image

(Clean Architecture 1장) 출시 때마다 개발자는 기하급수적으로 증가

image

하지만, 출시 때마다 생산성은 일정 수치에 수렴

imageimage

처음에는 만든 모든 것이 산출물이라 기술부채가 없음
출시가 거듭될 수록 개발자는 기존 코드를 파악 및 수정하는데 대부분의 시간을 쓰고, 새로운 기능을 추가하는 생산적인 일을 하는데 시간을 쓰지 못하게 됨

1-2. 개발 생산성

image

< Martin Fowler’s Design Stamina Hypothesis(블로그 참조) >
좋은 설계와 나쁜 설계의 누적 생산성을 보여줌
→ 설계 수익선을 지나 생기는 개발의 생산성 저하를 막아야 함

1-3. SW 공학의 특성

image

일반적인 공학의 경우,
설계와 빌드 중 빌드 비용이 압도적
건축물 완공 후에는 변경할 수 있는 것이 거의 없으므로 유지보수 비용이 상대적으로 낮음

image

재생산이 가능하다는 것은 누가 빌드를 하든지 동일한 결과물이 나오는 것
SW빌드는 인건비가 발생하지 않아 거의 무료임
그래서 설계는 굉장히 중요하며, SW 엔지니어는 설계를 잘 하는 사람, 좋은 코드를 작성하는 사람

image

새 코드 작성하는 일은 20%, 코드를 읽고 변경하는 일이 80%
코드 이해에 10배 이상의 에너지가 소요됨
내 코드도 2주 뒤에는 남의 코드처럼 보임
코드가 좋은 가독성과 좋은 설계를 가져야 하는 이유임

image

일정에 쫓겨 빠르고 지저분하게 개발을 하는 것은 결코 빠른 개발이 아님
SW의 경우, 비싸다고(비용이 많이 든다고) 품질이 좋은 것 아님(비정상적, 비직관적)
처음에는 비용이 많이 들어도, 수정할 때는 훨씬 비용을 절감할 수 있게 됨

개발자로서 테스트 커버리지를 높일 일정을 제공받고 싶다면,
테스트 커버리지를 높였을 때 결함율이 감소하고, 변경 요청시 빠르게 처리가 가능해 출시 기간이 짧아질 수 있다고 말해야 비즈니스 측에서 원하는 대답이 됨

1-4. 장인정신

image

VUCA시대에 좋은 SW를 개발하는 가장 좋은 방법은 애자일
하지만,
단순히 절차만 변경하고, 애자일의 개발 역량(TDD, refactoring, test 자동화, 단순한 설계 등)에 대해서 다루지 않으면 실패함
관련 지식과 경험은 학교가 아닌, 전문성을 갖춘 개발자가 공유를 해주는 방법이 유일함(이것이 SW의 장인정신, 애자일의 확장된 개념)

image

SW 장인정신은 공유 활동이 아주 중요
공유 활동 중 코드 리뷰는 누구나 쉽게 접근할 수 있음
온라인에서 code로 댓글 놀이를 하면 코드 리뷰 하는 느낌을 받을 수 있음

1-5. 코드 리뷰의 정의

image

(Wikipedia)
한 명 또는 여러 사람이 주로 소스 코드 일부를 보고 읽는 방식으로, 프로그램을 확인하는 SW품질 보증 활동으로써 구현 혹은 구현을 잠시 중단하면서 시행함
피어 리뷰, 풀 리퀘스트, 머지 리퀘스트라고도 불림

1-6. 코드 리뷰의 목적

image

코드 리뷰시 주목적 달성은 물론, 양방향의 배움이 일어남
피어 또는 주니어 간의 코드 리뷰에서는 기술(하드 스킬)을 배우게 됨
시니어가 주니어를 가르칠 때는 어떻게 소통해야 상대가 더 잘 받아들이는지, 친절함, 공감능력, 가르치는 방법 등의 소프트 스킬리더십을 배우게 됨
또한, 잘 하는 사람이 하는 것을 보며 동기 부여가 됨

image

팀원의 코드를 리뷰하면서 책임감이 생김 팀원의 일에 관심을 가지게 되고, 내가 팀원에게 줄 수 있는 것은 무엇일까 생각하게 됨 결과적으로 팀웍이 생김

코드 리뷰로 좋은 사례가 공유되고, 부족한 부분에 대해선 좋은 의견을 물어볼 수 있음 이런 공유활동이 지속되면 개발 문화가 개선됨

2. 코드 리뷰의 절차

image

  1. 저자(코드를 작성한 사람)가 변경된 내용에 대해 PR를 만들어서 리뷰어에게 줌
  2. 리뷰어는 글로 피드백을 줌
  3. 위 과정을 반복하다 리뷰어가 배포해도 되겠다는 판단을 한 뒤, 배포함

image

모든 산출물은 소비자를 위한 것
PR 또한 산출물이므로 작성한 사람이 아니라 리뷰어를 위한 것
리뷰어의 시간을 아껴주는 방향으로 작성해야함

3. 왜 코드 리뷰가 어려운가

image

“자신의 기술을 과대평가한 항공사들은 모두 망했음”
저자와 리뷰어 모두 자신이 틀릴 수 있다는 자세로 접근해야 함
처음에는 나의 코드에 대한 비판이 마치 나에 대한 비판같아서 힘들겠지만,
나와 나의 코드는 분리해서 생각해야 함

image

코드 리뷰를 개인적 공격으로 받아들이면 코드 리뷰의 의미가 없어짐
처음부터 리뷰를 잘 하기는 힘듦
사소한 것부터 언급하면서 차츰 잘 해나가는 방향으로 가야 함
나의 글에 충격받는 사람이 있을 수 있다는 것을 잊지 말아야 함
“파일 핸들 닫는 것을 잊어버리셨어요”를 “이 바보 같으니라구! 어떻게 파일 핸들 닫는 것을 잊어버릴 수 있지?”라고 받아들일 수 있음

image

Git의 등장으로 소단위 리뷰가 가능하면서 팀원간의 갈등이 많이 사라짐
(연사의 과거 경험)

4. 기법들

4-1. 효율적인 PR 방법

4-1-1. 지루한 작업은 컴퓨터로 처리

image

빌드, 테스트, 머지, 머지 컨플릭트 찾기 등은 기계가 더 잘 함
사람은 로직만 잘 짤 수 있도록 하기
익숙하지 않은 코드 포맷팅이나 약속되지 않은 포맷팅은 리뷰어를 힘들게 함(포맷팅을 전담하는 사람을 두는 곳도 있음)

image

툴만 잘 다루는 것은 의미가 없으나, 툴도 잘 다루는 것은 중요
툴을 잘 다루면 본질적인 문제를 생각하는데 노력을 많이 쓸 수 있지만, 툴에 익숙하지 않으면 툴에 집중하게 되어 본질을 놓치게 됨

4-1-2. 스타일 가이드를 통해 스타일 논쟁을 해소

image

스타일 정하는 데 많은 시간을 쓰지 않아야 함

  • 좋은 스타일이 있다면 가져다 쓰거나,
  • 자신만의 스타일 가이드를 점진적으로 만들어 가거나,
  • 위 두 가지를 조합하거나
    팀 내의 합의를 거쳐 하나를 선정하고 이를 지킬 것

4-1-3. PR을 올릴 때 주석 달기

image

description만으로는 설명이 부족할 수 으므로 PR을 한 저자가 구체적인 커멘트를 남기면 리뷰어들의 시간이 절약됨

4-1-4. 리뷰어에 모두를 포함하라

image 항상 여러 명에게 PR하는 것이 좋음

4-1-5. 의미있는 커밋으로 분리

image

혼자만의 프로젝트라도 커밋을 세세하게 나누어서 PR을 하면 보기 편함
코드 리뷰를 하지 않더라도 이 방식은 중요함

4-2. 효율적인 리뷰 방법

4-2-1. 리뷰는 즉시 시작

image

리뷰를 기다리는 것과 다른 것을 구현 하는 것이 동시에 일어나게 되면, context switching이 일어나 굉장히 비생산적이게 됨
빠르게 리뷰를 종료해주는 것이 좋음
이 과정이 선순환된다면, 사람들은 언제 리뷰를 처리하는 것이 효율적인지 알게 됨
리뷰가 올라오고 나서는 하루를 넘기지 않아야 함

image

코드 리뷰가 어려우면 더 자주해서 익숙해져라!
팀원들이 반나절 정도 작업한 양을 30분 내에 모두 리뷰할 수 있도록 PR 속 변경을 최소화 해야 함
리뷰어의 노고를 팀 내에서 조직적으로 평가하고 보상해 인정해 주어야 함

image

Latency를 수용할 수 있는지, throughput을 수용할 수 있는지
PR의 경우, Latency가 있지만, PairProgramming의 경우 바로 옆에서 피드백을 하므로 Latency가 없음
반대로 PR은 한 명의 코드를 여러 명이 리뷰하거나 그 반대도 가능하지만, pair programming의 경우 대부분 1대 1로 진행되기에 throughput 측면에서는 PR이 더 좋음
팀원들의 성향에 따라서 PR 또는 Pair Programming을 정하는 것도 좋음

4-2-2. 고수준으로 시작, 저수준으로 내려가라

image

처음부터 너무 많은 리뷰를 남기는 것은 위험
무조건 해결해야하는 것들(고수준)을 먼저 리뷰한 뒤,
보다 우선 순위가 낮은 것들(저수준)에 대해 리뷰하는 것이 좋음

4-2-3. 예제 코드 제공에 관대하라

image

자신이 코드를 잘 작성할 수 없다고 생각해서 리뷰어가 많은 예제를 제시한다고 생각할 수 있음
적당한 수의 코드 예제를 제공해야 함

4-2-4. 리뷰의 범위를 존중하라

image

4-2-5. 태그를 활용

image [Nit]는 nit picking(트집 잡기)에서 온 것
팀에서 합의한 태그를 이용해 고친다면 더 좋을법한 내용에대해 언급할 수 있음

4-2-6. 한 두 등급만 코드 레벨을 올리는 것을 목표로

image

저자가 D등급(간신히 돌아는 가지만 엉망인)의 코드를 쓴 뒤,
A+등급의 코드를 쓸 수 있는 리뷰어가 리뷰를 할 경우,
A+가 아닌 C나 B의 등급을 받게 도와야 함(강제하는 것이 아니라)
사람은 누구나 짧은 시간에 너무 많은 것을 습득할 수 없음

4-3. 피드백 방법

4-3-1. 절대 “너”라고 하지 마라(너는 왜 맨날 …)

image

누가 잘못을 했는지는 중요하지 않음
어떻게 해야 좋아질 것인가가 중요함
‘너는’이 아니라‘이 코드는’이라고 말해야 함(사람 지칭하지 말 것)
나 전달법을 사용해 소통할 것
제안하는 방법으로 대화하기

4-3-2. 건설적인 피드백을 하라

image

실수를 하지 않으면 배울 수 없음
자신이 알고 있는 방법만 사용하면 손가락은 빨라지고 실수는 없으나 절대로 실력이 늘지는 않음
실수를 통해 내가 이런 것을 배웠구나라는 용기를 얻는 것이 중요함
건설적인 피드백이 아니면 상처만 남기게 되므로 하고 싶은 말을 도저히 긍정적인 방법으로 할 수 없겠다는 판단이 들면 아무 말도 하지 말 것

4-3-3. 진정한 칭찬을 해라

image

칭찬이 존재하면, 팀원들이 나를 후원해주고 있다는 느낌을 받을 수 있음

4-3-4. 피드백은 명령이 아니라 요청으로 표현해라

image image

일상에서는 동료에게 명령하지 않으면서, 리뷰에서는 명령이 발견됨
리뷰에 리뷰어의 걱정만 표현을 해도 저자는 스스로 문제점을 발견할 수 있고 보다 책임감을 가지고 업무에 임할 수 있게 됨

4-3-5. 의견이 아니라 원칙에 기반하여 피드백하라

image

제안과 이유를 함께 제시해야 하며,
뚜렷한 이유는 모르겠지만 제시하고 싶다면 나 전달법을 사용해 소통할 것

4-3-6. 반복적인 패턴에 대해서 피드백을 제한하라

image

동일한 패턴의 실수를 했다면, 2-3개만 언급을 해도 저자는 스스로 살펴보고 동일한 패턴을 찾아내어 고칠 수 있음
최악의 경우, 정말 2-3개만 고치더라도 시간이 지나면 더 많이 고치겠지라고 생각하기

4-4. 교착상태 시

교착상태를 적극적으로 처리해라

image

  • 교착상태: 저자와 리뷰어 사이의 커멘트 승인과 반영 충돌 상태
    반드시 만나서 해결해야 함
    텍스트 뒤에 상대가 있음을 잊으면 안 됨

image

당장 SW가 최고는 아니지만 적당한 상태라면, 타협하는 자세도 필요함
동료가 퇴사하도록 만들면 영원히 최고의 SW는 기대할 수 없게 됨
갈등을 회피하지 않고 논리적으로 푸는 자세가 중요

image

VUCA 시대에는 뛰어난 한 사람보다 약간은 부족한 여러 사람들의 협업이 보다 좋은 결과를 만들어냄
팀원과의 협업 능력을 얻는 것이 훨씬 의미 있는 일임

4-5. 추가적인 사례

코드 리뷰를 하는 아주 재밌는 방법

image

20분 정도 짝을 이루어 멋지게 코드를 작성하는 것을 보여준 뒤, Revert 해 스스로 고칠 수 있게 하는 방법
20동안 가르쳐 준 내용을 혼자서는 2시간 동안 고치고 있을 수 있지만, 다음부터는 스스로 할 수 있게 됨
풀이를 보고 수학 문제를 푸는 것과 같은 논리임
풀이를 안 보고도 풀어내보면 다음번에는 맞출 수 있게 됨

image

완벽하게 하기 위해 죽자고 싸워서 팀원을 내보내는 것은 팀을 망가뜨리는 행위임

코드 리뷰 문화 정착의 어려움 / 극복방법

image

코드 리뷰의 시간을 확보하는 것은 저자의 노력(description 잘 달기, 커밋 잘 나누기, PR 사이즈 작게 유지하기, 자신이 만든 PR은 자신이 먼저 읽고 커멘트 달기)에 달려있음
내가 바보같이 짠 코드에 내 동료가 좋은 의견을 주었다고 받아들여야 함

image

뭐든 멋있어보이면 따라하려는 마음이 들게 됨

image

어떻게 하면 장인정신, TDD, pair programming과 같이 한 번에 실행하기 어려운 것들을 받아들일 수 있게 영감을 줄 수 있는가에 대한 대답

image

새로운 것을 도입하면 익숙하지 않기 때문에 고통의 계곡(valley of pain)에 빠지게 되어 성과가 떨어지게 됨
긍정적인 마인드로 꾸준히 하다 보면, 고통의 계곡에서 빠져 나가게 되며, 기하급수적으로 성과가 상승하게 됨
사람은 계단식으로 성장하며 계단의 앞에는 고통의 계곡이 있음
코드 리뷰도 마찬가지임
적응하는데 시간이 걸릴 뿐 그 이후에는 결실을 얻게 됨

코드 리뷰의 효과

image

코드리뷰를 잘 하기 위해 필요한 기술들

리팩터링

image

이 두 권의 책을 읽지 않고 refactoring을 한다고 말할 수 없음
Java로 쓴 책과 JavaScript로 쓴 책 모두 볼 것

image

Legacy Code 다루기

image

오래된 책이지만 인상적인 부분들이 많음

Clean Code & TDD

image

Unit Testing: 전통파(상태기반), 런던파(interaction기반)
Clean Code: 번역본도 있어서 내용이 어렵지 않음. 추천

FAQ

image

코드리뷰 자체에 얽매이지 말고 공유와 논의에 초점 맞추기
시간이 없어서 코드 리뷰를 못 하겠다면 개발 생산성와 개발 품질의 중요성에 대해 생각해 보아야 함
분명 생산성이 증대되는 일임

Q & A

image

항아리에 돌을 넣을 때는 큰 돌부터 넣어야 함
무엇을 중요하게 생각하는 지 따져보고 먼저 수행해야 함
우리에게 중요한 것이 품질이며, 설계라고 한다면, 코드 리뷰는 뺄 수 있는 문제가 아님
코드 리뷰에 시간을 따로 책정하면 안 됨
처음부터 포함이 되어있어야 함

FAQ

image

SW는 수학이 아니라 과학임
수학은 맞는 것을 증명할 수 있지만, 과학은 틀린 경우가 없다는 것을 증명해 나가는 것이지 맞는 것을 증명할 수 없음
버그에 대해 100% 안전해진다고 말할 수 없음

image

측정 항목들이 반기 혹은 1년의 기간 안에 얼만큼씩 좋아지고 있는데 이는 코드 리뷰의 결과라는 것을 증명해내어 상사를 설득해야 함
의사결정권자들이 원하는 것은 TDD, 좋은 아키텍쳐, 코드 리뷰 이런 것들이 아니라, 요구사항들이 얼마나 결함없이 빨리 배포 되느냐이기 때문임
자동화 테스트 작성, 리팩터링, 코드리뷰, 짝프로그래밍 등은 결과물을 잘 만들어내기 위한 수단이며, 우리가 어떤 도구를 사용할지는 우리 스스로 정하는 것임
왜 무엇을 언제까지는 상사가 정할 수 있음
어떻게는 상사가 정해주는 것 아님
상사의 허락을 받으려고 하는 것이 아님

Q & A

image

관련 영상 및 홍보 안내

“[LIVE] 지속가능한 SW 개발을 위한 코드리뷰 :: 4월 우아한테크세미나,” 유튜브 비디오, 2:06:22, 게시자 “우아한Tech,” 2022년 4월 27일, https://youtu.be/ssDMIcPBqUE