이번 글의 부제는 원래 <경력자에게 바라는 것들> 이었습니다. 그런데 무조건 경력자만 갖출 수 있는 역량은 아닌 것 같아 부제를 바꿨습니다. 그래도 앞번 글의 내용에 비하면 다소 연습이 필요한 항목들입니다. ‘이런 것까지 갖춘 사람에게는 높은 보상을 제시해야 하겠다’ 정도의 내용을 다룹니다. ‘10년차를 이기는 3년차’같은 사람이 되고 싶다면, 이번 글의 내용을 숙지해보면 어떨지 감히 제안해 봅니다.
상황에 따라 어쩔 수 없는 경우도 있습니다. 합리적이지 못 하고, 진취적이지 못 하고, 바뀌려고 하지 않는 조직도 있습니다. 이상을 이루기에는 현실이 너무 동떨어져 있어 “내가 뭘 더 해야 하나” 싶을 때가 있습니다. 그 정도면 됐습니다. 쇄신하려고 충분히, 차근차근, 최선을 다해 노력했다면 그 경험은 소중합니다. 위로하고자 하는 것이 아니라, 어딘가 다른 회사의 인터뷰어는 그 경험을 좋게 받아들일 겁니다. 축구선수도 자기에게 맞는 팀을 찾아 재능을 꽃피우는 것처럼요.
반복적인 작업은 누구에게나 스트레스입니다. 자주 발생하고, 긴 시간을 소비할 수록 더 그렇습니다. 이럴 때 짜증만 내다 끝내지 않고, 반복 작업을 어떻게 없앨 수 있을 지 고민하는 사람이 있습니다.
저희 팀에서는 Python을 쓰고 있습니다. 다른 패키지나 모듈의 요소를 끌어오기 위해, 다른 언어들도 그렇듯 import
문을 사용합니다. 과거에는 다음처럼 import를 해 놓고 사용하지 않는 unused import 때문에 가치가 낮은 작업들이 진행되곤 했습니다 (Python은 이런 걸 자동으로 안 지워 주거든요).
코드리뷰 도중 “unused import가 있으니 지워달라”는 코멘트를 달고, 수정하는 commit을 반영하는 일이 잦았습니다. 한 번은 unused import를 삭제하는 PR이 올라오기도 했습니다.
시간이 지나 시스템의 도움을 받기로 했고, isort와 autoflake라는 linter를 적용했습니다. 그리고 이것을 File Watcher에 묶어서, change가 발생하면 자동으로 실행되도록 만들었습니다.
그 뒤로 unused import가 포함된 코드는 더 이상 commit되지 않았습니다. 시간 낭비를 줄이고, 결과물의 기본값이 높아진 것입니다.
linter는 생각하기 쉽고, 적용하는 것도 어렵지 않습니다. 대부분 이미 linter를 쓰고 계실 테고, 아니더라도 금방 공부해서 적용할 수 있는 정도입니다. 저도 지금 생각하면 ‘내가 linter조차 없는 환경에서 개발을 했단 말이야?’ 싶습니다. 사실 일의 난이도보다 중요한 것은 일이 되게 만들기까지의 과정입니다.
우리 조직이 겪는 pain point가 무엇인지 감지하는 것
→ 이 단계가 가장 어렵습니다. 작은 아픔들은 보통 익숙해져서 당연하게 느끼기 때문입니다.
문제를 해결해줄 옵션을 나열하는 것
옵션들 중 가장 높은 레버리지를 줄 수 있는, 가성비 높은 작업이 무엇인지 판단하는 것
그 근거에 따라 팀과 리드를 설득하고 작업이 스케줄링되도록 만드는 것
작업이 완료된 후 실제로 pain point를 없앴는지 성공 여부를 평가하는 것
-
예전에는, 제가 야근을 하는 이유가 실력이 부족하기 때문이라고 생각했습니다. 사실 실력에 맞게 적당한 수준의 일을 주는 것일텐데요. 알고 보니 저마다의 요령이 있었습니다. IDE에서 단축키를 정말 잘 쓴다거나, 좋은 플러그인을 찾아서 쓰고 있거나, 자기만의 스크립트 모음집을 만들어 뒀다거나, 하는 식으로 생산성을 조금이라도 더 뽑아내고 있었습니다.
관성으로 일하다 보면 언젠가부턴 자기 일을 처리할 시간이 없어지게 됩니다. 시간을 쏟아붓는 식으로 일하지 않으려면, 일찍부터 효율화를 생각해야 합니다.
‘이걸 왜 해야 하나’라는 생각이 들 때가 있습니다. 정말로 가치 없는 일을 하고 있다면, 그 일을 하지 않을 수 있도록 시도하는 사람이 보기 좋습니다. 불평만 하며 꾸역꾸역 야근을 하는 것보다 훨씬 낫습니다.
마구잡이로 꼬여있는 코드를 보면 참 마음이 답답합니다. Python 2, Objective-C, Java 8, Spring MVC같은 키워드를 보면 어떤가요? Python 4에 대한 이야기가 나오고, Swift 5, Java 18, Spring Boot가 존재하는 지금은 너무 옛날 기술이 아닌가 싶습니다.
사실 이런 ‘옛날 기술’을 쓰는 개발 조직은 세상에 많습니다. 방법론이나 아키텍처에 대해 논할 때 나오는 TDD, DDD, Hexagonal Architecture, 심지어 코드리뷰마저 유니콘처럼 여겨지는 조직도 있습니다.
그들이 충분히 대단하지 못 해서 이러한 환경이 구성된 것은 아닙니다. 서비스를 중단 없이 고품질로 운영해야 하는 입장에서, 버전을 올린다거나 신기술을 집어넣는 건 리스크가 높기 때문입니다.
일정을 맞추느라 코드 잘 짜는 데에 신경쓰지 못할 때가 있습니다. 스타트업의 서비스가 보통 그렇습니다. 기능 하나가 나오고, 안 나오고가 투자유치나 데모의 성패를 가르기도 합니다. 초기 서비스의 성장은 어떤 예술적인 코드에서가 아니라, 빠른 속도로 ‘되게 만드는’ 조직 구조에서 비롯되는 경우가 많습니다.
다시 봐도 Python 2, Objective-C, Java 8은 고개를 갸우뚱하게 만듭니다. 그러나 중요한 일을 먼저 하다 보니, 예술적인 코드와 최신 기술은 중요도가 낮으니 발생한 자연스러운 일이라는 것입니다.
-
시장에서 어느정도 인정을 받아, 성장을 고도화하려는 조직은 시니어를 뽑습니다. 그들이 회사에 와서 해야 할 반응은 ‘와, 여긴 테스트도 안 짜고 코드리뷰도 안 하네’가 아닙니다. 이렇게 수많은 레거시가 복잡하게 엉켜있는 시스템을 어떻게든 굴러가게 만든 지금의 개발자들에게 존경을 표하는 것이 먼저입니다.
그리고 회사가 내줄 수 있는 리소스를 최대한 높은 가치로 변환해낼 고민을 해야 합니다. Goal을 설정하고, 동료들이 움직일 수 있도록 동기부여하고, 달성해나가는 모습 말입니다. 자신의 우수함을 과시하며 조직의 재능과 가능성을 뭉개버리는 것이 아니라, 모두가 자신을 추월할 수 있게 만들어야 합니다.
작은 기능 개발부터 프로젝트까지, 수많은 미션이 제안됩니다. 그러나 그것을 현실화하는 과정은 생각보다 순조롭지 않으며 여러 문제가 발생합니다. 열심히 만들던 기능이 spec-out되거나, 처음에 예상하지 못한 부분에 의해 공수가 더 필요하거나, 아예 프로젝트가 drop되는 경우도 있습니다.
열심히 만들던 것이 세상에 나가기도 전에 사라지는 상황은 누구에게나 힘 빠지는 일입니다. ‘이걸 왜 처음부터 생각 못 했을까’ 하면서 자책하는 경우도 많습니다. 반면에, 위기를 마주쳤을 때 이성적으로 대응하는 사람이 있습니다. 문제를 최대한 일찍 정확하게 알리고, 어떤 변화가 있어야 하는지 정리하고, 피해를 덜 받으려면 어떤 방법이 있을지를 제시하는 동료가 좋습니다. 팀의 혼란을 최소화하기 위해서 말입니다. 다음은 그 예입니다.
“작업 scope에서 기능 하나를 놓쳐서 예정보다 2일이 더 필요합니다. 그런데 이것이 비교적 독립적인 기능이라, 관련 QA 아이템을 시간적으로 뒷 순서에 배정할 수 있다면 일정 지연을 방어할 수 있을 것 같습니다. 이렇게 추가 작업과 QA를 병렬로 진행해볼 수 있을까요?”
또한, 위기가 앞으로 덜 발생하도록 하는 방법을 고민하는 것도 소중합니다. 작게는 자신의 업무 습관 영역을 개선하고, 크게는 조직 수준에 프로세스를 제안하는 방법이 있습니다.
제가 속한 조직은 B2B 비즈니스를 하고 있으므로, 단건의 VOC(Voice Of Customer)가 크게 다가오는 편입니다. B2C 비즈니스처럼 불만이 일정 이상 쌓이고 나서 대응하기에는 어려운 부분이 있습니다.
대신, 기능 설계를 할 때 그 고객 하나를 만족시키는 것보다 GA(General Availability)를 목표로 잡는 편입니다. 그리고 조금 길게 끌린 작업이 있다면 회고를 진행하기도 합니다. 기능 공장이 되지 않게 만들어가고 있는 것 같습니다.
모두 아시겠지만 프로젝트가 순조롭게 진행되도록 만드는 것은 모든 조직의 과업입니다. OKR, KPI, 애자일 코치와 같은 키워드가 사방에서 등장하는 것만 봐도 그렇습니다. 조직 수준에 대한 챌린지는 신중하게 한다고 치고, 개인 수준의 멘탈 관리와 회복력을 보여주는 것은 당장 할 수 있는 중요한 일입니다.
Form follows function.
형태는 기능을 따른다.
미국의 건축가 루이스 설리번(Louis Sullivan)의 말입니다. 100년이 넘은 개념이라, 건축학계에서는 사실 논쟁이 많은 이야기라고 합니다. 해석 중 하나인 ‘디자인에서 미학적 고려는 기능적 고려 다음이어야 한다’ 를 보면, 소프트웨어 엔지니어링에 정말 적합한 말이라고 생각합니다.
엔지니어는 고품질의 서비스를 만들어낼 의무가 있습니다. 고품질을 결정짓는 요소에는 빠른 속도, 대량의 트래픽 감당, 예외에 대한 적합한 핸들링, i18n, 접근성 등 다양한 것들이 있습니다. 이를 위해서는 이른바 ‘짱짱한’ 시스템을 만들어야 합니다. HA, fault-tolerance, scalability같은 키워드가 떠오릅니다.
그런데 이것을 서비스의 초기부터 빌드업하는 것이 과연 옳은지를 생각해볼 필요가 있습니다. 물론 미래에 발생할 미지의 상황을 대비하는 것은 좋습니다. 하지만 그것을 만들기 위한 공수나, 복잡도가 높아질 시스템을 생각해야 합니다. 미지의 상황이 과연 발생할지도 고민해볼 필요가 있습니다. YAGNI(You aren’t gonna need it), KISS(Keep it simple, stupid)같은 law가 통용되는 이유가 확실히 있습니다.
YouTube와 Facebook도 초기에는 그렇게 썩 아름답지 않았습니다. 처음부터 지금과 같은 YouTube의 퀄리티를 생각했다면, 코드의 아름다움이나 가독성을 깊이 생각했다면, 서비스가 세상에 너무 늦게 등장했을 것입니다.
초기 서비스는 기능 하나가 나오고, 안 나오고가 고객의 유입과 이탈, 투자유치의 성패를 결정하곤 합니다. 앞의 동료와 회사를 존중하는 사람 에서 다뤘던 내용입니다. 당장 기능을 만들어야 하는데 코드 아키텍처나 아름다운 시스템 디자인을 신경쓰는 것이 과연 옳은 투 인자지 해각 야 야합니다.
낭비를 경계하며 합리적인 엔지니어링을 해야 합니다. 최소한의 설계를 통해 필요한 것에만 집중해야 합니다. 그러나 반대로, 처음의 설계가 나중에 문제를 일으켜 수정 비용이 너무 커질 때가 있기도 합니다. 그래서 조금 추상적인 얘기지만 적정 선을 찾아야 합니다. 지금 시점에 적절한 엔지니어링이 무엇인지, 잠재적 위험을 탐지해 미래의 변화에 대한 수용도가 높은 시스템이 무엇인지를 잘 설계하는 것이 개발자의 역량입니다.
‘그래서 적절한 엔지니어링이 뭐라고?’ 라는 질문에는 아쉽지만 간단하게 답하기 어렵습니다. 조직마다 가치관도, 도메인도, 워크로드도 다르기 때문입니다. 사례를 들기에는 너무 구구절절하니 넘어가고, 참고할 만한 글로는 My Personal Experience with Overengineering vs. Under-engineering, How to avoid over-engineering 정도가 있습니다.
앞에서처럼 적절한 수준의 엔지니어링 을 하고 나면, 최소 수준을 만족한 결과물이 등장하게 됩니다. 그 이후에는 앞으로의 일을 고민하기 시작합니다. 로드맵은 조직에 따라 가치 판단의 기준이 다릅니다. 시스템의 안정성이 가장 중요한 경우도 있고, 성능 개선이 가장 중요한 경우도 있고, 어떤 기능을 개발하는 것이 가장 중요한 경우도 있습니다. 유의미한 로드맵을 구상하기 위해서는,
현재의 시스템에 무엇이 부족한지 찾는 감지 능력
부족한 부분을 개선할 적절한 작업을 분장하는 지식과 경험
리스트업된 다양한 일들 중 가장 가치 있는 것을 골라내는 판단력
조직이 리소스를 내줄 수 있도록 소구시키는 설득력
목표를 달성하도록 사람들을 움직이게 만드는 동기부여와 관리 능력
정도가 필요한 것 같습니다. 딱 봐도 어려워 보이듯, 어느 정도 경험과 기술적 배경에 의존하는 항목입니다. 동종업계의 경력자를 우대하는 이유가 이런 부분에 있는 것 같습니다. ‘생각은 크게, 행동은 작게’ 를 실천할 수 있기까지는 생각보다 많은 훈련이 필요하기 때문입니다.
멋진 프로덕트를 볼 때, ‘이렇게 대단한 시스템을 어떻게 빌드업했을까’ 라는 생각은 별로 안 드는 것 같습니다. 당연히 몇 년 걸렸을 것이고, 내가 하더라도 조금 오래 걸릴지언정 불가능하진 않겠다는 생각이 듭니다. 오히려 ‘이런 걸 해보자고 누가 아이디어를 냈을까, 어떻게 조직을 소구시키고 사람들을 움직이게 만들었을까’ 라는 감정이 먼저 듭니다.
당연한 이야기지만, 알아서 잘 하는 사람이 좋습니다. ‘알아서 잘 하는 것이 무엇인지’라고 한다면, ‘무엇을/어떻게의 내용을 직접 만들어낼 수 있는 것’ 이라고 답할 것 같습니다. 똑같은 코칭을 받더라도, 비교적 높은 수준의 결과물을 내기 위한 역량입니다.
작업을 대충 던져줘도 괜찮은 결과물을 가져오는 사람이 좋습니다. 문제를 구체화하고, 적합한 엔지니어링을 설계하고, 논의를 이끌고, 고려할 factor를 찾는 과정을 자체적으로 판단하고 처리하는 것입니다.
작업을 대충 주는 것이 무책임하다고 생각할 수 있습니다. 그러나 의외로 작업 분장을 완전히 해주지 못할 때가 더 많습니다. 단순히 매니저가 바빠서거나, 논의가 더 진행되어야 하거나(TBD; To Be Discussed) 등의 이유에서 ‘일을 맡기는’ 것일 뿐입니다. 그러므로 알아서 잘 하는 사람은 조직 입장에서 든든하게 보일 수밖에 없습니다.
이런 사람들의 공통점이 있습니다. 매니저의 의견이 절대적이라고 생각하지 않는다는 것입니다. 아무리 경험 많고 똑똑한 사람도, 많은 시간을 들여 고민하지 않으면 틀릴 수 있습니다. 저는 과거에 매니저가 틀렸을 것이라는 생각을 하지 않아 작업 진행이 어려웠던 적이 있습니다.
또한, 적절하고 과감한 지원 요청을 합니다. 먼저 자신이 할 수 있는 일과 할 수 없는 일을 적절히 분리합니다. 그리고 필요한 지원이 무엇인지 충분히 정리해, 조력자의 시간을 최소로 뺏으면서 최대의 지원을 얻어냅니다. 되물어볼 것 없이 대답이나 결정만 해 주면 되도록 하는 것입니다.
지원 요청이 소극적일 때가 있습니다. 대표적으로 돈이 소모되는 옵션을 아예 배제하는 경우가 있습니다. 하지만 그 비용을 쓸 만큼의 가치가 있다면 들고 가서 소구시키는 편이 좋습니다. 개발자들 시급에 숫자를 곱한다던가 하는 무식한 방법이라도 써서 말입니다.
-
당연히 처음부터 이런 역량을 가지기는 어렵습니다. 기술 수준, 비즈니스(도메인)에 대한 이해, 현재 시스템에 대한 이해, 경험 등이 부족하기 때문입니다. 점진적으로 어떻게 성장해나갈 수 있을지 다뤄보도록 합시다.
전반적으로 두 가지의 작업이 필요하다고 생각합니다. 알아서 할 줄 아는 범위를 늘리는 것과, 똑같은 일이라도 난이도를 높여 챌린지를 시도하는 것입니다.
초기에는 “이런 문제가 있으니 이렇게 고쳐보세요”같은 식으로, 무엇을/어떻게에 대한 작업 분장이 모두 완료된 채 작업을 받습니다. 시키는 일을 하는 단계입니다. 역량에 따라 디테일을 더 잡아줘야 할 때도 생기곤 합니다.
시키는 일을 잘 처리하다 보면, “이런 문제가 있으니 어떻게 해결할 수 있을지 가져오세요”같은 식으로 작업을 받기 시작합니다. 작업에 있어서 ‘어떻게’에 대한 부분을 위임받는 것입니다.
정답을 찾는 능력이 만들어지며, 동시에 문제와 위험을 감지하는 능력도 늘어납니다. 이 때부터는 문제 제기의 방향이 반대가 됩니다. “이런 문제가 있으니 이렇게 고쳐볼게요”같은 내용을 매니저에게 들고 가게 됩니다. 이 시점부터는 자연스럽게 온전한 권한위임이 가능하게 되며, 문제 제기의 퀄리티에 따라 직급이 바뀌기도 합니다.
‘물고기를 잡아주지 말고 물고기 잡는 법을 가르쳐라’는 말이 어울리는 주제였습니다. 본인이 성장하는 것을 매니저가 먼저 인식해 위임을 시도할 수도 있고, 직접 제시해볼 수도 있습니다. 위임을 해주지 않는다고 가만히 있기보다 요청하는 편이 당연히 더 좋습니다.
‘어디어디서 그렇다더라’는 무언가를 도입하는 근거가 될 수 없습니다. 기술, 방법론, 프로세스, 문화 등은 모두 우리만의 방식을 찾는 것이 중요합니다. 특히 조직 문화는 정해진 템플릿들 중 하나를 선택하는 게 아니라, 직접 만들고 성장시키는 것입니다. 스크럼, 애자일, 스프린트를 검색해 고스란히 따라하는 것은 초기 조직의 임시조치일 뿐입니다. 정답을 찾아가기 위한 노력이 필요합니다.
Google의 기술과 문화를 모두 적용한다고 하더라도 Google처럼 될 수 없습니다. 인재의 밀도 차이, 배경지식의 차이, 국가적인 문화 차이, 비즈니스의 차이 등 이유는 다양합니다. Java는 우수한 언어지만 팀의 선호도와 숙련도에 의해 배제될 수 있는 것이며, AWS는 편하지만 비즈니스의 특성 상(금융업을 한다거나 등) 사용하지 못할 수도 있는 것입니다.
잘 나가는 기업들은 자기들의 멋진 조직 문화를 전파하려고 합니다. 그러나, 잘 나가는 조직의 기술과 문화는 참고할 대상일 뿐이지 무작정 따라하려는 것은 좋지 않습니다. 단순히 따라하기만 해서는 본질을 흡수할 수 없습니다. 블로그 글 몇 문단만 읽고 갑자기 alignment day같은 걸 들이미는 것을 보면 아쉽습니다. 문화를 도입할 때에는 조직 구조부터 시작해, 팀을 지배하고 있는 정서를 이해하기까지 꽤 사전 조사가 필요합니다.
상황이 맞다면 Waterfall 방법론에 Assembly를 쓸 수도 있습니다. 무조건 좋고 나쁨은 없습니다.
기획자가 요구하는 대로 기능을 완벽하게 개발하긴 어렵습니다. 이것은 기술에 대한 배경지식의 차이 때문이므로 개발자의 세심한 타당성 조사와 피드백이 필요합니다.
작업의 실행 가능성을 조사하는 것은 기본.
작업이 정말로 목표를 달성할 수 있는지 검토하고, 효용이 없다면 진행하지 않는 것을 용기있게 제안.
기술적으로 불가능한 부분을 발견하고, 타당한 방향성을 제시해 기획 변경을 논의. 저는 특히 offset pagination vs cursor pagination에 대해 기획자와 논의하는 일이 잦았습니다.
작업의 side effect(특히 downside)를 파악하고, 설득력 있는지 판단. 보통은 속도가 느려지는 일이 발생하곤 합니다.
미래에 발생할 위험을 예상하고 엔지니어링으로 보완. 저의 경우 데이터 양이 늘어남에 따라 검색의 속도가 느려지는 일이 발생하곤 했습니다.
-
일반적인 사례를 하나 들어보도록 하겠습니다. 웹앱 프로젝트를 진행할 때였습니다. 회원가입 과정에서, 이메일이 이미 가입되었는지 중복체크하는 기능을 지원해야 했습니다. UX는 버튼 없이, 키보드 입력이 일정 시간 멈추면 검사하는 debounce 형태로 설계된 상태였습니다.
회원가입 여부는 서버 측에서 알고 있으므로, 별도의 HTTP API를 개발해 뒀습니다. API 호출량이 꽤 많은데, 계속 DB에 쿼리를 하고 있으니 in-memory caching을 통해 최적화해 보자는 이야기가 나왔습니다. feasibility check를 할 필요가 있었습니다. 최근 2주간의 로그를 덤프해서 실험을 해 봤습니다. hit rate가 얼마나 되는지, eviction이 얼마나 일어나는지, cache entry가 얼마나 빠르게 메모리 할당량을 도달하는지를 측정했습니다.
예상하겠지만, 이메일은 사람 수만큼 다양합니다. 따라서 대부분의 경우 cache miss가 발생했습니다. 게다가 debounce에 의해 아직 미완성된 내용도 API를 호출하니 cache entry가 빠르게 늘어나 eviction이 자주 발생했습니다. Hit rate가 낮은 캐싱은 의미가 적습니다. 또한 기존에 날리던 SQL SELECT문도 covering index인 쿼리였으므로, 시스템이 잘 유지될 가능성이 높아 보였습니다. 그렇게 caching 작업은 진행하지 않았고, 2년이 넘게 지난 지금도 잘 동작하고 있습니다.
사실 cache를 별 생각 없이 붙였어도 대충 잘 돌아갔을 일입니다. 메모리 최대치를 설정하므로, 적어도 문제가 되었을 가능성은 적습니다. 하지만 그것이 시스템을 정말로 개선하는 일은 아니었을 것입니다.
-
결정의 근거는 데이터가 되어야 합니다. “당연히 그럴텐데 데이터까지 봐야 하냐?”같은 추정은 설득력이 부족합니다. 데이터가 없는 것이 문제라면 수집하는 것이 먼저입니다. 데이터 기반 의사결정이 느리다는 반론도 많은데, 개인적으로는 가설, 추정, 주관을 근거로 한 의견과 토론하는 것이 더 어렵고 힘들었습니다.
그들이 침범하지 않을 거라 믿지 말고 내가 철저히 대비하고 있음을 믿어야 한다.
<세조실록>에 기록된 세조의 말입니다. 철저한 리스크 관리를 강조한 것입니다. 소프트웨어가 생활과 점점 밀접해지고 있는 요즘, 리스크 관리도 대충 할 수가 없게 되어가고 있습니다. 오래된 주제인 해킹에 대한 위협 뿐만이 아니라, 로직의 문제로 소프트웨어가 먹통이 되면 사람의 목숨이 위험해지기도 합니다. 테슬라의 자동차가 소프트웨어에 강하게 의존하고 있는 것을 예로 들 수 있습니다.
사건사고가 발생하고 나면, 재발 방지를 위한 시스템을 만들기 위해 힘씁니다. 소프트웨어도 그래야 하며 앞번의 글에서 한 차례 언급한 적 있습니다. 그러나 재발 방지는 사후의 일이며, 당연히 사전에 조치해 문제가 발생할 가능성을 줄이는 것이 좋습니다.
상상력이 뛰어난 사람들이 있습니다. ‘내가 만든 이 기능을 누군가 온 힘을 다해 뚫으려고 하면 어쩌지?’ 하는 생각으로 방어적인 로직을 작성하는 습관이 들어 있었습니다. 무엇이든 최소/최대값을 정하려고 하고, 이를 위해 기획자와 커뮤니케이션을 망설이지 않는 모습을 보였습니다. 예를 들어,
“이미지 업로드 기능에 validation이 더 필요합니다. 확장자를 png로 제한하고, 최대 용량을 10MB로 제한하는 것이 어떨까 하는데 기획 업데이트 가능할까요?”
“게시글 제목에 최대 길이 제한이 있어야 할 것 같습니다. 너무 과도한 제한은 없어도 되고, hard limit을 둔다는 입장에서 1,000글자 이상을 사용할 수 없도록 만들 수 있을까요?”
“이메일 인증 코드 전송을 현재 마음껏 할 수 있는 상태입니다. 비용과 연관되어 있는 기능이라, 트롤링의 여지를 없애는 게 좋을 것 같습니다. IP를 기준 삼거나 세션을 사용해, 일정 시간 내에는 이메일 전송을 재시도하지 못 하도록 제한하는 것이 어떨까요?”
잘 하기 위한 방법을 찾자.
현재의 시스템만 보고 개발 조직의 수준을 평가하려 들지 말자. 존중하자.
대부분의 프로젝트는 순조롭게 진행되지 않는다. 이성적으로 대응하고 팀의 혼란을 최소화할 수 있도록 커버하자.
오버엔지니어링을 경계하되, 수용도가 높은 시스템을 설계하는 적정 엔지니어링을 하자.
시스템이 더 개선되려면 무엇이 필요한지 생각하자.
위임을 받고, 일의 난이도를 높여 알아서 잘 하는 사람이 되자.
우리에게 맞는 기술과 문화를 찾자.
타당성 조사를 통해 의미 있는 일을 하자.
위협을 예측하고 미리 보완하는 사전 조치를 신경쓰자.