『소프트웨어 엔지니어 가이드북』

게르겔리 오로스, “소프트웨어 엔지니어 가이드북”, 이민석 역, 한빛미디어, 2024

개발자 커리어의 기본 사항

커리어패스

절대적으로 ‘좋은’ 커리어패스는 없다. 어떤 사람은 선형적인 엔지니어의 길을 걷고, 어떤 사람은 여러 직책을 오간다. 저자가 목격한 일반적인 커리어패스는 최소 12가지다: 평생 소프트웨어 엔지니어, 특정 도메인 전문가, 제너럴리스트/스페셜리스트 전환, 틈새 분야 전문 소프트웨어 엔지니어(SRE, 데이터 엔지니어 등), 계약직/프리랜서, 테크리드, 엔지니어링 매니저, 창업가, 비엔지니어 직군(데브렐, TPM 등), 매니저 전환, 앞선 항목의 조합, 비선형적 커리어패스(매니저 전환, 휴직, 경력단절, 복직 등)

비즈니스에는 수익센터와 비용센터가 있다. 수익센터는 비즈니스의 수익을 직접 창출하는 팀이다. 구글의 광고팀이 대표적인 수익센터이고, 어떤 회사는 영업 팀이 수익센터일 수도 있다. 비용센터는 직접적으로 수익을 창출하지는 않지만, 원활한 운영을 위해 필요한 팀이다. 팀의 활동이 필수적이지만 직접적으로 수익을 창출하지는 않기 때문에 비즈니스 관점에서 비용센터로 여겨진다. 많은 경우 수익센터에서 승진이 쉽지만, 엔지니어에게 수익센터는 지루한 팀으로 비춰지곤 한다. 주로 제품 팀은 수익센터로, 플랫폼 팀은 비용센터로 인식된다. 회사가 감원을 할 때 비용센터가 희생될 위험이 높다.

커리어 관리

커리어에 주인의식을 갖고 자신의 커리어를 주도하는 것이 기본이다. 당연히 일을 잘해야 하고, 주변에도 일을 잘하는 것이 보여야 한다. 주어진 업무를 시간 안에 높은 품질로 완수한다. 영향력이 높은 작업을 선택하고, 한 일을 사람들에게 적극적으로 알리자. 작업 일지를 작성하면 우선순위를 쉽게 파악할 수 있고, 연말 성과 평가에도 도움이 된다. 매일 중요한 코드 변경이나 설계, 토론, 계획 등 모든 작업 내용을 기록해두자.

지난 여름 이력서를 다시 작성하면서 지난 업무 기록을 뒤져보느라 진땀을 뺀 경험이 있다. 작업의 배경과 과정, 성과까지 잘 기록해두는 것이 좋겠다. 『제텔카스텐』 방식이 도움이 될 것 같다.

피드백을 적극적으로 받자. 코드리뷰, 아이디어 제안, 디자인 문서 등 피드백을 얻을 수 있는 방법은 많다. 개인에 대한 막연한 피드백보다는 구체적으로 자신이 수행한 일에 대한 피드백을 요청하는 것이 좋다. 대부분의 사람들은 요청하지 않는 이상 피드백을 주지 않는다. 무언가를 처음 해보거나, 새로운 환경에서 무언가를 알아가고 있을 때 피드백이 특히 유용하다. 반대로, 피드백을 전달할 때는 잘한 일을 칭찬하고, 상황과 그 영향에 초점을 맞춰 피드백한다. '이렇게 하라’고 지시하지 말고, 스스로 해결책을 찾도록 도와야 한다. 피드백에 대한 ‘투쟁-도피’ 반응은 인간의 본성이기 때문에 처음부터 상대방의 편임을 분명히 밝히고, 긍정적으로 마무리하자.

업무에는 세 분류, 스트레칭, 실행, 관성이 있다. 스트레칭 업무는 컴포트존을 벗어나서 새로운 것을 배우는 업무다. 스트레칭은 성장 속도를 높이고, 유연하게 만들어주지만 너무 오래 스트레칭을 하면 번아웃이 찾아온다. 실행 업무는 이미 알고 있는 기술과 경험을 활용해 처리하는 일반적인 업무를 말한다. 스트레칭을 어느 정도 마쳤다면 실행 업무에 집중해 업무량을 줄여 번아웃을 피해야 한다. 관성 업무는 자신의 능력보다 더 적은 양과 낮은 품질의 업무를 말한다. 정신적인 휴식을 취하는데 좋지만, 관성 업무가 길어지면 평판에 악영향이 생길 수 있으니 제때 벗어날 수 있어야 한다.

성과 평가

성과 평가는 특정 시점의 스냅숏에 불과하다. 평가자들은 평가 시점에 편향을 갖고 성과를 평가한다:

  • 최신성 편향: 최근 업무에 더 많은 관심을 갖고 평가함.
  • 엄격성 편향: 특정 팀원을 지나치게 엄격하게 평가함.
  • 관용 편향: 특정 팀원을 더 관대하게 평가함.
  • 뿔 편향: 한 영역에 대한 부정적인 피드백이 전체 리뷰를 덮음.
  • 후광 편향: 긍정적인 사건 하나가 전체 리뷰에 영향을 줌.
  • 유사성 편향: 평가자가 좋아하는 사람을 더 좋게 평가.
  • 중앙 성향 편향: 평가자가 공정성을 위해 모두를 비슷하게 평가.
  • 대조 편향: 대상 역할에 대한 기대치가 아닌 다른 역할을 기준으로 상대적 평가.

성과 평가와 장기적인 커리어의 연관성은 거의 없다. 성과 평가 한 번이 기대치를 충족하든, 초과하든 긴 전체 경력에는 큰 영향을 미치지 않는다. 경력은 성과 평가 주기가 아니라, 수십 년 후에 참여한 프로젝트와 인간관계, 습득한 기술, 해결한 문제를 기준으로 판단될 가능성이 더 높다. 성과 평가에 지나치게 집착하지 말고 장기적인 관점을 유지하자.

승진

빅테크에서 승진 및 성과 평가가 영향력 중심적으로 진행되면 '승진 지향 개발’이라는 불행한 결과가 발생할 수 있다. 기업은 당신의 직급이 올라갈수록 더 큰 그룹에 영향을 미치는 업무를 맡기고, 더 영향력있는 비즈니스 성과를 이끌어내길 기대한다.

스태프 엔지니어로 승진하려는 엔지니어는 조직 전체의 문제에 대해 기존의 타사 프레임워크를 사용하는 대신 자체적인 사내 솔루션을 개발하는 경우가 많다. (…) 기성 솔루션을 사용하면 '별일 아닌 것’처럼 치부되며, 시니어급 이상의 소프트웨어 엔지니어링 및 아키텍처/디자인에서 바라는 복잡성을 충족시키지 못한다.

구글은 16년 동안 채팅 제품을 20개나 만들었는데 이중 일부는 동시에 개발하기도 했다. 그림이 그려진다. 수십 명의 엔지니어와 매니저가 이런 채팅 프로젝트를 거쳐 다음 직급으로 승진한다. 그 뒤 다른 엔지니어와 매니저가 기존 제품을 수정하는 대신 더 큰 영향력을 가진 복잡한 프로젝트를 처음부터 만들어야 한다며 뛰어든다. 이렇게 20개의 채팅 제품이 생겨난 것이다.

경력에 대한 투자는 한참 뒤에야 성과를 보인다. A의 우선순위는 즉각적인 진급이다. 최선을 다해 최대한 빠르게 스태프 엔지니어로 승진하고, 직급을 유지한다. 하지만 다른 곳에서 기회를 찾기 어렵다. 직급이 낮은 포지션으로 이직하는 것은 원치 않으므로 현재 자리에 그대로 머문다. 반면 B의 우선순위는 호기심을 해결하는 것이다. 시니어 엔지니어로 승진한 뒤, 직급을 한 단계 내려 새로운 환경을 경험할 수 있는 회사로 이직한다. 이런 학습 곡선을 몇 차례 반복하며 B는 전문가가 된다. 수평적 이동이나 새로운 기술 스택은 경력에 즉각적 보상이 되지는 않지만, 장기적으로 좋은 투자다.

어디서나 통하는 접근법

제품 팀은 외부 고객을 위한 제품을 개발하는 엔지니어링 팀이다. 제품 팀에서 가장 큰 영향력을 발위하는 '제품 지향적 엔지니어’는 제품에 대한 아이디어와 의견을 적극적으로 제시하고, 비즈니스와 사용자 행동에 많은 관심을 갖는다. 또한 비엔지니어 그룹과 밀접히 소통하고, 제품과 엔지니어링의 절충안을 도출한다. 이들은 제품 자체에 애정이 있고, 제품에 대한 주인의식을 갖기 때문에 엔지니어링에서 벗어난다면 프로젝트 매니저가 될 가능성이 높다.

목적조직으로 구성된 제품 팀에서 일하면서 제품 지향적 엔지니어가 되기 위해 노력하기도 했는데, 내가 일상적으로 사용하지 않는 제품에 깊은 애정을 갖기가 어려웠다. 내가 엔지니어로서 기획이나 디자인에 어느정도로 의견을 제시해도 괜찮을지, 어느정도로 시간을 쏟아야할지 고민되기도 했다. 내가 본 제품 지향적 엔지니어들을 돌이켜보면 사용자로서 제품을 자주 사용하거나, 커머스 도메인에 대한 이해와 관심이 깊은 분들이었던 것 같다.

플랫폼 팀은 빠르게 성장하는 엔지니어링 조직을 확장하기 위한 플랫폼 엔지니어링을 담당한다. 제품 팀은 비즈니스 기능을 출시할 때 플랫폼 위에 제품을 구축한다. 플랫폼 팀은 기술적인 미션에 집중하며, 확장 가능한 솔루션을 구축하는 엔지니어링 업무를 수행한다. 사내 다양한 팀을 위한 인프라나 CI/CD, SDK 등을 개발한다. 이들의 주요 고객은 회사 내의 제품 팀 엔지니어나 비즈니스 팀의 동료다. 플랫폼 팀에서 일하면 복잡한 엔지니어링 과제를 주로 접할 수 있고, 하나의 제품이나 기능에 국한되지 않는 광범위한 영향력을 미칠 수 있으며, 높은 엔지니어링 자유도를 누릴 수 있다. 또한 고객과 떨어져 있기 때문에 장기적인 기술 계획이 가능하다. 다만, 제품 팀과 달리 비즈니스에서 중요한 지표를 쉽게 만들기 어려워 그 기여도를 증명하기 어렵다. 이로 인해 비용센터로 여겨질 가능성이 높다.

플랫폼 엔지니어의 생산적인 업무 방식은 다음과 같다:

  • 고객과의 공감대 형성: 대부분의 플랫폼 팀은 고객이 제품 팀의 소프트웨어 엔지니어라고 생각한다. 하지만 플랫폼 팀의 또 다른 고객은 제품 팀이 서비스를 제공하는 최종 사용자이기도 하다. 이 점을 잊지 말고 고객과 공감대를 형성하자.
  • 플랫폼을 사용하는 엔지니어와의 소통: 플랫폼을 사용하는 엔지니어는 플랫폼 팀과 쉽게 소통할 수 있어야 한다. 스스로 소개하고 언제든 질문해도 좋다고 말하자. 메일링 리스트와 채팅방 등 엔지니어가 언제든 플랫폼에 대한 질문을 남길 창구를 열어두자. 이런 관계를 구축하지 않으면 상아탑에 갇혀 아무도 원하지 않는 일만 하게 될 위험이 있다.
  • 플랫폼의 고객과 협업: 대부분의 플랫폼 엔지니어는 팀의 일원으로 플랫폼을 구축한다. 그러나 뛰어난 플랫폼 엔지니어는 때때로 '다른 쪽’으로 이동해 제품 팀과 함께 플랫폼을 통합하거나 구현하는 작업을 하기도 한다. 이렇게 하면 팀이 플랫폼을 어떻게 사용하는지 훨씬 더 잘 이해할 수 있고 재미도 있다!
  • 제품 팀에 순환 근무: 마찬가지로, 제품 팀에서 오랫동안 일하지 않았다면 가능하면 몇 주씩 돌아가면서 일하자. 제품 팀은 플랫폼 팀이 구축한 모든 것을 사용하므로 제품 팀과 관계를 맺자.
  • 긴급성과 집중력을 목표함: 플랫폼 팀에서 일하면서 출시에 대한 긴박감이 훨씬 덜하고 일반적으로 다른 일정 개입이 적다는 장점이 있다. 또 방해받지 않고 집중해서 일할 수 있다. 반면에 어떤 종류의 압박도 없으므로 중요한 작업을 완수해야 할 때 집중력이 떨어질 수 있다. 일의 우선순위를 명확히 파악하고, 그 일을 진행하면서 집중력을 유지하자.

제품 팀에서 일하면서 '기술 과제’를 갈망했던 과거가 떠오른다. 플랫폼 팀의 지향점은 내가 아카데미아와 인더스트리 사이에서 고민하던 지점과도 맞닿는 점이 있다. 아카데미아가 좋은 부분은 이론을 바탕으로 현실 문제 대한 장기적이고 범용적인 솔루션을 연구할 수 있다는 점이다. 그러나 내가 논문으로 제시한 솔루션을 누구도 사용하지 않을 가능성이 높고, 내 솔루션을 실제로 사용하는 사용자로부터 피드백을 받을 수 없다는 점(지도교수와 리뷰어가 실제 사용자는 아니니까)이 한계로 느껴졌다. 그런 측면에서 플랫폼 팀은 범용적인 솔루션을 장기적으로 연구할 수 있다는 점, 그런 솔루션이 실제 제품에 적용되어 즉각적인 피드백을 받을 수 있다는 점이 매력적이다.

이직

이직 후 새 직장에 입사했다면 초기부터 업무 일지를 작성한다. 매주 배운 것과 이해하지 못한 것을 최소 세 가지씩 적어보자. 소규모 기업에서는 일이 어떻게 돌아가는지 짐작하지 말고 물어봐야 한다. 대기업에서 소규모 기업으로 이직했을 때 특히 중요하다. 새로운 환경에서 불가능한 일을 제안하면 분위기를 저하할 수 있다. 대규모 조직에서는 더 복잡하다. 새로운 내용을 모두 기록하는 나만의 치트 시트 문서를 작성해보자. 소규모 기업에서 이직했다면 처음에는 많은 것이 이해되지 않을 수 있다. 정상이니 걱정하지 말자.

유능한 소프트웨어 개발자

업무를 완수하는 개발자

안정적으로 업무를 수행하는 엔지니어는 일을 작은 단위로 나누고, 현실적인 일정을 제시하며 스스로 막힌 부분을 풀어 일을 처리하면서 양질의 결과물을 만든다. 항상 최우선 과제를 완료하고, 최우선 과제에 위협이 되는 요청은 거절할 수 있어야 한다. 일을 하다가 막힌 부분이 있다면 뚫어야 한다: 러버덕, 종이에 문제 스케치, 공식 문서 참고, AI 도구 활용, 온라인에서 비슷한 문제 검색, 머리 비우기, 처음부터 다시 시작하기, 주변 지원을 받기 등.

작업 소요 시간은 어떻게 추정할까? 이전에 수행한 작업과 같은 작업이라면 쉽게 추정할 수 있다. 수행해보지 않은 작업이라면 범주를 나눌 필요가 있다. (1) 동료의 작업과 유사한 작업이라면 작업을 해본 동료와 논의해보면 된다. 처음 시도하는 작업이니 그보다는 기간이 더 필요할 것이다. (2) 잘 아는 기술로 잘 모르는 시스템을 통합해야 하는 작업이라면 상황을 예측하기 어렵다. 내부 동작 방식을 알 수 없기 때문에 막히는 부분이 생길 수 있다. 이 경우 먼저 프로토타입을 제작해 PoC를 한 뒤에 예상 소요 시간을 추정하는 것이 좋다. 추정치를 제시하기 부담스럽다면 최악의 경우를 제시하자. (3) 잘 모르는 기술로 잘 모르는 결과물을 구축하고 잘 모르는 시스템과 통합해야 한다면 더 어렵다. 잘 모르는 것을 세 종류: 통합하려는 시스템, 기술, 미지의 요소로 나눠보고, 프로토타이핑과 작업 세분화를 통해 미지의 요소를 줄여야 한다.

코딩

코드를 작성하는 만큼 읽어봐야 한다. 가장 좋은 방법은 코드 리뷰에 참여하는 것이다. 코드베이스가 익숙하지 않더라도 코드 리뷰에 참여해 동료의 변경 사항과 구현, 접근 방식을 메모해두면 도움이 된다.

소프트웨어 개발

저자는 경력 초기의 개발자에게 적어도 한 가지 영역을 깊이있게 공부하라고 조언한다. 하나의 블럽(지루하지만 필요한 기술)을 깊이 있게 배우면 기술 스택의 인접한 영역에 있는 다른 기술로 확장하기 쉬워진다.

생산적인 소프트웨어 개발자의 도구

기존 코드를 읽고 그 기능을 이해하자. 숙련된 엔지니어에게 코드베이스의 구성과 설계에 대한 설명을 부탁하는 것이 효과적이다. 직접 다이어그램을 그려서 코드베이스의 구조를 이해하는 것도 좋다. 이에 대한 치트 시트도 만들어보자.

다재다능한 시니어 엔지니어

업무를 완수하는 엔지니어

저자는 소프트웨어 개발을 소프트웨어 엔지니어링의 하위 집합으로 본다. 소프트웨어 개발은 기본 계획 수립과 코딩, 테스팅, 배포, 디버깅 등 소프트웨어를 구축하는 프로세스를 말한다. 소프트웨어 엔지니어링은 요구사항 수집과 접근 방식 분석, 소프트웨어 개발, 배포, 유지관리, 확장, 마이그레이션 등 보다 광범위한 프로세스를 말한다. <구글 엔지니어는 이렇게 일한다>에서는 "소프트웨어 엔지니어링은 코드 작성에 더해, 시간의 흐름에 따라 한 조직이 그 코드를 구축하고 유지보수하는 데 이용하는 모든 도구와 프로세스를 포괄한다. (…) 소프트웨어 엔지니어링이란 흐르는 시간 위에서 순간수간의 프로그래밍을 모두 합산한 것이다."라고 말한다.

긴급성과 중요도에 따라 작업의 우선순위를 정하자. (1) 긴급하고 중요한 작업은 바로 처리한다. (2) 중요하지만 급하지 않은 작업은 기록해뒀다가 나중에 한다. 마감이 정해진 작업은 시간이 지나면 긴급하고 중요한 작업이 된다. 기록해둔 할 일 목록을 한번 씩 정리한다. 더 이상 중요하지 않은 작업들이 되어 있을 수도 있다. (3) 긴급하지만 중요하지 않은 작업은 꼭 할 필요는 없다. 작업을 중요하게 취급하는 다른 사람에게 맡기거나 거절한다. (4) 급하지도 중요하지도 않은 작업은 거절하고, 반드시 이득이 있을 때만 참여한다.

협업 및 팀워크

이 문서를 인용한 문서