6  시니어 개발자

축하합니다! 드디어 시니어 개발자가 되었습니다!

막상 그 자리에 서 보니, 상상했던 것과는 조금 다르게 느껴지실 것입니다. 시니어 개발자로 취업하는 것과 시니어 개발자로서 뛰어난 역량을 발휘하는 것은 같은 일이 아닙니다.

알고 보니 이 업계에서 “시니어 개발자”는 매우 폭넓은 직함입니다. “좋아요, 이 사람은 엄밀히 말해 더 이상 신입이 아닙니다”부터 “다른 곳이었다면 이 사람은 스태프나 프린시펄이었겠지만, 우리는 수평적인 조직을 지향해서 모두를 시니어라고 부르니 받아들이십시오”까지 걸쳐 있습니다. 일종의 “여권” 같은 직함입니다. 거의 어디서나 통하지만, 회사 간에 한 직함이 다른 직함으로 정확히 어떻게 대응되는지는 복잡하고 경우에 따라 다릅니다.

저 자신도 시니어 개발자 스펙트럼의 어딘가에 있기 때문에, 다음 단계로 나아가는 방법을 개인적인 경험을 바탕으로 공유할 수는 없습니다. 하지만 다른 사람들의 조언으로부터 추론하고, 엔지니어링 사다리를 통해 다시 한번 교차 검증하여, 어떻게 하면 잘 해낼 수 있는지에 대해 근거 있는 의견을 제시할 수는 있습니다. 그러나 제 의견은 어디까지나 제 개인적인 의견일 뿐이므로, 이 장은 다른 장보다 더 비판적인 시각으로 평가하셔야 합니다. 초보자의 영역에서 멀어질수록 사람들이 실제로 겪은 경험은 더 다양해지고, 솔직히 말하자면 노골적으로 서로 모순되기까지 합니다.

우리는 주니어에서 시니어로 장(장 5)에서 시니어 개발자의 이상적인 자질 중 상당수를 간략히 다루었습니다. 이는 실제로 시니어로 채용되기 전에 이러한 자질 중 일부를 보여 주어야 하기 때문입니다. 하지만 이제 실제로 그 삶을 살고 있으니, 이러한 자질을 정말로 몸소 보여 주어야 합니다. 자기 자신을 위해서가 아니라면, 팀과 여러분을 우러러보는 주니어들을 위해서라도 말입니다.

6.1 해결책과 패턴

여러분은 흔한 문제에 대한 업계 표준 해법들에 익숙할 수도 있습니다. 여러분은 도구를 알고 있으며, 자신이나 다른 사람이 전에 겪어 본 문제를 해결하는 데 그 도구를 능숙하고 효과적으로 다룰 수 있습니다. 어려움은 새로운 문제에 부딪힐 때 찾아옵니다. 도구가 애초에 염두에 두고 설계되지 않은 문제, 편리한 가정이 무너지는 제약 조건 아래에서, 그리고 그런 규모에서 마주하는 문제들입니다. 도구가 더 이상 도움이 되지 않을 때, 그 도구에 대한 여러분의 지식 역시 더 이상 도움이 되지 않습니다.

도구를 사용하는 법을 아는 것도 좋지만, 언제 도구를 사용하지 않아야 하는지 아는 것이 더 좋습니다. 자신을 도구로 정의하면(“나는 ${FRAMEWORK} 프로그래머입니다”) 모든 문제를 그 도구로 해결하려 들게 됩니다. 이런 접근 방식은 실패로 이어지거나, 불필요하게 복잡한 해결책을 내놓게 만듭니다(이 역시 실패이지만, 훨씬 더 큰 대가를 치릅니다).

이를 넘어서려면 도구의 바탕이 되는 디자인 패턴을 이해하고, 진정으로 공짜인 것은 없다는 사실을 받아들여야 합니다. 디자인 패턴이라는 폭넓은 도구 상자를 갖추고 각 패턴이 무엇을 해결하며 무엇을 맞바꾸는지 잘 이해하고 있다면, 도구를 다른 용도로 활용하거나 직접 도구를 만들 수 있게 됩니다. 이 지식은 언어와 관계없이 오래 유지되며, 스택의 여러 계층에서 다시 적용할 수 있습니다. 이 지식은 놀라울 만큼 잘 확장되며 배울수록 더 빨리 배우도록 도와줍니다. 이는 초선형적인 Big L(장 42)을 이끄는 핵심 동력 중 하나입니다. 디자인 패턴에 관해서는 Gang of Four가 교과서를 썼습니다(JavaScript를 좋아한다면 Addy Osmani의 책을 참고하십시오). 하지만 컴파일러에 관한 드래곤 북, 운영 체제에 관한 공룡 책, Game Programming Patterns 같은 다른 기초 고전들도 잊지 마십시오. 시스템 설계, 알고리즘, 자료 구조에 관한 모든 지식 역시 유용한 패턴입니다. 다만 면접을 위해 벼락치기로 외우는 것이 아니라, 업무에서 실제로 사용해야 한다는 점이 다릅니다! 다음은 업무에서 실제로 사용할 수도 있는 자료 구조 & 알고리즘 목록의 예입니다.

6.2 속도 대 유지보수성

오늘날 대부분의 사람들은 “빠르게 움직이고 깨뜨려라(Move Fast and Break Things)”가 의도한 정신과 의도하지 않은 결과를 모두 이해하고 있습니다. 그러나 프로젝트의 성숙도가 달라짐에 따라 트레이드오프가 어떻게 달라지는지는 상대적으로 잘 이해되지 않고 있습니다. 작은 스타트업에서 R&D를 수행하고 있다면 반드시 빠르게 움직여야 합니다. 실패했을 때의 손해가 미미하므로 시스템과 프로세스의 가치가 낮기 때문입니다. 거대한 인프라 시스템에 코드 변경을 배포할 때는 아주 작은 실수 하나가 수억 달러의 손실을 단 몇 초 만에 일으킬 수 있습니다. 사람의 생명이 걸려 있을 때는 그 결과가 훨씬 더 참혹해집니다.

프로젝트의 성숙도에 적용되는 것은 개발자의 성숙도에도 똑같이 적용됩니다.

주니어일 때는 속도도 낮고 영향력도 작습니다. 주니어의 주된 임무는 코드가 동작하게 만드는 것이며, 넘어질 때는 시니어가 붙잡아 줍니다. 자신의 속도를 높이는 데 우선순위를 두는 것은 지극히 합리적입니다. 코드 표준에 미치지 못하는 작업을 했다면 시니어가 그 책임을 물을 것입니다.

하지만 시니어가 되면 이런 호사는 사라집니다. 이제 여러분에게는 독립적으로 출시할 수 있는 능력이 기대됩니다. 그 독립성의 일부는 여러분이 속도와 유지보수성 사이에서 올바른 트레이드오프를 할 것이라는 신뢰에서 나옵니다. 이는 여러분이 할 수 있는 일의 한계를 밀어붙이는 것보다는 – 누구나 자신이 쉽게 유지보수할 수 있는 것보다 두 배 복잡한 시스템을 만들 수 있습니다 – 앞으로의 가정 아래에서도 오래 지속되는 시스템을 만드는 것에 더 가깝습니다.

유지보수하기 쉬운 소프트웨어를 작성하지 않는다면, 그저 미래의 자신에게 문제를 만들어 주는 것일 뿐입니다. 그러므로:

  • 시켜서 테스트하는 것이 아니라, 테스트가 자신을 확장할 수 있는 유일한 방법이기 때문에 테스트합니다. 또한 깨지기 쉬운 테스트는 줄여 주는 일보다 만들어 내는 일이 더 많기 때문에, 그런 테스트를 작성하는 데 훨씬 더 신중해집니다. 그런 테스트는 구현 세부 사항을 테스트하며 마이그레이션을 어렵게 만듭니다(마이그레이션에 대해서는 아래에서 더 다룹니다). 구체적으로 열거된 비상 상황을 제외하고는, 프로덕션 코드는 해당 코드에 대한 테스트와 함께 병합되거나 아예 병합되지 않아야 한다고 고집합니다.
  • 버그를 만든 뒤에 고치기만 하는 대신, 애초에 버그가 생기지 않도록 노력합니다. 과거에 겪은 아픈 경험을 교훈 삼아, API 설계부터 변수 이름 짓기에 이르기까지 모든 일에서 도구를 활용하고 신중하게 선택합니다.
  • 여러분은 코드를 문서화하고 주석을 답니다. 이는 미래의 자신만을 위한 것이 아니라, 여러분이 더 크고 더 나은 일로 옮겨 갈 때 코드를 넘겨받을 사람들을 위한 것이기도 합니다.

경고: 완벽한 코드를 작성하는 데 빠져들면 개발 속도가 받아들일 수 없는 수준까지 떨어질 수 있습니다. 완료가 완벽보다 낫다는 것과 충분히 좋은 것이 최고보다 낫다는 것을 기억하십시오(장 16).

그러나 대부분의 조직은 유지보수성보다 속도를 최적화하도록 유인을 만듭니다. 이를 판단하는 한 가지 방법은 기능을 출시하는 데 들이는 만큼의 노력을 실수로부터 배우고 실수를 추적하는 데에도 들이는지 살펴보는 것입니다. 좋은 첫걸음은 비난 없는 포스트모템 문화를 확립하는 것입니다(출발점으로 AWS의 장애 포스트모템 템플릿을 빌려 써도 됩니다). 실수하는 것은 괜찮지만, 실수를 반복하는 것은 괜찮지 않습니다. 심각한 장애는 속도에 제동을 거는 역할을 해야 합니다. 이것을 후퇴로 여기지 마십시오. 여러분의 일은 단지 기능을 만드는 것이 아니라, 오래 지속되고 확장되며 어떤 상황에서도 복구할 수 있는 시스템을 만드는 것이기도 합니다. 포스트모템을 공개하면 고객의 신뢰를 크게 높이고 업계 전반의 개선에도 도움이 될 수 있습니다.

6.3 기술 부채

애자일 선언문의 공동 저자이자 자신의 이름을 딴 법칙을 만든 워드 커닝햄(Ward Cunningham)은 1992년에 이 용어를 처음 만들었습니다:

“처음 작성한 코드를 그대로 출시하는 것은 빚을 지는 것과 같습니다. 약간의 빚은 재작성을 통해 즉시 갚기만 한다면 개발 속도를 높여 줍니다… 위험은 빚을 갚지 않을 때 생깁니다. 완전히 올바르지 않은 코드에 쓰는 매 순간이 그 빚의 이자로 쌓입니다. 정리되지 않은 구현이 남긴 부담 때문에 엔지니어링 조직 전체가 부채에 짓눌려 완전히 멈춰 설 수도 있습니다.”

세상에! 부채라니 끔찍하게 들립니다! 도대체 누가 부채를 원하겠습니까? 당장 부채에서 벗어나십시오!

기술 부채에는 두 종류가 있습니다. 마틴 파울러는 신중한 부채와 무모한 부채를 구분합니다. Hashicorp는 노후 부채, 레버리지 부채, 우발적 부채라는 세 가지 부채 범주를 제시하지만, 이는 마틴의 생각과 충분히 밀접하게 대응하므로 이 책에서는 마틴의 구분을 따르겠습니다.

6.3.1 신중한 부채

신중한 기술 부채는 “낡은 코드”라고 볼 수 있습니다. 모든 것의 최신 버전을 사용하지 않는 코드. 더 이상 선호되지 않는 패턴을 사용하는 코드. 느린 코드. 아주아주 오래된 버그가 있는 코드. 이제 아무도 쓰지 않는 기능과 추상화를 지원하느라 장황해진 코드.

우리는 프로그래머입니다. 프로그래머는 마음속으로는 건축가이며, 현장에 도착하면 가장 먼저 하고 싶어 하는 일은 그곳을 불도저로 밀어 평평하게 만들고 웅장한 무언가를 짓는 것입니다. 우리는 점진적인 개보수, 즉 이것저것 손보고, 개선하고, 화단을 가꾸는 일에는 흥미를 느끼지 않습니다. - Joel Spolsky

주니어들은 이런 종류의 부채를 몹시 싫어합니다. 이는 그들이 일을 처리하는 최선의 방법이라고 배워 온 모든 것에 어긋나며, 물론 최선의 방법은 유일한 방법이기도 합니다.

시니어는 성공한 코드베이스만이 기술 부채가 될 만큼 오래 살아남는다는 것을 이해합니다. 그들이 이를 이해하는 것은 부채가 되어 버린 코드를 직접 작성해 보았기 때문입니다. 그들은 또한 그 부채를 대체하려고 시도해 보았고, 누구나 배우게 되는 똑같은 교훈을 얻었습니다. 그 기술 부채가 돈을 벌어 준다는 것입니다. 돈을 벌어 줄 뿐만 아니라, 아마 그 어떤 대체 시도보다도 뛰어날 것입니다. 오래된 코드는 실제로 사용되어 왔습니다. 그 코드는 프로덕션 환경에서, 그리고 대규모로 검증되었습니다. 수많은 버그가 발견되었고, 그 버그들은 수정되었습니다. 정의상 남아 있는 것은 치명적이지 않은 버그뿐입니다! 하이럼의 법칙(Hyrum’s Law)은 프로그램에서 관찰 가능한 모든 동작은, 심지어 버그조차도, 사용자가 의존하게 된다는 것을 가르쳐 줍니다. 버그를 고쳤더니 그 수정을 되돌려 달라는 불만이 들어오는 상황을 상상해 보십시오!

때로는 아직 문제 영역을 잘 알지 못하기 때문에 의도적으로 부채를 쌓아야 합니다. 주니어는 서둘러 모든 것을 DRY하게 유지하려 합니다. 하지만 이는 성급한 추상화를 낳고, 결국 후회하며 나중에 되돌려야 하는 상황이 됩니다. 시니어는 코드가 작성되는 것보다 훨씬 더 자주 복사되고, 읽히고, 옮겨지고, 삭제된다는 것을 이해합니다. 간결함이나 기발함을 위해 최적화하기보다는 피할 수 없는 변화에 대비해 최적화하는 편이 낫습니다.

팁: 이를 훌륭하게 시각화한 자료로는 Dan Abramov의 Deconstruct 2019 발표를 참고하십시오.

시니어로서 여러분은 기술 부채를 다루는 대가로 돈을 받습니다. 그렇기 때문에 가장 높은 보수를 받는 일자리 중 일부는 거대한 레거시 시스템을 다루는 반면, 열성적인 개발자와 취미로 개발하는 사람들은 최신 기술을 무료로 만지작거립니다. 하지만 그렇다고 부채가 끝없이 쌓이도록 내버려 둘 수 있는 것은 아닙니다. 얼마나 많아야 지나치게 많은 것인지, 그리고 비즈니스 목표를 계속 달성하면서 어떻게 부채를 갚아 나갈지 판단할 수 있어야 합니다.

스트랭글러(Strangler) 패턴 또는 파사드(Facade) 패턴은 기술 부채 관리 도구 모음의 일부로 가장 자주 언급됩니다. 이 패턴은 시스템을 계속 운영하면서 그 아래의 구현을 교체하는 데 유용합니다. 이를 변형한 좋은 방법으로 브리지(Bridge) 패턴이 있는데, 업그레이드할 때만 추상화하는 대신 모든 서드파티 의존성을 추상화하는 방식입니다.

제가 가장 좋아하는 소프트웨어 개발 관행 중 하나는 의존성을 자체 추상화로 감싸는 것입니다. 저는 서드파티가 제 코드 곳곳에 새어 들어와서 그 때문에 리팩터링이 몇 시간(심지어 며칠)씩 걸리는 상황을 정말 싫어합니다. - Sarah Dayan

하지만 여기서 핵심 기술은(특히 코드가 아닌 시스템 수준에서) 마이그레이션을 수행하는 것입니다. 이는 특히 고성장 스타트업에서 그러합니다. 그런 곳에서는 규모가 또 한 자릿수 커질 때마다 그 직접적이고 빈번한 부작용으로 코드가 낡게 됩니다. 이때의 플레이북은 위험을 줄이고, 가능하게 하고, 끝내는 것을 확실하게 해내는 것입니다.

소프트웨어 마이그레이션은 빠르게 성장하는 회사에서 일상과도 같으며, 저는 점점 더 효과적으로 마이그레이션하는 능력이 성장을 결정짓는 제약 조건이라고 생각합니다. - Will Larson

대규모로 운영할 때는 단점이 될 수 있는 것이 오히려 장점으로 바뀔 수 있습니다. 바로 프로덕션 트래픽을 활용하여 코드에 대한 확실한 신뢰를 얻는 것입니다. 대부분의 대기업은 수명이 긴 브랜치를 피해 왔으며, 이를 위해 기능 플래그를 사용하는 방향으로 수렴했습니다. CircleCI와 Darklang의 창업자인 Paul Biggar의 말을 들어 보십시오:

Dark에서 우발적 복잡성을 줄이는 한 가지 방법은 하나의 해법으로 여러 다른 문제를 해결하는 것입니다. 기능 플래그는 저희의 주력 도구입니다. 로컬 개발 환경, git 브랜치, 코드 배포를 대체하면서도, 물론 새 코드를 천천히, 통제된 방식으로 배포하는 전통적인 용도도 여전히 제공합니다.

그리고 Facebook이 마이그레이션을 수행하는 방식에 대한 Dan Abramov의 설명은 다음과 같습니다:

기능을 활성화하거나 비활성화하고 서로 다른 구현 사이를 전환하기 위해 우리는 기능 플래그에 폭넓게 의존합니다. 그래서 v1과 v2를 함께 체크인해 두고 사용자의 1%, 그다음에는 50%에게 (v2를 배포하는 동적 검사를 두어 적용하며) 지표에 회귀가 없는지 살펴봅니다. 그런 다음 수정이 실제로 효과가 있고 아무것도 악화시키지 않는다는 확신이 들면, 100%로 전환하고 이전 구현을 삭제합니다.

하지만 기능 플래그(Feature Flags)에도 비용이 따릅니다. Uber는 코드베이스를 어지럽히는 오래된 플래그를 엄청나게 많이 발견했습니다. 이 플래그들은 코드베이스를 더 복잡하게 만들고, 빌드와 테스트를 느리게 했을 가능성도 있습니다. 문제가 너무 심각해서 Uber는 이런 플래그를 찾아내 정리하는 내부 도구를 만들었고, 그 이름은 Piranha입니다. 이 도구는 6601개의 플래그를 찾아냈으며, 그중 17%가 사용되지 않고 있었습니다. 플래그 자체가 기술 부채가 될 수 있습니다.

6.3.2 무모한 부채

다른 종류의 기술 부채는 나이나 성장과는 아무 관련이 없습니다. 바로 무모한 부채(Reckless Debt)입니다. 이는 건너뛴 단계에서 비롯된 부채라고 생각할 수 있습니다. Thoughtbot의 Joël Quenneville은 이렇게 말합니다. “(무모한) 기술 부채란 개발 속도를 높이기 위해 코드 품질 면에서 지름길을 택하고 절차를 생략하는 것을 말합니다.”

“무모한(Reckless)” 부채를 식별하는 것 자체가 어려운 일입니다. 아무도 편법을 썼다고 인정하고 싶어 하지 않지만, 우리는 모두 그렇게 합니다. 켄트 벡은 “동작하게 만들고, 올바르게 만들고, 그다음에 빠르게 만들라(Make it Work, Make it Right, then Make it Fast)”라고 우리에게 촉구했지만, 많은 인센티브 제도는 개발자들에게 그저 “동작하게 만들고, 동작하게 만들고, 동작하게 만들라(Make it Work, Make it Work, Make it Work)”고 부추깁니다.

이 문제를 다루는 대중적이지만 불완전한 방법 하나는, 지표를 허용 가능한 수준 이상으로 악화시키는 코드를 커밋하지 못하게 하는 자동화된 코드 품질 시스템을 사용하는 것입니다. 이러한 도구는 미래의 부채를 현재로 끌어와, 일을 끝없이 미루다가 결국 손쓸 수 없는 지경에 이르게 하는 대신 출시하기 전인 지금 그 부채를 처리하도록 만듭니다.

현 상태를 지켜 내며 상황이 더 나빠지지 않게 막아 주는 도구는 정말 강력합니다. 예를 들면 테스트 커버리지, 타입 커버리지, 번들 크기, 성능 지표 등이 있습니다. API의 상당 부분은 한 번 테스트된 것을 어떻게 깨뜨리지 않을 것인가에 관한 것입니다. 오픈 소스에서는 투자가 부족하고, 빅테크에서는 비즈니스에 결정적으로 중요합니다. - Sebastian Markbåge

빌드 시간, 빌드 크기, 파일 길이, 테스트 커버리지, 코드베이스의 린팅이나 포매팅을 포함하여 자동화할 수 있는 모든 코드 품질 문제의 감지를 자동화해야 합니다. 자동으로 감지할 수 있는 오류에 코드 리뷰 시간을 한 시간 쓸 때마다, 개발자들이 서로 주고받는 과정에서 여러 시간이 낭비됩니다. 악역은 기계에게 맡기십시오. 반대로, 시스템에 담아낼 수 없는 의견은 너무 많이 갖지 않도록 하십시오. 그런 의견은 인지 부하를 늘리고, 사소한 논쟁(bikeshedding)을 부르며, 예상치 못한 문제에 부딪힌 개발자들에게 적극적으로 방해가 될 수도 있습니다.

무모한 부채(Reckless Debt)에 대한 또 다른 우려는 금융 부채 비유의 불일치에서 비롯됩니다:

  • 기술 부채 비유는 시간이 지남에 따라 비용이 대체 가능하고(모든 부채 문제가 동일함) 예측 가능하게 증가하며, 자원을 추가해서 대처할 수 있다(즉, 문제에 사람을 투입하면 된다)는 인상을 줍니다. 이 비유는 책임을 전적으로 코드베이스 내부에 둡니다.
  • 실제로 우리는 예측 가능성의 상실을 겪습니다(시스템을 건너뛰기 때문에 시스템에 대한 통제력을 잃습니다). 이는 자원을 추가할수록 위험이 커지고(맨먼스 미신 문제) 문제가 사람과 코드 사이의 상호작용에 있는 고유한(모든 코드베이스의 문제는 고유합니다) 상황을 만들어 냅니다.

그러므로 무모한 기술 부채에는 “기술 부채”보다 “증가하는 위험”이 더 나은 비유일 수 있습니다. 공교롭게도 이 비유는 부채를 해결하자는 생각을 설득하는 데 훨씬 더 도움이 됩니다. Rachel Stephens가 지적했듯이 “관리자는 이자 상환에는 관심이 없습니다… 하지만 위험에는 매우 큰 관심을 가집니다.”

무모한 부채(Reckless Debt)가 생기는 것을 원천에서 통제하려면, 회사의 모든 사람이 사용하는 공인된 기술 집합을 두는 것이 현명할 수 있습니다. Google은 구글러가 사용할 수 있는 “공식 언어(Official Languages)” 목록을 관리하며, 이를 지원하는 전담 언어 인프라 팀을 두고 있습니다. 표준화된 도구 세트를 사용하고 새로운 기술이나 패턴을 실험하는 데에는 제한된 “혁신 크레딧(innovation credits)”만 허용한다면, 대충 넘어갈 핑계가 줄어듭니다. 모든 것이 익숙하며, 코드 표준을 더 쉽게 지킬 수 있도록 자체 도구를 만들 수도 있습니다.

이 모든 시스템과 정책을 갖추더라도 코드베이스에는 틀림없이 무모한 부채(Reckless Debt)가 생겨날 것입니다. 이를 식별하고 우선순위를 정하는 정책을 어딘가에 문서로 작성해 두는 것이 좋습니다. 도움이 된다면 Hashicorp의 기술 부채 정책을 활용하십시오. 이는 여러분과 팀이 따를 수 있는 승인된 절차 역할을 할 뿐만 아니라, 당장 고통을 느끼지 않는 문제는 대수롭지 않게 넘기기 쉬운 경영진 및 기타 이해관계자와 맺을 수 있는 일종의 계약이기도 합니다.

6.4 멘토십, 앨라이십 & 스폰서십

시니어 개발자에게 “개인 기여자(Individual Contributor)”라는 말은 잘못된 명칭입니다. 이 역할에는 개인적인 것이 전혀 없습니다. 사실상 모든 회사는 시니어 개발자가 주니어에게는 멘토가 되고 팀에게는 역량을 몇 배로 키우는 존재가 되기를 기대합니다.

여러분은 회사에서 가장 똑똑한 사람일지도 모릅니다. 가장 깊은 지식을 갖추고, 가장 훌륭한 코드를 작성하며, 프로그래밍 역사상 그 누구보다도 빠르고 깔끔하게 티켓을 해치울지도 모릅니다. 자기 자신을 확장할 수 없다면 그런 것은 아무 의미가 없습니다. 모든 지식을 독점하고 멘토링이나 협업을 하지 않는다면, 회사에 여러분은 외부에서 고용한 에이전시만큼의 쓸모밖에 없습니다.

훌륭한 성과를 냈지만 거대한 병목이 되었고 어떤 체계적인 해결책도 받아들이기를 거부했던 천재 개발자, 릭의 실화를 들어 보십시오. 그는 확실히 개인 기여자(individual contributor)였습니다. 회사의 가장 큰 문제들에 기여했고, 결국 해고되었습니다.

10x 개발자가 되는 가장 좋은 방법은 자신이 아는 것을 10명에게 가르치는 것입니다. 기술이나 프로세스에 익숙하지 않은 엔지니어가 자신이 무엇을 하고 있는지뿐만 아니라 왜 그것을 하고 있는지도 이해하도록 시간을 들이십시오. “물고기 잡는 법을 가르쳐라”는 시니어 엔지니어에게 필수적인 역량이며, 이를 위해서는 인내심과 함께 조직의 다른 구성원에게 투자한다는 관점이 모두 필요합니다. 디자인 패턴을 전파하는 만큼 Apprenticeship Patterns도 전파하게 되어야 합니다. 그들이 충분히 역량을 갖추게 되면, 그들도 똑같이 하게 하십시오. 지식을 공유하는 문화를 장려하십시오. 시니어 엔지니어는 주변 사람들의 기술과 전문성을 끌어올립니다.

이를 실천하는 방법 중 하나는 많이 쓰는 것입니다(장 18). 이렇게 하면 여러분의 경험이 사람과 시간을 넘어 확장됩니다. 자신의 코드를 문서화하듯이, 자신만의 “API”를 문서화하고(예를 들어 개인 README를 작성하는 식으로), 말로 표현할 수 있는 한 최대한 많은 맥락과 경험에서 배운 것을 문서로 남겨야 합니다.

시니어 직함을 가진 사람으로서, 여러분은 회사 내 과소대표된 소수자들을 향한 무의식적이고 체계적인 편향을 지적할 수 있는 큰 힘을 가지고 있습니다. 지지자(ally)가 되십시오. 우리 업계는 지난 반세기 동안 엄청난 다양성 부채를 쌓아 왔으며, 이것은 지금 우리와 사회 전반에 해를 끼치고 있습니다. 이 단순한 사실을 인식하기 위해 “엄청나게 깨어 있는” 사람일 필요는 없습니다. 의도하지 않은 성차별과 인종차별은 채용 파이프라인, 승진, 프로젝트 배분 같은 큰 일에서부터 코드 리뷰와 발표자 구성 같은 작은 일에 이르기까지 일어납니다.

이것이 문제라는 데에는 동의하면서도 “내 일은 아니다”라고 여길 수도 있습니다. 이는 여러분의 힘을, 그리고 그에 따라 자신의 영향력의 원 안에서 변화를 일으켜야 할 여러분의 책임을 심각하게 과소평가하는 것입니다. 변화는 여러분에게서 시작됩니다. 우리가 살아 있는 동안 업계가 더 나아지기를 바란다면, 어떤 “D&I 이니셔티브”가 마법처럼 문제를 해결해 주기를 기다릴 것이 아니라 우리가 적극적인 역할을 해야 합니다.

Better Allies의 Karen Catlin이 제시한, 여러분이 도울 수 있는 다섯 가지 방법을 정리한 훌륭한 목록입니다:

  • 그 사람이 없는 자리에서 그 사람의 이름을 언급하십시오
  • 공개적으로 그들을 지지하십시오
  • 주요 회의에 초대하십시오
  • 의사 결정권자에게 그들의 커리어 목표를 공유하십시오
  • 역량을 키울 수 있는 도전적인 과제와 발표 기회에 그들을 추천하십시오

멘토십과 앨라이십도 훌륭하지만, 스폰서십은 그보다 더 좋습니다. 말로만 하기는 쉽습니다. 과소대표된 사람들에게 기회의 문을 열어 주는 데 적극적인 역할을 하십시오! Lara Hogan과 Samantha Bretous가 스폰서가 되는 방법에 대해 훌륭한 조언을 남겼지만, 이 조언을 실천하는 것은 우리 각자의 몫입니다. 누군가가 영향력 있는 자리에 오르도록 적극적으로 후원하면, 그 사람이 다시 다른 사람들을 후원할 수 있게 되므로 그 효과는 수십 년에 걸쳐 퍼져 나갈 수 있습니다.

직함 때문에 자만하지 않는 것이 중요합니다. 여러분은 어떤 면에서는 여전히 주니어입니다. 여러분에게는 여전히 배울 것이 있습니다. 여러분보다 주니어인 사람들도 여러분이 모르는 것을 알려 줄 수 있습니다. 여러분도 다른 사람에게서 발견하는 소프트웨어 개발에서의 인지 편향에 똑같이 빠질 수 있습니다. 겸손하십시오. 계속 갈망하고, 계속 우직하게 나아가십시오.

“모든 사람에게는 내가 배울 만한 무언가가 있으며, 그 점에서 나는 그의 제자입니다.” - 랄프 왈도 에머슨

6.5 비즈니스 임팩트

가장 가치 있는 엔지니어는 비즈니스가 성공하려면 무엇이 필요한지라는 관점에서 습관적으로 자신의 일을 바라보는 사람입니다. 이것은 다른 모든 기술과 마찬가지로 연습하고 키우고 가꾸어야 하는 기술입니다. - Charity Majors

모든 사람이 시니어 엔지니어에게 기대하는 마지막 요소는 “큰 그림”에 대한 어느 정도의 감각을 갖추는 것입니다. 사람들은 보통 그것이 무엇을 의미하는지 모호하게 말하지만, 대체로 여러분의 코드와 시스템이 회사가 돈을 벌고 쓰는 방식이라는 더 넓은 맥락 속에서 어디에 자리하는지에 대한 감각을 갖추는 것을 의미합니다.

기능보다 성과. 시니어 엔지니어라면, 예상치 못한 변수 때문에 사용자가 원하는 성과를 얻지 못한다면 완벽한 기능을 제공하더라도 아무 의미가 없다는 사실을 깨닫습니다. 주어지거나 합의된 요구 사항도 틀릴 수 있습니다.

주니어 엔지니어가 올바른 답을 찾기 위해 고용된다면, 시니어 엔지니어는 올바른 질문을 던지기 위해 항상 주의를 기울여야 합니다. 여기서 요구 사항을 명확히 하고 요령 있게 반론을 제기하려면 의사소통 능력, 특히 글쓰기 능력이 필수적입니다. 모두가 용어를 같은 의미로 정의하고 원하는 목표에 대해 같은 맥락을 공유하도록 하는 데 들인 시간은, 이미 코드가 작성된 나중 시점에 그 100배에 달하는 시간을 절약해 줄 수 있습니다. 이 개념을 시프트 레프트(Shift Left)라고 합니다:

IBM Research는 또한 버그와 결함이 소프트웨어 개발 생명 주기의 어느 시점에 발견되고 해결되었는지에 따라 이를 수정하는 데 드는 상대적 비용을 살펴보았습니다. 이 연구에 따르면 개발의 요구 사항 및 설계 단계에서 발견되고 해결된 결함은 제품 출시 후에 발견되고 수정된 결함보다 수정 비용이 60~100배 저렴합니다. (출처: Infostretch)

그림 「The rising cost of fixing defects later」은 저작권자의 별도 허락이 필요하거나 출처가 확인되지 않아 번역판에 싣지 않습니다. 원문 사이트에서 그림 보기

사실, 전략적으로 “아니요”라고 말하는 것이 여러분이 할 수 있는 가장 가치 있는 행동일 수 있습니다. 이전에 비슷한 실수를 해 본 경험이 있기 때문에, 여러분은 잠재적인 문제를 예견할 수 있습니다. 이런 방식으로 기여하는 것이 즉각적인 해결책을 제시하는 것보다 더 나은 경우가 많습니다. 때로는 자신이 올바른 일을 하고 있지 않다는 것을 깨달았을 때 자신의 업무를 재설계하는 것까지 나아가기도 합니다. 주니어 개발자로서의 목표가 조직에 녹아드는 것이었다면, 시니어로서 여러분은 중요한 순간에 두각을 나타낼 힘을 가지고 있습니다.

“저는 우리가 하는 일만큼이나 우리가 하지 않는 일을 자랑스럽게 생각합니다.” - 스티브 잡스

여러분이 미치는 영향에 대한 인식은 비즈니스를 넘어 업계와 커뮤니티로까지 확장됩니다. 기술이 강력하다고 믿는다면, 그 기술을 다루는 사람들에게 그 힘에 대한 책임이 있다는 것도 믿어야 합니다. 의료계에는 흔히 “무엇보다 해를 끼치지 말라”로 해석되는 히포크라테스 선서가 있습니다. 우리에게 그와 가장 가까운 것은 기술 선구자 테드 넬슨이 1974년 저서 Dream Machines에서 밝힌 “컴퓨터 해방 서약(the Computer Lib Pledge)”입니다:

컴퓨터의 목적은 인간의 자유입니다.

저는 컴퓨터를 통해 사람들을 자유롭게 하는 일을 돕겠습니다.

저는 컴퓨터 사제 집단이 대중을 혼란스럽게 하고 겁박하는 일을 돕지 않겠습니다.

저는 컴퓨터 시스템이 실제로 무엇을 하는지 끈기 있게 설명하고자 노력하겠습니다.

사람들을 떼어 내려고 “제가 그렇게 설계했기 때문입니다” 대신 “컴퓨터는 원래 그렇게 작동하기 때문입니다”처럼 오해를 부르는 답변을 하지 않겠습니다.

저는 악의 세력에 맞서 굳건히 버티겠습니다.

억압적이거나 모욕적이거나 불친절한 컴퓨터 시스템에 맞서 목소리를 낼 것이며, 애초에 그런 시스템이 구매되거나 만들어지는 것을 막지 못한다면 그것을 개선하거나 대체하기 위해 최선을 다하겠습니다.

저는 불의와 복잡함, 그리고 일부러 일을 어렵게 만드는 모든 회사에 맞서 싸우겠습니다.

저는 특히 인터랙티브 컴퓨터 그래픽이라는 새로운 시각화 도구를 통해 인간의 이해를 증진하기 위해 할 수 있는 모든 일을 하겠습니다.

저는 시스템을 이해하기 쉽고, 가능한 한 상호작용할 수 있으며, 사용자에게 재미있게 만들기 위해 할 수 있는 일을 하겠습니다.

다른 사용자가 가장 좋아하는 컴퓨터 언어가 COBOL이나 BASIC이라 하더라도 그것을 놀리지 않도록 노력하겠습니다.

6.6 추천 도서

시니어 개발자를 넘어 개인 기여자(Individual Contributor) 트랙을 계속 이어 가는 것은 이 책의 범위를 벗어나지만, 시작하는 데 도움이 될 몇 가지 자료를 소개해 드리겠습니다.