구글 엔지니어는 이렇게 일한다(타이터스 윈터스, 톰 맨쉬렉, 하이럼 라이트) - 03

3 분 소요


공감되거나 인상 깊었던 문장들은 다음과 같다.

  • 인프라는 더 자주 변경할수록 변경하기가 오히려 쉬워진다. 우리는 컴파일러 업그레이드 등의 목적으로 코드를 한번 수정해두면 거의 예외 없이 코드가 더 견고해지고 다음번 업그레이드 하기도 쉬워진다는 사실을 깨달았다. (P.56)
  • 코드 베이스에 영향을 주는 여러 요인들은 다음과 같다. 전문성(여러 방법에 대한 충분한 지식, 수백 번의 컴파일러 업그레이드를 성공적으로 마친 경험), 안정성(규칙적인 릴리즈로 릴리즈 사이의 변경량 최소화), 순응(규칙적인 업그레이드), 익숙함(업그레이드를 정기적으로 수행하기 때문에 그 과정에서 중복되는 작업을 찾고 자동화하려 노력), 정책(비욘세 규칙과 같은 유용한 정책과 절차를 갖춤). (P.56)
  • 개발 과정에서 문제를 일찍 발견할수록 비용이 적게 든다는 사실은 널리 받아들여지는 진실이다. (P.57)
  • 코드 커밋 전에 정적 검사나 코드 리뷰로 찾아낸 버그는 프로덕션 이후에 발견한 버그보다 훨씬 싸게 고칠 수 있다. 그래서 개발 프로세스 초기에 품질, 안정성, 보안 문제를 찾아 알려주는 도구와 관레를 제공하는 일은 구글 인프라 팀의 주요 목표 중 하나다. 완벽한 단 하나의 절차나 도구는 존재하지 않는다. 가능한 한 많은 버그를 그래프 왼쪽에서 잡기를 바라며 다층 방어(defense-in-depth) 전략을 구사한다. (P.58)
  • 인생이 그러히듯 소프트웨어 엔지니어링에서도 좋은 선택이 대체로 좋은 결과로 이어진다. (P.58)
  • 소프트웨어 엔지니어링에서 비용이란 금융 비용(e.g. 돈), 리소스 비용(e.g. CPU 시간), 인적 비용(e.g. 엔지니어링 노력), 거래 비용(e.g. 조치를 취하는 비용), 기회 비용(e.g. 조치를 취하지 않는 비용), 사회적 비용(e.g. 선택이 사회 전체에 미치는 영향)이 있다. (P.59)
  • 당면한 문제에만 최적화한 해법이 모든 가능성에 대비하는 범용적인 해법보다 성능이 뛰어날 가능성이 크다. 그래서 유틸리티 코드를 포크하거나 다시 구현하여 주어진 문제만을 풀도록 하면 사용성을 개선하거나 더 확실하게 최적화할 수 있다. (P.64)
  • 모든 개발자가 기존 솔루션을 재활용하는 대신 전부 포크해버린다면 확장성과 지속 가능성이 위협받는다. 라이브러리의 포크들 중 결함이 적용되는 것들을 모두 찾아내고 해당 포크를 이용하는 사용자도 모두 추적해야 한다. (P.64)
  • 다른 소프트웨어 엔지니어링적인 결정처럼 이 문제의 정답도 고정적이지 않다. 프로젝트 수명이 짧다면 포크해도 위험이 적다. 포크한 코드의 영향 범위가 제한적인 게 확실할 때도 포크하는 게 유리하다. 반면 데이터 구조, 직렬화 포맷, 네트워크 프로토콜처럼 프로젝트의 수명에 종속되지 않는 인터페이스라면 포크를 피하는 게 좋다. (P.64)
  • 시간은 기술 의존성과 소프트웨어 시스템뿐 아니라 의사결정에 활용되는 데이터도 달라지게 한다. 우리는 데이터에 기초한 의사결정을 강력히 지지한다. 하지만 데이터 자체도 시간이 지나면 변하고 새로운 데이터가 나타날 수 있음을 안다. 그러니 시스템의 생애 동안 과거에 내린 결정을 수시로 재고해봐야 한다. (P.65)
  • 근거(데이터)에 기초해 결정하되 측정할 수 없는 요인들에도 가치가 있을 수 있음을 명심해야 한다. (P.65)
  • 우리가 말하려는 바는 소프트웨어 엔지니어링이 프로그래밍보다 우수하다는 게 아니다. 단지 이 둘에 적용되는 제약 사항, 가치, 모범 사례가 서로 다르다는 뜻이다. 이 차이를 구분할 수 있게 되면 한 영역에서는 훌륭한 도구라도 다른 영역에서는 그렇지 않을 수 있음을 알게 된다. (P.65)
  • 프로그래밍은 코드를 생산하는 즉각적인 행위다. 소프트웨어 엔지니어링은 활용 가치가 남아 있는 한 오랫동안 코드를 유용하게 관리하고 팀 간 협업을 가능케 하는 정책, 관례, 도구 모두를 아우르는 종합적인 개념이다. (P.66)
  • 프로그래밍은 코드 생산에 관한 것이다. 반면 소프트웨어 엔지니어링은 프로그래밍을 확장하여 소프트웨어의 수명이 다할 때까지 코드를 유지보수하는 문제까지 고려한다. (P.66)
  • 코드의 기대 수명 동안 의존성, 기술, 제품 요구사항 변경에 대응할 역량이 갖춰져야 지속 가능한 소프트웨어다. 여러 이유로 변경을 받아들이지 않기로 선택하더라도 변경할 수 있는 역량 자체는 필요하다. (P.67)
  • 의사결정을 데이터 주도로 하겠다는 생각은 좋은 출발이다. 하지만 현실에서의 의사결정 대부분은 데이터, 가정, 선례, 논의를 종합하여 이뤄진다. 고려 요소의 대부분에 객관적인 데이터가 주어지면 가장 좋겠지만 순전히 데이터만으로 결정되는 경우는 드물다. (P.67)
  • 데이터 주도 방식은 시간이 흘러 데이터가 변하면(혹은 가정이 무너지면) 프로젝트의 방향이 바뀔 수 있음을 뜻한다. 잘못을 인정하고 계획을 수정하는 것은 당연하다. (P.67)

규칙적이고 잦은 업데이트, 개발 프로세스에서 이른 시기에 문제 발견하기 위한 장치들(e.g. 정적 코드 검사, 리뷰, 테스트 코드 등)은 흔히 말하는 짧은 주기의 피드백을 통해 프로젝트의 리스크를 끌어 내리는 애자일 방법론의 프랙티스(practice)와 비슷하다고 생각했다.

데이터 기반의 결정은 그 시점에는 타당할 수 있다. 하지만, 시간이 지남에 따라 변경될 수 있음을 인지하고, 새로운 컨텍스트와 데이터를 기반으로 다른 선택을 할 수 있어야 한다는 이야기가 마음에 와닿았다. 책의 내용은 개발에 한정된 이야기가 아닌 프로젝트 관점에서 비즈니스적인 선택도 포함된 것 같지만, 나는 개발에서 자연스레 생기는 기술적 부채 관점에서 공감됐다.

개발 과정에서 기술적 부채 생기는 이유 중 하나는 결정을 내리는 시점에 모든 것을 알 수 없기에 내린 잘못된 판단이다. 당시에는 타당해 보이는 선택이었지만, 시간이 지나서 새로운 기술이 나오거나 새로운 API 사용 방법을 알게 된다면 더 나은 설계와 구현으로 이어질 수 있다. 이 점을 인지하고 지속적으로 학습하고, 이를 통해 기술적 부채를 지속적으로 끌어 내려야 한다.

카테고리:

업데이트:

댓글남기기