Part I. 전제
Chapter 1. 소프트웨어 엔지니어링이란?
해당 챕터에서는 소프트웨어 엔지니어링과 프로그래밍의 차이에 대하여 다룬다.
- 소프트웨어 엔지니어는 시간의 흐름과 언젠가 변경될 가능성에 더 신경써야 한다.
- 소프트웨어 엔지니어링은 흐르는 시간 위에서 순간순간의 프로그래밍을 모두 합산한 것이다. (Software Engineering is programming integrated over time)
- 시간이 프로그램에 미칠 영향 알 수 있는 방법 → ‘이 코드의 예상 수명은?’
- 소프트웨어 기대 생애 동안 요구되는 모든 가치 있는 변경에 대응할 수 있다면 그 프로젝트는 지속 가능하다. 라고 할 수 있다.
- 소프트웨어 엔지니어링이란 여러 버전의 프로그램을 여러 사람이 참여해 개발하는 것이다.
- 소프트웨어 프로젝트의 팀 조직, 프로젝트 구성, 정책과 관례는 모두 소프트웨어 엔지니어링의 복잡성을 좌우한다.
- 조직이 성장하고 프로젝트가 확장될 수록 소프트웨어 생산 효율도 높아지는가?
- 개발 워크플로의 효율도 우리의 성장에 발맞춰 개선되는가?
- 우리가 따른 버전 관리 정책과 테스트 전략이 조직 규모가 확장되면 비례하여 비용을 증가시키는가
1.1 시간과 변경
→ 동작한다
와 유지보수 가능하다
를 구분 짓는 가장 중요한 요인
→ 하이럼의 법칙은 최선의 의도, 최고의 엔지니어, 꼼꼼한 코드 리뷰가 뒷받침 되더라도 공표한 계약(명세)이나 모범 사례를 완벽하게 구현해 냈다고 단정할 수 없는 현실을 표현
- API 소유자는 인터페이스를 명확하게 설명해놓으면 어느 정도의 유연성과 자유를 얻을 수 있다.
- 하지만 현실에서는 API 사용자가 (명세에는 없는) 기능을 찾아 활용하기도 하며, 그 기능이 유용해 널리 쓰이면 추후 API를 변경하기 어렵게 된다.
해시 반복 순서 예시
>>> for i in {"apple", "banana", "carrot", "durian", "eggplant"}: print(i)
...
durian
carrot
apple
eggplant
banana
해시 테이블의 원소 순서가 겉으로 밝히지 않은 나름의 알고리즘에 의해 정해짐
→ 그 알고리즘이 언제까지 유지되는지 아는 사람은 별로 없음.
→ “제 해시 컨테이너가 정해진 순서대로 결과를 낸다고 가정해도 될까요?”
→ “아니오”
→ “하드웨어, 언어 런타임, 데이터 구조를 변경할 일 없이 단명할 코드라면 그렇게 가정해도 괜찮아요. 하지만 코드가 얼마나 생존할지 모르거나 당신 코드가 의존하는 대상이 아무것도 바뀌지 않으리라 확신할 수 없다면 그런 가정은 옳지 않아요”
동작한다(it works)
와 옳다(it is correct)
의 차이
- 이용하는 API의 명세에 명시되지 않은, 즉 언제든 변할 수 있는 기능을 사용하는 코드는
임시 방편적인(hacky)
또는기발한(clever)
코드 - 반대로 모범 사례를 따르고 미래에 대비한 코드는
클린
하고유지보수 가능한
코드 - “기발한”이 칭찬으로 느껴지면 프로그래밍이라 하고, 질책으로 느껴진다면 소프트웨어 엔지니어링이라고 한다.
1.2 규모 확장과 효율성
- 소프트웨어 조직에서 가장 중요한 자산인 코드베이스 자체도 확장 가능해야 한다.
- 코드가 많아지고 변경 이력이 쌓이는 등의 이유로 빌드 시스템이나 버전 관리 시스템이 점점 느려진다면 어느 순간 더는 정상 운영할 수 없는 시점이 온다.
- ‘전체 빌드에 걸리는 시간’, ‘리포지토리에서 전체를 새로 내려받는 시간', ‘프로그래밍 언어 버전을 업그레이드 하는 비용’ 같은 지표는 적극적으로 관리하지 않으면 천천히 악화된다.
- 끓는 물 속 개구리가 되지 않도록 주의하자
- 엔지니어 한 명에게 할당한 작업이 있고, 조직이 10배 혹은 100배로 커졌다고 상상
- 조직이 10배로 커지면 이 작업도 10배로 많아지는가?
- 엔지니어가 해야 할 일의 양이 조직이 커질수록 늘어나는가?
- 코드베이스가 커질수록 작업량도 늘어나는가?
- 이 중 하나에 해당할 경우 작업을 자동화하거나 최적화 할 수단이 있는가?
- → 마지막 질문의 답이 아니오라면 확장성에 문제가 있는 것.
→ 공통 CI 시스템에 추가해 두지 않은 테스트는 인프라팀이 책임지지 않는다.
여담
Cause if you liked it, then you shoulda put a ring on it
(네가 나를 좋았했다면 프러포즈를 해줬어야지)
- 이걸 테스트와 연결시켜 표현한 것 같습니다.
- 왜 이름이 비욘세 규칙인지 궁금해서 찾아보았더니, 비욘세의 노래 중 Single Ladies에 이런 가사가 있다고 하네요
- 100명의 자바 엔지니어가 있는 조직에서 질문에 기꺼이 답해줄 전문가가 한 명만 있어도 곧 더 나은 자바 코드를 작성하는 100명의 엔지니어가 생겨난다.
1.3 트레이드 오프와 비용
- 원점 회귀(왼쪽으로 옮기기)
- 개발 과정에서 문제를 일찍 발견할수록 비용이 적게 든다.
- 타임라인에서 문제 발견 시점을 왼쪽으로 이동시킬수록 수정 비용이 줄어든다.
- 개념잡기 → 설계 → 구현 → 리뷰 → 테스트 → 커밋 → 카나리 → 배포
- 비용이란? 다음의 요소들을 모두 포함
- 경제적 비용 (돈)
- 리소스 비용 (하드웨어)
- 인적 비용 (엔지니어링)
- 거래 비용 (실행에 옮기는 비용)
- 기회 비용 (실행에 옮기지 않는 비용)
- 사회적 비용 (선택이 사회 전체에 미치는 영향에 대한 비용)
- 현상 유지 편향(status quo bias)과 손실 회피(loss aversion) 같은 치우침(bias)
- 구글은 사무용품과 일상적인 개발 시 드는 경비부터 글로벌 규모의 서비스를 준비하고 운영하는 방법에 이르기까지, 우리가 하는 모든 일과 관련한 비용/이윤 트레이드오프에 동일한 수준의 관심을 두고 명확히 계량하려 한다.
- 좋은 엔지니어링 결정이란 가용한 모든 근거 자료에 적절한 가중치를 부여하고 이러한 지식을 바탕으로 균형점을 잡는 일.
- 반드시 해야 하는 일 (법적 요구사항, 고객 요구사항)
- 근거에 기반하여 내릴 수 있는 최선의 선택
- 사례 : 분산 빌드 (p61)
- 정량화 된 상황과 정량화 되지 않은 상황.
- 제번스의 역설 : 효율이 늘어나면 자원 소비가 늘어난다. (p63)
- 비평하고 비평받는 법 배우기
Thoughts
- A. 우리는 코드를 짤 때 비용을 고민하면서 작성하고 있는가?
- A. 우리 코드가 오랫동안 지속가능하려면 어떠한 고민을 해야 할까?
- S. 코드를 최소화 하려는 노력
- YAGNI
- 코드를 반이나 지웠는데, 문제없이 작동한다?
- 정리를 그 때 그 때 해줬으면 참 좋았을 텐데
- Q. 내 코드는 내가 퇴사하는 날까지 돌아가야 한다.
- H. 히스토리를 어떻게 관리하는게 맞는가?
- A. 프론트엔드 코드는 오래가지 못한다?
- 프레임워크, 구조는 오래 가지만 컴포넌트는 오래 가지 못한다.
- backend → horizontal, frontend → vertical
- business logic / view layer 분리
- 리팩토링 할 이유가 있는가?
- 플랫폼 스쿼드의 존재 이유??
- 스쿼드에서 니즈가 있어서 개선을 하려고 하는데, 이렇게 하는게 맞는가?
- S. 구조가 구린데, 비즈니스가 동작한다? → 레거시다.
- A. 데이터 기반의 의사결정을 해야 하는데.. 할 수 없는 것들도 있다. 어떻게 해야 하나?
- H. 내가 하는 액션이 저 지표에 어떻게 기여할 수 있지?
- 어떻게 회사에 align 할 수 있지?
- S. 설계의 개선은 정량화를 할 수 있는 방법이 있다.
- 다만 이걸 깊게 연구하고 그런 것이 비즈니스에서는 중요하지 않다.
- G. HR 등 다른 직무에서도 성과를 정량적으로 측정하는 것에 관심이 많다.
- 측정할 수 없으면 개선할 수 없다. - 피터 드러커
- H. 비평하고 비평받는 법 배우기
- 이 둘을 나누는 것이 정말 애매하다.
- 협력적인가? 돕기 위해서 하는 건가?
- S. 엔지니어 : 엔진을 다루는 사람. 기계를 다룰 줄 아는 사람.
- 코드만 다룰 줄 알면 할 수 있는 일이 많지가 않다.
- 엔지니어의 평가 요소 Hard Skill ← 주니어 — 시니어→ Soft Skill
- 엔지니어 : 제한된 자원을 가지고 문제를 해결하는 사람.
- 우리는 마에스트로를 지향하는 것이 아님.
- 하이럼의 법칙 → 이 피드백 주기는 스타트업의 경우 시리즈 단계에 따라 진행
- 라운드 단계마다 해야 할 일들이 정해져 있다.
Action Items
- 코드를 최대한 쉽게 짜자. 어느 누가 보더라도 이해할 수 있도록.
Part II. 문화
Chapter 2. 팀 워크 이끌어내기
- 인간은 간헐적 버그들의 집합에 가깝다.
2.1 내 코드를 숨기고 싶어요
사람들은 자신이 진행 중인 작업물을 다른 사람이 보고 판단하는 걸 두려워 한다.
2.2 천재 신화
- 리누스 : 유닉스와 유사한 커널의 시제품을 만들어 메일링 리스트로 뿌린 것
- 현재의 리눅스는 초기 커널보다 수백 배는 크고 수천 명의 인재들이 함께 개발했다.
- 리누스의 진짜 업적은 이 사람들을 협업하도록 이끈 것
- 리눅스는 리누스만의 아이디어가 아니라 커뮤니티가 함께 노력해 이룬 결실
- 귀도 반 로섬 : 파이선의 첫 번째 버전을 작성
- 그 후 버전들은 수천 명의 사람이 아이디어를 모으고 기능을 개발하고 버그를 수정하며 만듦
- 스티브 잡스(매킨토시 제작팀), 빌 게이츠(마이크로소프트) 비슷함. 커뮤니티를 이끌어 집단적 성과물의 상징
2.3 숨기는 건 해롭다
- 혼자 일하려 한다면 실패할 위험성을 불필요하게 키우고 자신의 성장 잠재력을 속이는 것이다.
- 조기 공유?
- 이미 구현된 선례가 있는 것은 아닌지 파악할 수 있다.
- 초기 설계에 숨겨져 있는 근본적인 실수를 방지할 수 있다.
- 혼자하는 것보다 아무튼 더 빠르게 할 수 있다.
- 프로젝트의 버스 지수(Bus factor)를 높일 수 있다.
2.4 모든 건 팀에 달렸다
- 위대한 팀은 슈퍼스타를 잘 활용하지만 전체가 항상 개인의 합보다 크다.
- 사회적 상호작용의 세 기둥
- 겸손(Humility)
- 당신은 모든 것을 알지도 완벽하지도 않습니다. 겸손한 사람은 배움에 열려 있습니다.
- 존중
- 함께 일하는 동료를 진심으로 생각합니다. 친절하게 대하고 그들의 능력과 성취에 감사해합니다.
- 신뢰
- 동료들이 유능하고 올바른 일을 하리라 믿습니다. 필요하면 그들에게 스스로 방향을 정하게 해도 좋습니다.
- 겸손(Humility)
- 우리 자존감을 우리가 작성한 코드와 동일시해서는 안 됩니다. 나는 내 코드가 아님을 명심하세요.
- 자신과 만든 것을 구분짓고 자신을 믿고 동료를 믿으세요.
- 포스트모템(postmortem)
- 실패한 근본 원인을 분석하여 문서를 남기는 것이 실수로부터 배우는 핵심
- 포스트모템 문서가 쓸모없는 사죄, 변명, 지적으로 채워지지 않도록 주의
- 제대로 된 포스트모템에는 무엇을 배웠는지와 앞으로 무엇을 바꿀지가 담겨야 함
- 포스트모템에 담겨야 하는 것
- 사건의 개요
- 사건을 인지하고 해결에 이르기까지의 타임라인
- 사건의 근본 원인
- 영향과 피해 평가
- 문제를 즉시 해결하기 위한 조치 항목(소유자 명시)
- 재발 방지를 위한 조치 항목
- 해당 경험에서 얻은 교훈
- 구글다움(Googleyness)
- 모호함을 뚫고 번창한다.
- 끊임없이 변화하는 환경 속에서도 상충하는 메시지와 방향에 잘 대처하고, 합의를 이끌어내고, 문제에 대한 진전을 이룰 수 있다.
- 피드백을 소중히 한다.
- 피드백을 주고 받을 때 품위와 겸손을 유지하고 개인과 팀의 발전에 피드백이 주는 가치를 이해한다.
- 저항(항상성)을 극복한다.
- 다른 이들이 저항하거나 관성 때문에 움직이지 않으려 하더라도 야심 찬 목표를 세우고 밀고 나아간다.
- 사용자를 우선한다.
- 구글 제품의 사용자 입장에서 생각하고 존중하며 그들에게 가장 도움이 되는 행동을 추구한다.
- 팀에 관심을 기울인다.
- 동료들의 입장에서 생각하고 존중하며 팀의 결집을 위해 누가 시키지 않더라도 적극적으로 돕는다.
- 옳은 일을 한다.
- 모든 일에 강한 윤리 의식을 갖고 임한다. 팀과 제품의 진정성을 지키기 위해서라면 어렵거나 불편한 결정을 내릴 수 있어야 한다.
- 모호함을 뚫고 번창한다.
Thoughts
- H. 히스토리가 사람에게 디펜던시를 가지는 순간 문제가 생긴다.
- Q. 노션은 검색이 너무 불편하다.
- S. 주석이 도움이 될 때도 있지만, 주석과 완전히 다르게 작성이 된 코드도 있다.
- 주석이랑 문서는 엔지니어링 레벨에서는 커플링(coupling)이다.
- S. 한 사람이 다 만들고, 나머지가 다 따라가는 건 옳지 않다.
- 같이 만들어나가면서 개선하는 게 중요. 물론 쉽지는 않다.
- A. 회고에서 실패에 대한 액션 아이템을 제대로 정하고 제대로 지키고 있는가?
- 데이터 기반의 회고를 하고 있는가?
- 사람이 많아질 수록 회고에 대한 동작률이 급격하게 떨어진다.
- 결국 인사. 나와 비슷한 생각을 하는 사람을 채용해야 한다. 그렇지 않으면 뒤가 다 무너진다.
- 비평에 열려 있고 좋은 의사결정을 할 수 있는 사람들을 인사 단계에서 잘 찾아야 한다.
- Q. 인간은 실패에서 배운다. 내가 한 결정에 대해 후회하지 않는다.
- 회고가 없다면 길게 갈 수 없다.
- A. 회고에서 잘 한 것보다, 아쉬운 것들을 더 많이 쓴다.
- 비평인지 비난인지 판단하는 것은 듣는 사람의 몫이다.
- 이게 없는게 좋은 회고의 방향.
- Q. 대안이 없으면 반대하지 않는다.
- 1:1이 참 좋다.
- G. 퍼실리테이션 기법 : 어떤 말을 듣고 0.1초 안에 떠오르는 감정을 표현해 보시오.
- 대안이 없으면 반대하지 않는다. → 회사 입장에서는 OK지만, 개개인의 입장에서는 다를 수 있다.
- S. 내가 뭔가 문제를 발견했을 때 리포트 하는 것은 책임이다.
- 나쁜 예 : 세월호, F1, 새만금
Action Items
- 가능하면 하나의 프로젝트를 두 사람 이상이 작업하게 하자. (bus factor를 높이자)
- API와 문서간의 커플링을 줄이자 → e.g. GraphQL, code as document 를 많이 사용하자.
- good case : haylee의 프론트엔드 설계 개선 👍 → 이러한 case가 많아지게 하자.
- 회고 잘하자!
- 비평과 비난 차이는 동료간의 믿음, 유대감이 영향을 많이 끼치므로 이를 높일 수 있는 노력을 하자. (방법은 사람마다 case by case)
'끄적끄적 > Book Review' 카테고리의 다른 글
2023년 1월 독서 정리 (0) | 2023.01.29 |
---|---|
[구글엔지니어] Ch05 요약 및 토론 (2) | 2022.11.07 |
[오웬의 서재] #10. 사울 레이터의 모든 것 (2018) (0) | 2022.01.29 |
[오웬의 서재] #9. 뉴욕주민의 진짜 미국식 주식투자 (2020) Part 1. (0) | 2021.12.20 |
[오웬의 서재] #8. 실용주의 프로그래머 (The Progmatic Programer, 2000) Part 1. (0) | 2021.08.27 |