[세미나] 202204 우아한테크세미나-지속가능한 SW 개발을 위한 코드리뷰

2022-04-28

요즘 운이 참 좋다😊 딱 원하던 주제가 세미나로 나오다니!!
코드리뷰 라는 주제를 보자마자 바로 세미나 신청해버렸다.
팀 내에서나 외부에서나 코드리뷰를 할 때의 태도가 참 중요하다고 생각한다. 동작은 기계가 하지만, 이 로직을 만드는 건 사람이 하니까.
말씀하시는 내용 중에 많이 공감갔던 부분도 있었고, 상상되지 않을 그런 내용도 있었다.(이런 회사가 있..?!) 코드리뷰할 때의 기본적인(기술적인) 스킬 뿐만 아니라 태도/마음가짐에 대해 좀 더 정리할 수 있는 계기가 되었다👍
세미나 내용 중 중요하다고 생각한 부분만 블로그에 포스팅했다.

영상 링크 지속가능한 SW 개발을 위한 코드리뷰


1. 왜 코드리뷰를 하나?

1-3. 코드리뷰 목적 & 효과

주목적 : 품질 문제 검수(버그, 장애)

부가적인목적

  • 더 나은 코드 품질: 아키텍처 속성 개선을 위한 코드 개선
    • 향후 변경 비용 개선
    • 설계 개선 제안
  • 학습 및 지식 전달
    • 하드스킬
    • 소프트스킬(peer review로는 얻기 어려움. 상급자들과의 코드리뷰를 통해 얻을 확률이 높다)

효과

  • 동기부여 (더 나은 개발자가 되고자 하는 열망)
  • 상호 책임감 증대
    = 오너십 및 결속 ⬆️
    = 내가/팀원이 하고 있는 일에 관심을 준다.
    = 팀에서 일어나는 일 공유
  • 개발 문화 개선

3. 코드리뷰, 왜 어려울까?

리뷰어와 저자의 갈등 🔥

  • 저자:

    자신의 기술을 과대평가하지 말아야 한다. 코드에 비판은 ‘코드’에 대한 것임. ‘나’에 대한 비판이 아니다. 분리해서 생각해야 된다. 서로의 지식, 경험을 나누며 상호학습을 할 수 있는 기회다. 이 기회를 놓치지 않게 조심해야 한다.

  • 리뷰어:

    피드백 할 때 조심해야 한다. 생각을 글로 전달하기가 어렵다. 오해의 위험이 큼(톤, 표정의 부재)



4. 코드리뷰 기법

4-1. 효율적인 PR 방법

4-1-1. 지루한 작업은 컴퓨터로 처리하자 formatting (공백, 들여쓰기 오류 등) 별도의 커밋/pr로 분리할 것.
불필요한 부분 생략하도록 하자.
unsed import, declaration ⇒ IntelliJ preferences _ Editor _ inspections 에서 Unused import를 error로 처리하면 더 빨리 인지할 수 있다.

4-1-2. 스타일 가이드를 통해 스타일 논쟁 해소 (각자 스타일이 있음)
작성보다, 읽는게 10배 이상 더 품이 든다 ⇒ 고수준의 집중이 요구됨.
익숙하지 않는 코드 포매팅이 있으면 읽는 데에 더 시간이 오래 걸림.

4-1-3. PR 시 주석달기
리뷰어들의 시간을 절약하도록 하는 방법.
1 pr을 저자가 먼저 읽기!
2 리뷰어들을 위한 설명을 남긴다 ( i.e. A 부분으로 해도 괜찮을지 궁금하다 )

4-1-4. 리뷰어는 되도록 팀원 모두를 포함한다
많은 사람이 볼 수록 버그를 더 잘 찾아낼 수 있다

4-1-5. 의미있는 커밋으로 분리 (리뷰가 필요 없는 부분 분리해서 커밋)
2주 후의 나를 위해 커밋을 아주 작게 나눠서 커밋하는 것도 좋다.


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

  • 리뷰는 즉시 시작 (코드리뷰를 우선순위 high)

    • 빠른 피드백 ⇒ 선순환
      저자는 리뷰가 종료될 때까지 대기를 하기 때문. 업무 효율성 증대
    • 리뷰 라운드의 최대 시간은 하루
    • 리뷰는 처음할 때 어렵지만 쉬워질 때까지 습관화하자. 스크럼처럼!
    • PR에 표함된 변경이 적도록 노력해야 된다.
      • 리뷰를 받고 고칠 때 반나절 정도 작업할 양이어야.
    • 근본적인 문제는 사람들이 ‘리뷰할 시간이 없다’고 느낀다.
      • 성과에 도움이 안된다고 생각할 수 있다. (팀 내에서 리뷰의 가치를 높게 쳐야)
      • 조직적인 접근이 필요하다(잘하는 사람에게 더 좋은 성과를 주기)
    • cf. PR vs. Pair Programming.
      • 팀의 성향에 따라 달라진다. 외향적이면 페어도 좋다. 팀의 상황에 따라 적절히. 답은 없다.
  • 고수준 → 저수준으로 내려가기

    • 한 라운드에 20~50 개 씩 많이 하면 저자가 당황한다.
    • 고수준: 버그, 장애, 성능, 보안
    • 저수준 : Extract method, composed method, invert-if 등
    • 저수준은 선택적이며, 설계개선/변수명/직관적인 주석 등을 생각하면 좋다.
  • 예제 코드 제공에 관대하기

    • 저자를 기분좋게 하기위한 방법.
      코드예제 = 선물 🎁
    • 너무 긴 예제는 억압적으로 보임.
    • 라운드 당 2~3개의 코드 예제.
      많으면 저자가 코드를 작성할 수 없는 사람으로 생각한다는 신호.
  • 리뷰의 범위를 존중하기

    • PR에 포함되지 않은 라인은 리뷰 범위가 아님.
    • 예외 🔥 PR이 둘러싼 코드에 영향을 미칠 때
  • 태그 활용 ( Nit )
    Nit ? 고치면 좋지만 아니어도 그만. (저자가 무시할 수 있는 수준)
    리뷰어는 항상 더 개선할 수 있는 의견을 자유롭게 남길 수 있어야 한다.
    Nit가 달려있어도 대부분은 고친다.

  • 한 두 등급만 코드 레벨을 올리는 것을 목표로 🔥 LETTER GRADE
    완전하지는 않아도, 충분히 좋은 코드가 되도록 하자. 코드가 D등급이라면, C~B등급으로 올리는 걸 목표로 한다.
    승인을 보류하는 유일한 이유? 수 차례의 리뷰 라운드 후에도 코드가 F-grade 인 경우.


4-3 효율적인 피드백 방법

4-3-1. 절대 ‘너' 라고 하지 말라
최악의 3단 콤보 : 너는 왜 맨날…!
리뷰의 핵심은 코드 품질을 좋게하는 것이다. 누가 이렇게 잘못 된 아이디어를 냈는지 찾아내는 것이 아님.


4-3-2. 건설적인 피드백을 하라
I-message 기법 (코드에 대한 정정을 목표로. 저자에 대한 판단 ❌)
: 주어 를 빼라.

  • 오픈 커뮤니케이션
    • ~하는 게 어떨 까요
    • ~를 제안합니다
  • 건설적인 피드백은 개발자들이 그들의 실수에서 배우고, 역량을 증대하도록 동기부여함.
    코드리뷰 목적 : 팀의 생산성을 높이기. (경쟁유발❌)
  • 건설적인 피드백을 못하겠으면 하지말라. 참아라.

4-3-3. 진정한 칭찬을 하라
잘못된 부분에만 집중하지 말자

  • 주니어 or 신규일 경우, 리뷰에 민감하고 방어적일 수 있다.
    진심어린 칭찬은 긴장감을 낮춘다.
    당신을 도와주는 동료지, 잘잘못을 따지는 감시자가 아님을 인식시키는 것.

4-3-4. 피드백은 명령이 아니라 요청으로 표현해라
일상에서 동료에게 명령하지 않는다. (요청표현 사례 - 클래스가 너무 클 때)

  • 이 클래스를 별도의 파일로 분리할 수 있을까요? (의견)
  • 이 클래스는 너무 커지는 것 같은데 괜찮을까요? (걱정)

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

  • 제안하는 변경과 변경의 이유를 모두 설명하기
  • 단지 그냥 보기 싫거나 직관적이지 않을 수 있다
    ⇒ 객관적으로 설명하자. (’i-message; not you-message’)
    “이 부분은 이해하기 어렵다" ⭕️
    ”이 코드는 혼란스럽네요" ❌

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

  • 반복적인 패턴에 대해서 피드백 제한하자
    • 실수가 동일한 패턴임을 식별했다면 모든 경우를 언급하지 말라

4-4. 교착 상태 시 해결방법

교착상태를 알 수 있는 상황 (저자의 리뷰코멘트 반영 거부 / 리뷰어의 승인 거부)

  • 토론의 톤앤 매너가 날카로워지고 공격적이 된다.
  • 라운드당 리뷰 코멘트가 줄어들지 않음 (resolved 가 되지 않음)
  • 많은 저항이 보인다

4-4-1. 교착 상태의 문제점
교착 상태가 길어지면 관계가 나빠지고, 심각한 경우 한 쪽이 퇴사를 한다. 고수준의 품질을 얻을 기회가 사라진다.


4-4-2. 갈등해결책
a. 온라인으로 말하면 안됨. 직접 만나서 하도록 한다. 모니터 뒤에 사람 있어요 ~ 👩‍💻🧑‍💻
b. Agree to disagree 마음에 들진 않지만 이정도면 승인해줄게. 마음에 들진 않더라도 협업하는 역량이 더 중요하다.
   👉 ‘완벽’할 수 있는 설계는 없다. 할 수 있는 최고의 설계면 된다.
    팀 정신을 유지하기 위해 불완전한 해결책을 받아들이자.
c. 설계리뷰 고려하기.
    - 설계리뷰가 있었는지 확인
    - 설계리뷰때 논의되었어야 할 사항을 논쟁하는 건지 확인
d. 인정이 불가할 때
    - 상급자(팀장, 테크 리더)에게 말해서 해결하기
    - 다른 리뷰어 할당


4-4-3. 교착상태 회복하기
a. 상황을 관리자와 논의하기
b. 휴식 갖기. 안정될 때 까지 서로에게 PR 가급적 보내지 말 것.
c. 갈등해결책 연습하기


4-5. 코드 리뷰를 재밌게 하는 방법

  • 짝프로그래밍
    리뷰어가 어떻게 고치는 지 보여주고 REVERT.
    저자가 봤던 부분을 재작성 하는 것. 물론 리뷰어가 20분만에 하는 걸 저자가 2시간 넘게 스스로 개선할 수 있으나, 개인 역량 성장에 초점을 둔다.
    짝프로그래밍 한 부분에 대해선 스스로 생각하는 방법을 배웠으므로, 비슷한 로직을 설계할 때 그 부분은 리뷰어의 공수가 적게 들 것임.
  • 최선 을 지향. 완벽 추구는 지양(맹목적인 완벽추구는 좋은 자세가 아님).
    • 모든 설계 결함이 실제 문제로 이어지진 않는다.
    • 팀 정신을 위해 불완전한 해결책을 받아들일 것.
    • 코드리뷰의 정신: 비난이 아니라 배움을 목적으로 한다.
  • 저자의 노력이 가장 중요하다.
    • 리뷰어 n명의 시간을 절약함.
    • 효율적인 리뷰 SSAP 가능
  • 리더의 관심과 의지 → 정착되는 데 가장 중요함. 비즈니스 value에 많은 도움이 된다는 걸 인지하자.
  • 코드 비난에 대한 두려움 낮추자. 수용하는 자세 필요
  • 멋져 보여야 한다
    ⇒ 따라하고 싶어지니까.
  • 코드리뷰를 SNS 댓글 달기(놀이)로 인식을 하면 코드리뷰를 즐길 수 있다
  • 고통의 계곡을 견뎌라
    배울 때, 고통의 계곡이 있다. 이 계곡을 버티고 지나가야 성장할 수 있음을 알자.

4-6. 코드리뷰를 잘 하기 위해 필요한 기술(서적)들 📚

  • 리팩터링 (Refactoring 2nd. edition)
    • 매일 리팩토링하자!
      네이밍 수정 / extract method(composed method) / 응집도 높이기
  • Working effectively with legacy code
    • Legacy 코드 다루기
    • 매우 옛날 책이라 지금과는 맞지 않는 부분이 있다는 걸 감안하고 볼 것.
  • TDD (Unit Testing)
  • Clean Code
  • 기법 / 절차에 의존하지 말 것. 적절히 섞자. 정답은 알아서 찾는 것이다. 상황에 맞게.
  • 주기는 짧게, 자주. PR 사이즈 작게.

Q&A

  • 회사 규모에 따른 코드리뷰 방법과, 초기→성숙으로 갈 때 단계?
    팀이 조금 크면, 같은 그룹의 사람들끼리 의견을 준다.
    초기엔 1개만 → 시간이 흐를수록 여러개를. baby system.

  • notion 으로 코드리뷰를 하는 곳
    latest vs old 버전비교(side-by-side)로 보는게 좋다. 툴을 써야 한다. 투자를 하자.

  • non-tech 기업에서는 비전공/비개발자들이 조직에 있는 경우가 많은데 어떻게 코드리뷰를 할까?
    관심으로 시작하자. 옆사람에게 의견을, 관심을 주자. 서로 의견을 주지 못할 것 같다고 생각하지 말자.

  • 리뷰어의 응답을 기다리다 지체되는 현상이 발생할 때 어떻게 할까
    팀에서 정할 수 있다. 오전 30분, 오후 30분 등으로.
    제대로 리뷰를 하지 못한 부분에서 사고가 터지면 모두가 책임을 져야한다고 생각.
    모든 생산자는 소비자를 먼저 생각해야 된다.
    만든 사람이 수고로우면 쓰는 사람이 편하다.

  • 가장 좋았던 경험, 나빴던 경험
    사내 강의에서 한 걸 그 다음주에 바로 적용된 코드리뷰를 봤을 때
    ~라는 개념을 알려줬는데, 업무시간에 그와 관련된 책만 읽어서 주변 사람들이 고통받았다.

  • 코드 구현시 주석을 어느정도까지? 변수명 짓는 법? 디렉터리 구조?
    클린 코드를 읽자. 변수 짓는 법은 ‘의도’를 명확하게만 보여주면 된다. 디렉토리 구조? 레이어드, 헥사고날 등 여러 기법이 많음. 적합한 걸 선택해야 한다.

  • 코드리뷰 성과 측정방법?
    accelerator 책과 관련. 수치화를 해야 된다. 배포에 걸린 시간, 버그 발생 빈도 등. 상급자와 약속을 할 땐 자신있는 것을 약속해야 된다. 허락이 필요하지 않는 부분 굳이 허락을 구하지 말라.

  • 코드 리뷰 때 리뷰할 부분을 실제로 실행해 보는 것도 좋은 방법이다.

  • 한개의 pr에 대해 리뷰할 때 평균 어느정도 시간이 소요되나?
    리뷰할 때 오래 걸린다는 건, pr이 크거나 설계가 엉망일 때.
    코드리뷰를 많이 할 수록 개당 어느정도 걸리는 지 사이즈가 나온다. 연사의 경우 5분 내외.

  • 변경된 라인이 200 라인정도 여야 보기 쉽다. (라인수 기준)

  • PR 기법?

    • 기능 중의 일부가 의미있게 완료되면, 전체를 완료하지 않더라도 pr 하기
    • 혹은, 한 사이즈로 보낸다고 한다면 commit 을 잘 해야된다. 커밋 단위로 체크해서 봐달라는 말을 해야된다.

소프트스킬 관련 질문

  • 페어 리뷰/프로그래밍을 할 때, 어느 순간 키보드를 잡고 있었다. 남의 코드를 맘대로 고치면 기분나빠하지 않나?
    저자가 결정하는 것이다. 기분 나쁘면 저자가 반영하지 않아도 된다고 생각.

  • 리뷰 받은 내용이 오히려 코드를 읽기 난해하게 하는 등 퀄리티를 낮추는 것이라면 ?
    팀장한테 말하거나
    크게 중요하지 않는다면 본인이 져주거나 등등 여러가지 방법을 찾아라

  • 짝 코딩을 시도할 때 잘 할 수 있는 방법?
    레터 그레이드를 생각하면 된다. 상대의 등급에 따라 맞춰서 하자. D등급일 때 B- ~ C 등급으로 올리는 걸 목표로 하거나, 코드리뷰로 대체한다거나. 여러 방법을 고안해보자.

  • 회사지원할 때, 정말로 코드리뷰/공유 등 문화에 신경쓰는 지 알아볼 수 있는 방법?
    블라인드 / 기술블로그 / 주변 사람들 / 면접 때 질문하거나 등.

  • 연사(백명석님) 의 유튜브 중 추천할만한 것은?
    최근 업로드 한 것의 10분 짜리 보는 걸 추천한다.


마무리

마지막으로 한마디: 지금이 정말 이직할 때인지 생각해라.
지금 직장에서 배울 수 있는 게 있는지 생각해봐라. 배울게 별로 없고, 다른 곳에서 배우고 싶은 게 많다면 이직해라. 짧게 보고(처우, 네임밸류 등) 이직하는 것은 좋지 않다. 나의 성장, 커리어를 쌓아가는 것이 중요하다.



코드리뷰가 왜 개발문화로 떠올랐을까를 생각하려면 왜 중요해졌을까 라는 걸 떠올리면 좋을 것 같다. 1인 개발자 회사인 경우를 제외하고는 ‘나와 다른 누군가’와 일을 해야 한다. 이건 무조건적인 조건문 아닐까. 아이스브레이킹 시간에, 백명석 연사님은 이렇게 말했다.

배움은 양방향이다. 개발은 나 혼자 성장하는 게 아니라, 다른 사람까지 성장시키는 일이다.
자신의 역량을 높이는 것 뿐만 아니라, 공감대를 가진 사람이 좋은 인재다.

‘가’라는 개발자가 잘 못한다고 해서 끝까지 개발을 잘 못할 거라는 보장은 없다(노력을 한다는 가정하에). 잘 할 때까지 배제시키고 업무 능력이 뛰어난 개발자만 일하게 하는 건 엄청난 낭비다. 잘하지 못해도 서로 도와가면서 시너지를 만들어나가는 것이 팀이 아닐까? 코드리뷰는 그 역할을 하는 거고👀.