2/1/2018

2017년 반성2018년 방향

2017년은 개인적으로 만족 스럽지 못한 한해였다. 이것 저것 (이직, 세미나, 스터디, 주말출근 등등) 열심히 많은 것을 한 것 같아 보이는 한해였다. 하지만 개인적으로는 성공스럽지 못한 한해였다.

나는 개인 테스크를 트렐로 보드를 사용해 관리한다. 회고를 위해 트렐로 보드를 살펴보았고, 2017년 나는 실패한 한해라는 것을 너무나 쉽게 깨달을수 있었다.

인간은 실수를 반복한다.”또한 몇 년 동안 같은 실패를 반복했다. 한해 한해 계획을 세웠고, 실패해왔다. 그래서 올해 새해 계획은 조금 다르게 세워보려 한다. 반기새목 (반성 기반 새해 목표 설정)

반기새목 (반성 기반 새해 목표 설정)

먼저한해 실패한 부분과 성공한 부분을 구분하고, 실패한 부분은 실패 요소를 명확히하고 이를 토대로 개선 방향을 찾는다. 성공한 부분은 성공 이유를 알아보고 실패한 부분에 적용한다.

잡식

나는 개발자다. 뒤늦게 개발을 시작했고, 열등감 덕분에 방향성 없이 정보를 무작정 입력하려는 안좋은(?) 학습 버릇이 있다. 이러한 학습방법은 나를 빠르게 성장시키고 커리어를 정하는데도움이 되었다. 이러한 학습법이 잘못됐다는 것이 아니다. 학습자의 수준에 따라 효율적인 학습방법이 존재한다고 생각하며, 현재의 나의 수준에서 기존 학습방법은 한계가 있었기에 변경은 불가피했다. 올해는 학습 방향은 UnManaged Language를 기반으로 알고리즘자료구조 학습 이며, 이를 달성하기 위한 커리큘럼을 세우고, 테스크로 만들어 학습할 것이다.

테스크는 최대한 구체적이며, 작게, 실행가능한 수준으로 수립

2017년 한해 트렐로에 수많은 카드들이 만들어졌다. 이 중에 과연 나에게 의미가 있는 카드가장이나 될 것인가? 대략 20% 정도 되는것 같다. 왜 이렇게 의미없는 카드들이 많이 만들어 진것일까?

상사가 계획없이, 생각없이 부하직원에게 업무를 지시해 고통을 주듯, 나 또한 나에게 고민없이 테스크를 할당하고 좌절감에 빠지게 만들었다. 그렇다고 이러한 테스크들이 할가치가 없고 신경쓰지 않아도 될것들은 아니다. 다만 따로 괸리되고 인지되어야필요가 있다. 2017년에 하나의 보드에 모든 테스크를 관리했다면, 올 한해는 TODO, BACKLOG, BUCKET 으로 보드의 성향을 구분할 것이다. 한단계나아가 TODO 같은 경우는 월별로 보드를 만들어 관리할 것이다.

목표는 버킷리스트가 아니다.

2017년 트렐로 보드에 생성된 테스크를 살펴보면 오픈소스, 기술 문서 번역, 세미나 발표 등과 같은 버킷리스트 비슷한 테스크들이 있다. 올해는 버킷리스트와 목표는 구분해서 계획을 세울것이다. 예를들면 오픈소스 기여와 같은 막연한 목표는 트렐로 보드를 따로 만들어 관리, 2018년 올해 목표계획과 같이목표와 세부목표를 나눌것이다.

패턴 그리고 습관

2017년 11월, 12월은한해가장 바쁜 시즌이었다. 총 15번의 온/오프라인 면접코딩테스트. 이외에도 파이썬 격월 세미나 스피커, 회사 프로젝트 릴리즈, 인수인계, 퇴사기념 세미나, 퇴사, 영어스크립트 암기, 무엇보다 충실한 신혼생활 등… 어느날은 면접을 보고 출근해 일하고, 퇴근면접을보는 미친일정을 진행했다. 물론 이런 날은정신이 아니었다.

당연한 얘기지만 개인일정이 바쁘다고 회사일정에 지장을 주면되었기에 주말 출근 혹은 1~2시간 일찍 출근하고 퇴근했다.

평상시 새로였다면 위와 같은 일들을 절대해내지 못했을 것이다. 이 기간동안 나는 새로운 생활패턴 혹은 습관을 적용했다.

얼또 - 얼리또라이

일찍 일어나는 또라이가 세상을 바꾼다

일명 얼또 라는 이름의 페이스북 그룹인데, 한정된 시간에 너무 많은 과업에 스트레스를 받던중 나에게 맞는 시간관리 기법을 찾기 시작했고, 간단한 생활 패턴의 변화로 이를 시도해보기로 했다. 찾았던 여러가지 장법중 하나가 새벽형 인간이었고, 이를 실행하는 그룹인 얼리또라이가입하고 활동하게 되었다. 이 그룹의 목표는하나다 일찍일어난다. 이토록 단순한 실천이 얼마나 많은 파급효과를 갖는지는 깊게 고민해보지 않은 사람들은 쉽게 얻을없다.

최대한 간단히 정리해보자면, 아침에 일정하게 얻을있는 개인 시간이 생긴다. 나와 같이 의지가 약한 사람에게 퇴근 후에 2~3시간 정도의 개인시간을 지속적으로 갖는다는 것은 너무나 어려운일이다. 의지가 약한데 아침이나 저녁이나 뭐가 다를까? 라는 의문을 가질있다. 이런 의문이 생긴다면 조금고민해 보거나 실제로 일찍일어나 보길 바란다. 아침과 저녁의 차이가 무엇인지 깨달을있을 것이다.

어쨌든 아침 일찍 일어난다는 생활 패턴 하나로 2~4시간의 통제가능한 개인 시간을 얻었고, 이직 준비와 자기개발에 투자했다. 부가적인 효과로 집중 가능한 개인시간을 충분히 갖음으로서, 집중해서 일하지 못했을발생하는 극도의 스트레스 또한 제거할있었다. 정리하자면 11월, 12월은 2017년짧은 시간에 많은 것을 이룩한달이었다. 결국 나머지 실패한 기간과 성공한 기간의 가장차이는 패턴안에서 일정관리였다. 일정한 패턴이 있을때 시간 통제가 가능해지고, 정확한 계획 수립이 가능해지며, 실행 가능성은 높아졌다.

정리

생각나는 대로 정말 두서없이 정리를 해보았다. 쓰고 보니 크게 3가지 대명제가 정해 졌다. 첫 번째는 학습할 주제방향 선정, 두 번째는 계획수립관리 방법, 세 번째는 성공적인 목표달성을 위한 습관. 개인적으로 가장 중요하게 생각되는 명제는번째 습관이며, 2018년의 성공 실패여부는 습관 얼또달려있다. 기억해 새로야. 얼또!! 대강 방향은 정해졌고, 이제 2018년 희망찬 계획을 세우러!!! Here we go!!!

셀프 공약: 2018년 공휴일 68일1주당 하루(스페셜찬스) 52일 합을 제외한 245일(365-(68+52)) 얼또를 실천한다. 홍석희에게 20만원 스벅상품권을 선물한다.

28/12/2017

[2017 파이썬 연말 세미나 라이트닝토크] Dream of selo in the hello world - 이새로찬

Python Seminar Pycon 2017 파이썬 연말 세미나
15/12/2017

OS Disk Format and File system

2018년 새해 맞이 준비를 위해 개인포맷을 진행했고, MAC 파일시스템에 대한 이해를 위해 정리를 해보려 한다.

  • APFS : Appple 파일시스템, APFS는 SSD(솔리드 스테이트 드라이브) 및 기타 모든 플래시 저장 장치의 기본 파일 시스템으로, Mac OS 확장(HFS+)을 대체합니다.
  • MAC OS Extended (Journaled, Encrypted, Case-sensitive)
    • MAC OS 파일시스템, 저널링 기능 추가.
    • 저널링 파일 시스템 : 주파일 시스템에 변경사항을 반영하기 전에, 저널안에 생성되는 변경사항을 추적하는 파일시스템. 시스템 전원문제시스템 다운으로 부터 파일의 손상 가능성이 낮다.
      • 원리: 파일과 디렉토리의 변경은 여러 개의 쓰기 오퍼레이션으로 실행하고, 이러한 이유로 전원공급이나 시스템 오류와 같은 인터럽트로 인한 데이터의 손실 가능성을 낮출있습니다. 정리하자면 작동을 작은단위로 나누어 실행함으로서 중간에 인터럽트가 일어나도 멈춘지점을 추적할있습니다.
      • Journal(일기): 변경사항을 기록하는 특별 구역
      • 정리하자면 저널 파일시스템은 변경사항을 기록하는 특별구역(저널)을 할당하고, 문제가 발생할 경우, 저널을 읽고, 읽은 내용을 되돌리는 것으로 복구가 이루어진다.
      • 필요한 이유: 유닉스 파일 시스템에서 파일을 지우는 것은 크게단계다. 첫번째 삭제 파일의 디렉터리 엔트리를 삭제한다. 두번째 파일이 차지하던 공간과 아이노드를 해제하여 free space map에 표기한다. 해당과정 중간에 시스템 문제가 발생할 경우 다음과 같은 이슈가 생긴다. free space map이 갱신되지 않아 스토리지 누수발생한다. 또는 지워지지 않은 파일 영역이 쓰기 가능상태(free)로 표시되어 다른 내용으로 덮어쓰여 질 수 있다.
    • Encrypted File System : 저장 데이터 암호화
    • Case-sensitivity : trate upper case and lower case as distinct

Reference

OS file system
13/12/2017

[성공하는공부법] FRALD

개발자의 덕목중 하나는 지속적인 학습이다. 최근 학습에 실패한 이야기 라는 좋은 글을 읽었다. 저 글의 내용처럼 개발자에게 학습은 덕목이며, 그렇기에 학습 방법에 대한 고민은 자연스럽게 따라오게 된다.

나는 비전공자며, 기반지식이 부족하다. 이러한 열등감으로 나는 CS에 관련된 주제를학습해왔다. 최근 2달 정도는 알고리즘을 공부했다. 하루에 1시간 정도 퇴근투자했다. 학습 방법은 주로 Hello Coding 그림으로 개념을 이해하는 알고리즘 책을 따라 학습하거나, codewars같은 코딩플랫폼을 풀었다. 처음에는재미있었다. 머리도 좋아지는것 같고, 무언가 공부하는같은 느낌이 들었다. 그러나 내가 느낀 성취감과 반대로 나의 지식은 그리 많이 발전하지 않았다.

사실 나는 이런 결과를 초래할 것을 누구보다 잘알고 있었고, 경험했다. 하지만 다시한번 실패했다. 과거의 나는 학습의 행위보다는 학습방법론에 관심이 많았고, 어떻게 공부할 것인가?개발자가 되기전, 꽤 오래전에 읽었다. 핵심내용인 일정 주기를 갖는 인출 연습의도적인 학습중요하다는 점에 감명 받았다. 하지만 아쉽게도 단순히 감명 받고 끝났다나는 멍청이다말미잘이다사실 그당시 백수였고 지적유희를 위해 그냥 읽기만 했다

하지만 다시 한번 실패하지 않기 위해 이렇게 시간을 들여 글을 쓰고 있고, 글을 쓰면서 머릿속을 정리하며 되새김하고 있다.

성공적인 학습을 위한 FRALD

FRALDFun, Repeat, Achivement, Link, Difficulty앞글자를약어다. 푸랄드!, 프랄드! 프으뢀드! 라 불리며, 성공적인 학습 싸이클을 만들기 위한 핵심 요소 5가지를 명칭한다. 프뢀드!! 사실 방금 글쓰면서 잔머리를 굴려 지었다프뢀드!!

FRALD

  • 재미 (Fun) 있다.
  • 의도적으로 반복 (Repeat) 한다.
  • 성취감 (Achivement)느낀다.
  • 지식을 연결 (Link) 한다.
  • 해결가능한 어려움 (Difficulty)극복한다.

요소들은 크게는 학습의 효율성과 지속성 측면으로 나누어질있다. 그러나 한쪽의 장점만 갖는것은 아니고요소들의 상호작용으로 성공적인 학습 사이클이 만들어질 것이다.

Fun

재미 (Fun) 있다.

나에게 가장 중요한 첫번째 요소는 재미다. 재미는 행복의 원동력이며, 행복하고 재미있게 살기 위해 학습을 하고, 새로운 것을 경험한다. 학습도틀에서 벗어날수 없다고 생각한다. 적당한 수준으로 하는 것이 아닌 진정 뛰어난 사람이 되기 위해서 재미첫번째 요소라 생각한다. 이유는 명확하다. 재미자연스럽게 몰입과 집중력을 극대화 시키며, 특별한 동기부여 없이 학습을 지속시킬있다.

Alt text

Repeat

의도적으로 반복 (Repeat) 한다.

인간의 뇌는 망각기능이 뛰어나다. 뇌가 받아들일있는 용량은 한정되어 있고, 우리가 의식하는 모든것을 받아들인다면, SF 영화에서 볼수있는 머리(통) 큰 외계인의 뇌를 갖고도 부족할지도 모른다. 그렇기에 생존을 위해서라도 뇌는 망각하고, 불필요한 정보를 잊어야한다. 그렇게 우리가 노력해 학습한 지식도 망각되어진다. 슬프다. 열심히 공부했는데그렇다고 방법이 없는것은 아니다. 잊혀지지 않기 위한 방법이 있다. 의도적으로 반복하는 것이다. 의도적으로 반복하는 방법은 여러가지가 있겠지만, 큰틀은 다음과 같다.

인지와 인출을 적절히 반복

동일한 지능을 갖는사람이 동일한 자원과 집중력을 투자했을때 차이가 난다면, 인지와 인출의 불균형 으로 효율적인 학습이 이루어지지 않고 있을 가능성이 높다. 내가 그랬다. 이 부분은 어떻게 공부할 것인가?읽어보면 답을 얻을있다. 사실 고백하자면, 오래되서 세부적인 내용은 기억이 나지 않는다인지와 인출의 불균형으로 효율적인 학습을 하지 못하면, 이와 같이 학습했지만 기억나지 않는 상황에 처한다

Achivement

주기적으로 성취감 (Achivement)얻는다.

학습에서의 성취는 노력에 대한 합당한 보상으로 볼수있다. 보상의 구체적인 예로는 돈, 학습 결과물, 칭찬, 명예, 개인만족 등이 있을있다. 하지만 지속적인 학습을 위해서는 앞서 예를보상을 조금 구체화하고 계획적으로 얻을 필요가 있다.

학창시절 우리는 좋은 대학에 진학하기 위해 수능시험을 준비한다. 수능이라는 시험은 너무나 길고 끝이 보이지 않는 마라톤과 같다. 이러한 마라톤에서는 지치지 않는 꾸준함이 승패를 가른다. 어떤 학생들이 좋은 대학에 가는것일까? 대부분의 좋은 대학에 입학한 친구들은 고등학교 입학부터 혹은 중학교 시절부터 공부를 잘했다. 또한 수능성적 뿐만 아니라 내신성적도 뛰어나다. 1등을 해본 학생은 다음에도 1등을 하고 성적이 많이 떨어저야 상위권에서 크게 멀어지지 않는다. 그들은 중간고사, 기말고사에서 수능시험에 나오지 않는 체육, 도덕, 가정 까지 100점을 맞는다. 1등을 하면 단순한 순위로서의 보상이 아닌 인정, 명예, 주변의 부러움과 같은 전리품을 얻는다. 이러한 보상은 다음 시험을 준비하는 에너지가 된다. 그렇게 성취와 지속성 이라는 선순환 바퀴를 굴리며 좋은 대학에 간다. 물론 예외는 있다. 하지만 모두가 알다시피 원래 잘하는 놈이 좋은대학 간다.”

나는 개발자 입문연봉과 주변사람들의 인정을 보상으로 성취감을 얻었다. 하지만 최근에는 그러한 보상으로 얻는 성취감이 예전만큼 크지 않다. 그래서 개인 프로젝트를 하고 결과물로 성취감을 얻으려 했지만 현실적인 시간 문제로 번번히 실패했다. 최근 고민이 많다.

학습한 지식들의 연결은 기억력 강화는 물론 지식에 대한 이해를 고도화 시킨다. 개발을 하다보면 문득 깨닮을을 얻을 때가 있다. 아하 이게 이런 개념이였구나!!”. 사전에 머릿속에 모호한채로 남겨진 지식이 다른 지식과 연결되면서 이해수준이 높아지는 단계다. 공부했던 지식을 활용하여 무언가 만들때 이러한 지식들의 연결이 활발하게 이루어지고, 쌓여있던 지식들이 연결되면서 폭팔적으로 성장하곤 했다.

Difficulty

해결가능한 어려움 (Difficulty)극복한다.

학습주제나 학습과정의 적절한 난이도 선택은 효율적이고 지속적 학습을 위해 중요하다. 사실 어떤 지식을 공부 하냐에 따라 학습난이도가 중요하거나 혹은 아닐수도 있다.

개발지식을 예로 들자면, 주어진 시간과 집중 가능한 시간을 대략 산정하여 해결 가능한 주제와 학습범위를 선정하는 것이 중요하다. 난이도 선정이 어렵다면 막연한 고민보다는 일단 부딪혀보고 결정하는 것이좋다.

결론

머리속 이곳 저곳에 흩어저 있는 공부하는 법에 관한 지식들을 연결하기 위해 포스팅을 작성했다. 그러나 내가 안다고 느꼈던 지식들은 이미많이 망각되어졌다. 앞으로는 FRALD(프뢀드…;;;) 요소들을 충족해가며 학습할 것이다. 마지막으로 의도적으로 프뢀드 요소들을 의도적 인출을 하면서글을 마무리 하겠다. Fun, Repeat, Achivement, Link, Difficulty

마무리하면서 프뢀드 다섯가지 요소가 바로 떠오르지 않았다안다는 착각에 빠지지 말고, 제대로 학습하자. 프뢀드!!!!!!!!!!!!!!!!!!!!!!!!!!”

Reference

성공하는공부법
12/12/2017

[성공이란 별거 없다] 삶의 방향 상호작용

우리가 살아가는 삶의 방향은 우리가 겪고, 느끼는 모든 접촉과 모든 감정의 연결이 만들어낸 결과가 아닐까? 본인의 삶의 방향이 잘못됬다 생각된다면, 현재 맞이하는 접촉과 감정의 변화를. 반대의 경우라면강한 접촉과 감정을 느낀다면 어떻할까?

성공이란 별거 없다
12/12/2017

장고(Django)에서 멀티 데이터베이스 셋팅

배경지식

시스템 규모가 작을때는 일반적으로 하나의 데이터베이스에서 모든 데이터를 관리합니다.(로그같은 특수 목적의 데이터는 제외) 이유는 데이터 양이 많지 않은데 굳이 멀티 데이터베이스를 쓰면서, 관리 포인트를 늘일필요가 없고, 데이터베이스 늘어날때마다 모든면에서 복잡도가 매우 높아집니다.

하지만 대륙을 넘나 드는 서비스를 한다거나, 단일 데이터베이스에서 감당하기 힘든 데이터가 쌓인다면, 복잡도를 감수하더라도 멀티 데이터베이스를 고려해야할 상황이 생깁니다. 지금 저희 www.mymusictaste.com 서비스가 위에서 언급한가지 상황에 쳐해있고, 해결 방향을 찾아가는 과도기 입니다. 이런 배경을 갖고 개발을 진행하고 있으며, 이번 제가 맡은 업무중 하나는 여러개의 Django app 중 (저희는 서비스 별로 app을 나누고 있습니다.) 하나를 다른 데이터 베이스로 이전하는 작업을 하게 되었습니다.

django support multiple database ?

장고는 멀티데이터베이스를 지원합니다. 아주디자인된 웹프레임웍 답게 멀티데이터 베이스를 Config 설정에서 간단히 지원합니다. 하지만데이터베이스의 통신을 위한 라우팅은 개발자의 몫입니다. 일반적으로 라우팅을 해주지 않는다면, default 데이터베이스가 사용됩니다.

The default routing scheme ensures that if a database isn’t specified, all queries fall back to the default database.

How to route to which Database ?

그렇다면 멀티데이터 베이스에 어떻게 라우팅 할것인가? 위에서도 말했지만 라우팅은 부분은 전부 개발자의 몫이다. 공식문서에 가이드가 있지만 random 을 활용한 example 정도 수준이며, Google 검색결과 매우 다양한 방식의 구현을 찾아볼수 있다. 모델 수준에서 사용할 database명시하는 경우도 있고, 라우터를 세세하게 작성하는 경우도 있었다. 나는 첫번째 방법인, 모델 수준에서 사용할 데이터베이스를 명시하는것은모델 수준에서 routing을 관리해야하기 때문에 좋지 않은 디자인으로 생각했고, 두번째 방법을 선택하기로 했다.

구현 샘플 코드설명

예제는 순서대로 진행하면 된다. 초기 프로젝트라면 쉽게 구성할있지만, Legacy가 많은 코드라면 고생을 각오해야한다. 말씀 드리지 않아도 아시겠지만, 아래 작성된 코드와 방식은 이해를 위한 샘플이지 best example은 결코 아니다.

define database setting

데이터 베이스를 생성 후, 커넥션 정보를 셋팅파일에 추가한다.

settings.py

DATABASES = {
    'default': {
        'NAME': 'master',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'spam',
    },
    'auth_db': {
        'NAME': 'auth_db',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'swordfish',
    },
}

define routing

커스텀 라우터 모듈을 작성 후 settings.py 에 작성된 라우터를 사용한다고 선언한다.

router.py

class MultiDBRouter(object):
    def db_for_read(self, model, **hints):
        if model._meta.app_label == 'auth':
            return 'auth_db'
        return 'default'
        
    def db_for_write(self, model, **hints):
        if model._meta.app_label == 'auth':
            return 'auth_db'
        return 'default'

    def allow_migrate(self, db, model):
        if db == 'auth_db':
            if model._meta.app_label == 'auth':
                return True
            else:
                return False
        return True

settings.py

...
DATABASE_ROUTERS = [
    '<router_path>',    # e.g) snsproject.core.routers.MultiDBRouter
]

grant mysql user

(MySQL 기준) 새로운 database를 생성하고, application 에서 connection을 맺으려 할시 Access Denied 에러가 발생할 것이다. 이를 해결 하기 위해 application user에 새로 생성한 database의 접근 권한을 부여하자. 위 작업은 root 권한 혹은 user 권한 변경이 가능한 DB user가 필요하다.

GRANT ALL ON <database_name>.* TO 'selo'@'%';

synchronizing new database

> python manage.py migrate --database=auth_db

when migration issue is raised

만약 마이그레이션을 진행시 마이그레이션 이슈가 발생한다면 기존 마이그레이션 파일의 변경이 필요할수도 있다. 장고 마이그레이션은 매우 편리하지만 100퍼센트 완벽하지는 않아보인다. 이러한 부분은 개발자가 풀어야할 숙제이며, 나는 다음과 같은 방법으로문제를 해결하려한다.

  1. 에러가 발생한 마이그레이션 파일을 수정한다. 아래는 멀티디비 구현방식에 따라 달라질있다.
  2. 분기 추가 후 위 sync명령어 재구동.
from django.db import migrations

def forwards(apps, schema_editor):
    if not schema_editor.connection.alias == 'default':
        return
    # Your migration code goes here

class Migration(migrations.Migration):

    dependencies = [
        # Dependencies to other migrations
    ]

    operations = [
        migrations.RunPython(forwards),
    ]

마치며

항상 느끼는거지만 장고는 정말 정말 많은 기능을 품고 있다. 멀티 데이터베이스도 간단하게(???) 지원한다. 하지만 어디까지나 장고가 추구하는 디자인과 API 표준을 벗어나지 않는 범위에서 구현된 프로젝트에만 해당되는 이야기다. 그리고포스팅에서는 다루지 않았지만 1.7 이하의 버전을 쓰고 있다면가지 제약이 존재한다.

Reference

Django