-
7년차 개발자의 번아웃 - 과연 내가 번아웃이 올 자격이 있을까?
개발자의 3, 5, 7년 슬럼프 이야기
2021-12-30 20:12
난 요즘 연차를 일부러 깎아 말하는 경향이 있지만, 굳이 따지면 8년차다. 최근에 번아웃과 8개월 정도를 씨름하다 이제 다시 자리를 잡아가는 중인데, 회고 겸 흑역사 셀프생성 겸 나의 번아웃 전투기를 작성하기로 했다. 올 초 정도인 7년차 쯤 찾아온 번아웃(혹은 슬럼프)의 이야기다. 난 ㄱㅏ끔... 슬럼프가 찾아온다... 주니어때는 직장인의 3.5.7 슬럼프를 우스워했다. 직장인 3/5/7년차마다 슬럼프에 빠진다는 말이 굉장히 우습다고 생각했던 것 같다. 나는 개발이 항상 내 천직이라고 생각했고 (직업만족도 150%) 어떤 때에는 일찍 퇴근하는 것보다 야근하는 게 더 즐거웠던 적이 많았으니, 언젠간 성장 상승곡선이 완만해질 때는 오더라도 하락할 때가 올 거라고는 생각해본 적이 없다. 내가 가장 타격을 받지 않는 말이 (혹은 오히려 화나는 말이) ‘소연님 그렇게 한다고 알아주지 않아요’라며 농담반 진담반으로 퇴근을 보채던 동료들의 잔소리였는데, 난 이 모든 게 정말 좋아서 하는 일이었기 때문에 열두 시를 가리키는 시계 같은 것들은 방해요소라고만 생각했던 적이 있었다. 슬럼프를 이해하지 못했던 3년차 만 2년을 찍고 딱 3년차로 넘어가는 즈음부터 내가 굉장히 날아다녔는데, 일단 주어진 업무에서 어려운 것이 하나도 없었고 무조건 연차가 많다고 테크리딩을 하는게 아니라는 것도 깨달았다. 기회와 권한을 흔쾌히 양보해준 당시 동료들과 매니저 덕분에 무려 3년차가 테크리딩을 했었고, 그 뒤로도 연속으로 4개의 프로젝트를 리딩하며 매해 꾸준하게 높은 동료평가를 받았다. 그래서 그랬는지 슬럼프란 것은 나랑 거리가 먼 개념이라고 생각했다. 3년차 김소연의 모습 5년차에 찾아온 매너리즘은 이직으로 해결이 되었다. 그러다 갑자기 만 5년이 가까워지던 때에 매너리즘이 찾아왔었는데, 매너리즘을 겪던 당시의 가장 큰 고민은 크게 아래 2가지였다. 나와 주변 동료들 간의 온도 차가 다르다고 느껴진다. 생각해보니 난 업무를 잘하는 것이지, 개발을 잘 하는 건 아닌 것 같다. 프로젝트를 테크리딩했지만 어쨌든 동료들의 마인드케어를 하는 매니저는 아니었기 때문에, 나 혹은 동료들보다 프로젝트가 더 중요할 때가 많았다. 어쩔 땐 동료들을 극한으로 몰아가거나 상처를 주기도 했었고, 그런 온도 차를 해결(?)하는 데에 코딩보다 많은 시간을 쏟다 보니 내 모습이 개발자 같다고 느껴지지 않았다. 안된다는 사람들을 보면 될 때까지 안 해서 그렇다고 생각했었다. 그리고 내가 과연 개발자로서 좋은 평가를 받는 게 맞는가? 하는 생각도 자주 들기 시작했던 것 같다. 난 A를 위해서 B를 하는 건데 B를 더 인정받고 있는 기분이랄까. 그러나 그렇게 몇 달을 날 괴롭히던 매너리즘은 이직함으로써 의외로 쉽게 사라졌다. (그전에는 이직이란 선택지를 생각해본 적이 없어서 주어진 상황에서만 문제를 해결하려 했었다.) 환경이 변화 된 후 날 괴롭히던 많은 생각으로부터 편안해졌고, 새로 만난 동료들과 새로운 업무 속에서 긍정적인 동기부여를 받으며 매너리즘은 자연스레 사라지게 되었다. 그때 써놓았던 글을 읽으면 이제는 더 이상 와닿지 않지만, 짠하기도 하고 성숙함과 동시에 미숙했구나 싶다. 그 당시 작성한 글 7년차에 찾아온 번아웃은 이직으로도 해결되지 않는다. 그러다 7년차가 되는 즈음 다시 한번 슬럼프가 찾아왔다. 5년차에 찾아온 슬럼프가 매너리즘이었다면, 7년차에 찾아온 슬럼프는 번아웃이란 단어가 정말 잘 어울린다. 그러나 시간이 많이 지난 지금에야 번아웃이라고 이야기하지만, 사실 처음엔 위의 2~3년전쯤 찾아온 매너리즘 수준 정도의 슬럼프라고 생각했었다. 2~3년전 찾아온 매너리즘은 이직으로 해결을 했으니, 이직이 도움이 될 거라는 착각도 했다. 물론 그렇다고 해서 바로 이직을 결심한 건 아니고 내 나름의 할 수 있는 최대한의 많은 것들을 하고 결정을 내렸다. 임원 알레르기가 있다는 시덥지 않은 농담이나 하던 내가 1차 리더, 2차 리더, 3차 리더, 심지어 (구)리더까지 찾아가며… 나의 슬럼프를 업무를 통해 극복할 수 있도록 노력했다. 나 혹은 파트원들의 슬럼프가 생길 때마다 퇴사자를 만들 수는 없다는 생각이었다. 나와 파트원들의 근무환경을 개선하기 위해서, 회사의 방향에 우리가 공감하고 따라갈 수 있기 위해서, 우리가 정말 잘 할 수 있는 그런 일들을 하기 위해서. 대충 그런 노력과 싸움들을 했다. 이번에도 마찬가지로 내 롤이 꽤 이상해졌다. 내가 이런 것들을 생각보다 잘한다는(wellX not stressfullyO) 사실을 깨달았고, 개발 실력보다는 언변과 추진력이나 책임감 같은 것들로 업무 능력을 인정받고 있다는 기분이 들었다. 게임으로 치자면 스탯을 이상하게 찍었다. 스탯 잘못 찍은 개발자 (추진력 1650/1650, 개발 0/0) 그러던 중에 이직 오퍼를 받았고, 리더들과 길고 긴 상담 끝에 결국엔 새로운 회사로 이직하게 되었다. 그런데 이직을 하면 이 무기력한 매너리즘이 해결이 되어야 하는데 그렇지 않았다. 오히려 더 심해졌다. 그제야 깨달았다. 아 이거 매너리즘 아니구나. 내 번아웃은 더 이상 나의 내일이 기대되지 않는 것이었다. MBTI나 애니어그램 같은 심리/성향 테스트를 하면 공통적으로 나오는 키워드가 ‘성과지향’이다. 난 굉장히 목표지향적이고 낙천적이며 과업을 즐기는 사람이(었)다. 매너리즘은 성장이 잠시 정체되어있던 나에게 성취감을 안겨줌으로써 해결되었던 반면, 번아웃은 그런 과업조차 무게감으로 느껴졌다. 새로운 일이 시작되었는데 전혀 기대되지 않았고, 나를 자극시키는 태스크들이 이제는 내 몸을 눌렀다. 모든 것에 지쳐있었고 업무능률이 저하되고 있음을 느꼈다. ‘워크=라이프’였던 나에게 업무능률의 저하는 삶의 질까지 영향을 미쳤다. 더 이상 내일이 기대되지 않았고, 돌려 막기 하다시피 하루를 끝내면 이제 이 모든 것을 그만하고 싶다는 생각을 종종 했다. 그냥 해이해진 것뿐인데, 왜 나는 예전처럼 다시 추스르고 돌아가지 못하고 있을까? 이제는 그럭저럭 먹고살 만한 건가? 내 꿈을 잊어버렸나? 생각해보니 그렇게 아등바등 살 필요도 없지 않나? 아니 잠깐, 내가 아등바등 살긴 했나? 이쯤 부터 일상 자체도 무기력해지기 시작했다. 그저 1차원적인 쾌락을 쫓는 사람이 되어버렸다. 먹고 싶을 때 먹었고 자고 싶을 때 잤다. 스스로와 타협했고, 날이 갈 수록 책상이 점점 어질러졌다. 재미있는 일이 하나도 없었다. 그러나 난 번아웃이 올 자격이 없다. 내가 번아웃이라고 생각하지 않았던 이유는 단순했다. 난 번아웃이 올 만큼 많은/강도높은/어려운 일을 하지 않았다. 빡세던 첫 회사를 5년을 다녀도 괜찮았는데, 이 정도에서 무슨 번아웃? 그것도 2년밖에 안 다녔는데? 사무실에 출근해서 동료들과 합을 맞출 때는 여전히 재밌다. 딱히 안 쉰 것도 아니다. 아니 오히려 연차 잘 썼다. 좋은 리더와 동료들 덕분에 리프레시 기회도 여러번 받았고 되려 내가 회사에 갚았으면 갚아야했지 못 받은건 없었다. 그런데 그럴때마다 무력함이 더 커져갔다. 전투형 인간인 내가 회피형 인간이 되어가는 것 같았다. 집중도도 자꾸만 떨어지고, 1.5인분을 해도 모자른 마당에 1인분도 못 하고 있다는 기분이 들었다. 심지어 PO를 제안 받을때 평소의 나라면 굉장히 신나고 두근거려야하는데 그때는 부담감으로만 다가왔었다. '번아웃은 핑계고 사실은 그냥 일을 하기 싫은건 아닐까?'하는 죄책감에 괴로워했었다. 진짜 이러다가는 남에게 피해를 끼치겠다 싶을때, 원인을 곰곰히 생각해보기로 했다. 사실 이 단계가 가장 어려웠다. 번아웃 그게 뭔데. 어떻게 하는건데. 관련된 책도 많이 읽어보고 혼자 여행이라도 떠나서 생각할 시간을 가졌더라면, 더 양질의 성찰이 가능했을 것 같다. 그러나 그럴 기력조차 없어서 그냥 가성비 성찰을 했다. 사무실에서 일하기 싫을 때마다 옥상에 올라가며, 출퇴근할때마다 창 밖을 바라보며, 잠 드는게 아쉬워서 눈을 감으며. 한번에 바로 떠올리지는 못했다. 그냥 추적을 하고 또 하다보니 도달한 원인들이다. 1. 내가 컨트롤할 수 없는 업무의 연속 딥러닝 프로젝트를 잠시 할 때 딱 이런 박탈감을 느꼈었는데, 어떠한 데이터를 가지고 최적화된 모델링을 한다는 것이 나에게는 정량적이지도, 정성적이지도 않다고 느껴졌다. 하이퍼파라미터를 미세하게 조정하며 데이터에 맞는 모델을 찾아가는 과정에서 얻은 성과가 나의 능력 같지 않았다. 수상을 했지만 남의 잔치에 와 있는 기분이었다. 그 뒤를 이어서 맡게 된 그 당시의 업무도 마찬가지였다. 분명 나에게 권한이 있긴 한데.. 뭔가 애매하게 있었다. 앱 개발을 하려면 API를 만들어주는 사람이 있어야 하는데, 백엔드 개발 조직에는 나의 권한이 없기 때문에 뭘 할 수가 없었다. 조직장들을 열심히 설득해서 인력을 충원하고 나면 그 인력들은 priority가 더 높은 다른 업무들에 배치되었다. 어느 순간엔 내가 개발자가 아니라 사업을 따러 다니는 사람 같았다. 푸하하.. 그런데 그럴 수밖에 없는 상황이어서 내가 뭘 어떻게 할 수 없었다. 글로 써놓으니 내가 쉽게 포기한 것 같지만 난 장장 2년을 그 환경을 만드는 데에 많은 시간과 마음을 썼다. 홍보하겠다고 기술 블로그도 만들고.. 서버 개발자 입사할 때마다 간이고 쓸개고 다 빼줄 것처럼 엄청 잘해줌.. 여튼 할 수 있는 최대한의 노력을 다하는 것 같은데 상황이 나아지질 않는다는 생각에 박탈감을 많이 느꼈다. 앱이 왜 이렇게 느리냐는데, 가장 잘 해결할 수 있지만 절대 해결하지 못하는 나 2. 과도한 셀프 채찍질 올해 초부터 목표를 달성하는 방식을 바꿨었다. 작년까지는 task 단위였다면 올해는 time 단위로 측정하기 시작했는데, 30분 단위로 내가 무엇을 했는지 기록하는 것이다. 처음에는 원하던 하루의 목표를 이룰 때마다 기뻤다. 그러나 어느 날엔 유튜브를 보거나 친구를 만나면 그날 나의 목표를 이루지 못한 것이 되었다. ‘아 공부를 했어야 했는데..’, ‘책을 읽었어야 했는데..’ 이런 반성을 매일 해야만 했고, 7색 형광펜으로 시간마다 무엇을 했는지 색을 칠하다 보면 빨간색으로 색칠된 ‘유튜브’, ‘넷플릭스’ 칸들이 나에게 잘못된 하루를 보냈다고 혼을 내는 것 같았다. 이 주엔 유튜브도 보지 않았고 약속도 잡지 않았다. 3. 체력의 하락 갑분 체력? 할 수도 있지만 그만큼 번아웃의 원인을 깊게 추적했다. 일차적인 원인은 COVID19일 수도 있지만, 헬스장에 출입할 수 없게 되면서 꽤 오래 지속된 아침 운동 습관이 한 방에 무너졌다. (물론 홈트를 하면 되지만 하지 않음.) 내가 고강도 운동을 했던 건 아니지만, 그 1시간의 운동을 안 함으로써(혹은 그만큼 식사와 술로 스트레스를 풀면서..) 체력이 떨어지고 체중이 늘었다. 2~3개월 정도 쉬다가 다시 운동을 하게 되었는데, 살이 찐 것을 만회하고 싶어서 탄수화물을 잘 안 먹었다. 그랬더니 체력이 더 떨어졌다. 체력을 기르려고 운동을 하는 건데 체력이 없어서 운동이 안 됐다. 쉽게 피곤하고 쉽게 지치는 날들이 계속되었다. 체력을 되찾으려면 체력을 길러오세요. 채찍질의 대가였던 내가 이세계에선 번아웃의 원인? 이런 과정을 통해 내/외부적인 요인이 모두 작용했다는 결론을 내렸다. 다만 외부적인 요인이 주원인이었다면 환경이 바뀜으로써(=이직) 해결이 되어야 했는데 그러고도 번아웃이 지속되는 걸 보니 내부 원인이 더 크다고 생각했다. 난 열심히 살아보려 했던 건데 나 자신을 괴롭히고 있는 꼴이라니. 스스로 불러온 번아웃에 짓눌려 그러다 멈춰보니, 번아웃의 원인을 찾으려 고민하는 과정이 의외로 이 번아웃을 이겨내는 데에 도움이 되고 있었다는 생각을 문득 하게 되었다. 높은 자존감에 감춰져 있던 내가 아닌 지쳐서 보잘것없는 인간 김소연을 돌아보며 지속적인 회고를 했었고, 번아웃 기간 이전의 나를 회고하는 것으로 시작해서 내가 지향하는 것의 본질이 무엇인지에 approach 하는 과정이 꽤 도움이 되었던 것 같다. 돌이켜보니 어느 순간부터 나는 ‘성장하는 나’보다 ‘완벽한 나’만을 사랑하고 있었다. 이걸 깨닫는 데에 참 오랜 시간이 걸렸다. 성장이라 함은 매 순간 더 나아져야 한다는 것이 아니다. 가끔은 절기도 하고 넘어지기도 하는 것이다. 나는 이제 받아들이고 극복해야 한다. 글을 시작할 때 ‘이제 다시 자리를 잡아가는 중’ 이라고 했는데, 나는 아직 이 시행착오의 비용을 받아들이는 과정(아직 싸우는 중)에 있다. 과거의 난 무의식중에 긍정적인 결과만 취급했었고, 긍정적이지 않은 것들은 과정을 잘 포장해서 결과로 만들기도 했었다. 완전한 결과 중심적인 나에게, 불명예스러운 나의 모습을 인정하는 것은 생각보다 많은 용기가 필요했다. 번아웃은 결과 중심의 사고를 하던 내가, 지나온 과정을 깊게 성찰할 수 있던 부정적이고도 특별한 기회다. 그러니 나는 이 번아웃을 끌어안기로 했다. 과정도 나고 결과도 나다. 1. 직무를 변경했다. 번아웃을 해결하려고 이직한 게 아니라 번아웃 중에 이직을 한 것이지만, 어쨌든 이직하면서 직무를 변경했었다. 6년 동안 앱 개발을 하다 보니 업무에 있어서 더는 어려운 게 없었고, 할만한 수준을 넘어 재미없는 수준까지 왔었던 것 같다. 어차피 은퇴할 때까지 앱 개발만 하다가 늙을 것은 아니니 다른 것을 해보자는 결론을 내렸다. 그렇게 이직 후 현재는 풀스택 웹 개발자로 일하고 있다. 이 자체가 번아웃 해결에 직접적인 도움이 되진 않았지만, 적어도 새로 이직한 상황에서 민폐를 끼치면 안 된다는 생각에 번아웃을 극복하려고 마음먹을 수 있는 계기가 되었던 것 같다. 그리고 또다시 새로운 동기부여를 줄 수 있다는 점에서 일상에는 변화가 찾아왔으므로 꽤 시기적절한 선택이었던 것 같다. 2. 주 단위의 주기적인 회고를 시작했다. 원인을 숙청하는 걸 넘어서, 이제까지 서툴렀던 Self-care를 앞으로는 좀 더 잘 해내고 싶었다. 나를 되돌아볼 시간이 주기적으로 필요하다고 느끼면서, 단기적인 check point들이 있어야 하고 마인드케어에도 시간을 들이는 것이 중요하다는 생각을 하게 되었다. 무엇보다 번아웃의 원인을 또다시 나에게서 찾아내는 수치를 다시 겪고 싶지 않다는 반성이 가장 크게 작용했다. 다만 앞으로는 이번에 겪었던 과정을 끊임없이 되풀이하며 내 자신에게 시행착오의 비용을 적립해주기로 했다. 결과가 안 좋았어도 과정이 좋았거나, 과정이 아쉬웠어도 결과가 좋다면 긍정적인 것으로 인정하기로 했다. 배운 게 있다면 실패가 아니고 시행착오인 것으로 인정할 것이다. 스스로 꾸준한 실패를 주입하고 적립해서, 번아웃 바이러스를 대비하는 백신을 맞기로 했다. 3. 아침 수영을 다시 등록했다. COVID19가 물론 무섭긴 했지만, 무기력한 내 모습이 더 싫었던 것 같다. 체력을 다시 기르는 게 다른 것보다 중요할 것 같았다. 등록한 뒤로도 여전히 무기력함과 싸우는 중이라 안 나갈 때도 있었지만, 큰맘 먹고 수영을 다녀오고 나면 세상 누구보다 잘살고 있는 것 같아서 “원데이 자존감 pass”가 생긴다. 그리고 적어도 수영 중에는 아무 상념 없이 수영만 하게 되니까 힘든 것도 모르고 즐겁고 재밌기만 하다. 나에게는 또 다른 도피처이자 순기능이다. 혹시라도 번아웃/슬럼프 키워드를 통해 이 글을 보게 되신 분들께 이 짤을 헌정하고 싶다.
-
니들은.. 수동배포 같은거 하지마라.. 😎
Android앱에 Fastlane과 Firebase App Distribution을 통한 CD 자동배포 적용하기
2021-07-17 00:06
재직중인 회사의 기술블로그에 올리브영 안드로이드 테스트앱 자동배포하기라는 제목으로 글을 기재했는데, 사족을 지우고 조금 더 깔끔하게 개인 블로그에도 남겨보고 싶어 글을 일부 수정해서 가져왔다. (회사 블로그에 글을 작성할 땐 왠지 모르게 괜한 사족을 붙여 둥글둥글한 느낌으로 작성하게 된다..) 참고로 부제는 니들은.. 수동배포 같은거 하지마라.. 😎 그럼,, Start~! 📢 테스트앱 올라갔어요! 우리 회사에서 서비스하고 있는 ‘올리브영’ 앱은 PlayStore Beta로 테스트앱 관리를 하고 있었다. feature 단위 건의 개발이 완료되면 버전별로 테스트 앱을 배포하고 QC를 진행하는 방식인데, 가장 기본적인 방법일 수도 있지만 이게 여간 짜증나고 불편한 것이 아니다. 1. 테스트앱을 제공하는데 너무 많은 시간이 걸린다. 개발이 완료되면 앱을 빌드한뒤 플레이스토어에 업로드해야한다. 우선 2차 인증을 거친 구글 로그인을 해야하고 적당한 릴리즈노트와 함께 앱을 업로드하면, 앱파일을 첨부하는데 일정 시간을 소요한뒤에 앱을 제출할 수 있다. 업로드가 완료되면 바로 제공되는 것도 아니고, 약 30분의 ‘출시준비중’ 단계를 대기한 후에 테스터들에게 앱이 제공된다. 2. 앱이 제공되고나면 QA엔지니어에게 직접 알려야한다. 앱이 제공되고나면 QA엔지니어에겐 누가 알려줄까? That’s Me..^^.. 🧚♀️ 앱 업로드 후 30분동안 ‘출시준비중’ 상태를 뺑글뺑글 도는 것을 지켜보다가, 출시가 완료되면 QA엔지니어에게 호다닥 달려가서 알려준다. (호외요 호외~) 3. 테스터가 추가될때마다 일일이 추가해야하고, 오랫동안 기다려야한다. 신규 테스터를 추가하기 위해서는, (1) 플레이스토어 계정을 전달받아야하고 (2) 전달받은 계정에 수기로 권한을 등록해야한다. (3) 권한을 획득한 테스터는 플레이스토어에서 ‘베타 참여하기’ 버튼을 누른 뒤 (4) 약 4시간을 기다려야 테스트앱을 다운받을 수 있다. 이게 진짜 별거 아닌 것 같은데, 많이 들어올 땐 하루에도 몇번씩 이 문의가 들어온다. (바빠 죽겠는데 권한 추가하고 가이드 메일까지 보내줘야함. 환장할 노릇..) 4. 이전 버전을 테스트할 수 없다. 한번에 1개의 버전만 테스트가 가능하다. 그나마 TestFlight는 ‘이전 빌드 보기’통해 과거 버전의 앱도 설치할 수 있어서, iOS는 이 방법으로 기능별 버전을 분리해서 QC를 진행하고 있는데, 플레이스토어는 가장 최신 버전의 앱만 제공할 수 있어 동시다발적으로 여러개의 QC를 태울땐 난감해진다. 또 프로덕트에 앱이 출시되고나면, 자연스레 Beta에 등록된 앱이 이전 버전이 되면서 무효화 되기 때문에 Beta앱을 또 다시 빌드해서 등록해주어야한다. 안 그래도 챙겨야할게 한두개가 아니라 바쁜 배포날.. 또 하나의 배포 태스크인셈.. 매번 할때마다 너무 비효율적이라고 생각했다. 🤷 Bitrise가 아니라 fastlane을 선택한 이유 회사 블로그엔 글을 쓸때 이 부분을 엄청 구구절절하게 썼는데, 사실 원래는 무조건 Bitrise를 쓰고싶었다.. 허락도 받고 예산확보까지 받아놨는데… 내부망에서만 접근가능하도록 구성된 Git 환경 때문에 처참하게 적용 실패했다. 😔 너무 익숙해져서 내부망에서만 접근 가능하다는걸 깜박했던 것 같다. 🧚♀️: 마젤토브 힘내봐.. 마젤토브 빌드해봐.. 🤖: (뭐래..) 근래 블로그에서 했던 드립중에 가장 맘에 드는 드립 Android도 iOS만큼 fastlane과 궁합이 괜찮을까? 굳이 이야기해보자면, 일단 다 떠나서 Firebase Distribution으로 테스트앱을 제공하자는 목표가 1차적으로 설정되어 있었고, 그 과정에서 Firebase의 공식 document에서도 fastlane 연동방법을 공식적으로 안내해주는것을 보고 괜찮겠군 싶었다. 어차피 iOS 앱에도 fastlane 적용중이었고.. 나중엔 젠킨스까지 연동해서 CI까지 쉽게 적용할 수 있을 것 같아서 마음에 들었다. 🎬 본격적인 적용기! 🏃 이제 적용해보자! 자 이제 플랫폼 검토가 끝났으니 적용을 해야한다. Firebase 공식문서인 Distribute Android apps to testers using fastlane을 참고해서 쉽게 적용할 수 있었다. 1. Google 자격증명 획득 서비스 연동을 위해 API키를 생성하고 Google PlayStore에 등록해줘야한다. 스크린샷을 첨부했으나, 회사 보안 지침상 문제가 될만한 내용들은 모두 가렸고 그나마 노출되는 정보는 스크린샷을 촬영하기위한 테스팅 정보들이다. (열심히 가리느라 힘들었다 💦) 1. Google Play Console > 설정 > API 액세스 > 새 서비스 계정 만들기 > Google Cloud Platform 링크 클릭 2. 'Google Play Android Developer' 프로젝트 선택 > 서비스 계정 만들기 클릭 3. 서비스 계정 정보 입력. 이 때 역할을 필수로 '서비스 계정 사용자'로 설정해주어야 한다. 4. 서비스 계정이 생성되었으면, '키 관리' 메뉴로 이동 5. 키 추가 > 새 키 만들기 > JSON > 만들기 클릭 후 생성된 키를 기기에 저장 6. 다시 1번의 Google Play Console로 돌아오면 신규 서비스계정이 생성된것을 확인할 수 있다. 여기서 '액세스 권한 부여' 버튼을 클릭 7. '앱 권한' 메뉴에서 타겟 앱을 설정하고, '계정 권한' 메뉴에서 '관리자 권한'을 부여한 후 '사용자 초대' 버튼을 클릭하여 완료 2. Firebase App Distribution 활성화 Firebase console에서 App Distribution 메뉴에 진입하여 기능을 활성화해준다. 3. fastlane 설치 macOS 기준으로 fastlane 설치하는 방법을 설명한다. 터미널에서 하기 명령어를 실행하여 fastlane을 설치한다. $ brew install fastlane 프로젝트 경로로 이동하여, fastlane을 초기화해준다. 해당 과정에서 패키지명과 위 사전작업 단계에서 설정한 JSON 파일 경로를 입력하게 된다. ~/workspace$ fastlane init (옵션) fastlane이 정상 설치 되었는지 확인하려면 아래 명령어를 입력해준다. ~/workspace$ bundle exec fastlane test 4. fastlane과 Firebase App Distribution 연결 fastlane을 Firebase App Distribution과 연결해준다. ~/workspace$ fastlane add_plugin firebase_app_distribution 하기 명령어를 입력하여 인증을 위한 Google Auth URL을 받아온다. ~/workspace$ bundle exec fastlane run firebase_app_distribution_login > Open the following address in your browser and sign in with your Google account: > https://accounts.google.com/o/oauth2/auth.... 터미널에서 출력된 페이지 URL을 브라우저로 실행하여 인증한 뒤, 반환되는 인증코드를 콘솔에 입력하면 Refresh Token이 발급된다. 해당 토큰을 환경변수로 설정해준다. $ export FIREBASE_TOKEN={token} 5. 배포 lane 설정 마지막으로 배포를 위한 lane 명령어를 생성한다. workspace의 ./fastlane/Fastfile 파일을 열어 하기 블록을 추가해준다. ... desc "Lane for distribution" lane :distribute do gradle( task: "assembleDevelop", build_type: "Release" ) firebase_app_distribution( app: "(Firbase App ID)", groups_file: "fastlane/testers-groups.txt", release_notes_file: "fastlane/release-notes.txt", debug: true ) end 각 설정값 별 상세 옵션은 Firebase App Distribution - 3단계: Fastfile 설정 및 앱 배포 문서에서 확인하실 수 있다. 우리 앱은 앱개발담당자/QA/기획자/협력사 정도로 구분해서 각 테스터들 그룹을 만들고, 해당 그룹의 정보가 위치한 txt 파일을 바라보도록 설정했다. 릴리즈노트도 이런식으로 작성하면 관리에 더 용이하다. 🚀 배포 시작 실행 이제 번거로운 빌드-업로드-배포-확인요청 4단계를, 단 한줄만으로 완료할 수 있다! $ fastlane distribution # 만약 gradle permission dined 오류가 발생한다면 하기 명령어로 권한 부여 후 재시도 해준다. ~/workspace$ chmod +x gradlew 👾 테스터 추가 이제 마지막으로 테스터들을 추가해야한다! 일일이 메일계정을 취합받아서 등록하는 방법과 URL을 통해 직접 참여할 수 있도록 유도하는 방법이 있는데, 당연히 후자로 ㄱㄱ Firebase console에서 초대 링크 > 새 초대 링크 > 그룹 선택 > 링크 만들기 클릭 💁 QA 엔지니어 초대 위에서 만든 링크를 이제 QA 엔지니어들에게 전달하기만하면 된다. QA 엔지니어는 링크를 통해 테스트앱을 설치할 수 있다. 이때, ‘App Tester’라는 앱을 설치하면 향후에도 계속 편하게 테스트앱을 받아볼 수 있다. 테스터들은 링크를 클릭한 후 이메일 주소를 입력하면, 메일에서 Firebase의 친절한 안내를 따라 앱을 설치할 수 있다. 마치며 회사블로그에 글 실으려고 처음으로 만들어본 주작 톡.. 거창하게 자동배포 어쩌고 하긴했는데, 사실 약 반년간 이 프로젝트하면서 비효율적인 부분이 너무 많고 날이 갈면 갈 수록 점점 바빠져서 충분히 개선 될 수 있을 부분들에 더 이상 힘 쏟고 싶지 않았다. 🤢 Firebase App Distribution 적용하는 것도 벼르고 벼르던 일 중에 하나였는데 드디어 해내서 정말 기분 좋다ㅠㅠ! 이제 하루 30분 정도 아꼈으니 일주일동안 약 2시간 정도는 개발 더 할 수 있다.. 🥳 (기뻐야하는데 왜 눈물이 나지..)
-
Github Profile 꾸미기
README.md를 활용한 나만의 깃헙 프로필 만들기
2021-02-24 15:44
작년 여름 Github 신기능으로 프로필 영역을 꾸밀 수 있는 Design Github profile using README.md 포스팅이 공개되었다. 나도 한번 해봐야지하다가 바쁘다는 핑계로 미뤄왔는데, 최근 CV 정리하면서보니 더 이상 미루면 안 될 것 같아서 이제서야 해보았다. 😉 🌈💖✨휘황찬란하고 화려해진 제 프로필 좀 보세요❣️💕💛 프로필 생성하기 GitHub에는 여러 이스터에그가 있는데, username.github.io 이름의 repository를 생성하면 이 블로그처럼 GitHub Pages를 활용한 블로그를 생성할 수 있다. 프로필 또한 이 이스터에그 중 하나로 github user name과 동일한 이름의 repository를 만들면 You found a secret!이라는 메시지와 함께 README.md 파일로 깃헙 프로필을 작성할 수 있음으로 알려준다. Github 접속 > Repository > New 클릭하여 신규 repository를 생성해준 뒤 이름을 본인의 username과 동일하게 입력한다. 생성할 때 Add a README file 항목을 활성화해주면 직접 README.md 파일을 만들지 않아도 된다. 확인 버튼을 누르면 respotiroy가 만들어지고, Add a README file 옵션을 활성화했을 경우에는 README.md 파일이 함께 생성된다. (혹은 직접 만들어도 된다.) 기본으로 'Hi there 👋' 내용이 입력되어있다. 이 때 프로필로 가보면 위의 README.md 파일과 같은 내용으로 프로필 영역이 생긴것을 확인할 수 있다. 힘차게 흔드는 손 발견! 이제 이 README.md 파일을 마음껏 수정해서 프로필 영역을 작성하고 꾸미면 된다. 프로필 꾸미기(1) - 본문 작성 Shields.io : 본문에 뱃지 넣기 나의 경우에는 연락처 정보와 스킬셋 기술을 위해 Shields.io를 사용해서 뱃지를 넣었다. https://img.shields.io/badge/<LABEL>-<MESSAGE>-<COLOR> 형태로 파라미터를 잘 넣어주면 적당한 모양의 뱃지 이미지가 생성된다. 또한 logo, logoColor, labelColor 등의 여러 쿼리를 함께 사용할 수 있다. 예를들어 위처럼 안드로이드 로고와 ‘Android’ 문구가 들어간 연두색의 뱃지를 생성하려면 아래 형식으로 가능하다. <img src="https://img.shields.io/badge/Android-3DDC84?style=flat-square&logo=Android&logoColor=white"/> 색상코드와 사용가능한 로고의 목록은 simpleicons.org에서 확인할 수 있다. 프로필 꾸미기(2) - Pined repo 활용하기 프로필 메인의 repository 고정 영역을 gist를 활용한 여러 라이브러리를 통해 꾸밀 수 있다. 나는 2개의 라이브러리를 사용해서 꾸며봤는데, 커밋시각을 분석해서 아침형 개발자인지 저녁형 개발자인지 알려주는 productive-box와 깃헙 stats를 나타내는 github-stats-box를 사용했다. productive-box : 커밋시각 통계 노출하기 나는 아침형 인간..! 사전 작업 gist.github.com에서 public으로 신규 gist를 생성한다. 제목과 내용은 향후 자동으로 업데이트 될 예정이므로 일단 아무렇게나 작성하면 된다. github 토큰생성 페이지에서 gist와 repo scope를 활성화하여 token을 발급한다. 이 때 발급된 토큰은 페이지를 빠져나가면 다시 얻을 수 없으니 클립보드 등에 잘 저장해둔다. 라이브러리 사용 productive-box repository를 fork한다. 우측 상단의 Fork 버튼을 누르면 된다. fork 된 나의 repository의 Action 탭에서 enabled 버튼을 눌러 Action을 활성화한다. .github/workflow/Schedule.yml 파일을 수정하여 환경변수를 작성해준다 GIST_ID: 사전 작업의 1번 step에서 생성된 gist의 id (gist URL은 gist.github.com//로 생성되기 때문에 주소창을 보면 된다.) TIMEZONE: 타임존을 적어준다. Asia/Seoul 형식으로 적어주면 된다. Settings 탭 > Secrets에 접속한 뒤 New repository secret 버튼을 클릭하여 환경변수를 설정해준다. GH_TOKEN: 사전 작업의 2번 step에서 발급받은 토큰 gist를 내 프로필에 고정한다. Action 주기(1시간)에 따라 자동으로 갱신 적용되나, 즉시 적용하고 싶다면 README.md 파일을 수정하는 등 파일에 변화를 주면 즉시 적용된다. github-stats-box : Github Status 노출하기 사전 작업 gist.github.com에서 public으로 신규 gist를 생성한다. 제목과 내용은 향후 자동으로 업데이트 될 예정이므로 일단 아무렇게나 작성하면 된다. github 토큰생성 페이지에서 gist와 repo scope를 활성화하여 token을 발급한다. 이 때 발급된 토큰은 페이지를 빠져나가면 다시 얻을 수 없으니 클립보드 등에 잘 저장해둔다. 라이브러리 사용 github-stats-box repository를 fork한다. 우측 상단의 Fork 버튼을 누르면 된다. fork 된 나의 repository의 Action 탭에서 enabled 버튼을 눌러 Action을 활성화한다. .github/workflow/Schedule.yml 파일을 수정하여 환경변수를 작성해준다 GIST_ID: 사전 작업의 1번 step에서 생성된 gist의 id (gist URL은 gist.github.com//로 생성되기 때문에 주소창을 보면 된다.) ALL_COMMITS: true일 경우 나의 전체 커밋을 카운트하고, false일 경우 작년 커밋만을 카운트한다. K_FORMAT: true일 경우 1.5k와 같이 숫자를 “k”로 포맷팅하여 노출한다. Settings 탭 > Secrets에 접속한 뒤 New repository secret 버튼을 클릭하여 환경변수를 설정해준다. GH_TOKEN: 사전 작업의 2번 step에서 발급받은 토큰 gist를 내 프로필에 고정한다. Action 주기에 따라 자동으로 갱신 적용되나, 즉시 적용하고 싶다면 README.md 파일을 수정하는 등 파일에 변화를 주면 즉시 적용된다. 그 외 더 많은 gists 라이브러리 찾아보기 matchai/awesome-pinned-gists에 여러 라이브러리들이 정리되어있다. Twitter를 연동하여 내 최근 트윗을 보여주거나 Spotify를 연동하여 최근 재생 음악을 보여줄 수 있고, 그 외 내가 많이 사용하는 언어 등의 정보들도 노출할 수 있다. 백준 solved.ac 랭킹 노출하기 나는.. 백준을 잘 애용하진 않아서(핑계임) 브론즈따리라 차마 갖다 쓰진 않았지만, 다른 개발자들은 mazassumnida/mazassumnida 라이브러리를 활용해서 solved.ac 랭킹을 많이들 노출하는 것 같다. (라이브러리 이름이 ‘마자씀니다’ 인가봄..) stats 등급 노출하기 나는 pinned gist를 활용해서 github stats를 노출했지만, anuraghazra/github-readme-stats 라이브러리도 있다. 이걸 활용하면 여러가지 테마로 stats를 노출하고, 등급 정보까지 산정(?)할 수 있다. 최저 B 등급부터 시작하는 개발자의 센스가 돋보이는 라이브러리다. 🌱 제 깃헙도 놀러오세요..!
-
if only VS if else
내 코드를 방해하는 else를 찾아서 🐠
2021-02-23 14:49
요즘 알고리즘 공부 차 매일 릿코드 문제를 랜덤으로 풀고 있는데, 문제를 풀던 중 흥미로운 점을 발견했다. // 1번 코드 if (condition) { var += A; } var += B; // 2번 코드 if (condition) { var += A + B; } else { var += B; } 1번 코드와 2번 코드는 룩은 달라도 동일한 로직을 수행하고 동일한 결과를 제공한다. condition이 true일 때는 var 변수에 A와 B가 추가되고, false일 때는 var변수에 B만 추가된다. 난 대게 Return elary pattern, Guard clauses refactoring 등의 패턴에 따라 1번 코드를 많이 봐왔고 또 1번 코드로 많이 짜왔지만, 사실 상 2번코드로 짠다고해서 큰 차이는 없다고 생각했기 때문에 코드리뷰 등의 과정에서 해당 패턴을 유심히 본 적은 없다. 릿코드의 824. Goat Latin 문제를 A개발자와 각각 풀면서 둘이 거의 유사한 로직을 구현했는데, 코드의 time complexity가 같음에도 불구하고 희한하게 두 코드에서 6ms 내외의 run time 차이가 있었다. 한줄 한줄 분석하며 원인을 찾다보니 한명은 1번 코드로 짰고 한명은 2번 코드로 짰는데 그 부분에서 run time이 차이난다는 것을 발견하게 되었다. else 구문의 비용? 참 희한한 일이다. else if도 아니고 단지 else일 뿐인데 이걸 사용하느냐 아니냐로 차이가 난다고? 처음에는 변수에 값이 assign 되는 시점의 차이인가하고 여러 테스트 케이스를 만들어 돌려봤는데, 변수 할당이나 공간 복잡도 등의 문제는 아닌 것 같다는 결론을 내렸다. else coast, early return time complexity 등의 키워드로 검색을 했으나 대체로 코딩 스타일과 가독성에서 1번 코드로 짜는 것이 좋다는 글들 말고는 딱히 속도와 비용에 대해서 이야기하는 글을 찾지 못했다. 그러던 중 If statement vs if-else statement, which is faster?라는 은혜로운 글을 발견하게 되었다! if only VS if else accepted 된 답변에서는 if only 케이스와 if else 두 케이스를 비교해서 컴파일 결과를 비교한다. if only: mov DWORD PTR [rbp-8], 5 cmp BYTE PTR [rbp-4], 0 je .L2 mov DWORD PTR [rbp-8], 6 .L2: mov eax, DWORD PTR [rbp-8] if else: cmp BYTE PTR [rbp-4], 0 je .L5 mov DWORD PTR [rbp-8], 6 jmp .L6 .L5: mov DWORD PTR [rbp-8], 5 .L6: mov eax, DWORD PTR [rbp-8] 컴파일러의 최적화 옵션이 적용되어 있지 않은 경우에는 어쨌든 if only가 더 효율적이라고는 한다. 그러나 이는 굉장히 미미함을 강조하고 있다. The latter looks slightly less efficient because it has an extra jump but both have at least two and at most three assignments so unless you really need to squeeze every last drop of performance (hint: unless you are working on a space shuttle you don’t, and even then you probably don’t) the difference won’t be noticeable. Return Early Pattern 호기심 때문에 if only VS if else를 비교하기는 했지만, 사실 요즘 컴파일러는 최적화 되어있을 뿐더러 유연하게 동작하기 때문에 차이라고 말하기엔 의미 없는 것으로 보인다. 그리고 속도/공간 복잡도를 이야기한다쳐도, 어느 정도의 의미있는 차이가 아니고서는 상호간의 이해와 유지보수가 편안한 코드를 작성하는 것이 중요하다고 생각한다. 추후 만약 누군가가 2번 코드로 작성한 것을 리뷰하게 되더라도 딱히 denied 하진 않겠지만, 가독성 및 유지보수 측면에서 1번 코드로 작성하도록 suggestion 정도는 할 것 같다. 1번 코드는 Return Early Pattern으로 통용되며, 이 패턴으로 작성했을 때의 장점은 하기 항목으로 정리할 수 있다. 들여쓰기의 깊이가 1레벨이기 때문에 선형적으로 코드를 읽을 수 있다. positive result를 함수 끝에서 빠르게 찾을 수 있다. 예외를 먼저 처리한 뒤 비즈니스 로직을 구현하기 때문에 불필요한 버그를 피할 수 있다. TDD 방식과 유사하므로 코드를 테스트하기가 더 용이하다. 오류가 발생되면 즉시 종료되므로 더 많은 코드가 실행될 가능성이 없다. 관련 내용은 관련 패턴인 Else Considered Smelly와 Arrow Anti Pattern의 내용을 읽어보면 도움이 많이 된다. 또한 구글링 중에 발견한 Return Early Pattern 글에 정리가 잘 되어있어서 생각을 정리하는데 크게 도움이 되었다.
-
내가 올 해 이룬 것들, 2020년 연말정산
개발자 2020년 회고
2020-12-29 20:47
🐭 쥐띠해였던 올 2020년이 시작될 때, 올 한해는 나의 해라며 멋진 한 해를 만들어보자고 다짐했던 기억이 난다. 그러나 전례없이 막강한 코로나 바이러스가.. 2020년을 덮쳐버렸고.. 목표했던 많은 것들이 틀어지고 무산되며 하루 빨리 코로나 바이러스가 끝나기만을 기다리다 결국 이렇게 2020년을 마무리하게 되었다. 유난히 어렵고 아쉬움이 많이 남은 해였지만, 그래도 밝은 마음으로 나의 2020년을 회고해보려고 한다. 📚 읽은 책 올 해는 총 10권의 책을 읽었다. 여름에 아이패드를 잃어버린 뒤로는 반년 가까이를 책 한 권 안 읽고 보내다 10월에 이북리더기를 구매한 이후에서야 다시금 책을 읽기 시작했다. 해리포터와 마법사의 돌: 해리포터를 정주행하고 싶어져서 시리즈 1권부터 읽기를 시작했다가, 잠시 접어두고 다른 책을 먼저 읽어야지! 했던게 어쩌다보니 1권만 읽고 끝나버린 정주행이 되었다. 검사내전: 초반에는 사례집을 읽는 것 같은 가벼움에, 후반에는 김웅검사의 가치관과 신념을 읽을 수 있는 무게감에 재미를 느끼며 읽었다. 일 중독 검사의 모습을 통해 여러모로 직업정신에 대한 동기부여가 되었다. 아주 작은 습관의 힘: 목표를 습관으로 수립하고, 그 습관을 점수화하여 매일 1%의 성장을 할 수 있도록 도와준다. 덕분에 습관화를 목표로 데일리 점수체크 루틴을 계획할 수 있었다. 팩트풀니스: 언론에 선동당하지 않는 법과, 전 세계 국가들의 발전단계 별 도달한 수준을 자세하게 설명한다. 동물농장: 소련 공산주의의 시작과 번영 그리고 몰락을 이해하며, 웃기게도 민주주의 국가에 살고 있음을 감사하게 생각하게 되었다. 국가의 발전보다 나의 발전이 우선적일 때, 결국 나의 발전은 국가의 발전이다. 데미안: 읽으면서 내내 데미안을 향한 싱클레어의 감정은 사랑이었다고 생각했다. 다만 ‘알고보니 그 사랑은 데미안의 에바 부인이었다!’ 이런 전개가 좀 아리송하긴했는데.. 책 내용대로 무언가의 이끌림이 작용했던 것이라는 생각이 든다. 동급생: 반전이 있는걸 알고 읽어서 생각한 만큼의 큰 반전은 아니었지만, 너무 절묘하고 생생해서 실화 기반 소설이 아닐까하는 착각마저 든다. 우정을 묘사하는 방식이 데미안과 비슷해서 일부분이 약간 겹쳐보였다. 1984: 디스토피아 문학을 읽고싶어서 읽게 된 책이다. 오만과 편견: 해리포터를 읽을 때는 영화속의 이미지가 소설을 잡아먹곤했는데, 이 책은 새로운 이야기를 읽는 것 마냥 영화와는 또 다른 이미지들을 그리면서 읽었다. 번역이 엉망이여서 힘들게 읽었다. 멋진 신세계: 내용과 결말 자체는 굉장히 가볍고 어렵지 않으나 읽고 난 뒤의 생각만큼은 무겁게하게 되는 책이었다. 나의 디스토피아는 무엇일지 고민하게 되는 책이다. ⛰ 등반한 산 올 해는 8개의 산을 등반했고, 그 중 7개의 정상석을 올랐다. 한라산: 일출을 보기 위해 잠을 자지 않고 바로 밤 새 산을 타느라 춥고 졸려서 힘들었는데, 그 만큼 역대급 일출을 보아서 행복했다. 수락산: 하산 길에 발을 헛디뎌서 난간에 빠지는 사고가 있었지만 그것 빼고는 참 쉬운 산이었다. 생각보다 암벽의 난이도가 높지 않아서 아쉬워했다. 북한산: 아이젠을 안 챙겨가는 멍청한 짓을 해서 깔딱고개까지 갔다가 하산했다. 그래도 하산 길에 자리잡아서 아침과 함께 일출은 봤다. 금오산: 한 여름에 오른 거라 중간 길은 케이블카를 이용했는데도 정말.. 힘들고.. 더웠다.. 나중에 봄이나 가을 쯤 동굴이 있는 코스로 다시 한번 오르고 싶다. 지리산: 일출산행이었지만 기상악화로 인해 해가 구름과 눈보라에 가려서 일출을 보지 못하고 내려왔다. 덕분에 지리산 일출산행을 다시 도전할 명분이 생겼다. 팔공산: 지리산 일출산행을 실패하고 바로 다음날 오기에 팔공산으로 일출산행을 도전했다. 다행히 일출이 꽤 예쁘게 떴으나, 철조망 때문에 일출을 제대로 관찰하기가 어려웠음에 아쉬움이 남는다. 덕항산: 태백산 일출산행 전 몸풀기 겸 올랐는데, 풍경이 없고 나무숲 뿐이여서 아쉬웠다. 그래도 올라갔다 내려오며 수다떨고 커피마시기에 좋은 산이었다. 태백산: 올해 마지막 산이자 일출이 가장 예뻤던 산이다. 천제단 너머로 떠오르는 해가 참 예뻐서 아직도 그 광경이 생생히 떠오르는데, 나중에 봄이 오고 풀이 예쁘게 피면 다시 한번 일출을 보러 가고싶다. 💻 진행한 프로젝트 회사 업무로 총 4개의 프로젝트를 진행했다. 딥러닝 프로젝트부터 ReactNative, 하이브리드 프로젝트까지 진행했으니 나름 폭 넓게 진행한 셈이다. 그리고 틈틈이 사내블로그를 만들었다. 딥러닝 수요예측 시스템: 행사상품의 월별 판매량을 예측해서 재고를 절감하는데 기여했다. 딥러닝에 대해 지식이 전무한터라 이 프로젝트를 진행하며 꽤나 고생을 많이했다. 출퇴근길에 꾸준히 인강도 듣고 매일 늦게까지 남아서 하이퍼파라미터나 인풋값들을 변경해서 조금이라도 더 나은 결과를 얻으려고 신체적으로나 심적으로 많은 무리를 했었다. 덕분에 SCM 산업대상도 수상하는 등 대내외적인 성과가 있어서 그래도 나에게 유종의 미를 거두게 해준 프로젝트이다. 인마이백: 본격적으로 ReactNative를 해보게 된 프로젝트이다. 과거에 잠시 다른 프로젝트를하며 ReactNative를 훑어본적은 있다고 생각했는데, 이번 기회를 통해 본격적으로 한 뒤에야 이제 제대로 ReactNative를 경험해봤다고 말할 수 있는 수준이 된 것 같다. 다만 ReactNative를 경험해본 팀원이 없어 삽질을 많이 한 덕분에 우리가 옳은 방향으로 잘 나아가고있는지를 잡아줄 수 있는 사람이 없던 것이 아쉬웠다. 올영EZ, 올리브라운지: 영업본부 구성원들을 위한 사내 한정 앱이다. 하나는 매장 카운셀링을 위한 태블릿 앱이고, 다른 하나는 소통/학습을 위한 모바일 앱이다. 두 앱 모두 하이브리드 앱이라 앱에서 할 일은 크게 없었지만, 올리브라운지를 진행하면서 처음으로 iOS 프로젝트를 다루게 되었고, FCM 푸시나 생체인식 등 간단한 기능들을 붙여가며 iOS를 손에 익힐 수 있었다. 사내 블로그: 올리브영 기술 블로그를 만들었다. 내 블로그와 마찬가지로 Github Pages와 Jekyll을 써서 구현했다. 업무도 업무 나름대로 바빠서 거의 해커톤하듯이 만들었다. ✏️ 공부 ADsP: 딥러닝 프로젝트를 진행하며 업무 지식도 익힐겸해서 매일 아침 1시간씩 일찍 출근해서 ADsP 공부를 했었다. 다만 시험 직전 봄 쯔음부터 코로나 바이러스가 확산되며 시험이 연달아 취소됐고, 아직까지도 시험에 응시하지 못한 상태다. 내년에 다시 시도할지 말지 고민이 된다. TOEIC, Opic, 전화영어: 승진조건이긴 했지만, 공인 영어 성적도 만들 겸해서 겸사겸사 영어공부를 했다. 학원을 다니면 좋았겠지만 돈도 없고 시간도 없는 직장인이라 아침마다 전화영어를하며 영어공부를 했다. 토익은 4번이나 접수했지만 코로나 때문에 취소되며 응시하지 못했고, 오픽만 응시해서 목표했던 성적은 획득했다. 내년부터는 분기별로 오픽을 응시해서 등급을 올릴 예정이다. Swift + iOS: 서적과 구글링으로 공부를 하며 프로젝트를 진행하다가, 연말되어서는 패스트캠퍼스 강의를 끊어서 iOS 강의를 수강했다. 구글링으로도 어찌어찌 프로젝트를 잘 수행한다고 생각했는데, 역시 좋은 강의를 듣는게 최고인 것 같다. 아직은 간단한 토이프로젝트를 만들 수 있는 수준밖에 안 되지만 내년에는 개인 프로젝트를 진행하며 본격적으로 이력화해볼 예정이다. 알고리즘: 대학생 친구들과 함께 매주 1회 알고리즘 스터디를 진행했다. 회사 팀에서도 신규 인력을 채용할 때 코딩테스트 문제를 선정하게 되는데, 정작 나도 못 푸는 문제들이 있어서 경각심을 갖고 스터디를 시작하게 되었다. 매 주차별로 분류 하나씩을 과제로 풀며 공부하고, 돌발 문제를 풀어보는 식으로 진행하고 있는데 시작 전에 비해 실력이 많이 향상된 것을 느낀다. 아직도 잘 푸는 문제는 잘 풀고 못 푸는 문제는 못 풀곤 하지만 꾸준히 반복학습을 진행하니 웬만한 분류들은 풀 수 있게 되었다. 운전면허: 작년에 차를 사려고 기능까지 따놨다가 마음이 식어서 그대로 기능만 합격한채로 방치해뒀었는데, 기간 만료 안내를 받고 허겁지겁 다시 도로연수를 받아서 바로 취득했다. 따고 나니 그때는 왜 그렇게 검정을 어려워했나하는 생각은 들지만, 역시 어렵긴 어렵다. 주행 자체보다 길을 외워야한다는 부담감이 더 컸던 것 같다. 그래도 이제 운전면허를 획득하게 되어서 해피! (면허는 바로 장농으로 들어갔다.) 💪 운동 수영: 코로나가 확산되기 이전과, 잠잠해졌던 중간중간엔 매일 아침 수영을 했다. 올해는 접영을 마스터하려고했으나, 강습 기간이 간헐적이여서 지속적으로 배우지 못했다. 웨이트: 수영을 못하게 되면서 헬스에 재미를 붙이고 싶어 PT를 등록했다. 주 2-3회 정도 웨이트를 진행하며 두달만에 근육량이 +2kg 가까이 늘었다. 런데이: 주 3회 유산소 달리기를 하며 30분동안 쉬지 않고 달릴 수 있는 체력을 만드는데 집중했다. 😷 새로운 일상 재택근무: 코로나가 본격화된 3월부터 재택근무를 시행했고, 재택근무를 통해 내가 생각보다 의지가 약한 사람이라는걸 알게되었다. 요즘은 자발적으로 꾸준히 사무실로 출근하고있다. 입원: 7월 경 1주 넘게 지속되는 복통을 참다가 어느 순간 맹장염이 의심될 정도로 아파져서 병원에 갔는데 대장에 문제가 있음을 알게되고 급작스럽게 입원을 하게 되었다. (사실 이렇게 해프닝으로 마무리 되어야 하는 이야기였는데, 6개월 뒤인 지금 나는 또 다시 같은 증상으로 입원을 해서 블로그 글을 쓰고있다.) 코로나 검사: 총 3번의 코로나 검사를 진행했다. 아파서 한번, 회사에 확진자가 나와서 한번, 그리고 입원을 위해 한번. 원래 아파도 병원에 잘 가지 않는 편인데, 올해는 주위 사람들을 위해서라도 아플때마다 병원에 가려고 노력했다. 🏆 연말정산 사내 수상: 진행했던 프로젝트 2개가 회사 연말 시상식에서 각각 최우수상을 수상했다. 주식: 금액으로는 얼마 안 되지만 실현손익 +70.29%를 달성했다. 상반기에 인버스에 홀려서 -4% 정도의 출혈이 있었으나, 하반기에 중타를 잘 쳤다. 🎸 기타 버킷리스트 중 하나인 퀸 콘서트에 다녀왔다. 사실 13년도에 이미 이루긴했었지만, 올해는 락 페스티벌이 아닌 단독 콘서트였기 때문에 감회가 새로웠다. 회사 전사영상에 인터뷰 출연과 엔딩을 장식했다. 엔딩요정이라고 알아봐 주는 분들이 많았다. 마치며 코로나 때문에 반강제로 쉬어가는 한 해가 되었다. 사실 돌이켜보면 코로나 탓을 하기엔 내 의지가 부족했던 것도 크지만, 올해의 시행착오를 통해 내년 목표는 외부 요인으로 인해 무너지지 않도록 더 단단히 바로잡을 수 있는 큰 가르침을 받을 수 있었다. 연말 회고를 쓰는 것은 단순히 정리에 목적이 있다고 생각했는데 쓰다보니 내 후년을 어떻게 보내야할지에 대한 각성에도 효과가 큰 것 같다. 내 후년 이맘때 쯤 2021년 회고록을 작성할 때에는 더 큰 유종의 미가 있었으면 좋겠다. 2020년을 수고하며 보낸 나에게 박수를 보내고 싶다. 👏