퇴사 그리고 이직, 그 다음.

5년의 마침표..

2014년 11월, 레진에 합류하여 2019년 7월 퇴직때까지 거의 5년 이란 시간을 보내왔다. 레진의 기억은 사람으로 시작해서 사람으로 끝난 회사의 느낌이다. 레진에 입사하기로 마음 먹은 것도 레진의 구성원들이 너무나 좋았기 때문에 그 가운데 나도 들어가고 싶다라는 열망이 컸었고, 반대로 퇴사할 때는 내가 더 이상 누군가에게 자극을 줄 수 없는 퇴물이 되어버렸나..라는 자괴감(?)으로 인해 내 커리어의 불안함을 해소하고, 내가 줄 수 없으니 다시 다른 사람으로 부터 자극을 받고 싶었다. 언제나 그렇지만 난 나를 위한 결정들을 해왔다. 간혹 주변에서 나의 푸념을 듣고 너무 남을 위하는 것 아니냐 라는 말을 종종 듣는데, 사실 딱히 그렇지 않다. 나는 이기적이고, 역시 사람은 이기적인 것. 하지만 여러 가지 힘든 상황에 있는 팀을 두고 이직을 결심했을 때, 미안한 마음과 안타까움은 사실 아직도 쉽게 지워지지는 않는다. 이것은 시간이 지나야 해결될 것이고, 이전 회사가 내가 있을 때보다 더욱 잘되어서 내가 왜 퇴사했지? 라는 부러운 마음이 들도록 응원하는 것이 위선적인 위로일 것 같다. 일단 그래도 유명한 퇴사짤들 처럼. 마침표를 찍으니 후련했다.

이직 과정.

나이가 들수록 이직의 코스트는 상당하다. 새로운 분야로의 전환은 어렵고, 기존의 것들은 연차에 맞게 또는 상대의 기대수준에 맞게 높아야하며, 낮은 연봉은 가족에게 부담이 된다. 이런 복잡하고 힘든 상황에서도 이번 이직을 마음 먹기로하고 결정한 사항은 바로 “해외취업”이 었다. 이미 결론을 말하자면 해외취업은 실패했고, 현재의 회사에 합류하게 되었다. 우리 아이들의 나이가 더 많아기전에, 그리고 나의 기술력이 더 떨어지기 전에 적정한 몸값을 받을 수 있는 해외 회사로 나가려고 정말 많은 곳에 이력서를 제출하고 면접을 봤다. 지금 이야기지만 초반에 너무 대형회사에 시도한 것이 조금 작전 실패였다. 해외 면접의 연습을 좀 해보면서 도전했으면 결과가 다르지 않았을까 망상을 해본다. 해외 면접의 결과는 실패이지만 어찌보면 포기라고 볼 수도 있다.(정신승리) 거의 마지막에 진행된 캐나다의 A사 면접이 onsite까지 진행될 시점에 현실적인 이슈들을 정리하고자 와이프님과 이야기해보니, 우리 가족은 한국에서 살아야할 운명이었다. 조금 일찍이 알았더라면 힘들게 면접보고 시간을 쓰지 않아도 되었을껄 이라는 원망과 해외에 나가서 짊어져야할 가장의 불안감과 압박을 피해도 될 것 같다는 안도감이 동시에 밀려왔다. 복잡한 마음으로 이직의 목표가 사라졌다. 이때 살짝 멘탈이 나갔다. 그래도 이미 이직 패달을 밟아서인지 관성으로 멈출 수가 없었다. 레진에서 마음이 멀어져버렸다. 레진에서 기댈 수 있었던 선배가 떠난 다는 소식이 세간에 퍼지면서, 친분때문인지 많은 분들이 나 역시 이직해야하는 것 아니냐는 이야기와 분에 넘치는 자리들의 추천을 많이 해주셨었다. 어찌 보면 그냥 밍기적 거리면서 이직을 포기하려던 나의 멘탈에 불을 붙인 것일 수도 ㅋ. 그러던 와중에 투트랙으로 진행되었던 e사와 카카오가 최종합격을 하게 되었다. e사의 처우가 좋은 상황이었지만, 뼈때리는 선배 개발자 분의 조언으로 카카오로 이직 결정하게 되었다. 복잡한 생각들이 많았지만, 결정했다. 그래 가보자 카카오! 뭔가 슈퍼 개발자들에게 빨대를 꼽을 수 있을거야! 라는 마음으로!

휴식.

레진에는 e사의 최종합격때 퇴사 통보를 하였고 카카오는 퇴사하고 최종합격 통지를 받은 상황이었기에 카카오에 입사일자를 조정해. 인생의 마지막(?) 방학 3주를 보낼 수 있는 찬스를 얻었다. 하지만 여기서 이야기하는 것인데, 아이들이 있으신 분들 중 퇴사때 개인 시간을 보내고 싶은 분들은 방학시즌 퇴사는 비추합니다 ㅋ. 난 인생의 마지막 방학이 애들과 함께하는 방학이 되어 결국 아이들과 그 동안 바빠서 함께하지 못했던 시간을 충전하는 시간으로 보내졌다. 개인의 시간을 가지고 싶었던, 그리고 카카오에 가기전에 작은 프로젝트를 하나 마무리하고 싶었던 플랜은. 뻥 하고 터졌다. 사실 더 부지런하게 꼼꼼히 시간을 보냈다면 할 수 있었지만, 쉬는 시기에 그렇게 타이트한 시간 사용을 하고 싶지않았다. 그래도 아이들과 시간을 많이 보낸 것이 나중에는 절대 후회하지 않는 시간이었을 거라고 생각한다. 쉬는 동안에 그래도 틈틈이 한번 보자. 말로만 했던 주변 지인들을 많이 만나서 이야기 나누고, 그동안 뜸했던 오피스 투어를 쭉 돌면서 언제가 다시 뛰어들지 모르는 스타트업 세상에 연을 이어 놓았다. 3주란 시간 짧게 느껴졌지만 그래도 바쁘게 힐링을 했다.

첫 출근, 첫 업무

결국 그 날이 왔다. 이직 첫 출근. 어색한 마음에 신규인력 교육반에 들어가고 교육 끝에 버디(?)크루와 함께 정말 더 어색하고 묘하게 긴장되는 업무공간에 들어섰다. 아직 3개월 이란 시간 밖에 지나지 않아서, 아직도 업무공간에 들어가는 것에 떨림이 있지만 그 때는 더 떨렸다 ㅋ. 모든게 새롭고 생소한. 하지만 빨리 적응하고 싶었고, 빨리 뭔가 하고 싶었다. 왜냐! 들어오기전에 카카오에 기대한 것들이 컸기 때문에! 입사전에 카카오를 추천해주신 분의 이야기를 들어보니 재미있는 일들이 많이 있었다. 특히 팀에서 사용하는 기술 스택이 너무 내 취향이었기 때문에. 하지만 현실은 사뭇 달랐다. 현장은 현장이다. 레진과 마찬가지로 서비스를 운영하는 팀이다 보니 밀려오는 운영이슈와 신규 피쳐들의 구현. 어디선가 많이 보아왔던 업무 루틴들과 레거시. 거기에다 팀장이 날 뽑아놓고 떠난다는 소식과 첫 업무가… 전혀 생각지 못했던 Rails 업무까지. 살짝 당황했다. 역시 회사는 회사다. 뭐든 완벽한 곳은 없다. 그래도 내가 인복이 많아서 인지 팀원 분들이 너무 좋다. 여기 틈바구니 안에서 잘 자리 잡으면 롱런할 수 있을 것 같다.

그래서.. 내가 해야할.

롱런. 오래 다니기. 근데 내가 귀가 얇고 인내력이 좋지 못해 이런거 잘 못한다. 동기 부여가 떨어지면 또 힘든 결정을 하려들 것이다. 그래서 내가 이 팀에서 할일 들을 찾아서 동기부여가 떨어지지 않는 광맥들을 만들자고 생각했다. 근데 이미 팀에 엄청난 다이아몬드 레거시 광산이 자리잡고 있었다. 존재는 알지만 아무도 건드리지 않으려하는. 그래서 결정했다. 이 광산의 첫 곡괭이질을 내가 함으로써, 식지 않는 동기부여 광맥을 만들기로. ㅋ 어찌 보면 무모할 것도 같지만, 언젠가 누군가는 손을 데야할 것이라면 미루지말고 내가. 그리고 지금의 팀원들을 설득해서 합류시키면 팀에 큰 하나의 마일스톤을 함께 할 수 있는 기회가 생길거로 기대했다. 사실 그래서 아직 곡괭이질은 아니지만 갱도 설계 계획을 팀에 공유했다. 아마 팀원분들이 미심쩍고 불안해할 수 있지만, 혼자가 아니라 같이하면 잘 될거라 생각한다. 이거 붙들고 있으면 시간이 진짜 총알 같이 갈거다. 할거가 너무 많아서 ㅋㅋ. 벌써 재미있고 기대된다.

누가 이 후기겸 일기를 볼지는 모르겠지만, 나 처럼 동기부여 계속 만들며 자기 채찍질하는 것을 좋아하시는 분이 있다면 아래의 공고로 팀에 지원하시길. 듣기로는 T/O가 열려 있는 모양이다.

카카오톡 서버 개발자 모집

팀원분들에게 나의 계획에 참여할 수 있도록 추가 발표자료들을 만들어야한다. 지금도 코드랩을 짜다가 회고를 너무 미루면 못쓸 것 같아 휴식겸 넋두리. 지난달에 회고를 남겨야겠다고 생각했을 때는 쓸 이야기들이 머리속에 가득이었는데, 하루가 다르게 머리가 나빠져 다 까먹었다. 두서없는 나의 일기 회고는 여기서 후다닥 마무리한다.

광맥 프로젝트가 자리를 잡을 시점에 공유해보자.

---------------------------------------- "퇴사 그리고 이직, 그 다음." 끝 ----------------------------------------
project 100

도전 Projects 100!

이게 뭐냐하면 지속적인 학습을 위해 시작하는 프로젝트로 일단 하루에 하나의 알고리즘 문제를 풀어보자는 취지. 사실은 @sjpark이 leetcode 100개 풀었다는 이야기와 카카오에서 진행하는 프로젝트100을 보고 따라하는 개인 toy project. projects로 복수인 것도 이번에는 알고리즘이지만 다음번에는 다른걸로!

Projects 100의 첫 번째!

위에 말한 것 처럼 매일 하나의 알고리즘 문제를 풀자. 아래와 같은 Ground Rule도 있다!

  • easy만 풀자
  • 메인 언어가 아닌 언어로 풀자

어차피 하기로 한거 조금이라도 도움이 되기위해. easy로만 하는 이유는 혹여나 나의 귀차니즘이 난이도를 넘어서면 이 프로젝트가 깨질까봐. 일단 시작한 프로젝트니 한 번은 끝까지 이끌어가기 위함이다.

진행 중인 프로젝트의 repo는 여기를 구경하면 된다.

One more thing

사실 이 글도… 죽어있는 블로그의 health check 정도의 글. ㅋ

---------------------------------------- "project 100" 끝 ----------------------------------------
DDD(Domain-Driven-Design, 도메인 주도 개발)을 익혀보자

DDD?

누가 아재 개그로 예전 노래 “DDD”를 이야기했지만 그것이 아니다, 그리고 TDD와 같은 개발방법론도 아니다 이것은! Domain-Driven-Design 즉, 설계방법론이다.

DDD의 목적은 프로젝트 스택홀더간 모두의 프로젝트 이해와 커뮤니케이션 수단의 통일성을 만들어 기획자부터 개발자까지 프로젝트 커뮤니케이션 코스트 낭비를 최소화하기 위한 설계방법론이다. 조금 더 풀어말하면, 기획자는 개발자들이 고민하는 설계 모듈화와 설계시 고민들에 대해 이해하고 개발자는 기획자들이 생각하는 서비스 도메인과 코어 도메인을 이해하여 어느 부분이 프로젝트의 핵심 가치인지를 분간하고 개발하게된다. 이 과정으로 프로젝트의 Goal을 모두가 동일하게 이해하게된다. 이로인해 프로젝트는 기획에서 설계까지 원하는 방향으로 잘나갈 것을 기대하는 설계 방법론이다.

그렇다면!

과연 이게 잘될까? 어떻게하면 저런 멋진 일이 일어날 수 있을까? 결국 공부해서 적용해보고 시행착오를 겪어봐야할 것이다. 다행히도 새로 합류하게된 팀에서는 몇 개의 프로젝트를 DDD로 수행하고 시행착오 중에 있다. 팀원들이 겪은 시행착오를 빨리 이해하고 앞으로 개선 점들을 같이 고민하기 위해 DDD에 대한 나의 지식을 빨리 끌어올리기위해 학습해보자.

알고 싶은 것들 목록

  • 우선 DDD 방법과 순서

  • DDD로 했을 때 좋은 선례의 package structure들.

    장단점 왜 알고 싶냐? - 개발자이다보니 프로젝트 설계 후 구현시의 고민도 된다. 설계가 잘 마무리되어도 코드레벨의 프로젝트 구조까지 만드는 것은 아니기에 이 부분도 궁금하다. 첫 구조는 차후 바뀌기 힘들고 단순히 묶음 편의성만으로 만든 구조도는 항상 원하는 결과물의 장애가 되었기 때문에, DDD로 했다면 구조 역시 그에 맞는 구조가 있을거라 생각.

  • Event Storming 이후의 개발 프로세스

    신규 개발, 유지보수 시에 개발하는 프로세스들 - 역시 개발자 관점에서 DDD 사후 프로세스에 관심이 있다. DDD는 처음 시작때만 적용되는 것이 아니라 유지보수 시에도 적용된다. 이때도 신규 개발시와 동일하게 적용될지 수정되는 모듈 파트만 진행될지 궁금하다.

  • DDD가 적용되는 범위가 프로젝트 단위인지 아니면 서비스 전체 아키텍쳐인지에 따라서도 고려 사항들이 다를 듯.

    DDD로 만들어질 결과물의 범주가 대/중/소에 따라 개발자들이 고려할 부분이 달라질 것 같다. 프로젝트 크기별로 고민해야할 부분들이 어떻게 다를지 알고 싶다. 예를 들어 프로젝트 별로 라면 DDD package sturcture 설계등의 작은 단위로안에서 고려, 전체 서비스에 대한 아키텍쳐라면 전체 서비스의 환경 구성에 대한 고려 처럼.

학습 참고 자료들

  • Domain Modeling Made Functional - F#
    • 팀에서 스터디로 사용한 책. 이제 읽기 시작….책이 두껍다. 영어다…(ㅠ.ㅠ)
  • Event Storming and Spring with a Splash of DDD

    • DDD 경험이 많다는 Pivotal Advocator가 쓴 글로 DDD에 대해 짧게 오버뷰 한 글. 내용이 좋다. Sample : https://github.com/ddd-by-examples
  • Domain Driven Design - Modeling

    대협님의 글. 개인적인 요점을 잘 정리해놓으셔서, 개념파악 후 내 생각과 비교해서 읽어보기 좋다. 특히 모델링에 관한 부분이 이해하기 좋게 써주셔서 많은 도움이 된다. DDD에서 제일 중요한 것은 결국 도메인 분석과 모델링!

  • Domain Driven Design and package organization

    • DDD에서의 패키지 구조 관련 글, 알고 싶었던 고민 사항에 대해서 어느 정도 해소시켜주는 글이다.
    • 여기서 나오는 구조도
      • 하나의 도메인 패키지 내부에 관련 모든 코드를 한방에 떄려넣기
        • 도메인 관련 코드를 한눈에 볼 수 있어 좋음.
        • 인프라 관련 클래스들이 코어 도메인과 같이 있으면 의존성 관점에서 올바른 설계가 어렵다.
          • 어떤 점이 어려운지 궁금. 생각해보자 - 글에서는 클린 아키텍쳐나 육방(hexagonal) 아키텍쳐설계를 시도하고 싶을때, 도메인로직을 모든 인프라와 의존성 없이 pure하게 만들기가 어렵다는 점을 들었다.
          • clean, hexagonal이 중요하게 생각하는 점이 core logic의 pure 함인지 또 공부 필요
        • 결국 이 글에서는 한방에 떄려 넣는 것 보다는 인프라와 도메인은 패키지 레벨에서 분리해야한다고 주장.
      • First DDD approach : 4 Layers - UI, Application, Domain and Infrastructure (하지만 infra는 설계상 crosscutting concerns에 대한 것 때문에 3개의 기타 레이어에 묶어야함)
        • 패키지 최상단은 4개이지만 Infra하위로 다시 UI, Application, Domain이 만들어지는 구조
        • 장점 : 정적 분석을 통해서 기대하는 의존성을 쉽게 강제화할 수 있다. 기능의 entry point가 Application layer로 모여있다.
          • 찾고 싶은 로직을 관련 기능 코드에서 시작해서 따라 보면 쭉 볼 수 있다.
          • 근데 이건 패키지와 관련이 없어도 볼 수 있는 것 아닐까? 어떤 점이 나은 점인지 잘 모르겠네…
        • 단점 : Verbose(워딩이 길다 정도의 의미), Infra가 너무 내재화되고 직관적이지 않다.
          • 내재화는 많은 고민거리들을 만들어 내는 요인이된다.
            • 모든 3layer의 로직인 infra에 투영(mirroring)이 되어 코드 과부하(복붙같은 느낌?)를 만든다.
            • 투영되는 것은 직관의 문제와도 배치된다. db의 adapter들이 infra의 sub package로 events 하위에 만들어지게 되면 어느 순간 adapter를 찾는 것이 db자체를 찾는 일이된다.
              • 음..이건 무슨 말인지 좀 와닿지가 않네..
      • Second DDD approach 첫 패키징에서 infra쪽 이슈를 해결하기 위한 접근.
        • infra 하위의 각 3layers의 sub 패키징을 제외하고 인프라 기능으로 구분하여 3 layer에 제공하는 형태로 수정
          • 우리가 흔히 작성하는 common 패키지 형식이 됨
  • Java Spring DDD (Domain Driven Design) 설계 방법론 (2) – Project Packaging

    • 여기도 동일한 4 layers.
    • 첫 글의 결론 DDD approach와 동일
    • 하지만 application에 포함되는 비즈로직과 domain에 포함되는 비즈로직의 차이가 뭘까 고민했었는데 그 내용이 살짝 언급되었다. 이걸로 pivotal글과 엮어 생각하면 application은 결국 기타 서비스와 차별점이 되는 application의 주요 비즈로직이 들어가는 곳 정도로 이해가 된다.
  • DDD에 구조도를 찾는 나의 태도에 대한 다른 의견 : https://stackoverflow.com/questions/540130/where-do-i-find-some-good-examples-for-ddd
    • DDD는 코드 결과물에 대한 것이 중요한게 아니고 접근 그 자체에 대한 과정이 중요하다는 것.
    • 구조도는 캐바캐이기 때문에 뭐가 좋다라는 것이 어려운 것임.
    • 그나마 추천한 것은 DDD 책 저자가 만든 샘플 코드 : https://github.com/citerus/dddsample-core
  • DDD on MSA
    • https://medium.com/design-and-tech-co/implementing-domain-driven-design-for-microservice-architecture-26eb0333d72e
  • CQRS FAQ
    • 팀원에게 추천 받은 post
    • 내가 할 법한 질문거리들에 대한 답들이 간결하게 되어있어서, 이해되는 것도 있고 추가로 찾아야할 포인팅으로 접근하기 좋게 정리됨.
    • 덤으로 CQRS관련 질답도 보게됨
  • Wikipedia
    • DDD : https://en.wikipedia.org/wiki/Domain-driven_design
    • Event Storming : https://en.wikipedia.org/wiki/Event_storming
  • Youtube
    • Domain Driven Design - Eric Evans
    • What I’ve learned about DDD since the book - Eric Evans
    • DDD & Microservices: At Last, Some Boundaries - Eric Evans
  • PDF
    • https://www.infoq.com/minibooks/domain-driven-design-quickly/

이해한 것들과 궁금증….and ONE MORE THING!

팀의 결과물에 대한 이야기와 위의 내용들을 접하면서 알게된 점은 그동안 프로젝트를 해오면서 느꼈던 기획과 결과물의 괴리감. 그리고 서로의 상황에 대한 설득의 피로도. 이런 부분들이 많이 개선될 걸로 생각된다. 프로젝트 자체의 완성도에 대한 기대도 당연히 크지만 이런 방법론은 잘 운영이 된다면 팀간의 불화(?)와 불신 등 업무상에 불필요하게 얻게되는 스트레스를 줄여주어 좋은 회사문화를 가꾸는 초석이 될 것이란 생각이다. 항상 개발방법론을 무엇으로 하느냐에 많이 고민을 해왔었는데. 이제서야…DDD란 것을 보고 적용해볼 생각을 하니 기대가 크다. 너무 기대하면 실망도 크다지만 나이들고 나서 보는 팀운영 관점과 프로젝트 운영관점에서 너무 매력적이다. 기대해 보고 싶다.

그리고 One More Thing!

DDD문서들을 접하면 같이 나오는 것이 CQRS다. 이전에 CQRS만 따로 학습해서 알고 있었는데 DDD가 결국 설계시 Command와 Query가 구분이 되기 때문에 자연스럽게 CQRS에 대한 적용이 용이하고 필요하다. 단지 Event Sourcing의 장점을 필두로한 CQRS로만 알고 있다가 DDD 설계 장점을 녹여낼 수 있다는 것을 알게되니 CQRS에 대한 framework들과 library들을 추가로 또 학습해보자!

끝…..이고 싶지만.

앞으로의 시행착오도 쭈욱 남겨보자.

---------------------------------------- "DDD(Domain-Driven-Design, 도메인 주도 개발)을 익혀보자" 끝 ----------------------------------------
2019.05.23 오늘의 구글링

오늘의 구글링

Kotlin + Mybatis : argument mismatch issue

  • 문제점 : kotlin data class로 만든 entity class를 mybatis mapper의 javaType으로 사용하면 argument mismatch가 발생한다.
  • 원인
    • 해당 class의 resultMap이 association을 가지고 있으면 발생한다.
  • 해결
    • data class에 no arguments constructor를 생성하면 해결된다.
    • googling을 해서 찾은 거는 아니고 row 정보로 resultmap constructor를 찾을 때 nested map이 존재하는 경우 no args constructor를 호출하는 부분이 있는 것을 보고 위처럼 해보니 동작함.
    • 시간이 급하여 (no args constructor를 사용하는 이유)[[https://github.com/mybatis/mybatis-3/issues/101]]는 차차 다시 확인해보자
      • 이유는 연속된 nested 객체가 계속 constructor를 사용하게되면 resultmap 객체 생성시 메모리 이슈가 발생한다는 것
    • https://github.com/mybatis/mybatis-3/issues/1382 이것도 참고.
---------------------------------------- "2019.05.23 오늘의 구글링" 끝 ----------------------------------------
2019.05.22 오늘의 구글링

오늘의 구글링

기존 lombok 코드들이 kotlin에서 동작이 안되네.

  • query : kotlin lombok
  • 결과 : delombok..하는 수 밖에
    • mapstruct도 안된다면 이건 우리 프로젝트에서 좀 커다란 문제..kotlin에서는 kotlin용으로 해야하나? 찾아봐야겠다.

MYSQL : You can’t specify target table ‘table’ for update in FROM clause

---------------------------------------- "2019.05.22 오늘의 구글링" 끝 ----------------------------------------