스토리 홈

인터뷰

피드

뉴스

조회수 1092

린더를 만들고 있는 이유 1.0

여러 인공지능 서비스가 우후죽순 생겨나고 있습니다. 그리고 각각의 '인공지능 비서'들이 내세우는 주요 기능 중 하나는 바로 일정 관리죠. 그럴만도 한것이 일정관리야 말로 인간이 가장 큰 보조를 받을 수 있는 영역 중 하나이기 때문이라고 할 수 있겠습니다.개인 비서가 없어봐서 모르겠지만 영화나 드라마를 보면 주로 훤칠하게 잘생긴, 또는 아름다운 비서가 회장님이 묻기도 전에 그의 다음 일정을 알려줍니다. 내가 언제, 어디서, 무엇을 해야 하는지 끊임 없이 기록하고 상기 시켜주는 사람이 옆에 있다면 나의 삶도 여러모로 편해질수 있지 않을까요.이러한 측면에서 볼 때 다양한 인공지능 서비스가 나오고 있다는 점은 환영 할 일이지만, 그 서비스들이 실질적으로 사람들의 삶에 도움이 되는 기능들을 갖추고 있느냐는 완전히 다른 차원의 질문이 될 수 있습니다. 이름만 인공지능일 뿐이지 할줄 아는 것이라고는 내가 입력한 일정을 당일 아침에 읊어주는 수준이라면, 그것을 '비서'라고 부르기에는 부족할지 모릅니다.대부분의 사람들이 일정을 놓치게 되는 이유는 주로 해당 일정을 기록해두지 않기 때문입니다. 바쁜 생활 속에서 모든 일을 일일히 기록하기는 매우 어렵고, 나중에 해야지라는 생각으로 묻혀두었던 일정들은 어느새 지나있기 마련이죠.진정으로 똑부러지는 일정 도우미라면 내가 일정을 직접 입력하기도 전에 내가 선호할 만한 일정들을 먼저 정리하여 제시할 수 있어야 합니다. 우리는 여러개의 일정 중 가장 끌리는 것을 선택하기만 하면 되는것이죠. 그렇다면 위와 같이 사용자가 일정을 입력하기 전 먼저 선택지를 제시하기 위해서는 무엇이 필요할까요?현재 히든트랙팀에서 제공하고 있는 일정구독서비스, 린더( https://linder.kr )는 화장품 세일일정, 학교 학사일정, 프로야구 경기 일정 등 다양한 일정들을 한데 모아 개인의 캘린더로 구독 받을 수 있도록 돕고 있습니다. 현재까지 약 2만명의 사용자가 7천개가 넘는 다양한 일정들을 받아보고 있죠.아직 린더의 데이터는 아이돌 스케줄, 학사일정, 프로야구 경기일정 등에 국한되어 있지만, 이후 공연 티켓팅, 쇼핑몰 세일 등 다양한 분야로 확장해나갈 계획입니다. 기존에 심한 건망증으로 매번 놓쳤던 티켓팅이나 세일 일정이 있다면 린더를 통해 해당 일정을 놓치지 않고 실행에 옮길수 있게 되는것이죠.내가 직접 기록하지 않더라도 내 캘린더의 표시 되어있는 일정을 통해 행사나 이벤트에 참여할 수 있으며 주요 일정들에 대해서는 푸시알림을 통해 일정 시작 전 행사 정보를 파악 할수 있습니다. 락페스티벌을 좋아하시는분이라면 주요 락페스티벌의 티켓팅 및 공연 일정을 받아볼수 있고, 마라톤을 좋아하시는 분이라면 연간 마라톤 일정을 미리 확인 할 수 있게 되는것이죠.현재 린더는 캘린더를 통해 일정을 제공하고 있지만 이는 어디까지나 린더가 정보를 제공하는 여러 채널 중 하나일뿐입니다. 포화 된 앱 시장에서 돌파구를 찾고자 일시적으로 캘린더 플랫폼을 사용하고 있지만, 저희가 확보하고 있는 일정 데이터는 캘린더 뿐만이 아닌 모바일앱, 챗봇, AI스피커 등 다양한 형태로 제공 될 수 있습니다.캘린더에 표시도 안 한 2학기 수강신청을 10분 전에 내게 먼저 알려줄수 있는 앱이 있다면 멋지지 않을까요. 아침에 일어나자마자 고대하던 신상 구두가 출시 되었음을 알려주는 스피커가있다면 사랑스럽지 않을까요.잊고 있었던 티켓팅, 화장품 세일, 축구 경기, 신상 출시를 알려주는 당신만의 비서를 만들기 위해 저희 팀에서는 지속적으로 서비스를 개선해나가고 있습니다.아직 써보지 못하셨다면 사용해보신후 가감없는 피드백 부탁드리며, 내가 만들어도 이것보다 잘만들겠다 싶으신분이 있으시면 제게 연락주세요 ( june@linder.kr ). 제가 잘 꼬드겨서 저희팀으로 모셔갈수 있도록 하겠습니다 :)2017년 8월 2일. 목을 다쳐 하루종일 침대에 누워있지만 더 이상 잠은 안오는 어느날 밤.#히든트랙 #챗봇 #기술기업 #개발자 #개발팀 #인사이트 #경험공유
조회수 1415

대시보드 만들다 문득,

 고수의 프레젠테이션은 늘 심플하다. 읽기 좋은 보고서는 한 페이지로 요약된다. 가진 정보가 많다는 건 좋은 일이지만 때론 감당할 수 없는 양에 압도 당하고 교란 당한다. 정보는 권력이 된다. 그것의 불균형은 누군가에겐 돈을 벌어다 주고 누군가에겐 좋은 일자리를 준다. 정보가 있는 곳엔 그래서 늘 사람과 힘이 몰린다. 하여, 정보제공자에겐 막중한 책임역시 따라야 한다 생각한다. 제공할 정보가 사실에 기반해야 하는 건 물론이고 더 중요한 건 진정 필요한 콤팩트(compact)한 정보만을 제공해야 한다는 것이다. 현재진행형인 대시보드(dashboard) 프로젝트 과정에서 위와 같은 생각이 들었다. 그러면, 주관과 사욕을 완전히 배제하고, 내가 드러내고 보여주고 싶은 정보가 아니라 최대한 많은 이에게 가치롭게 활용되는 정보는 어떤 형태여야 할까? 스스로 답을 내렸다.  우선 사람별, 상황별로 다른 관점과 해석이 양립할 수 없는 요소로 구성돼야 하고, 전달과정에서 요구되는 추가적 배경지식은 불필요해야 하며 필요하다면 극히 적은 양이어야 한다. 무엇보다 관련된 이는 누구나 궁금해 해야 할 것이어야 하고 부차적인 것을 제외한 본질만을 담고 있어야 한다. 이 같은 정보를 핵심정보라고 정의하면 핵심정보는 각각의 업이 가진 '본질적 성장 방정식(fundmetal growth equation)'과 연관이 깊다. 본질적 성장 방정식이란 현 시점에서 비즈니스의 성장을 추진하는 모든 핵심요소, 즉 핵심적인 성장 지렛대를 표현한 간단한 공식을 뜻한다. 제아무리 시가총액 1조를 넘은 기업일지라도 그들의 성장공식을 대여섯 가지의 핵심요소로 도식화하는 것은 가능하며 그것은 제품, 서비스가 가진 성격별로 달라진다. 본질적 성장 방정식을 <진화된 마케팅 그로스 해킹>이란 책에서 나온 사례를 인용해 예시를 들면 아래와 같다.# 이베이의 방정식{아이템을 등록한 판매자의 수}x{등록된 아이템의 수}x{구매자의 수}x{성공적인 거래의 수}=총 매출 성장# 어느 온라인 뉴스사이트의 방정식{웹사이트 트래픽}x{이메일 전환율}x{활성 사용자 비율}x{유료구독으로의 전환율}+다시 찾은 구독자 =총 구독자 매출 성장 이베이의 방정식을 보면 트래픽 양보다는, 거래량을 일정수준 이상 유지하는 것이 성장에 있어 더 중요한 미션일 것이다. 그래서 신규 셀러와 동시에 판매 아이템에 대한 공급이 지속적으로 원활히 이뤄져야만 한다. 아울러 매일, 매주 등록되는 아이템 개수와 그것의 품질, 카테고리 같은 것도 광장히 중요한 관리요소 중 하나일 것이다. 한편, 어느 온라인 뉴스사이트의 경우 트래픽의 양은 광고매출과 직결되고 신규 독자 확보의 가능성을 높여주는 성과의 선행지표다. 뉴스레터 이메일은 수신자를 이후 결제 - 유료구독 -할 확률이 높은 활성 사용자로 전환시키는 데 주력할 것이다. 그래서 사이트를 드나드는 빈도가 높은 활성 사용자층을 얼마나 두껍게 유지하느냐는 온라인 뉴스 비즈니스에서 관건 중 하나일 것이다.  참고: https://www.youtube.com/watch?v=PvSW0ri7AEg기본적인 매출 성장 방정식을 소개하는 강의 동영상이 있어 첨부한다 이처럼 본질적 성장 방정식을 구성하는 요소를 해부해보면 어떤 정보가 현 시점에 우리의 비즈니스를 이끄는 핵심정보이고, 비교적 불필요한 정보인지, 잘 드러난다. 또한, 생각한 것보다 관리해야 할, 혹은 제공해야 할 정보가 적다는 것에 놀란다 - 개인적으론 충격이었다.  페이스북 광고 관리자 페이지에서 관찰할 수 있는 데이터 필드 수는 맞춤설정 활용 시 약 300개까지 지원된다. 그들 중 절반은 서비스와 관련성이 적거나 매일 추적한다 해도 당장의 마케팅 관련 의사결정에 도움을 주지 못하는 것이 대부분일 수 있다. 구글애널리틱스에서 제공하는 지표 또한 마찬가지다. 이탈률을 체크하는 것이 중요하다고들 하지만, 서비스의 태생적 특성 상, 신규 사용자 유치를 위해 지속적이고 공격적인 온라인 광고가 불가피하다면? 때론 업계 평균보다 높은 이탈률이 당연한 것이고 그것이 가진 시사점은 적을 수도 있다. 단지 '쿨'해 보이는 지표를 관찰할 게 아니라 각각의 비즈니스 '실정'에 맞는 성장 방정식을 꾸리고 그것을 지켜 보는 게 중요하단 말이다. 결론적으로 다시 대시보드 이야기로 돌아가면, 정보판으로써 구실하기 위한 최소요건으로 대시보드에는 성장 방정식을 이루는 구성요소만 들어있으면 된다. 그것들이 최소요건이자 거의 대부분이다. 그 외 정보는 실제로는 불필요하거나 수요가 낮은 정보일 가능성이 높다. 물론 그런 정보는 필요에 따라 '드릴 다운' 방식으로 제공하는 것도 좋겠다. 하지만 당장의 우선순위는 아니란 것이다. 대시보드의 첫인상은 고수의 피티처럼 심플하고, 잘 짜여진 보고서 앞 한 장 요약본처럼 말하는 바가 적확해야 한다.블랭크 코퍼레이션의 CI내밀한 이야기가 될 수 있는데, 대시보드 프로젝트를 진행하며 자사 비즈니스의 본질적 성장 방정식은 어떻게 생겼을까, 혼자 그려봤다. 디지털 마케팅  중심적 사고이기 때문에 주관적이며 생각차는 있을 수 있다. 그리고 미래의 가변적 환경을 반영하지 않았다. 어차피 대시보드에선 미래를 projection하지 않기 때문이다.# (현 시점 기준) blank의 방정식{상품기획력}x{콘텐츠 파워}x{SNS 광고비}x{광고유입후 0일-1일내 구매하는 이의 비율}x{재구매율}x{고객생애가치}= 성장의 크기 방정식 안에 bold체로 표시된 요소를 살펴보자. 내가 생각하는 - 공식적인 내용이 아니다 - 우리의 모델 안에서 {SNS 광고비}는 성장(매출)의 크기를 좌우하는 핵심인자다. 광고를 통해 설득 당한 잠재고객을 단번에 구매로 이끌 수 있는 흡인력 - 앞선 방정식에선 {광고유입후 0일-1일내에 구매하는 이의 비율}로 표시했다 - 을 지속하느냐 또한 DR(direct response ; 직접 반응) 마케팅에서 관찰하고 관리해야 할 주요요소다. 이후 구매자의 {재구매율}과 {생애가치}도 이해하고 관리할 수 있다면 완벽할 것이다. 하지만 해당 지표의 정의와 계산은 마냥 쉽지 않기에 정밀한 설정 안에서 관련 정보의 해상도를 높이는 일이 요구된다. 이 정도의 정보가 현 시점에서 마케팅 유닛에서 필수적으로 관찰하고, 유관부서에 공유해야 할 핵심지표가 될 수 있을 것이다. 대시보드 상에 CTR(클릭률), CPC(클릭당비용), CPM(1,000회 노출당비용)과 같은 매일의 광고지표를 넣었다간 보는 이로 하여금 복잡성만 가중시킬 뿐이다. 전자상거래 마케팅 과정에서 오직 알아야 할 정보는 "광고비를 얼마나 효율적으로 투자해 얼마를 벌었는가"라고 생각한다. 현재 페이스북이 제공하는 구매 최적화 광고의 알고리듬 상에선 구매 수와 CPA(액션당비용, 구매당비용) 외 다른 지표들은 그때그때 알고리듬 컨디션에 따라 결정되는 후행지표이자 수단일 뿐이다 - 이 부분은 나중에 기회가 있다면 더 설명해보고 싶고 다른 이와 토의하고 싶다. 불과 얼마 전까지 - 아니면 지금까지; - 난 아마도, 엑셀 시트에 피봇테이블을 덕지덕지 붙여넣고 형형색색으로 트렌드를 표시하면 좋은 정보가 되는 줄 착각했었다. 그리고 난 데이터분석가도 아니고 고급통계지식이 풍부한 편도 아니다. 프로그래밍을 할 줄 알아 데이터 처리기술이 남다른가? 고작 엑셀 단축키와 기본 함수를 사용해 평균보단 빠르게 잔머릴 굴리는 정도다. 하지만 최근에는 시각화, 데이터분석, 고급통계지식 모두 중요한 정보를 전달하는 수단일 뿐이란 생각이 든다. 자기위로적 감상일 수 있지만, 정말로, 정보를 다루는 데 있어 그러한 스킬보다 중요한 건 진정 필요한 정보를 옥석 가리듯 가려내는 정보 분별력이라고 생각한다. 수단에 현혹돼 정작 알맹이는 없고, 누구에게도 도움되지 않는 보고서를 만드는 일이 어떤 마케터, 사업PM에게도 없었으면 하는 바람이다.(끝)Jin Young Choi회사원
조회수 1013

개발자의 경력관리란?

경력이 아닌 업력이 되는 단계에 이르러야 가능한 것 아닌가 합니다.대부분의 경력은 '어느 회사의 누구'라는 표현에서 만들어진 것이 아닙니다.진정한 경력의 결과는 '자신의 이름'이 곧 브랜드화 되는 것입니다.매우 당연하게,하루 이틀, 한 두해 한다고 해서 얻어지는 것이 아닙니다."10년 경력!"10년 이상 한 분야나 하나의 도메인, 하나의 테크, 하나의 경력, 하나의 경험을 꾸준하게 파고들었을 때에 얻어지고, 그러는 경험속에서 인사이트, 통찰력이 생기게 됩니다.물론. 그래서, 20대에도 명성을 얻을 수 있는 '경력관리'가 가능하다고 이야기합니다.(실제 얻은 사람을 많이 봤습니다. 그들은 10대에 시작했죠. )회사의 테두리 내에서 얻을 수 있는 '경력'은 '경험'일뿐입니다.자신의 이름을 중심으로 기술할 수 있을 때에 '경력'이라고 이야기할 수 있습니다.개발자라면...글을 써서도 얻을 수 있고,강연을 해서도 얻을 수 있고,GitHub에 오픈소스를 공개하면서도 얻을 수 있습니다.현재 30대와 그 이전의 개발자라면...10대와 20대도 똑같습니다.40대, 50대 이후를 준비하세요.반복적인 일, 똑같은 일, 회사의 프로세스의 하나인 일만 하는 '사람'이라면...그냥, 그 회사의 톱니바퀴가 되는 것입니다.대부분 '경력관리'가 잘 안됩니다.앞으로 50대 이후에도 '브랜드'를 얻을 사람이 되려면...자신의 '경력'관리를 잘 해야 얻을 수 있습니다.나중에 닭 튀기거나 치킨 배달할 것이 아니라면...관리를 잘해야 합니다.경력관리가 가능하려면 어떤 회사를 찾아야 할까요.다음을 기억하세요.1. 구루급 개발자가 있는 회사를 찾으세요.2. 자신이 주도적으로 무언가를 만들 수 있는 권한과 책임을 줄 수 있는 회사를 찾으세요.3. 커뮤니티나 외부 강연, 외부 오픈소스 개발 행사에 적극 참여할 수 있는 기회를 주는 회사를 찾으세요.4. 반복적인 업무와 정체된 마켓에서만 반복적으로 서비스를 하는 회사는 회피하세요.5. 우리 도메인은 원래 이래, 이 일은 원래 이래... 이런 식으로 이야기하는 '상급자'가 있는 회사를 피하세요.6. 쉽게 설명할 수 있도록 준비하고, 리뷰를 할 수 있는 기회와 시간이 주어지는 회사를 찾으세요.그리고, 마지막으로...비전은 누가 주거나 만들어 주지 않습니다.결국, 자기 자신이 찾아야 하는데...이것도, 주변에 이야기가 통하는 '구루급 개발자'가 있어야 그나마 방향성을 찾기 좋습니다.혼자 고민하거나,주변에 비슷한 사람들끼리 고민해봐야 답이 안 나옵니다.꼭, 기억하세요!'구루급 개발자'와 상의하세요.그분들은 실패와 성공, 포기와 단념, 선택과 집중에 대해서 알고 있답니다.퇴근시간이라면..구루급 개발자에게 치맥 한잔 하자고 하세요!
조회수 1722

소프트웨어 개발자에게 성공이란...

소프트웨어 개발자들이 생각하는 ‘성공’이라는 단어와 키워드에는 어떤 것들의 의미를 포함하고 있을까? 한편으로는 단편적이고 획일적인 ‘성공’이라는 단어에 너무 많은 개발자들이 매몰되어 있는 것 아닌가 하는 생각을 해본다. 필자 스스로 실무경력 20년을 넘겨서 소프트웨어 개발을 하고 있는 경험을 바탕으로 주변의 성공한 개발자들에 대해서 혼자 생각해 보았다.일반적으로 의미의 ‘성공’이라는 것이 무엇을 의미하는 것인가에 대한 정의는 이번 칼럼의 말미에서 이야기하도록 하자. 정말 많은지 모를 대한민국에서 성공한 개발회사나 개발된 서비스들을 살펴보는 것부터 시작을 하는 것이 정답인지는 필자도 잘 모르겠다. 성공적인 서비스나 소프트웨어, 프로그램은 세상에 선보인다는 것. 그러한 것을 만들어낸 순수한 아이디어나 원천기술로 무장한 기술로 축적되었고, 그 아이디어를  뛰어넘어, 새로운 기술이라고 할 수 있는 것을 보유한 제품이나 상품들이 얼마나 되는지에 대해서부터 냉정하게 필자는 잘 모르겠다라고 먼저 인지하고 넘어가자. 아니, 다시 말하자면, 냉정하게 국내에서 그런 것을 본적이 별로 없는  듯하다.더욱더 삐딱하게 이야기하자면, 국내에서 성공한 개발 서비스들은 대부분 아류작이거나 남의 아이디어를 도용한 제품과 서비스들이 대부분이 아닌가라고 생각한다. 심지어는 특정 솔루션 시장은 오픈소스를 그대로 제품에 반영해 두고서는 자신의 제품인 것처럼 위장하는 사례까지 보이고 있으니, 과연 대한민국 소프트웨어 시장은 과연 얼마나 ‘성공’이라는 키워드를 그대로 사용해도 되는지에 대해서 매우 의문시된다.(물론, 필자의 삐딱한 시선에서만 그렇게 보일지도 모른다.)대한민국의 소프트웨어 시장에서 1위를 지키고 있다고 하는 서비스와 제품들이 되려면 어떻게 해야 하는가?. 삐딱하게 이야기하자면, 오로지, 대한민국에서 성공한 개발회사나 개발자가 되려면, 창의적인 아이디어나, 독특한 아이디어로 무장하는 승부수를 던지기 보다는, 해외의 서비스 중에 알차고, 괜찮은 것들에 대해서 관심을 가지는 것이 중요하다고 생각한다. ( 그래서, 영어공부를 잘해야 하는지도 모르겠다. )필자가, 대기업과 신규사업기획을 할 때에 작업하는 내용을 보고서는 경악을 금치 못했던 경험을 한적이 있다. 정말 상당한 컨설팅 금액( 수십억을 넘긴 비용 )을 지불해서, 대기업이 유명한 컨설팅업체를 통해서 신규사업에 대한 기획과 아이디어에 대한 컨설팅을 받는 것에 전문가의 한 사람의 참여했었다. 그런데, 그 중요한 작업의 모티브는 해외에서 이미 성공적으로 안착한 서비스에 대한 분석과, 한국에서의 서비스 시에 벌어질 일에 대해서 예측을 하는 일을 하고 있었다는 점이다. 새로운 아이디어가 아니라는 점이다.물론, 성공한 서비스를 도입해서, 로컬 화한다는 것 또한 매우 어려운 일이라고 생각하지만, 대부분의 새로운 기획이나 신규 서비스에 대한 작업들의 대부분을 이런 식으로 진행한다는 이야기를 들었을 때에 받은 충격은 정말 놀라운 경험이었다, 물론, 지나고 나서 생각해보니, 그렇게 놀랄만한 경험도 아니었는지 모르겠다. 대부분의 대기업들이 이런 식으로 한다는 이야기를 듣고 더 놀라기는 했지만. 물론, 이렇게 로컬화 한다는 것 자체도 대단한 도전이고 어려운 점이라는 것은 인정한다고 하지만, 이런 로컬화와 아류작에 대해서 비판적인 시야를 가진 필자의 생각은 그렇다.성공한 서비스들은 대부분 아류작들이다?냉정하게 국내에서 성공한 대부분의 서비스들은 아류작들이고, 복제본들이고, 독창적인 아이디어보다는 해외 서비스를 대부분 국내에 안착한 서비스라고 생각한다. 심지어 독창적인 mp3 플레이어마저도, 아이팟의 생태계가 한층 더 발전적인 시장을 창출했으니, 국내에서 만들어진 디지털적인 요소들 중에 독창적인 것이 얼마나 있는가?필자는 생각한다. 예술에 있어서 복제와 창작의 차이는 매우 크다는 것을. 물론, 소프트웨어 개발이 이런 예술에 비견될 정도의 가치를 부여해서 그런 것 만은 아니다. 소프트웨어 개발은 아이디어와 구현하고자 하는 추진력과 열정이 결합되어져서 만들어지는 최고의 가치 구현을 위한 세계이기 때문에 그렇게 생각할 뿐이다.필자가 좋아하는 만화 중에 ‘맛의 달인’이라는 만화에 나온 표현을 그대로 옮기자면 다음과 같은 장면이 나온다. 프랑스의 유명한 요리를 그대로 일본에서 구현하지만, 그 요리에 대한 평가는 ‘프랑스의 요리를 그대로 구현한 요리이다’. ‘매우 아름답지만 최저의 요리’라는 평가를 받는다. 그러한 최저의 요리라는 평가를 받은 이유는 ‘로컬화 한다는 것은 실정에 맞게 고치고, 연구 개발한 맛이라면 완벽하겠지만. 너무도 프랑스 요리와 똑같이 만든 것은 처절한 아류라는 점이다. 지금 먹은 요리에는 프랑스 요리사의 모습이 그대로 남아있다는 점. 원형이 프랑스의 것을 그대로 답습했다는 것.오리지널을 복사했다는 냉정한 평가는 정말 명확하다. 요즘 가장 국내에서 최근에 성공한 서비스를 이야기한다면, 카카오톡과 애니팡을 예로 들 수 있겠다. 다른 사람들은 어떻게 평가할지 모르지만, 정말 대단한 성공을 가진 것은 사실이다. 하지만, 둘 다 원형을 그대로 복사했을 뿐, 새로운 것은 아무것도 없다는 점이다. 아니, 오히려. 기존의 원형을 대한민국의 안 좋은 통신사의 서비스와 결합한 케이스라고 평가를 해야 정확하지 않을까 한다. 원형을 오히려 퇴보시킨 서비스라고 평가하고 싶다.카카오톡은 WatsApp을 그대로 복제했다. 대표적으로 등록되어진 전화번호로 연계하는 원형의 아이디어를 그대로 받아들였다. 하지만, 카카오톡의 새로운 신규 비즈니스 모델인 게임센터는 자체적인 생태계를 만들어서 통제하려 하는 기존의 통신사의 방식과 그다지 차이가 없다고 보인다. 뭐, 돈을 벌어야 하는 기업의 입장을 반대하는 것이 아니다. 단지, 필자의 삐딱한 시선으로는 진보를 위한 선택이 아니라, 퇴보를 위한 선택이었다는 점이 불편할 뿐이다.애니팡도 마찬가지이다. 기존의 게임방식을 그대로 복제했다. 그리고, ‘하트’라는 이름으로 무분별한 ‘스팸’을 활성화해서, 기존 통신사들이 SMS에서 얻어들이는 대량 SMS 발송을 통한 이익을, 그대로 실현한 점이다.물론, 카카오톡이나 애니팡의 ‘이익 실현 구조’는 매우 성공적으로 국내에 론칭한 것은 사실이고, 이러한 구조로 ‘돈’을 벌어야 한다는 점이 매우 안타까울 뿐이다. 개인적으로는 ‘국내’에서는 어느 정도 ‘돈을 버는 성공은’할 수 있지만, 해외에서까지 성공적으로 론칭할 것인지는 조금 의심스럽다. ( 어차피, ‘돈’을 벌면 성공이라는 관점으로는 매우 대성공이다. )넥슨의 카트라이더와 마리오 카드와 같이 일일이 나열하기에는 너무도 많은 사례들이 있어서 굳이 더 나열하지 않겠다.다만. 정말 중요한 것은 복사보다는 진짜가 더 좋다는 점이다. 가령, 오리지널이 존재하는 영역이나 예술과 같은 고부가가치의 영역에서는 ‘화가나 작가가 다른 사람의 작품을 흉내내면  웃음거리밖에 되지 않는다’는 점을 이야기하고 싶다. 필자 개인적으로는 ‘그런 웃음거리를 통한 수익실현’을 그렇게 높게 평가하고 싶지 않기 때문이다.대표적으로 통신사는 ‘스팸’과 ‘보이스 피싱’을 해결하지 못하는가? 에 대해서 필자는 그렇게 생각한다. ‘대량 SMS수입’을 포기하지 못하고, ‘전화번호를 통한 대량 통화의 수익’을 포기하지 못하는 구조적인 문제 때문에 그렇다고 생각한다.과거에 문제가 된 iOS6로 업데이트가 되면서 SKT 아이폰4S에서 발생한 전화번호 호출의 문제, ‘112 신고가 안 되는 아이폰’이라는 기사와 사건에 대한 문제의 근본적인 원인은 SKT가 국제표준 방식을 따르지 않아서 발생한 문제라는 것을 모르는 사람들이 정말 많다. 이 문제를 더 파고들어가면, 부당한 SMS수입을 얻고 있는 국내 통신사들의 부도덕한 점도 드러난다. 2003년 이후 3G 서비스(WCDMA)가 도입되었지만, 문자 메시지 국제표준이 기존의 80 byte에서 140 byte로 늘어났지만, 정작 통신사들은 국제표준규격을 지키지 않으면서 연간 수백억의 이익을 부당하게 얻어냈다. 다만. 아이폰4s 출시 당시 KT는 140바이트를 맞추었지만, SKT는 아직도 80 byte였다는 점을 예로 들고 싶다.국제표준을 따르거나, 해외의 서비스가 ‘돈’이 되는 것에는 빠르지만, ‘돈’이 안 되는 기준에는 미온적이고, 대처가 느린 것에 대해서는 참으로 훌룡(?)한 성공적인 방법이라고 평가를 굳이 필자와 같은 주변 사람이 할 필요가 있을까 한다. 그런 훌륭한 평가는 비싼 컨설팅 비용을 지불한 뛰어난 전문가들이 할 것이기 때문에...내 주변에 성공한 개발자와 성공한 벤처 사업가...성공한 개발자. 고급 승용차를 몰고, 출근하는 개발자의 모습을 본다면, 성공한 개발자의 향기를 느낄 수 있을까? 물론, 일반적으로 그럴 수 있다고 생각한다.자본주의 사회에서 ‘돈’은 그 사람을 평가하는 가장 기본적인 ‘수단’이기 때문이다. 성공하지 못한 필자는 아니지만, 필자 주변에는 고급 승용차인 BMW나 벤츠를 직접 몰고 다니는 성공한 개발자들이 여럿 있다. 그리고, 상당히 많다. 사업을 하는 사람으로부터, 프리랜서인 사람까지 매우 다양하다.분명, 그들은, 자신만의 서비스와 제품을 실현하였고, 시장에서도 안정적인 자신만의 브랜드를 확립하였고, 후배들로 존경을 받고 있으며, 직원들에게 비전과 꿈을 주고 있으며, 새로운 기술과 시장에 대해서 언제나 도전하고 있는 사람들이 있다.그들은 충분히 ‘성공’한 사람들이다.‘복제’와 ‘아류작’이 아니더라도. 독특한 자신들만의 서비스와 제품을 구현하여 성공한 개발자들이 분명 존재한다.그들의 성공요인을 주변의 사람으로서 살펴본다면, 몇 가지의 요인이 있다고 정의할 수 있다. 그것들을 필자의 주관적인 생각으로 정리해보면, 크게 4가지 정도로 정리할 수 있다고 본다.하나. 그들은 뛰어난 개발자는 아니었다.그들은 아주 탁월한 능력을 소유한 개발자들은 아니었다는 점이다. 그리고, 아주 뛰어난 학벌을 가진 개발자들도 아니었다. 개발자 동호회에서 만난 친구도 있고, 직장생활이나 사회생활에서 만난 사람도 있었지만. 그들은 아주 탁월한 재능을 지녔거나, 엄청난 코딩능력, 뛰어난 직관을 지닌 사람만은 아니었다.순수한 개발 능력만 놓고 본다면, 오히려, 뒤처지는 개발자들이었는지도 모른다. 하지만, 뛰어난 개발자들이나 아이디어를 가진 사람들과 친하게 지냈으며, 그들의 도움을 자연스럽게 얻어내는 소통의 달인은 아니었지만, 개발자 커뮤니티에 매우 즐겁게 활동을 하던 사람들이었다.둘. 그들은 우직하지만, 묵묵하게 자신의 상품과 아이디어를 다듬었다.그들은 하나의 아이디어가 실현되는 것을 쉽게 포기하지 않았다. 사업을 하기 전에는 그 아이디어를 실현하기 위해서 애썼고, 속한 회사가 아이디어에 대해서 낮은 평가를 하는 것에 대해서도 크게 실망하지 않았다. 오히려, 반대를 해도 해당 서비스와 제품, 기술에 대한 애정이 정말 높았으며, 그것을 실현하려고 매우 애썼다.처음에는 언제나 소프트웨어는 단순한 것부터 시작한다.그 단순한 것을 꾸준하게 다듬고, 소프트웨어에서 제품으로 다듬어서 시장에서 가치를 인정받을 수 있도록 수년 이상을 투자하고 노력해야만 얻어진다. 그것은 스티브 잡스도 똑같았다. iOS는 하루 이틀 만에 나온 소프트웨어가 아니기 때문이다.심지어, 몇 년 동안 밥을 굶더라도, 자신이 생각하는 가치를 실현하기 위해서 포기하지 않고 도전했던 우직한 도전이 오히려 성공을 만들어 내었다. 분명, 훌륭한 소프트웨어는 뛰어난 기술로 만들어지는 것만은 아니다는 것을 요 근래에서야 필자도 느낀다.필요한 가치가 적정한 가격에 구현되어진 것이 정말 필요하다는 점이다. 뛰어난 기술이 뛰어난 제품을 만드는 것이 아니라, 뛰어난 제품이 뛰어난 기술을 만든다는 것이다. 그것이 사용자들로 하여금, 또 다른 가치를 얻을 수 있는 기능을 제공한다는 것에 대해서 굳이 설명하지 않더라도, 그들은 그 아이디어와 생각을 실현하기 위해서 자신만의 길을 걸었다.정말 우직할 정도로... 필자 주변의 그들은, 몇 년을 일 년에 몇백만 원을 벌더라도, 그 꿈을 포기하지 않았다.셋. 시장과 세상의 시선을 그렇게 두려워하지 않았다. 자신의 ‘가치’와 ‘비전’을 실현했다.자신의 아이디어와 자신의 서비스, 제품을 지키기 위해서 약간의 주변 사람들에게 욕을  얻어먹는 것을  두려워하지 않는다. 필자가 아는 어떤 기업은 시장에서는 냉혈안이라는 말도 듣고, 불법 복제된 제품에 대해서는 가차 없는 소송도 불사하는 어떤 기업을 알고 있다. 하지만, 그 회사와 그 사장에 대해서 필자는 비난하지 않는다. 왜냐하면, 그는 기업 내부의 직원들에게는 절대 급여를 밀리지 않고, 야근을 시키지 않는 최고의 사장이었기 때문이다.시장과 타인에게는 가차 없지만, 자신이 생각한 비전을 실현한 회사를 만들기 위해서 언제나 최선을 다하는 사람이었을 뿐이다. 그리고, 자기 것을 지키기 위해서 애를 썼고, 직원들과의 거리도 언제나 적절하게 유지했다. 냉정하게 기업과 사업이라는 것은 자선사업이 아니라는 것을 잘 알고 있었다. 충분하게 돈을 벌고, 외제 승용차를 사장은 타고 다니지만 ( 외제 승용차를 타는 것도, 대한민국은 간단하다. 법인세를 충분하게 낼 정도로 수익이 생기면, 그 수익으로 차를 리스해서 타면 간단하다는 대한민국의 세법 구조 때문이다. ), 모든 직원들에게 그 이익을 100% 나누어주지는 않는다. 직원은 직원일 뿐이니까.그들은 회사의 재정이 힘들어지면 소속된 직원을 힘들기 전에 내보낼 줄도 알고, 필요하다면... 해고도 그리 어렵지 않게 결정하는 사람도 있다, 영업기밀을  들고나간 직원과 소송도 불사했다. 차라리, 친구와 따로 술을  마실지언정, 직원들과의 ‘관계’는 냉정하고 쿨한 관계를 유지했다. (물론, 그렇지만. 인간관계가 깨어지는 것을 매우 괴로워하는 사람들이다. 다만, 아래 직원들에게 속시원히 이야기를 못할 뿐이다. )넷. 필요한 기술자나 기술은 기필코 얻으려 노력했다.그들은 자신이 부족한 점을 잘 이해하고 있었다. 부족한 것을 오히려, 더 널리, 많이 이야기를 하였다. 그리고, 그것을 커버하기 위해서 매우 많은 노력을 한다. 다 잘하고자 하는 팔방미인이 되는 것이 아니라, 자신이 부족한 점을, 자신이 가장 잘하는 것으로 커버하려 애쓴 것이다. 전문적인 기술을 소유한 사람에게 도움 요청하는 것을 부끄러워하지 않고, 도와준 사람에게 충분한 대우나 접대를 잊지 않았다. 그래서, 그들이 도와달라고 하면, 주변의 전문가들이 아낌없이 그를 도와준다.그 이외에서 그들은 그렇게 ‘성실’하게 일하는 친구들은 아니었다. 실제, 사장이었던 그들이 직원의 입장으로 회사를 다닐 때에는 근태 문제로 지적을 받은 친구들도 꽤 많다는 점이다. 아마도, 사업이나 자신이 좋아하는 일을 하는 것과, 어떤 일이 주어진 상태에서 일을 하는 것은 분명 다른 지도 모르겠다. 직원일 때에 불성실하지만, 자신의 일을 할 때에 성실한 것은 전혀 상관관계가 없어 보인다. 한편으로는 ‘사장’이나 ‘자신의 일’을 하는 사람의 경우에는 특별하게 ‘근무시간’이라는 것 자체는 큰 의미가 없다는 점이 더 정답일 것이다. 하여간, 그들은 성공한 개발자들이고, 성공한 기업인이 되어 있었다. 자신만의 제품이나 서비스를 만들면 자연스럽게 ‘사장’이 되어버리는 것이 소프트웨어 업계의 현실인 듯하다.그렇다면, 대한민국에서 ‘성공’이란 ‘돈’을 의미하는가?강남의 최고급 아파트와 외제 승용차가 성공을 의미할까?자신의 뛰어난 기술력으로 커뮤니티에서 인정받고, 유명해진 명예를 얻는 것이 성공을 의미할까? 다른 사회현상을 생각하면서 다시 한번 비교해보자.요즘 개발자들도 오디션 프로에 영향을 받은 듯하다. 요즘 연예계 지망자들이나 배우나, 가수를 꿈꾸는 친구들이 선배나 멘토들에게 묻는 것이 언제나 똑같다고 한다.그것은 ‘빠르게 성공’하고 ‘빠르게 명예’를 얻는 방법이 무엇이냐 묻는 것이다.어렵고 복잡하고, 길게 걸리는 방법은 무시하고, 오디션 프로에서 1등을 해서, 빠르게 성공하는 방법만을 생각한다고 한다.물론, 그 방법도 있을 것이다.소프트웨어의 세계에도 똑같은 방법이 있다. 대표적인 방법이 유명대학을 가서, S 멤버쉽이 되고, 대기업에 입사해서 경력을 쌓은 다음, 해외의 서비스를 적당하게 분석하다가, 성공적으로 론칭한 서비스를 재빠르게 국내에 도입해서 성공에 이르게 하는 방법이 아마도 가장 빠른 방법일 수 있겠다.물론, 이 방법으로 ‘성공’을 쟁취하려 하는 개발자라고 하더라도. 비난하지 않는다.분명, 그 길은 대다수 ‘성공’이라고 부른다. 하지만, 그 길을 선택하고 집중하는 것 또한 매우 어렵고 힘든 길이다. 선택한다고 얻을 수 있는 길도 아니다.가령, 이 글을 읽는 독자가 학생이라면. 가장 먼저 명문대학을 가는 것부터 시작해야 할 테니, 당장, 이 내용을 덮어버리고, 국영수를 공부하는 것에 몰두해야 하기 때문이다.사실, 가장 넓게 알려진 성공으로 가는 길은 가장 가기 어려운 길인지도 모른다. 경쟁이란 정말 어렵고 힘들 것이라는 것을 잊지 말자.본론으로 다시 돌아와 보자. 개발자로서 '성공'이란 무엇을 의미하는가? 아니, 개발자로서 비전을  갖는다는 것은 무엇을 의미하는가?  원천적으로 개발자의 삶이란 어떻게 살아야 하나요라고 묻는다면,이 문제는 정말 어렵고, 사람마다 다르기 때문에 최선을 다하는 것이 정답이라라는 교과서적인 답변만 늘어놔야 하는지도 모르겠다.이점에 대해서는 이제는 폐간했지만 오랫동안 개발자들의 벗이 되었던 마이크로소프트웨어 잡지에 대해서 원망을  슬쩍해보자.그것은, 나에게 ‘정말 대단히 큰 재미’를 선사했다는 것이 나에게 가장 처음 다가온 충격이었는지도 모른다. 처음에 가진 꿈은 그냥, ‘소프트웨어 개발’을 통해서 삶을 영유할 수 있는 것만으로 나는 행복했다는 점이다. 그래서, 이 소프트웨어의 세계로 진입하게 된 마이크로소프트웨어에 대해서 원망을 해야 하는지도 모르겠다.하지만 필자는 소프트웨어로써 ‘개발자로서 성공’을 하기 위해서, 이 직업과 삶을 선택한 것이 아니라, ‘개발자로 살기 위해서’이 삶을 선택한 것이었다. 나이를 먹고, 무언가를 목표로 살아온 경험을  되돌아본다면, ‘돈’과 ‘명예’를 선택하지 않았을 때에, 오히려, ‘돈’과 ‘명예’를 얻지 않았는가 하다. 오히려, ‘돈’을 선택하던 시기에 ‘돈’을 더 많이 잃어버린 경험도 가지게 되었다.이제는 주변을  되돌아보면, 필자는 꽤 넓은 스펙트럼을 가지게 되었다는 것을 느끼게 된다. 한때는 고인이 되셨지만 대통령이셨던 분부터, 수천억을 소유한 재벌 총수, 의료재단과 대학법인을 소유하신 분, 병원의 원장님들을 비롯한 분들을 비롯하여, 출판계, 영화계, 물론. 다수의 소프트웨어 개발자들까지. 매우 넓은 사람 관계를 만들어본 것 같다.그중에 소프트웨어 개발자들은 참 착하고 바보스러운 사람들이 많은 것 같지만, 한편으로는 너무도 욕심이 많은 사람들이 존재하는 참, 신기한 동네이다.그리고, 여러 계층을 경험해보니. 모든 계층은 똑같이 피라미드 구조를 가지고 있다는 점이다. 대부분 다 똑같았다. 하층의 사람들은 싼 가격에 노동력과 지식을 제공하고, 상위 레벨에서는 적절한 대우 이상과 재미있고 신기한 일들을 많이 한다는 점이다. 이 부분은 어느 계층이나 똑같다.대표적으로 출판일을 경험했을 때에 자신의 이름이 들어간 편집장이 되는 사람과, 그것을 목표로 기획자로 일하는 직원의 급여 수준이나 처우, 대우는 정말 최고급 아키텍트와 SI 개발자를 비교하는 것 이상으로 그 상대 감은 소프트웨어 개발세 상의 것 이상으로 매우 컸다.행복한 개발자라고 한다면, ‘개발이 정말 재미있고’, ‘개발도 잘하고’, ‘소프트웨어 개발 피라미드의 상층부의 일’을 하고 있다는 사람이 있다면. 그 사람은 정말 행복할 것이다. 뭐, 그런 사람은 이 글을 읽고 있지도 않을 것이다.그러나, 개발이 재미있지 않거나, 개발을 뛰어나게 잘하지도 못하고, 소프트웨어 개발 피라미드의 하층부에서 일하고 있다면, 어떻게 생존해야 하는 가에 대해서 정말 심각하게 고민해야 한다.이 글을 읽는 독자가 이제 개발자의 길을 시작한 사람이라면 고민해라, 소프트웨어 개발을 비롯한 모든 전문적인 직업들은 새로운 것을 배우고, 익히고, 소모하면서 계속 변화되는 것을 즐길 줄 알아야 재미있는 직업이다. 그런 것이 아니라면, 정말 힘들고, 피곤하고 어려운 것이 전문직과 같은 직업이다. 만일 그런 것이 힘들다면 다른 일을 알아보는 것이 현명하다.소프트웨어 개발자들과 가장 비슷하게 일하는 웹디자이너들의 푸념이 있다.‘낮은 급여에 야근은 허구한 날, 거기에. 불투명한 미래’에 대한 그들의 이야기를 들으면서, 흔히 소프트웨어 개발자들은 그 질문에 답변한다. ‘너희들은 모니터라도 크지’라고. 대부분의 프로젝트들은 ‘분석’에 의해서 ‘일정’을 만들지 않고, ‘일정’을 통해서, ‘품질’을 선택한다고 봐야 한다.‘정말 하고 싶은 것이 무엇인가?’개발자들에게 물어보면, 대부분 당황하는 경우가 많다. 이것은 개발자이기 때문에 답변을 못하는 것이 아니라, 자신의 비전이나 꿈에 대해서 명쾌하게 정의하지 못하고 있기 때문이다. 주변의 초보 개발자들에게 이야기하고 싶은 점은...가끔은 수필집이나 여행기, 그리고. 다른 사람의 생각과 꿈에 대한 글을 많이 읽어보라고 권하는 것이다. 그러면, 그 비전과 꿈에 대해서 이야기해달라는 사람들이 꽤나 있고는 하다.문제는 그 비전은 누가 정해주는 것이 아니라, 자신이 생각하거나, 자신이 발견하는 것이 옳지 않냐고 다시 이야기를 해준다. 물론, 이렇게 이야기하는 사람도 있다.‘저는 이번 프로젝트에서 인정을 받아서, 다음 프로젝트를 수행할 때에는 팀장이 되고 싶어요!’라고 이야기할 수 있다. 하지만, 이런 ‘단기적인 비전’을 말하는 것은 아니다. 이런 ‘단기적인 비전’만을 따라가다 보면, 냉정하게 수단만 중요시 여기게 되고, 목적 자체를 잃어버린 인생의 방랑자가 될 가능성이 매우 크다.내가 생각하는 ‘성공’이란 과연 무엇인가?또 하나는, 그 ‘성공’의 목표를 너무 작게 가져도 문제이고, 너무 커도 문제라는 점이지만, 그래도, ‘꿈’과 ‘목표’가 있다는 것 자체가 재미있고, 신기하지 아니한가?‘성공은 자신이 정한 것을 이루는 것’을 의미한다고.그럼 ‘꿈’을 어떻게 정의하나요?1. 10년, 20년, 30년 후의 자신의 모습을 상상해보고 정의해봐라.2. 현재 내가 좋아하는 모든 것들을 적어봐라.3. 내가 가장 잘하고 가장 인정받는 것을 적어봐라.보통은 이렇게 끄적거리다 보면, 무언가가 조금은 구체적인 비전이 나올 수도 있지만, 아무렇지도 않은 것이 나올 수 있다. 하지만, 일단, 끄적이기 시작했다면, 다음번에는 좀 더 잘할 수 있다는 것이 중요하다. 가장 중요한 것은 ‘내가 비전에 대해서 생각하기 시작했다’는 점이다. 일단 작심 3일이라도 중요한 결정이다. 그것은, ‘결정’을 하고 ‘결심’을 하기 시작했다는 것이기 때문이다.일단, ‘써야 한다’. ‘생각은 생각일 뿐이다’주변의 개발자들이 가장 잘 못쓰는 말 중의 하나가 ‘머릿속에 다 있다’라는 말이고, ‘글로 쓰기에 너무 어려운 이야기’이다라는 이야기가 가장 잘못된 것이라는 것을 잘 모르는 경우가 많다.‘머릿속에 다 있다’라는 이야기는 한번 생각은 해봤으나, 결론을 내리지 못하였다는 이야기로 들리고, ‘글로 쓰기 어렵다는 이야기’는 그만큼 정리가 안되고, 그 일에 대해서 잘 모른다는 이야기와 똑같다.10년 20년 특정 도메인에서 일한 베테랑이라고 하는 개발자와 일을 할 때에, 자신이 하는 일은 너무도 복잡하여, 설계도나 다이어그램, 순서도, 타이밍 차트 등을 그릴 수 없다는 사람들이 있다.그들과 이야기하고, 그 업무를 다이어그램과 설계도로 만들어 주어도, 그들은 그것 말고, 설명이 안 되는 그 무언가가 있다고 이야기를 한다. 물론, 필자는 그때에 이렇게  이야기해준다.‘만일 그러한 것이 존재한다면. 그것은 당신만이 생각하는 경험이나 당신이 소중하게 생각하는 가치인지 모른다. 하지만, 그것은 어떤 지식이 되기에 매우 부족한 것일 수 있다. 지식은 설명하기 쉽고, 이해하기 쉬운 것이 지식이다. 설명하기 어려운 경험은 정규화되거나 전달되어지기 매우 어렵다’더 쉽게 이야기하면. ‘쉽게 설명하거나 글자로 남기지 못한다면, 당신은 그것에 대해서 잘 알고 있지 못한 것입니다’비전이나 목표 잡기가 너무 어려워요?!그렇다면, 당장 휴일에 컴퓨터를 내버려두고, 아이폰이나 패드와 같은 스마트하다고 우기는 디지털기기를 집안에 던져두고 여행을 떠나는 것이 현명한 방법이겠다. 그리고, 다른 매체를 들여다보고, 개발자 이외의 사람들을 만나서 이야기해보라라고 권유해야 하는 것이 맞을  듯하다.생각 이상으로 소프트웨어 개발자의 세계는 정말 좁다. 그리고, 단편적인 지식들과 단편적인 경험들만이 존재하는 세상인지도 모른다. 그래서, 소프트웨어 개발자들은 ‘관심의 폭을 넓히고,’ ‘자신을 확장’하는 것이 결론적으로는 더 뛰어난 개발자가 된다는 것을 나중에야 깨달을 것이다. 마지막으로 이야기한 한다면, 소프트웨어 개발자에게 ‘성공’이란 일단... 전혀 해보지 않았던 것을 도전해보는 것, 그리고. 삶은 소프트웨어 개발처럼 버전을 나누어서 설명하기 어렵다는 것을 이해하고. 무언가 계속 새로운 것에 도전한다는 것이 진정한 ‘성공’ 아닌가 한다.#와탭랩스 #와탭 #개발자 #개발 #프로그래머 #성공 #성공한개발자
조회수 901

맛있는 인터뷰: 잔디 그로스 팀 개발자, Hugo

 역삼 맛집▲ 금강산도 식후경이라 했던가? 맛있는 인터뷰가 맛있는 이유는 늘 음식과 함께 하기 때문이다오늘 온 맛집. 분위기가 심상치 않다. 어떤 곳인지 소개해달라. Hugo(이하 ‘휴’): 역삼역 근방에 있는 ‘산촌’이란 곳이다. 얼마 전 버디런치 장소 물색을 위해 ‘다이닝코드’로 역삼역 주변 한식집을 찾던 중 발견했다. 예로부터 어르신들이 찾는 곳은 맛집이라는 얘기가 있다. 보면 알겠지만 어르신들이 많다. 괜찮은 가격에 건강한 음식을 섭취할 수 있는 곳이라 많은 듯 하다. 그리고.. 우리도 건강을 챙겨야 하는 나이다. 몸에 좋은 곤드레밥, 메밀 전병을 먹으며 함께 하는 건강한 인터뷰가 되었으면 하는 바람에 이 곳을 선택했다.깔끔한 답변 고맙다. 이제 본인 소개를 부탁한다. 휴: 반갑다. 개발자 Hugo다. 잔디 그로스 팀(Growth Team)에서 로우 데이터(Raw data) 가공, 분석을 통해 유의미한 지표를 보여주는 데이터 분석 툴 ‘스프링클러’를 개발하고 있다. 잔디 멤버들 사이에서 유독 명성이 자자하다 휴: 여러분의 관심을 먹고 자라는 임무를 수행하다 보니 그런 듯 하다. Hannah, Jihoon, Jane 등과 함께 GWP 팀으로 활동해서 많이들 알아봐 주시고 격려해주시는 것 같다. * GWP 팀? GWP는 Great Working Place의 줄임 말이다. 단어 그대로 물리적+비물리적 최고의 업무 공간을 만들기 위해 TF팀 형태로 구성된 그룹이 다양한 활동을 한다. 예를 들면, 할로윈 파티 개최부터 탕비실 냉장고 음식 채우기 등 업무 환경 개선을 위해 크고 작은 일을 수행한다. ‘비선실세’라는 얘기도 돌던데? 휴: 천부당 만부당한 말씀이다. 그저 잔디를 사랑하는 멤버 중 한 명이다.스프링클러? 휴: 잔디 그로스 팀에서 자체적으로 만든 분석 툴이다. 쉽게 말하면 잔디 데이터 분석과 가공에 최적화된 잔디 전용 구글 어널리틱스(Google Analytics)로 보면 된다. 스프링클러를 통해 잔디 DAU(Daily Active User) 파악, 마케팅 채널 별 효율 측정, 유저 별 사용량 측정 등을 할 수 있다.  스프링쿨러▲ 잔디의 모든 데이터를 가공, 분석해 보여주는 스프링클러잠깐! 유저 별 사용량 측정도 스프링클러를 통해 가능하다고 했는데 잔디 팀이 유저의 모든 정보를 열람하는 건가? 휴: 많은 분들이 오해할 수 있을 것 같은데 그렇지 않다. 스프링클러에서 열람할 수 있는 유저 별 사용량 확인은 특정 채널을 통해 유입된 유저가 메시지를 몇 건 보내고, 파일 업로드를 얼마나 하는지 정도다. 유저가 어떤 메시지를 주고 받는지, 어떤 파일을 올리는지 등 개인 정보는 원칙적으로 잔디 팀이 접근할 수 없다.   스타트업은 시간과 리소스 관리가 생명이다. 구글 어널리틱스와 같은 훌륭한 툴이 있는데 굳이 자체 데이터 분석 툴을 만든 이유가 무엇인지? 휴: 날카로운 질문이다. 나도 처음에 왜 스타트업에서 데이터 관련 팀을 꾸려 분석 툴을 만들려고 하는지 이해가 가지 않았다. 하지만 좀 더 생각해보니 잔디에서 발생한 데이터에 특화된 분석 툴이 있어야 정확한 결과를 얻을 수 있고, 이를 통해 스타트업 특유의 린(Lean)한 개발이 가능할거란 결론에 도달하였다.   듣기엔 스프링클러의 사용성과 분석 능력이 뛰어나 독자 서비스로 나오는 것 아니냔 루머가 있었다. 사실인가? 휴: 하하. 루머일 뿐이다. 다만 그런 생각을 갖고 그로스 팀과 최선을 다해 스프링클러 개발을 하고 있다. 어쨌든 좋게 봐주셔서 이런 루머가 나온 것 같아 담당자로서 기쁘다.   스프링클러에 애정이 많을 것 같다 휴: 내게 잔디도 소중하지만 스프링클러도 무척 중요하다. 소박한 꿈이 있다면 스프링쿨러가 내가 없어도 100% 완벽히 잘 돌아가게 만들고 싶다. 물론, 분석 툴로서 멤버들이 원하는 결과를 보여줄 수 있도록 정교하게 만드는 것도 중요하다.   그로스 팀은 과거 ‘맛있는 인터뷰’의 Kevin을 통해 소개한 바 있다. 당시 개발자 중 몇 명을 차출해 그로스 팀에 합류시킨 걸로 알고 있는데 여러 개발자 중 Hugo가 차출된 이유가 있다면? 휴: 평소 데이터 마이닝 분야에 관심이 많아 대학원에서 관련 공부를 하기도 했고, 그로스 팀 초창기 모든 업무를 책임지던 팀장 겸 팀원 Kevin이 추천해 팀에 합류하게 되었다. 아, 그로스 팀 오기 전엔 백엔드(Back-end) 개발자 포지션으로 있었다. 팀을 옮길 땐 백엔드 개발자들로부터 ‘배신자’란 오명과 함께 모진 고문과 학대를 받았다. 하하.. 농담이다.   다른 얘기를 해보자. 잔디에 어떤 이유로 조인했는지 궁금하다 휴: 건방진 말일 수 있지만 내 의지대로 무언가 만들고 싶었다. 대한민국 수 많은 개발자들이 그렇겠지만 회사에서 내가 할 수 있는 건 생각보다 한정돼 있다. 아이디어를 내도 예산 때문에 혹은 기타 다른 이슈 때문에 반려되기 일쑤였다. 어떻게 보면 그런 현실에 대한 반발심으로 잔디를 선택한 게 가장 크다고 볼 수 있다.   잔디에서는 생활은 만족스러운가? 휴: 70% 정도?   왜 70%인가? 휴: 장-단점이 있지만 장점이 조금 더 크기 때문에?   그럼 장점부터 말해보자 휴: 합당한 이유가 있다면 내가 하고 싶은 일을 진행할 수 있다는 점이 큰 장점이다. 그 일을 실행하기까지 절차도 이전까지 다녔던 회사 대비 상당히 간소화되어 있어 부담감도 적다. 각 분야에서 두각을 드러낸 사람들과 함께 일하고 있다는 점도 매력적이다. 다들 자부심을 갖고 일하고 있어 자극을 받는다.   단점은? 휴: 장점이 때에 따라 단점으로 보일 때도 있다. 논리적인 어프로치가 필요할 때도 있지만 분명 전쟁터로 돌진하는 돌격병 같은 저돌성이 필요할 때도 있다. 그럴 땐 일부터 치고 보는 자세가 필요한데 그 때를 놓치는 경우가 눈에 보여 개인적으로 아쉽다.   스트레스는 어떻게 푸는지? 휴: 주말에 13시간 이상 잔다. 밤에 10시간, 낮에 3시간. 남는 시간엔 수영이나 등산을 한다.   등산? 휴: 집 바로 뒤에 나지막한 산이 있다. 평소 자연을 좋아하는데 등산을 하다 보면 산의 나무나 풀, 바람을 보고 즐길 수 있어 좋다.   생각보다 감성적인 남자라 당황스럽다 휴: ^^ ▲ 감성적인 남자로 보이는 그는 한 때 해병대 전우였다.수영은 시작한지 얼마 안됐다고 들었다 휴: 작년 10월부터 시작했다. 이제 갓 1년이 넘었다. 작년 초부터 체력적으로 처진 것 같은 느낌이 들어 이대론 안되겠다 싶어 수영을 시작했다. 등산과 함께 꾸준히 하는 운동 중 하나다.   꾸준히 운동하고 있는데 달라진 점이 있다면? 휴: 몸도 몸이지만 정신적으로 건강해졌다. 확실히 체력이 떨어지면 부정적인 생각을 하는 경향이 있는 것 같다. 운동을 시작하기 전과 후의 마음 상태가 정말 많이 다르다. 앞으로도 꾸준히 운동을 할 생각이다.   곤드레밥과 함께 한지 벌써 1시간 가까이 됐다. 인터뷰 질문도 다 소진되어 이전 맛있는 인터뷰 주인공이었던 David이 남긴 질문을 묻고 싶다 휴: 준비됐다.   잔디 멤버 중 전생에 공주나 왕자였을 것 같은 사람은? 휴: 왕자는 디자인 팀의 Ben. 도도하고 말수도 적고. 공주는 디자인 팀의 Yujin (A.K.A Summer)? 얘기는 많이 안 해봤지만 말도 고급스럽게 하는 것 같다. 두 사람 모두 괜찮은 사람들이라 이번 인터뷰를 통해 점수를 따보고 싶다.   전략적인 답변 감사하다 휴: ^^   마지막 질문이다. ‘맛있는 인터뷰’의 백미는 다음 인터뷰이에게 현재 인터뷰이가 질문을 남기는 것이다. 다음 사람에게 묻고 싶은 질문이 있다면? 휴: 잔디 멤버 중 내 주변 괜찮은 남자 사람이나 여자 사람을 소개시켜주고 싶은 사람은?   오늘 맛있는 곤드레밥 덕분에 잘 먹었다. 계산은 인터뷰이가 한다는 거 다시 한번 더 상기시켜 드리며 인터뷰 마무리하겠다 휴: …^^#토스랩 #잔디 #JANDI #개발 #개발자 #개발팀 #인터뷰 #팀원 #팀원소개 #팀원인터뷰 #기업문화 #조직문화
조회수 2625

개발자 직군 파헤치기 2 | 게임 개발자

게임 개발자국내 게임 산업에서 모바일 게임의 매출액은 2011년 4235억원에서 2013년 2조3276억원으로 2년 만에 6배 가까이로 늘어났습니다.(출처:한국콘텐츠진흥원) 한국 모바일 게임은 해외에서도 인기를 끌고 있는 추세입니다. 뿐만 아니라 최근 엄청난 인기를 끌고있는 배틀그라운드는 한국 게임 산업의 가능성을 증명합니다. 배틀그라운드는 작년 한 해 7621억원의 수익을 거두면서 2017년 가장 큰 수익을 거둔 PC 게임 패키지 1위를 차지했습니다.배틀그라운드의 일러스트게임을 좋아하는 사람이라면 한번쯤은 게임 개발에 관심을 가져보았을 것입니다. 특히 프로그래밍을 하는 사람이라면 자신의 게임을 만들어보고 싶다는 생각을 해보거나, 게임 회사에서 일 하는 것을 고려해보았을 것입니다. 그러나 한편으로는 압도적인 근무 시간에 대한 부담으로 게임 개발자가 되겠다는 생각을 접게 되신 분들도 많습니다.이번 포스팅은 게임 개발자에게 필요한 역량이 무엇인지 알아보고, 게임 개발자의 두 가지 커리어 종류에 대해 설명하려고 합니다. 또한 지금 당장, 코딩을 전혀 할 줄 모르는 상태에서 게임 개발에 도전해볼 수 있는 방법 또한 소개해드리겠습니다.게임 개발자에게 필요한 역량게임을 만들기 위해서는 그래픽을 다루는 능력, 스토리와 레벨을 기획하는 능력, 3D 모델링, 그래픽 엔진을 다루는 능력 등 많은 영역들에서 전문성을 필요로 합니다. 물론 이 모든 것을 전문적으로 다루는 사람이 되기란 불가능에 가깝습니다. 그렇기 때문에 스토리라인과 컨셉 구성은 기획자가 담당하고, 기획자의 아이디어는 개발자와 그래픽 디자이너의 손을 거쳐 게임의 모습을 갖춥니다. 그래픽 디자이너가 시각적 구현을 맡는다면, 개발자는 PC나 모바일에서 게임이 실행될 수 있도록 만드는 작업을 하게되는 것입니다. 게임 개발자도 결국 개발자 직군의 일환이기 때문에 일반적으로 개발자들이 많이 다루는 언어에 대한 숙련도나 프로그래밍 능력이 필요합니다. 그러나 게임 개발자의 경우 다른 직군의 개발자에게는 필수적이지 않은 지식을 필요로 할 때가 있습니다. 아래에는 특히 게임 개발자들에게 중요한 세 가지 요소입니다. 1. 프로그래밍 언어대부분의 대규모 게임 회사들은 C++을 가장 많이 사용합니다. 모바일 게임이 대세로 더오르면서 C#을사용하는 경우가 많아진 것은 사실입니다. 그러나 PC, 모바일, 비행기 제어 프로그램까지 폭넓게 지원하는 고성능의 3D 게임을 개발하기 위해서는 여전히 C++이 최적이라는 평가를 받습니다. 주의할 점은 C/C++은 계속해서 발전하고 있는 언어라는 점입니다. 언어를 배우기 위한 서적, 인터넷 강의 등은 무궁무진하지만 중요한 것은 최신의 것을 배워야 한다는 점입니다.2. 게임 엔진게임 엔진은 간단하게 말해 게임을 개발하는 과정을 쉽게 만드는 ‘도구’입니다. 중력 같은 기본적인 물리 효과나 오브젝트 사이의 충돌 여부를 판정하는 ‘컬라이더’ 등, 개발에 필요한 기본적인 기능이 탑재되어있기 때문에 게임 엔진은 개발 과정을 획기적으로 단축시켜줍니다. 가장 많이 쓰이는 게임 엔진은 유니티와 언리얼입니다.이 글을 읽고 있을 대부분의 분들이 개발을 배우는 과정에 있다는 가정하에 학습의 용이함을 기준으로 비교해보면, 유니티의 경우 공식적으로 지원하는 교육 프로젝트의 수는 9개입니다. 그러나 공식적인 자료 외에도 한글 서적이나 온라인 강좌들은 매우 풍부합니다. 반면에 언리얼이 제공하는 공식 교육 프로젝트는 수십개입니다. 대부분이 한글 자막을 지원해줄 뿐만 아니라 다양한 주제를 경험할 수 있습니다. 언리얼의 한계라면 공식 채널 외에서 학습할 수 있는 자료나 커뮤니티가 아직까지는 많지 않다는 점입니다. 3. 수학게임 개발자에게 수학은 매우 중요하고도 기본적인 것입니다. 특히 3D 게임을 다루고 싶다면 수학적 지식과 역량은 매우 중요한 부분을 차지할 것입니다. 물론 위에서 말한 게임 엔진이 수학적인 계산이나 물리와 관련된 문제들을 해결해 줄 수는 있습니다. 그러나 게임 엔진을 활용한다 하더라도 기본적으로 그것이 어떻게 작동하는지는 이해해야 합니다. 그렇기 때문에 이산 수학, 즉 벡터, 행렬, 집합, 논리 연산 등에는 능숙할 필요가 있습니다. 게임 개발자의 커리어게임 개발자가 되기 위한 길이 게임 회사에 취직하는 것만 있는 것은 아닙니다. 최근에는 크게 성공하는 인디 게임, 즉 대규모 회사가 아닌 저예산의 1인기업 혹은 작은 팀단위로 만들어 내는 게임들의 사례가 늘어나고 있습니다. 게임 회사에 취직하는 것만큼 확실한 방법이 없다는 생각을 갖고 계신 분들, 혹은 자신만의 게임을 만드는 것에 강한 매력을 느끼시는 분들을 위해 두 가지 커리어 옵션을 비교해 보았습니다.1. 대규모 게임 회사대부분의 게임 개발자가 특정 회사에 소속되어 일을 합니다. 회사에 소속되어 있기에 안정적인 수입이 보장된다는 것이 첫번째 장점이라면, 두번째 장점은 혼자서는 절대 만들 수 없는 규모의 게임을 개발하는 데에 기여할 수 있다는 점입니다. 한 마디로 말해 완성도 있고 유명한 게임에 일조 했다는 자부심을 가질 수 있게 되는 것입니다. 또한 주니어 개발자로서 풍부한 경험을 가진 시니어 개발자를 포함해 배울 점이 많은 사람들로 구성된 팀에 소속될 수 있다는 것 또한 큰 장점입니다.한편 회사의 크기가 큰 경우에는 각 사람이 맡는 개발의 영역이 매우 세분화 되어있기 마련입니다. 자신이 느끼기에는 조금 지루하고 단순한 일이라고 생각되는 일을 맡게 될 수도 있습니다. 그러나 반대로 말하면 디자인, 기획, 마케팅 등 개발 외의 업무 등에 신경을 쓰지 않고 오직 자신의 일에 집중할 수 있는 환경이 제공되는 것이기도 합니다.2. 인디게임 개발규모가 있는 회사에 취직하는 것이 아니더라도 게임을 만들 수 있는 방법은 많습니다. 또한 안정적인 수입이 보장된 것은 아니지만, 성공하는 경우 생각는 것보다 그 수익이 큽니다. 예를 들어 트리오브라이프를 개발한 오드윈게임즈는 1년 간 20억의 매출에 도달했습니다. 단지 한 사람이 2주 동안 만든 게임, 숨바꼭질은 한 달만에 5000만원의 수익을 냈습니다. 물론, 이를 성공 신화에 불과하다고 말할 수도 있기 때문에 분명히 감수해야 하는 위험이 있는 커리어인 것이 사실입니다. 인디 게임 간에도 경쟁이 매우 치열하기 때문입니다.그럼에도 불구하고 소규모로, 혹은 혼자서 게임을 개발하는 사람들은 게임에 대한 애착을 가지고 개발 과정 전체를 아우르며 작업할 수 있다는 점에서 만족감을 느낍니다. 특히 투자 규모나 시기에 구애를 받지 않고 개성적인 게임, 만들고 싶은 게임을 만들 수 있다는 것이 장점이라고 할 수 있습니다. 지금 시작하기게임 개발을 하고 싶은데 어디서 시작해야 하는지를 막막해하고 있다면, 무조건 일단 만들어보기 시작하는 것이 중요합니다. 자신의 아이디어, 혹은 이미 있는 게임들을 가지고 점점 난이도를 높여가며 여러 프로젝트를 실행해 보는 것이 좋습니다. 이는 실력을 쌓는 데에도 도움이 되지만, 이후에 훌륭한 포트폴리오가 되기도 합니다.일단 만들어보라는 조언도 막막하신 분들을 위해 준비한 것은 무료로 사용할 수 있는 게임 개발 프로그램들입니다. 코딩을 전혀 할 줄 모르는 사람부터 완성도 있는 게임을 만들고 싶어하는 사람들까지 다양한 수준에서 접근할 수 있는 도구들을 소개해드리겠습니다.1.Flow CreatorFlow Creator는 코딩을 해본 적이 없어도 간단한 드래그앤드롭으로 게임을 만들 수 있는 웹사이트입니다. 시각적으로 논리적 구조를 짤 수 있기 때문에 어떤 언어도 배워본 적이 없어도 됩니다. 무료 버전의 경우 5개의 레벨, 50개의 개체로 제한이 되어있지만 유료 버전의 경우 앱으로 만들어 스토어에 올릴 수도 있습니다.2. StencylStencyl도 Flow Creator와 마찬가지로 프로그래밍 언어가 아니라 Stencyl의 사용법만 잘 익히면 훌륭한 게임을 만들 수 있습니다. 사용법이 Flow Creator에 비해 좀더 까다로운 것은 사실이지만 결과물의 완성도가 더 높습니다. 또한 이미 만들어져있는 코드블록 외에도 직접 코드를 작성하고 라이브러리를 불러오는 등 확장할 수 있는 가능성도 있습니다.3. Game Maker StudioGame Maker는 위의 두 가지 프로그램처럼 드랙 앤 드롭으로 만들 수 있지만, Game Maker Language(GML)이라는 자체 언어를 활용하여 만들 수도 있습니다. GML을 사용해서 게임을 만드는 것은 프로그래밍을 학습하는 데에도 도움이 될 것입니다.게임 개발자의 종류는 정말 많다.오늘 포스팅에서 언급한 게임 개발자는 일부입니다. 게임 개발자의 종류에는 온라인 게임, 모바일 게임, 콘솔 게임 등 정말 다양하고 무궁무진합니다. 여러분들이 어떤 게임 개발자가 되고 싶든 중요한 것은 게임에 대한 열정인 것 같습니다. 자신이 정말 하고 싶고 좋아하는 게임을 만든다는 것은 세상에 의미있는 프로그램을 만드는 개발자만큼이나 행복한 개발자겠지요. 다음 편에는 더 재밌는 개발자 직군으로 찾아오겠습니다.
조회수 1894

출시의 기록 - #1 랜딩페이지

이 글은 "친구끼리 쓰는 라이브 스트리밍 앱, 라이비오(LIVEO)"의 앱 출시 과정을 담는 글입니다. 어디까지나 현재 겪고 있는 과정을 기록하는 것으로, 최선의 방법이 아닐 수도 있으니 더 좋은 방법이 있다면 언제든지 소개 부탁드립니다.앱을 출시하게 되면서 가장 먼저 준비하게 되는 것 중에 하나. 웹사이트이다.지난 사업인 위제너레이션이나 오드리씨 모두 웹 사이트 자체가 중심이 되는 사업이었기에, 팀 내에 웹 개발자가 있었고 직접 사이트 제작을 건드려야 할 일은 따로 없었다.그러나 라이비오라는 앱 서비스를 준비하게 되면서, 팀 내 개발자들은 앱 서비스 개발에 바쁘고 웹 사이트는 기본적인 소개의 역할만 담당하면 되기 때문에, 직접 사이트를 만들게 되었다.이렇게 가장 기본적인 소개의 역할만을 담당하는 한 페이지짜리 웹 사이트를Promotional Landing Page, 혹은 랜딩 페이지라고 줄여서 부른다.우리는 총 세 가지 과정을 거쳐 웹 사이트를 만들어왔는데, 순서대로 아래와 같다.[1] 시중에 떠도는 HTML5 템플릿을 활용해 앱 개발자분께 부탁하여 간단하게 직접 만들었다[2] IMXPRS 라는 서비스를 이용하여 직접 만들었다[3] Instapage 라는 서비스를 이용하여 직접 만들었다결론만 말하자면 IMXPRS 는 내가 어떻게 알았는지 모르지만 완전 비추인 서비스이다.직접 만드는 것도 돈은 들지 않지만 그 때 그 때 커스텀이 안되기 때문에 불편하다.알아본 결과 랜딩페이지 제작으로는 주로 wix(바로가기) 나 Instapage(바로가기)를 추천하는데, 두 서비스가 유사하지만 개인적으로 Instapage 의 디자인이 더 마음에 들어서 선택하게 되었다.*wix의 경우 한글 버전이 있고, 이후 결제를 붙이는 것이 좀 더 용이하다고 알고있다.각각의 템플릿과 기능을 보고 적절한 것으로 선택하면 될 것이다.Instapage 사용 경험의 경우 개인적으로 10점 만점에 9.5점을 줄 정도로 아주 높다.당연히 직접 개발하는 것 만큼이야 커스텀이 안되겠지만, 매우 쉽게, 꽤 높은 수준으로 커스텀이 가능하다.예를 들어, 애초에 사용한 템플릿은 위의 템플릿이었는데, 아래와 같이 커스텀했다                                                  애초의 템플릿                                                   최종 결과물거의 다른 모습임을 알 수 있는데 그만큼 커스텀이 정말 쉽다는 뜻이다.- 기본적인 디자인은 모두 템플릿에서 제공하며- 핵심이 되는 Headline 및 본문 글꼴을 수정할 수 있고- 원하는 이미지 등을 손쉽게 원하는 위치에 삽입하고, 요소를 원하는 위치에 원하는 크기로 넣는다- 배경 사진 또한 유료 사진을 즉석에서 보고 어울리는 것을 쉽게 결제할 수 있다- 모바일 페이지도 자동 생성되며 별도로 변경할 수 있다(!)이러한 기능들 덕택에 개발자나 디자이너가 아니더라도, 30분~1시간만에 어느 정도 수준의 랜딩페이지를 손쉽게 완성할 수 있다.가장 마음에 들었던 부분은 외부 서비스와의 연계인데, 특히 이메일 주소를 받는 등의 추가기능이 필요한 경우 Integration 탭에서 정말 쉽게 넣을 수 있다. (라이비오의 경우 현재 이메일 주소를 받는 부분은 Mailchimp 라는 타 서비스와 연결되어있다.)                        Edit > Integration 탭에 가면 볼 수 있는 수많은 서비스들향후에는 좀 더 공식 사이트스러운 것들이 필요하겠지만, 초반 몇 달간 사용하기에 손색이 없는 서비스라고 생각한다. 일정 기간동안 무료로 제공되며, 향후 이용료를 낸다. (위의 사이트 수준이면 월 $29 정도)완성된 홈페이지: http://liveo.me랜딩 페이지는 이 정도로 하고, 이후 스마트 앱 배너를 추가할 계획이다.모바일로 랜딩페이지에 접속하면 앱 설치로 유도하는 배너이다.이 부분은 SDK 연동 등도 필요해서 개발자분들의 바쁨이 조금 잦아들면 출시 직전이나 직후에 넣으려고 한다. 관련 서비스는 branch.io 등이 있다.                                Smart App Banner 사례: 맨 위에 저거...사실 처음에는 랜딩 페이지(Promotional Landing Page)니, 스마트 앱 배너(Smart App Banner)니 하는 용어 자체를 몰라서 관련 서비스를 찾기가 어려웠다. 하지만 일단 용어를 알고나니 관련하여 이용할만한 좋은 서비스들이 많았다.혹시 앱 출시를 처음 해 보는 팀이 있다면 앱 출시 마케팅 자체에 대한 조사를 먼저 하고 큰 그림을 그려둔 후 가지를 쳐가며 준비하기를 추천한다. 개인적으로 어떤 부분을 모르는지, 어떤 부분을 알아야 할지를 알 수 있어 훨씬 수월했던 것 같다.하나 하나 완성된 모습으로 채워가는 과정이 왠지 괴롭고도(?) 재미있다.앞으로 소셜미디어와 프레스킷을 만들어가는 과정도 담아보기로 한다.+ 여담: 배경색 선정은 페이스북 '포토샵 완전정복' 디자이너 그룹의 힘을 빌었다.  투표의 힘!정말 많은 분들이 투표에 참여해주셨고 그 중 아는 언니가 준 의견 덕분에 지금의 검은 색상 옵션을 추가하게 되었다.사실 내가 처음 밀었던 색상은 아래의 보라색이었고 우리 팀도 대표님 제외하고 모두 보라색을 택했다 ㅋㅋㅋ 그러나 디자이너들의 의견은 가차없이,검은색 > 민트색 > 보라색 이었다.역시 기술만 있는 나에게 디자이너의 안목을 기르기란 끝없는 과제이다.이 글은 "친구끼리 쓰는 라이브 스트리밍 앱, 라이비오(LIVEO)"의 앱 출시 과정을 담는 글입니다. 어디까지나 현재 겪고 있는 과정을 기록하는 것으로, 최선의 방법이 아닐 수도 있으니 더 좋은 방법이 있다면 언제든지 소개 부탁드립니다.#라이비오 #경험공유 #출시 #업무프로세스 #인사이트
조회수 2236

영화 ‘앤트맨’을 통해 알아 본 안드로이드 나인패치(Android 9 Patch)

시작영화 ‘캡틴 아메리카: 시빌워’를 본 사람이라면 작은 ‘앤트맨’의 존재감이 누구보다 컸다고 말할 수 있습니다. 앤트맨은 가장 중요한 전투 신에서 자유자재로 신체 크기를 바꾸며 맹활약을 한 히어로인데요.안드로이드에도 이런 앤트맨처럼 크기를 자유자재로 바꾸되, 해상도를 그대로 보존하여 앱을 구현하는데 큰 도움을 주는 이미지 저장방식이 있습니다. 바로 나인패치입니다. 포스팅을 통해 나인패치를 이해해보고자 합니다.나인패치 이해하기#사이즈는 바뀌지만 내용은 그대로영화 속 앤트맨은 핌입자를 통해 분자보다 더 작은 양자 사이즈만큼 작아졌다가, 비행기보다 더 큰 사이즈로 변하는 히어로인데요. 핌 입자를 사용시 질량에는 변화가 없어 작아진 크기에서도 정상 어른의 펀치와 같은 위력을 줍니다.나인패치 역시 앤트맨과 같은 특징을 가지고 있는데요. 우리가 사용하고 있는 핸드폰의 해상도는 제각각 입니다. 하지만 이미지를 그 해상도에 전부 맞춰서 제작하기에는 무리가 있죠. 그렇기 때문에 디바이스에 표현되는 아이콘이나 버튼 등에 확대 되는 영역을 지정해줍니다. 그러면 큰 해상도에 이미지를 적용 하여도 픽셀이 깨지지 않고 확대된 이미지를 사용 할 수 있습니다.좀 더 정확하게 설명하자면, 이미지를 9분할 하여 확대되는 영역과 아닌 영역을 구분하여 저장하는 방식이며 이미지 확장자는. 9.png가 됩니다. 아래의 그림에서 살펴보면 빨간색 화살표 영역은 늘어나고 흰색 영역은 늘어나지 않게 됩니다.나인패치 이미지가 어떤 구조를 가지고 있는 어떻게 동작하는지에 대해 추가적으로 설명해보겠습니다.우선, 나인패치는Stretchable area와 Padding box 두가지의 영역으로 나뉩니다.Stretchable area는 늘어나는 영역은 이미지를 늘려주는 구간을 설정해주는 나인패치 영역입니다. 그래서 가로, 세로 어떤 크기로 늘어나도 형태가 깨져 보이지 않습니다.Padding box는 이미지 위에 어떠한 내용물을 어느 위치에 표시할지 정의 하는 영역입니다.버튼 크기가 변경되어도 정보 표시 영역을 나인패치로 잡아 좌우,상하 여백은 그대로 두고 이미지 확대/축소에 따른 텍스트가 정리되어 보여집니다.나인패치는 1px 검정색 선의 길이와 여백을 이용해서 늘려주고 싶은 이미지 영역과 표현하고 싶은 텍스트의 영역을 지정할 수 있는 것입니다.조금은 복잡해 보이지만, 나인패치로 지정하는 과정이 필요한 이유는 모바일은 한정된 용량을 가지고 있기 때문에 용량을 줄여서 하나의 이미지로 다양하게 사용할 수 있도록 하기 위해서 입니다.나인패치 만들어보기#만드는 방법나인패치를 만드는 방법에는 여러가지가 있습니다.   1. 포토샵으로 만들고, 확장자를 name.9.png으로 저장   2. 안드로이드 sdk 도구를 다운로드하여 만든다.       https://developer.android.com/studio/?hl=ko   3. Android Asset Studio 활용       http://romannurik.github.io/AndroidAssetStudio/nine-patches.html그중에서 툴 설치도 필요 없고 쉽게 만들 수 있는 3번의 방법을 활용하여 간략하게 나마 만들어보겠습니다.#우리는 그저 감사하게 사용할 뿐세상은 넓고 금손이 많은 것 같아요. 빠르게 만들수 있는 방법을 선택하겠습니다. 위 3번의 주소를 타고 사이트에 접속하면 아래와 같은 화면이 보여집니다.나인패치를 만들 수 있는 웹 툴인데, 저 사이트에는 나인패치 뿐만 아니라 안드로이드 디자인을 위한 다양한 툴을 제공하니 한번 참고해보시면 좋을 것 같습니다. 언제 이런걸 만들 생각을 하셨는지 한번 더 자괴감과 감사함을 느끼며 샘플 버튼 이미지를 불러옵니다.왼쪽 패널을 보면 이미지의 리소스 해상도를 지정하는 부분과 Drawable 이름을 편집할 수 있는 기능이 있습니다. 이름을 변경하게 되면 zip파일로 다운 받았을 때 변경된 이름으로 다운로드 됩니다.자 그럼 불러온 이미지가 가운데 화면에 보여집니다. Stretch Regions는 늘어나게 되는 부분을 설정하는 것입니다. 화면에 보이는 얇은 검은 선으로 Stretch Regions을 지정하면 됩니다.위와 같이 설정하게 되면 해상도에 따라 붉은색 부분이 늘어나게 됩니다.Contetns Padding은 안에 들어가는 텍스트가 들어가는 여백을 설정해줍니다.오른쪽 패널에서 Preview로 텍스트가 들어가는 것을 확인하면서 설정 할 수 있습니다.With content를 체크해주셔야 텍스트가 보여집니다.완성되면 Assets 탭에서 zip파일을 다운로드 받아주세요.다운로드가 완료되면 drawable name.9.zip으로 다운로드 되고 zip파일을 압축해제 하면 해상도 별로 나인패치 파일이 생성됩니다.부족하지만 나인패치에 대해 알아가는 시간이 되었기를 바라며, 이번 글은 여기서 마무리 하겠습니다.#에이치나인 #디자이너 #개발자 #협업툴 #크래커나인 #솔루션기업
조회수 2574

Radix? Redis!

얼마전부터 antirez twitter에서 radix tree 관련 트윗이 올라왔습니다. 얼마 지나지 않아 antirez가 radix tree를 구현한 rax 프로젝트를 공개하고 redis의 cluster hash_slot의 저장구조를 radix tree로 수정 되는것을 보았습니다.그동안 antirez의 코드 읽으면서 배우는 게 많았고, 자료구조에 관심이 많아서 살펴보기 시작했습니다. radix tree를 왜 구현 했는지, 어떻게 구현쟀는지 알아보고 radix tree를 redis에 어떻게 적용하였는지도 알아보겠습니다.antirez는 redis의 hash-slot -> key 구조에서 중복으로 인한 메모리 사용을 줄이기 위해 radix tree 를 만들었다고 합니다. 이 포스트에선 rax를 적용시킨 redis cluster로 이야기를 진행 하겠습니다.“현재는 hash-slot -> key에만 사용되지만 추후에는 다양한 곳에 사용 예정”이라는 트윗redis cluster?redis에는 cluster 기능이 있습니다.6대 이상의 redis 노드를 cluster 구성하면(최소 leader 3대, follower 3대 구성해야 cluster 가능) 16384개의 hash_slot이 노드 갯수에 맞게 분배가 됩니다. 즉 3대의 leader로 cluster 구성하면 각각의 leader는 0 ~ 5460, 5461 ~ 10922, 10923 ~ 16383 hash_slot을 나눠 가집니다.cluster 구성 후 client가 데이터 저장/삭제/조회 명령어를 redis server에 전송할 때 마다 key의 hash값을 구하고 어떤 leader hash_slot에 포함되는지 찾습니다.# example 127.0.0.1:7000> set hello world # hash_slot = crc16("hello") & 0x3FFF 계산된 값이 현재 접속한 leader의 hash_slot 범위에 있다면 그대로 실행 되지만 다른 leader의 hash_slot 이라면 에러를 발생하고 다른 leader로 이동하라고 힌트를 줍니다.cluster 구성 후에 노드를 추가 하거나 제거 할 경우 각 leader의 hash_slot을 재분배 하고, hash_slot에 맞게 key도 재분배 되어야 합니다. 단순하게 생각하면 leader의 hash_slot 재분배한 후 모든 key를 재계산하고 hash_slot에 맞는 leader에 할당 하는 겁니다.[현재까지 저장된 keys].forEach(v => { hash_slot = crc16(v) & 0x3FFF // leader에 할당된 hash_slot에 맞게 분배 }) 하지만 antirez는 redis Sorted set 데이터 타입의 구현체인 skiplist 을 이용하여 문제를 풀었습니다. skiplist는 member와 score를 저장하고, score를 기준으로 정렬합니다. skiplist의 member에는 key를 저장하고 score에는 key의 hash_slot을 저장합니다.(변수명 slots_to_keys)slots_to_keys 정보는 cluster 구성된 모든 노드가 저장합니다. 이후 재분배가 필요해지면 16384개 hash_slot을 leader 갯수에 맞게 재분배 하고 slots_to_keys에 저장된 “key:hash_slot” 정보를 가지고 해당 hash_slot의 key를 조회 및 재분배 합니다. 즉 slots_to_keys에 이용하여 재분배시 발생하는 계산을 없앤것입니다.잘 했구만 뭐가 문제냐?redis에 key가 추가/삭제 될때마다 slots_to_keys에 데이터가 저장되고 지워집니다. redis에 저장되는 key 갯수가 증가 할수록 slots_to_keys의 크기도 커짐을 의미 합니다.(※ 메모리 사용량)또한 leader 갯수에 맞게 16384개 hash_slot을 leader에 재분배하고, 각 hash_slot에 맞는 key를 찾고 할당 합니다. 예를들어 slots_to_keys에서 score 0인(hash_slot 0을 의미) member를 조회해서 0번 hash_slot에 할당, score 1인 member를 조회해서 1번 hash_slot에 할당 하는 방식으로 0 ~ 16383 hash_slot을 진행합니다.앞에서 말한 hash_slot에 속한 key를 조회 하는 GETKEYSINSLOT 명령어가 있는데 여기에 이슈가 있습니다.cluster GETKEYSINSLOT slot count # slot: hash_slot 번호 # count: 특정 hash_slot에서 조회할 key 갯수 # example 127.0.0.1:7000> cluster GETKEYSINSLOT 0 3 # 0번 hash_slot의 key를 3개 조회한다. "47344|273766|70329104160040|key_39015" "47344|273766|70329104160040|key_89793" "47344|273766|70329104160040|key_92937" 사용자가 특정 hash_slot에 몇개의 key가 저장 되었는지 모르기때문에 count에 Integer.MAX 를 대입하는데, redis는 hash_slot에 실제로 저장된 key 갯수와는 상관없이 client가 전달한 count만큼의 메모리를 할당합니다.} else if (!strcasecmp(c->argv[1]->ptr,"getkeysinslot") && c->argc == 4) { /* cluster GETKEYSINSLOT */ long long maxkeys, slot; unsigned int numkeys, j; robj **keys; // ... 명령어의 4번째 인자를 maxkeys에 할당, 즉 사용자가 입력한 count if (getLongLongFromObjectOrReply(c,c->argv[3],&maxkeys,NULL) != C_OK) return; // ... keys = zmalloc(sizeof(robj*)*maxkeys); numkeys = getKeysInSlot(slot, keys, maxkeys); addReplyMultiBulkLen(c,numkeys); for (j = 0; j < numkeys>zmalloc maxkeyscluster GETKEYSINSLOT unnecessarily allocates memory그래서 메모리도 적게 차지하면서(압축 가능) key와 key의 hashslot을 효율적으로 저장 및 조회가 가능한 자료구조가 필요했고 antirez는 radix tree를 선택합니다.※ 뜬금 없는데 2012년, redis 자료형에 Trie를 추가한 P/R이 생각났습니다.radix tree 구현한 rax 알아보기시작하기전 radix tree (Wikipedia) 위키 페이지의 그림을 보고 감을 잡은 후에 아래를 보시면 잘 읽힙니다.자! 이제부터 rax의 주석과 코드를 보면서 어떻게 구현됐는지 알아보겠습니다.Noderax의 노드 구성은 다음과 같습니다.typedef struct raxNode { uint32_t iskey:1; /* Does this node contain a key? */ uint32_t isnull:1; /* Associated value is NULL (don't store it). */ uint32_t iscompr:1; /* Node is compressed. */ uint32_t size:29; /* Number of children, or compressed string len. */ unsigned char data[]; } raxNode; 노드의 정보를 담고있는 32 bit(iskey, isnull, iscompr, size)와 key/value 그리고 자식 노드의 포인터를 저장하는 unsigned char data[]가 있습니다. 특이한 점은 key/value를 동일한 노드에 저장 하지 않고 key가 저장된 노드의 자식 노드에 value를 저장합니다.※ 사진 출처위 그림을 예로 32 bit 정보가 어떤걸 의미하는지 알아보겠습니다.iskey는 노드가 key의 종착역(iskey:1)인지 중간역(iskey:0)인지 나타내는 flag입니다. 1, 3 노드는 iskey:0 이고 2, 4, 5, 6, 7 노드는 iskey:1이 됩니다.isnull은 value의 null 여부를 표시합니다. unsigned char data[]에 key/value 그리고 자식 노드의 포인터를 저장하므로 value를 찾으려면 계산이 들어갑니다. 불필요한 연산을 줄이기 위해 만든 필드 같습니다.Trie는 각 노드에 한글자씩 표현 하지만 Radix는 압축을 통해 한 노드에 여러 글자 표현이 가능합니다. 이를 나태내는 플래그 iscompr 입니다. 노드가 압축된 노드(iscompr:1)인지 아닌지(iscompr:0)를 나타냅니다.size는 iscompr 값에 따라 의미가 다릅니다. iscompr이 1이면 저장된 key의 길이를 의미하고 iscompr이 0이면 자식노드의 갯수(저장된 key의 갯수)를 의미합니다.위 4개 정보를 이용해서 한 노드의 크기를 구하는 코드는 아래와 같습니다.#define raxNodeCurrentLength(n) ( \ sizeof(raxNode)+(n)->size+ \ ((n)->iscompr ? sizeof(raxNode*) : sizeof(raxNode*)*(n)->size)+ \ (((n)->iskey && !(n)->isnull)*sizeof(void*)) \ ) ※ 노드에 value 주소를 저장하거나, 마지막 자식 노드 포인터를 알고 싶을때 사용합니다.FindraxLowWalk 함수를 이용해 key가 존재 하는지 판단합니다.size_t raxLowWalk(rax *rax, unsigned char *s, size_t len, raxNode **stopnode, raxNode ***plink, int *splitpos, raxStack *ts) rax에 “ANNIBALE” -> “SCO” -> [] 로 저장 되어있을때 어떤 값을 리턴하는지 알아보겠습니다.*s 가 “ANNIBALESCO”이고 len이 11 인 경우# splitpos: 0, return value: 11 "ANNIBALE" -> "SCO" -> [] ^ | *stopnode *s가 “ANNIBALETCO”이고 len이 11인 경우# splitpos: 0, return value: 9 "ANNIBALE" -> "SCO" -> [] ^ | *stopnode *s의 길이 len과 return value가 같다면 rax에 key가 존재하는 것입니다. *s의 길이 len과 return value가 다른 경우 어디까지 매칭됐는지 보여주는 return value와 어떤 노드에 어디까지 일치했는지 표현하는 *stopnode, splitpos를 통해 추가 정보를 얻을수 있습니다.InsertraxLowWalk 함수를 이용해서 저장할 위치를 찾습니다. (*stopnode, splitpos, return value)1번에서 구해진 데이터를 이용해서 새로운 노드 생성 및 링크를 연결합니다.rax에 “ANNIBALE” -> “SCO” -> [] 상태에서 “ANNIENTARE”를 저장하는 과정입니다.1. raxLowWalk 함수를 이용하여 저장할 위치 탐색 splitpos: 4, return value: 4 "ANNIBALE" -> "SCO" -> [] ^ | *stopnode 2. *stopnode, splitpos 데이터를 이용하여 노드 분리 "ANNI" -> "B" -> "ALE" -> [] 3. iscompr: 0인 노드 "B"를 기준으로 새로운 key 저장 ("B"와 "E"는 같은 노드) |B| -> "ALE" -> [] "ANNI" -> |-| |E| -> "NTARE" -> [] RemoveraxLowWalk 함수를 이용해서 저장할 위치를 찾습니다. (*stopnode, splitpos, return value)1번에서 구해진 데이터를 이용해서 노드 제거 및 compress가 가능다면2가지 경우가 있습니다.마지막 노드만 iskey: 1이고, 연속으로 iscompr:1인 노드가 된 경우마지막 노드만 iskey: 1이고, iscompr:1 -> iscomplr:0 -> iscomplr:1 노드 구조가 된 경우입니다.첫번째 경우를 알아 보겠습니다. rax에 “FOO” -> “BAR” -> [] 상태에서 “FOO”를 지우는 과정입니다.1. raxLowWalk 함수를 이용하여 저장할 위치 탐색 splitpos: 3, return value: 3 "FOO" -> "BAR" -> [] ^ | *stopnode 2. 해당 key 삭제, 여기서는 자식노드가 있으므로 노드 삭제는 하지 않고 노드의 iskey: 0으로 세팅 "FOO" -> "BAR" -> [] 3. compress가 가능한 경우 진행 "FOOBAR" -> [] 두번째 경우를 알아 보겠습니다.0. "FOOBAR"와 "FOOTER"가 저장된 상황입니다. FOOTER를 지우는 경우입니다. |B| -> "AR" -> [] "FOO" -> |-| |T| -> "ER" -> [] 1. raxLowWalk 함수를 이용하여 저장할 위치 탐색 splitpos: 0, return value: 6 |B| -> "AR" -> [] "FOO" -> |-| |T| -> "ER" -> [] ^ | *stopnode 2. 해당 key 삭제 "FOO" -> "B" -> "AR" -> [] 3. compress가 가능한 경우 진행 "FOOBAR" -> [] cluster 정보는 어떻게 저장되나?기존 skiplist 자료구조를 이용했던게 어떻게 변경 되었는지 알아보겠습니다.server.cluster->slots_keys_count[hashslot] += add ? 1 : -1; if (keylen+2 > 64) indexed = zmalloc(keylen+2); indexed[0] = (hashslot >> 8) & 0xff; indexed[1] = hashslot & 0xff; memcpy(indexed+2,key->ptr,keylen); if (add) { raxInsert(server.cluster->slots_to_keys,indexed,keylen+2,NULL,NULL); } else { raxRemove(server.cluster->slots_to_keys,indexed,keylen+2,NULL); } 먼저 slots_keys_count 변수를 이용하여 각 hash_slot의 key 갯수를 저장합니다.그리고 key는 hash_slot(2 byte) + key, value는 NULL로 rax에 저장하여 특정 hash_slot에 속한 key 조회를 쉽게 만들었습니다.마치며rax 구현과 rax가 어떻게 redis에 적용됐는지 보면서 오랜만에 재밌게 코드를 읽은것 같습니다. 개인적으로 데이터 관련 유용한 무언가를 만드는게 목표인데, 이런 좋은 코드들을 하나 둘씩 제것으로 만드는것도 과정이라 생각하며 진행했습니다.앞으로 rax가 redis에서 어떻게 쓰일지 흥미롭고, Redis를 Saas 형태로 제공하는 업체들이 언제 적용할지도 궁금합니다.긴 글 읽어주셔서 감사합니다.cluster, rax 관련 antirez twitterRedis cluster Insertion cluster Issuesame amount data hash table vs radix treehashset + ziplist -> radix tree + listpack 1/5replace Hashset with Radix treeraxNode에서 사용한 flexible memberflexible memberrax 를 이용한 Redis Streams(2017.12.17일 업데이트)Redis Stream#잔디 #토스랩 #JANDI #기술스택 #도입후기 #Redis #인사이트
조회수 1737

아키텍트, 개발 리더십의 변화...

보통, 하나의 서비스를 개발하는데 얼마나 걸리며, 그 시간 동안 어떤 일을 '구체적'으로 진행시켜야 하느냐에 따라서 아키텍팅의 관점이 변화된다.자주 쓰는 장표 중의 하나이다. 간단하게 설명하면 과거의 비즈니스와 현재의 비즈니스의 차이를 디지털 서비스로 만들어 내는 기간으로 표시한 것이다.과거에는 하나의 디지털 비즈니스가 동작하기 위해서 데이터를 수집하고 분석, 기획, 구현, 실행하기까지 대부분 8.5개월에서 10개월 정도의 시간이 소요되었고, 이렇게 만들어진 서비스들은 실제 고객과 단절되어 있는, 내부 시스템에 가까웠다는 것을 표현한다.그리고, 디지털 비즈니스의 세계에서는 모바일로 실 고객과 커넥티드 되어 있으며, 각 비즈니스가 실제 수집부터 실행까지 1주에 동작되는 세계를 표현한다.이 차이는 정말 개발 조직과 개발 리더십에 많은 차이를 주게 된다.Classic Business에서는 8개월 이상의 방향성이 흔들리지 않도록, 전체적인 방향성이 흐트러지지 않도록 개발 리더십을 발휘하는 것이 중요했다. 특히, 초기의 개발 조직을 세팅하고 예산과 비즈니스의 완성과 실 서비스 후의 이익과 같은 경영적인 판단이 더 중요하던 시기였기 때문에, 실제 소프트웨어를 만들어내는 관점은 디테일하고, 기능적인 것에 집중화된 상태로 개발 조직이 구성되고, 리더십도 그것을 최대한 끌어내는 것에 집중했다.또한, 내부적 조직의 문제로 일이 더디게 진행되거나, 품질이나 세부적인 문제를 쥐어짜거나, 어떻게든 일정을 맞추기 위해서 조정하는 조정자의 역할도 매우 큰 상태였다. 개발 리더십도 그런 관점에서 구성되었고, 기술적인 변화도 거의 없이 초기에 결정된 상태로 대부분 진행되었다.그런데, Digital Business의 세계로 넘어오면 이것은 완전 다른 구도를 가지게 된다.1주 단위의 개발 및 배포까지 매우 유연한 상태로 가동되고, 이 단위는 기술적 선택과 실패가 매우 빠르게 반복되는 것을 의미하게 되며, 개발 조직은 말 그대로 작게 세분화되고, 전체적인 방향성은 계속 유동적으로 변화하게 된다.24시간 내에 하나의 개념이 수립되고, 이를 배포까지 진행시키기 위한 매우 다양한 시도들을 선택할 수 있게 하며, 기획 조직과 개발 조직이 하나의 '지표'나 '시각화'된 장표를 보고 빠르게 판단하게 할 수 있다.매우 빠른 순간 판단이 중요하며, '몇 분'간격으로 회사의 운명을 결정할 수 있는 서비스의 론칭도 가능하게 한다.관리적인 방법은 DevOps의 자동화된 환경과, 세분화된 배포 권한, 기획자들과의 유기적인 환경들을 보다 효율적으로 운용할 수 있는 방법들에 대해서 개발 리더십은 고민하게 된다.어떻게 빠르게 일을 효과적으로 움직일 것이며, 빠른 판단을 할 수밖에 없다. 빠르게 변화하는 기술 스택을 더 잘 알고 있는 것은 개발 조직이기 때문에, 아키텍트나 개발 리더의 권한은 계속 실무자에 가깝게 내려가게 되는 것이 순리에 가깝다.현재 DevOps를 지향하고 있는 개발 조직에서 아키텍트가 지향하는 것은 크게 개념적으로 변화한 것은 없다. '고객과 비즈니스를 이해하는 개발'임에는 틀림없으나, 기존의 아키텍팅과 많이 달라진 것은 실시간 서비스에 대한 분석과 기획의 변화, 데이터 중심의 개발 구조의 시각화를 통해서 개발 조직을 통제한다기보다는, 개발 조직을 숨 쉬게 만드는 '심장'과 같은 역할을 하게 된다.마치, 비즈니스가 빨라지면, 심장도 빨리 뛰고, 비즈니스가 좀 수월해지면 호흡을 고를 수 있는 형태...현재의 아키텍트는 개발 조직의 '심장'과도 같아.속도와 박자, 전체적인 흐름을 중시하는 것이 현재의 아키텍트의 역할이다.건축가인 아키텍트들에게는 엄청난 규칙과 법칙, 책임의 범위가 상당하다. 하지만, 소프트웨어 아키텍트들에게는 그런 책임이 법적으로 제시되고 있지 못하고 있다. 보통 소프트웨어 아키텍트라고 한다면, 부정적인 환경에서 제대로된 소프트웨어를 만들 수 없기 때문에 부당한 개발환경을 담당할 가능성이 없다는...그래서, SI현장에서 아키텍트는 거의 나오지 않는다고 봐야 한다. 슬프지만. 그리고, 마지막으로... 아키텍트는 '직위'나 '권위'가 아니다. '롤'일뿐이다. 그뿐...
조회수 1939

Kubernetes에 EBS 볼륨 붙이기

Kubernetes에서 컨테이너에 Persistent Volume을 붙이는 방법은 몇가지 있다. 여기서는 Kafka 서비스를 예로 삼아 주요 접근방법을 간단히 알아본다.Kubernetes v1.4.0를 기준으로 문서를 작성한다.Static말이 Static이지 수동 마운트를 뜻한다. 기본적으로 관리자가 EBS 볼륨을 만들고특정 Pod에 그 볼륨을 붙이는 작업을 한다. Volumes 문서에 나오는대로 하면 간단하다.apiVersion: v1 kind: Service metadata: name: kafka1 labels: app: kafka1 tier: backend spec: ports: # the port that this service should serve on — port: 9092 name: port targetPort: 9092 protocol: TCP selector: app: kafka1 tier: backend — - apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kafka1 spec: replicas: 1 template: metadata: labels: app: kafka1 tier: backend spec: containers: — name: kafka1 image: wurstmeister/kafka imagePullPolicy: Always volumeMounts: — mountPath: “/kafka” name: kafka1volume ports: — containerPort: 9092 volumes: — name: kafka1volume awsElasticBlockStore: volumeID: vol-688d7099 fsType: ext4여기서 핵심은 다음의 두 줄 뿐이다.awsElasticBlockStore: volumeID: vol-688d7099Dynamic수동으로 볼륨을 붙이는 방법은 간단해서 좋다. 하지만 Autoscaling하는 서비스에 넣기에는 아무래도 무리다. 서비스가 뜰 때 요구사항에 맞는 볼륨을 스스로 만들어 붙이는 방법도 있다. Kubernetes Persistent Volumes를 참고해 작업해본다.우선 Kubernetes 생성할 EBS 볼륨의 사양을 정한다.# storages.yaml apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: default1a provisioner: kubernetes.io/aws-ebs parameters: type: gp2 zone: ap-northeast-1a iopsPerGB: “10” — - apiVersion: storage.k8s.io/v1beta1 kind: StorageClass metadata: name: default1c provisioner: kubernetes.io/aws-ebs parameters: type: gp2 zone: ap-northeast-1c iopsPerGB: “10”default1a를 선택하면 ap-northeast-1a Availablity Zone에 기가바이트당 IOPS는 10인 General SSD EBS 볼륨을 생성한다. 이제 다시 Kafka의 돌아가면apiVersion: v1 kind: Service metadata: name: kafka1 labels: app: kafka1 tier: backend spec: ports: # the port that this service should serve on — port: 9092 name: port targetPort: 9092 protocol: TCP selector: app: kafka1 tier: backend — - apiVersion: extensions/v1beta1 kind: Deployment metadata: name: kafka1 spec: replicas: 1 template: metadata: labels: app: kafka1 tier: backend spec: containers: — name: kafka1 image: wurstmeister/kafka imagePullPolicy: Always volumeMounts: — mountPath: “/kafka” name: kafka1volume ports: — containerPort: 9092 volumes: — name: kafka1volume persistentVolumeClaim: claimName: kafka1volumeclaim — - kind: PersistentVolumeClaim apiVersion: v1 metadata: name: kafka1volumeclaim annotations: volume.beta.kubernetes.io/storage-class: “default1a” spec: accessModes: — ReadWriteOnce resources: requests: storage: 300Gi이제 awsElasticBlockStore가 아닌 PersistentVolumeClaim을 통해 볼륨을 할당받는다. kafka1volumeclaim은 default1을 기준으로 스토리지 정책을 정하므로Availablity Zone: ap-northeast-1aIOPS: 기가바이트당 10General SSD300Gi 이상인 스토리지를 원한다는 요구사항을 기술한다. 위의 설정은 이러한 스토리지에 부합하는 EBS 볼륨을 생성하여 kafka1 Pod에 할당한다.분석Dynamic은 Autoscaling에는 적합하나 kubectl delete [service] 또는 kubectl delete [deployment] 등의 명령을 수행하여 서비스를 내렸다가 다시 올린 경우에 기존에 쓰던 볼륨을 마운트하지 않고 새 볼륨을 만드는 문제가 있다. 물론 delete를 하지 않고 서비스를 업데이트만 하는 경우에는 볼륨이 유지되지만 이래선 아무래도 문제의 소지가 많다.그래서 또다른 시나리오를 고민해볼 수는 있다. 짧게 설명하자면관리자가 Volumn Pool을 만들어놓고 Autoscaling 서비스가 이 풀 안에서 볼륨을 할당받게 한다. 이러면 앞서 본 두 가지 방식의 장점을 골고루 흡수할 수 있다.flocker 또는 glushterfs 같은 스토리지 관리 서비스를 활용해도 좋다. 하지만 배보다 배꼽이 큰 것 같은 느낌이 들지도 모르겠다.#데일리 #데일리호텔 #개발 #개발자 #개발팀 #인사이트 #꿀팁
조회수 958

원하는 대로 뭉치는 GROUP BY

편집자 주전문 용어는 특정의 학술 용어나 기술 용어를 말하는데, 대개 둘 이상의 단어가 결합하여 하나의 의미 단위에 대응하는 말, 곧 합성어의 성격으로 되어 있다. 아래와 같은 전문 용어는 단어별로 띄어 씀을 원칙으로 하나, 편의상 붙여 썼다. 1) 수행 결과 > 수행결과2) 수행 시간 > 수행시간3) 실행 계획 > 실행계획Overview지난 글에서는 ORDER BY를 파헤쳤습니다. 이번에는 ORDER BY만큼이나 자주 쓰이는 GROUP BY를 알아볼 시간인데요. GROUP BY는 컬럼 값을 그룹짓고(중복을 제거하고) 이에 대해 건수나 값의 합을 계산할 때 사용합니다.지난 글 보기: 순서대로 척척, ORDER BY지난 글 보기: 단일 TABLE을 SELECT하자! 1.GROUP BY의 이해GROUP BY의 기본적인 문법은 아래와 같습니다.SELECT     MBR_NM FROM test.TB_MBR_BAS GROUP BY     MBR_NM  ; 실행계획은 아래와 같습니다. 테이블을 전부 읽어서 temp를 만들고 GROUP BY를 수행하라는 의미죠. GROUP BY가 수행되는 것은 Extra에 Using filesort가 표시된 것으로 유추할 수 있습니다.참고로 Using filesort는 GROUP BY, ORDER BY, DISTINCT 등의 정렬과 관련한 작업을 수행하면 나타납니다. Query를 수행해볼까요?위와 같은 결과가 나왔는데, 수행시간은 3.77초가 걸렸습니다. 이 Query는 MBR_NM의 중복을 제거해서 화면에 표시한 것입니다. 이번에는 아래의 Query를 수행해보겠습니다.SELECT     MBR_NM      ,COUNT(*) FROM test.TB_MBR_BAS GROUP BY     MBR_NM  ; 바뀐 것이 있다면 SELECT 절에 COUNT(*) 가 추가된 것입니다. 실행계획은 다른 점이 없습니다.COUNT(*)는 레코드의 건수를 계산할 때 사용합니다. 위의 계획은 MBR_NM의 값이 같은 건수를 출력하라는 의미입니다. 수행해보겠습니다.수행시간은 3.64초로 비슷하게 나옵니다. 위의 내용을 보면 강나영 1437건, 강다은 1465건, 강도연 1445건 … 인 것을 알 수 있습니다. 만약 테이블의 전체 건수를 알고 싶다면 어떻게 할까요? 아래와 같이 수행해보세요.SELECT     COUNT(*) FROM test.TB_MBR_BAS  ; 수행결과는 다음과 같습니다.2.GROUP BY의 응용(1): 나이 구하기이번에는 나이 컬럼을 추가하고 이름별 나이의 합을 구해보겠습니다. 아래의 명령으로 컬럼을 추가합니다.ALTER TABLE test.TB_MBR_BAS ADD COLUMN AGE TINYINT UNSIGNED DEFAULT 0 COMMENT '나이'; 컬럼이 추가되고, 다음과 같은 구조를 갖출 겁니다.AGE 컬럼에 모두 0이 들어간 것을 알 수 있다.SELECT     * FROM test.TB_MBR_BAS ; 0으로 들어간 값을 1에서 100 사이의 임의 값으로 변경하겠습니다. 만약 내용을 변경한다면 아래 예시와 같이 UPDATE문을 사용하세요. UPDATE test.TB_MBR_BAS SET AGE = TRUNCATE(RAND()*100,0)+1 ; test.TB_MBR_BAS 의 AGE 컬럼 내용을 변경하라는 명령을 하기 위해 RAND() 함수를 쓰고 임의의 값을 발생시겼습니다. UPDATE 및 SELECT를 수행하면 값이 변경된 것을 알 수 있습니다.SELECT     * FROM test.TB_MBR_BAS  ; 변경된 값이번에는 이름이 같은 사람들의 나이 합을 구해볼까요? 합을 구할 때는 SUM 함수를 사용합니다. SELECT     MBR_NM     ,COUNT(*)     ,SUM(AGE) FROM test.TB_MBR_BAS GROUP BY     MBR_NM ; 실행계획은 AGE 컬럼을 추가하기 전과 바뀐 것이 없다는 걸 알 수 있습니다. 실행결과를 보겠습니다.수행시간은 4.3초 걸렸습니다. ‘강나영’이란 이름을 가진 사람의 건수는 1,437건이고, 나이의 합은 74,092인 것을 알 수 있습니다. 합산만 하면 의미가 없으니 평균 나이를 구해보겠습니다. 방법은 SUM / COUNT하는 방법과 AVG 함수를 이용하는 방법 두 가지가 있습니다.SELECT     MBR_NM      ,COUNT(*)      ,SUM(AGE)      ,SUM(AGE)/COUNT(*)      ,AVG(AGE) FROM test.TB_MBR_BAS GROUP BY     MBR_NM  ; 실행계획은 이전과 달라진 부분이 없습니다. 수행결과를 보도록 하죠.수행시간은 5.6초 정도 걸렸습니다. 좀 더 빨리 수행하면 좋을 텐데 말이죠. 시간을 단축시키려면 어떻게 해야 할까요?3.GROUP BY의 응용(2): 수행시간 단축하기기본적인 방법은 GROUP BY할 컬럼으로 INDEX를 생성하는 것입니다. MBR_NM으로 INDEX를 생성해보겠습니다.CREATE INDEX IX_MBR_BAS_02 ON test.TB_MBR_BAS (MBR_NM); 생성 후, 이전 Query를 수행합니다.SELECT     MBR_NM      ,COUNT(*)      ,SUM(AGE)      ,SUM(AGE)/COUNT(*)      ,AVG(AGE) FROM test.TB_MBR_BAS GROUP BY     MBR_NM  ; 아래의 실행계획이 달라진 것을 알 수 있습니다.실행계획을 보면 전체를 읽어서 처리하는 부분은 사라졌습니다. 대신 IX_MBR_BAS_02 INDEX를 사용하는 것으로 나옵니다. 이미 정렬된 구조를 갖추고 있는 INDEX에서는 GROUP BY 수행 시, 또 정렬하지 않아도 됩니다. 그래서 별도 정렬인 Using filesort가 Extra에 나오지 않은 것이고, GROUP BY에 INDEX를 사용하는 것으로 해석할 수 있습니다. 그렇다면 시간은 얼마나 줄었을까요? 수행해보겠습니다.0.5초 정도 걸렸습니다. 기존 5.6초보다 훨씬 많이 개선된 것을 알 수 있습니다. 시간은 단축되었는데 결과는 같습니다.이번에는 IX_MBR_BAS_02를 기존 MBR_NM에서 MBR_NM, AGE로 생성해 보겠습니다.DROP INDEX IX_MBR_BAS_02 ON test.TB_MBR_BAS; CREATE INDEX IX_MBR_BAS_02 ON test.TB_MBR_BAS (MBR_NM,AGE); INDEX를 생성하고 이전 Query를 수행합니다.SELECT     MBR_NM      ,COUNT(*)      ,SUM(AGE)      ,SUM(AGE)/COUNT(*)      ,AVG(AGE) FROM test.TB_MBR_BAS GROUP BY     MBR_NM  ; 달라진 것이 있다면 Extra에 Using index가 표시된 것입니다. 기존에 INDEX가 MBR_NM으로만 구축된 Query는 IX_MBR_BAS_02 INDEX로 GROUP BY하고, TB_MBR_BAS에서 AGE 합을 구한 것입니다. 하지만 INDEX가 MBR_NM, AGE로 구축된 이번 경우는 IX_MBR_BAS_02 INDEX를 이용해 GROUP BY 와 AGE의 합까지 구한 것이죠. 물론 결과는 같았지만, 수행속도는 0.3초로 개선되었습니다.4.GROUP BY의 응용(3): 특정 조건의 결과 출력WHERE마지막으로 성이 김 씨인 경우에만 GROUP BY하여 값을 출력해보겠습니다. 위의 Query에서 WHERE로 조건만 더하면 되는데요.SELECT     MBR_NM      ,COUNT(*)      ,SUM(AGE)      ,SUM(AGE)/COUNT(*)      ,AVG(AGE) FROM test.TB_MBR_BAS WHERE MBR_NM LIKE '김%' GROUP BY     MBR_NM  ; 위의 이미지처럼 WHERE 조건이 들어가면서 type이 index에서 range로 바뀐 것을 알 수 있습니다. 이것을 해석하면 ‘ IX_MBR_BAS_02를 WHERE조건의 범위만큼 처리하라는 것’입니다. 실행결과를 보죠.HAVINGHAVING 절은 GROUP BY로 SUM, COUNT, AVG한 값을 필터 조건으로 걸고 싶을 때 사용합니다. 예시로 위의 Query에서 AVG(AGE) 값이 50보다 작은 것을 출력해보겠습니다.SELECT     MBR_NM      ,COUNT(*)      ,SUM(AGE)      ,SUM(AGE)/COUNT(*)      ,AVG(AGE) FROM test.TB_MBR_BAS WHERE MBR_NM LIKE '김%' GROUP BY     MBR_NM HAVING AVG(AGE) < 50>결과를 출력하면 아래와 같습니다.AVG(AGE)가 50보다 작은 값들이 출력된 것이 보이는군요.글을 마치며간단한 예제를 소개해드렸지만 큰 규모로 GROUP BY를 하면 재미있는 결과들을 만날 수 있습니다. 예를 들어 대한민국 전체 국민을 대상으로 GROUP BY를 실행하면, 평균 나이가 가장 많은 성 씨를 찾을 수 있습니다. 인구통계학 분석에 적용하면 100년 안에 없어질 성 씨를 알 수도 있고요. 응용할 수 있는 범위가 아주 많겠죠? 이상으로 GROUP BY에 대한 소개를 마칩니다. 글한석종 부장 | R&D 데이터팀hansj@brandi.co.kr브랜디, 오직 예쁜 옷만#브랜디 #개발자 #개발팀 #인사이트 #경험공유

기업문화 엿볼 때, 더팀스

로그인

/