2022 회고

HYUNGU, KANG·2022년 12월 31일
3

이런저런 이야기들

목록 보기
8/12
post-thumbnail

돌아보면 개발 이외의 것들은 모두 흐릿하게 기억나는 만큼 치열한 2022년이었다.

유일하게 선명히 기억나는건 4월 즈음 구글에서 날아온 이메일 한 통 뿐,, 3월 한달동안 내가 3km 밖에 안걸었다는..

6~7월까지는 일에 파묻혀 살다보니 휴식 시간에는 동굴안에 들어가서 나를 온전히 돌아볼 충분한 시간도 없이 그저 지친 몸을 휴식하는데 바빴고
잠과 일이 반복되는 루틴속에서 무언가 다른 생각을 골똘하게 할 일도 없거니와, 일조차도 혼자 해서 사람과 육성으로 대화할 일이 없다보니, 감정조차 결핍에 가까운 상태였던것 같다. 과장되게 기억이 남아서 실제로는 아닐 수 있지만 🙄

그렇게 2022년의 3/4을 지내서 그런지, 마지막 분기엔 연애/인간 관계/직장/여러 제안들을 포함해서 이런 저런 생각과 감정들을 느낄만한 일들이 감사하게도 많았다.
그 계기들 덕분에 여러 측면에서 컴포트존에 갇혀있는 나를 제대로 볼 수 있었고, 배가 튀어나온 지금 내 모습은 내가 상상하던 30대의 모습이 전혀 아니었다.
덕분에 나 자신을 리프레이밍하고 인생관을 재설계하고 내/외적인 변화를 시작하는 시발점으로 삼을 수 있었다.
내 한계를 인정했고, 더 높은 목표를 세울 필요가 있다고 생각이 들었다.

조금 이른 회고 에서도 짧게 작성했었지만, 올해에 대한 너무 짧은 감상평이었고..
면허도 따고 작성 시점 이후로 많은 일들이 있었기 때문에, 어떤 일들이 더 있었고 내년엔 어떤것들을 할것인지 다시 한번 작성을 해본다.

2022년은 아래와 같이 세가지 키워드로 설명이 될 수 있을것 같다.

  • work and life
  • relationships
  • think and ego

Work and life

밸런스

그동안 갈고 닦아왔던 실력을 회사에 증명을 한다고 생각을 하기도 했었고, 온전하게 개발에 집중을 했다고 생각되는 한 해였다.

하지만 9월에 절실하게 느꼈던것은... 재미있고 사랑하고 오랫동안 하고 싶은 일이지만, 내 삶의 전부가 아니라는것이다.
결국 일도 삶의 일부이고, 좋아하고 오랫동안 하고싶다면 장기적 관점에서 바라봐야 한다.

인정하기 싫었지만 일 또한 사람처럼 거리를 적당히 유지해야 오래 간다는 것

내 리소스를 다른 무언가를 위해서 사용하는 일이라면, 인간은 결국 보상에 대해서 기대를 하게된다. (여기에서는 나와 회사이다.)
당연히 월급으로 보상을 해주지만, 회사에서 원한다거나 향상심이 있는 개발자라면 따라오는 야근으로 인한 추가적인 리소스 소비가 있다.

이 보상 심리와 기대 라는것은 리소스를 쓰면 쓸수록 눈덩이처럼 굴러 커지는데.. 이 거대한 눈덩이를 맞기 전에 회사에서 깨부숴 주어야 다시 열심히 굴리는데, 올해 나의 눈덩이를 회사에서 부숴주지 못했고.. 나는 이 눈덩이를 직격으로 맞았다.

커리어를 성장시키고 싶다면 노력하고 몰입하는 태도는 "당연히" 필요하지만, 휴식 없이 달리기만 하는것은 동시간 대비 효율이 상당히 떨어진다.
휴식이야 일이 끝난뒤에 틈틈히 취하기는 했지만, 이제는 반대로 행할 시간이 온 것 같다.

휴식하는 시간을 정해두고, 남는 시간에 일을 하자. 휴식이라도 해둬야 맞았을때 덜아프다.

아무튼, 조금 더 일에서 멀어져야 몸과 마음이 건강해지겠다고 생각했다.

커리어

올해는 두개의 라이브러리를 바닥부터 새롭게 만들고 배포했다.
Calls SDK for React-Native 그리고 UIKit for React-Native.

사실 라이브러리 배포나, backward 를 고려한 개발등, 라이브러리를 개발하는데 있어서 필요한 대부분의 경험들은 사운드짐에서 혼자 있을때 충분히 시도를 해본터라 일적으로 어려운것은 손에 꼽았다.
Self-service 에 너무 익숙해져서 그럴까? 내가 원하는 방향으로 구성하고 디자인하고 설계하고, 다른 플랫폼 프로덕트와 인터페이스를 맞추고.. 그동안 갈고 닦은것을 뽐내는 느낌이었달까. 작업의 대부분이 내가 다 익숙하게 해왔던것이었고 재미있었고, 완벽하진 않았지만 원하는 퀄리티로 힘써서 빠르게 잘 해낸것 같다.

오히려 라이브러리를 사용하는 사람들과의 커뮤니케이션이 더 어려웠다. 상상 이상이었고, 이 부분에서 제일 스트레스가 많았다.😵
어느정도 수준까지 내려와야, 일반적인 개발자들이 라이브러리를 범용적으로 사용할 수 있는지에 대한 생각을 많이 던져준 경험이었다.
덕분에 이 길을 계속 걸어갈것인가에 대한 물음표는 이미 생겨버렸고, 이 또한 조금 더 고민을 해봐야 답이 나올것 같다.

UIKit

React-Native 의 특성상 커뮤니티에서 만들어진 네이티브 모듈이 많았기 때문에 Native 관련된 라이브러리들은 모두 인터페이스를 구현하는 식으록 설계했다.
사실 인터페이스라는 개념 자체가 프로그램 설계의 대부분을 차지한다고 생각하는 나로서는, 디자인 패턴을 외워두고 명확하게 구분하지는 못하(않)는데, Adapter 로 볼 수 있을것 같다.

Navigation 또한 지금은 react-navigation 이 주류가 됐지만, 고객사를 상대해야하는 특수성이 있는 이상 레거시 프로젝트가 있을 수 있기때문에, 기능을 화면 단위로(Fragment) 만 제공을 하고 Navigation 핸들러와 링크를 하는것은 개발자에게 모두 위임을 했다.
예를 들면 채팅 목록 화면은 GroupChannelListFragment, 채팅 화면은 GroupChannelFragment 컴포넌트에 각각 렌더링이 되는데
이를 고객이 본인이 사용하는 Navigation 연결하고, Fragment 컴포넌트의 props 에 화면 이동하는 함수를 직접 선언을 해줘야 한다.

각 화면 단위인 Fragment 는 하나의 Module 로 구성이 되어 있는데, 이 모듈은 여러개의 컴포넌트로 구성이 돼있다.

예를 들면 GroupChannelFragment 의 경우에는 GroupChannelModule 을 사용해서 화면이 그려지고

GroupChannelModuleProvider, Header, MessageList, Input 컴포넌트 등으로 구성이 된다.

그래서 유저가 특정 화면의 컴포넌트를 교체하고 싶을때는, 모듈을 생성할때 컴포넌트 교체만 하면 쉽게 갈아치울 수 있도록 설계했다.

const GroupChannelFragment = createGroupChannelFragment({
  Header: (props) => <Text onPress={props.onPressHeaderRight}>{'My custom header'}</Text>,
});

const createGroupChannelFragment = (initModule?: Partial<GroupChannelModule>): GroupChannelFragment => {
  const GroupChannelModule = createGroupChannelModule(initModule);
  return (props: GroupChannelFragmentProps) => {
    
    // ... business logic
    
    return (
      <GroupChannelModule.Provider
        channel={channel}
        enableTypingIndicator={enableTypingIndicator}
        keyboardAvoidOffset={keyboardAvoidOffset}
      >
        <GroupChannelModule.Header />
        <StatusComposition loading={loading} LoadingComponent={<GroupChannelModule.StatusLoading />}>
          <GroupChannelModule.MessageList />
          <GroupChannelModule.Input />
        </StatusComposition>
      </GroupChannelModule.Provider>
    );
  }
}

이렇게 strict 한 구조가 있다는것은, 유지보수나 추가적인 개발을 할 때에도 모두가 정해진 rule 을 따라서 동일한 코드 구조를 유지할 수 있는 이점도 있고, 이는 새로운 인원이 왔을때 빠르게 프로덕트 이해도를 높이고 설계에 불필요한 고민을 덜어내는데 도움을 준다. 새로운 화면을 추가할때 스크립트로 템플릿을 생성하고(scalffolding) 시간을 줄일 수 있는 이점도 있다.

추가적으로 각 컴포넌트를 개발하고 모듈로 합쳐서 코드를 작성하는 부분에서도 깔끔한 구조를 확보할 수 있었다.
다만 아쉬운 부분이 있다면, 명확하게 어떤 책임들을 Fragment 에서 정의하고 모듈로 전달할것인가에 대한 부분을 정의하지 못했다는것이다.
때문에 각 계층별 책임이 조금 불분명해져 버렸고, 이미 레거시가 되어버렸다.
다음번에 설계를 한다면, 레이어와 책임에 대한 영역을 조금 더 깊게 생각해봐야겠다.

기타 경험

react-native-calls 를 만드는것은 이미 개발된 native sdk 가 있어서, 크게 어렵지 않았다.
간단한 native module 을 만드는 경험은 몇번 있었지만, native component 를 만드는 경험은 처음이었고, 때문에 나름 가치있는 경험이었다.

다만 샘플을 만들때, voip 와 같은 기능들은 native 의 실행 사이클에 심하게 의존이 되어있어서
app 이 켜진 이후에 js context 가 생성되는 react-native 의 특성상 이 부분이 조금 골치아팠다.

예를 들면, voip 에 의해서 app 이 켜지고 js context 가 생성되고 react-native 가 사용이 될 수 있는 상태에서 voip 에 관련된 로직이 실행되면서 정보들이 들어와야 하는데, 이 부분에 대해서 이해도가 없으면 react-native 환경이 만들어지기 전에 voip 관련 로직들이 실행이 되어버리고, 이후에 react-native 환경이 만들어져서 순서가 맞지 않아버리는 등.. 아무튼 그런 몇몇 이슈들이 있었지만 어찌저찌 잘 만들었다.

--

내가 입사했을때는, chat sdk v4 가 사내에서 한창 작업중이었는데 3~4월 즈음에 슬슬 릴리즈를 준비하는것 같았다.
난 chat sdk 팀은 아니었지만, typescript 와 module 에 대해서 경험이 있었기에
v4 부터 도입되는 tree shaking 그리고 그를 위해서 모듈화된 코드들을 ts 로 컴파일 하는데 도움을 주기로 했다.

SDK 를 init 할 때 분리되어있는 모듈을 import 하지 않으면 코드가 분리되어야 했다.
큰 문제가 있었는데.. 이 분리된 모듈들의 엔트리별로 typescript 코드를 읽어서, 정확하게 모듈별로 dts 를 분리를 해내는 rollup 플러그인이 없었다.
명확히 말하면 javascript 코드들은 모듈별로 잘 분리가 되는데...
type definition 파일들이, 모든 파일에 대해서 추출이 되거나, named exports 가 아닌 부분들에서 충돌이 발생한다거나 했다.
또 노출되기를 원하지 않는 interface definition 들을 제거할수도 없었다.

그래서 javascript 는 rollup 을 이용해서 추출하도록 하고, type definition(dts) 파일들만 별도로 추출하는 dts-compiler 라는 툴을 내부에 typescript compiler 와 api-extractor 를 사용해서 만들었다.
레퍼런스가 있기는 했는데, 거의 초기 구조만 익히는데 도움이 되는정도여서 AST viewer 로 tree 를 까보면서 만들었다.

  1. api-extractor 를 사용해서 각 entry 파일(모듈)별로 dts 파일들을 추출해내고
  2. typescript compiler 를 사용하여, 추출한 모든 타입들을 중복을 제거하여 단일 파일에 몰아넣고, 단일 파일에서 필요한 전처리(노출하지 않을 인터페이스 제거 등)를 한 뒤에
  3. 모듈 파일별로 re-exports 하는 식으로 작성했다.

다만 문제점이 모듈별로 re-exports 를 해주어도, IDE 별로 라이브러리의 타입을 인식하고 auto-import 를 하는 기준이 달랐는데
Webstorm 의 경우 단일 파일을 디렉토리 뎁스를 높여서 넣어놓고, package.json 에 작성한대로 파일들의 위치를 플랫하게 일치시켜놓으면 정상적으로 auto-import 가 되는 반면, VSCode 에서는 이런식으로 각 모듈들을 import 를 한번씩 해 줘야 정상적으로 인식을 했다.

*이런 기준 때문에 VSCode 에서는 단일 파일에서 import 하는 순간, auto-import 를 모두 가장 상위인 단일 파일에서 꺼내오는 이슈가 있다.

*Metro bundler 에서도 package.json exports 를 인식하지 못하는 이슈가 있어서, 파일 경로들을 플랫한 구조로 만든 이유도 있다.

오픈소스

React-Native 에 두개의 Contribution 을 했다! 🦄
내 커리어의 70% 인 기술에 기여를 하니 감동이 남달랐다. 이제 어디가서, "나 RN 컨트리뷰터야" 를 시전할 수 있다.

하나는 회사에 들어온지 얼마 안됐을때, Android 에서 SDK 의 일부 API 가 정상적으로 전송이 되지 않는것을 발견하고는 해결한 이슈이였다.
문제 자체는 코드에 고려되지 못한 예외 케이스가 있었던것이었고, 해결 자체도 조건을 하나 추가하는정도로 수정이 될만큼 심플했다.

다른 하나는 꽤 오래전에 만들어둔 iOS 에 한글 work-break 지원이 되도록 추가한 PR이었는데, 그동안 Fabric 아키텍쳐가 추가 되면서 Fabric 아키텍쳐 컴포넌트에도 추가를 해줘야 했다.
확실히 느꼈던건, 2021년에 PR을 열기 위해서 작업을 할때는 코드 수정이 어려웠는데, Fabric 컴포넌트에 추가를 할때는 크게 어렵지가 않았다.
내 실력이 늘었거나 아키텍쳐가 단순하게 변경이 됐거나 일텐데, 솔직히 큰 수정사항은 아니라서 가늠이 안간다.

--

정기적으로 월 1~2만원 정도는 오픈소스 프로젝트들에 후원을 꾸준히 하고 있었는데 고민끝에 중순즈음에 중단했다.
이유는 투자나 경제 흐름이 안좋아서인게 영향도 있었지만, 디자인 저작권료를 지급해주던 계약사에서 사업자 양수양도를 진행해버리는 바람에 트러블이 생기면서 취미 자금에 문제가 생긴게 원인이 가장 컸다.
사실 큰 돈은 아니지만, 계획을 벗어나서 돈을 쓰는건 마음에 안들어서 과감히 중단했다. 다시 상황이 좋아지거나, 내년 계획 중 일부인 월 소득을 높이는게 마무리가 된다면 다시 시작을 하지 않을까 생각해본다.

사이드 프로젝트와 배움

올해엔 진행한 사이드 프로젝트가 없다.

진짜 없었다.

12월 31일에, 신년 목표를 세우고 trends 를 파악하고 instagram story 에 공유할 수 있는 프로젝트를 잠깐 해볼까 생각했으나 접었다.

--

2022년에는 기술을 배우기보다는, 배움을 나누는 법을 많이 배웠다.

내년에는 동영상 강의나 콘텐츠도 계획하고 있기 때문에, otterji 에게 지식을 나누면서 겸사겸사 톤이나 발음 그리고 말할때의 습관 같은것도 교정하기 위해 레코딩도 조금 해뒀다. (요 공유한 지식에 기반해서 경쟁 상대로, 발표 또한 함께 했는데 뿌듯했다. Fastlane 영상 / 슬라이드)

react-native-seoul 오프라인 밋업이 올해부터 다시 시작을 하게돼서 참여를 했는데
바쁜 와중에 조장이 되고.. 사다리 타기로 발표자로 당첨이 되면서 조원들과 함께 자료를 준비하고..
(그 후에 알게된 사다리 타기 확률 높이는법: https://www.youtube.com/watch?v=NjIsRV7xnHs)

그래도 조원들이 잘 따라와줘서, FlatList 에 관련된 발표를 준비하고 마칠 수 있었다. (FlatList 영상 / 슬라이드)
시간이 부족하다보니 자료만 준비하고 발표는 거의 리딩만 해서, 개인적으로 완벽하지 못한 프레젠테이션이라 조금 아쉬웠다.

대학생때나 사람들 앞에 섰지 졸업 이후에는 그럴 기회가 없었는데, 정말 오랜만에 사람들 앞에 서서 재밌었다.

뭔가를 배우는것은, calls 라이브러리를 만들면서 Kotlin 을 학습하고 사용한 정도?
Rust 는 배워보려 했으나, 지금은 라이브러리 레퍼런스만 수집하고 있다... 내년에 도전해보려 한다.
그냥 개인적으로 Rust 를 배우지 않는다면, 5년 후에는 굉장히 뒤쳐져 있는 개발자가 될것같은 느낌이다.

면허

나에게는 운전이라는게 수능이나 군대처럼, 언젠가는 하겠지만 지금 당장은 아니라서 와닿지 않는 그런 일이었는데, 드디어 결착을 냈다.

학원을 다니기엔 시간과 돈이 아까워서 실내 운전연습과 여자친구 차로 연습을 하고 시험을 봤고
다행히도 장내 기능만 처음 한번 떨어지고, 나머지는 한번에 붙었다. (아이러니 하게도 면허 시험장은 차가 있어야 가기 편하겠더라)

처음엔 도로만 나가면 멘붕오고, 이건 뭐 거의 종합 스포츠 마냥 신경 쓸게 많아서 어려웠는데
확실히 인간은 적응의 동물이라고... 몇번 하다보니 할만해져서, 면허따고 한달만에 gv70 계약도 해버렸다😤 아무튼 활동 반경이 확 넓어져서 대만족이다.


Relationships

감정이 깊어지고 생각이 많아지면 인생이 흔들리고 다시 단단히 자리잡는다.
일만 하느라 지쳐있었는데, 이런 저런 사람들 덕분에 옛날 생각도 나고 여러 감정을 느끼고 생각들도 많이 하면서 풍부한 한해로 마무리 될 수 있었다.
5년 전은 내가 어떤 대화를 좋아하는지 명확하게 알 수 있었으면서도 철학적인 물음을 많이 던졌고, 인생의 한페이지에 결론을 내린 해였었는데 그때의 생각이 특히나 많이 났다. 거기에 그치지 않고 파생되어 다른 이런저런 생각거리들을 나에게 던져주기도 했고.

시간과 경험을 가장 중요하게 생각하는 나에게는 특히나 올해의 끝자락이 더 특별하게 다가왔는데, 올해가 일만 하고 아무런 결과 없는 한해로 마무리되지 않았기 때문이다.
내가 바라는 결혼과 이성관에 대해서도 한번 더 생각을 해보고 고민을 해볼 수 있는 계기도 있었고.
내년 초는 여러가지에 대해서 답을 찾는 시기가 되지 않을까 한다. 이게 삼십대인가?


Think and ego

12월에는 중요한것은 꺾이지 않는 마음 이란 문구를 보면서, 눈물도 찔끔 흘리고 많은 생각을 하며
일뿐만 아니라 한 사람의 인생을 구성하는 여러 분야에서 적용되는 일차적인 깨달음들이 있었다.

  • 모든 선택은 내가 하는 것이다.
  • 대체 불가능한 선택지는 없다.
  • 선택지를 다양하게 얻기 위해서는, 나의 가치가 높아야 한다.
  • 가치가 높으면 증명하려 애쓸 필요도 없다.

그리하여..

이것 저것 재밌어 보이는걸 해보려는 생각이 대강 있었지만, 필요 없는것들은 과감하게 끊어내지 않을까 한다.
내년은 아래의 우선 순위를 목표로 나를 깎아서 가치를 한차원 더 높이는데 집중하는 한 해가 될것 같다 🫠

  • 시간을 소비하는 만큼 정신/물질적인 가치를 주지 않는것들 끊어내기.
    관점에 따라서는 모든것들이 대상이 될 수 있을 것 같다.
  • 월 고정소득 높이기.
    돈이 많으면 시간의 질과 양을 확보하는데 유리하다는걸 더욱 느끼고 있다. 꿈은 크게 가지라고 구체적인 목표는 800~1100만원이 될 것 같다.
  • 운동 꾸준히 하기.
    지속중이다. 체지방 감소, 골격근량 증가 순으로 목표를 정하고 진행하고 있다.
  • 지속 가능한 취미 찾기.
    월 2회는 꾸준히 할 수 있는 취미를 찾는게 목표다. 요리 혹은 복싱/테니스/실내 볼더링같은 스포츠를 일단 생각중이다.
  • 영어를 본격적으로 학습해보기.
    수준과는 상관없이, 스피킹을 겁내지 않고 하는게 목표이다.

(구체적인 액션 플랜들은 사적이므로 생략하겠다.)


장래희망이 초등학생때부터 대학생이 될때까지 단 한번도 바뀐적이 없을 정도로 프로그래머가 되는게 꿈이었다.
적성에도 너무나 잘 맞아서 이 일을 사랑하고, 좋아하는 사람들과 이런 일을 한다는게 너무나도 운이 좋고 감사하고 행복한 일이다.

지금 내 모습도 좋지만 이대로 가다간 올라갈 천장이 더이상 많이 남지 않았다는 생각이 든다. (개발 자체가 아닌 커리어나 인생 관점에서)
개발이 이제 다른 꿈을 위한 수단이 되어야 하지 않을까 하는 생각을 해보면서, 2022년을 마무리 해본다.

profile
JavaScript, TypeScript and React-Native

0개의 댓글