스토리 홈

인터뷰

피드

뉴스

조회수 808

[어반 테이스트] 씹고 뜯고 맛보고 즐기는 복지의 탄생! 불이아 역삼점을 다녀오다!

어반베이스에 새로운 복지가 생겼어요!이름하여, 어.반.테.이.스.트.직원들에게씹고뜯고맛보고즐기는 행!복!지!원! 제도인데요!3명이 1팀이 되어 10만원의 맛집탐방비를 지원받아서근무시간 중 2시간을 이용해 맛집에 다녀올 수 있는 제도랍니다 ㅋㅋㅋ(미식가와 대식가가 많은) 어반베이스 직원들에게는 둘도 없고 셋도 없는 아주 훌륭한 복지라고 할 수 이쬬!!! <어반 테이스트>의 첫 번째 팀은 바로 개발부문의 현우님, 현목님과 마케팅부문의 현주님이에요!어색한 듯, 어색하지 않은 이멤버, 리멤버가 다녀온 훠궈계의 성지, 불이아 역삼점'얼마나 맛있는지' 후기를 살펴 보겠습니다 :) 조금 과하게 먹고 싶은 “금요일엔 훠궈지~”- 불이아 역삼점 -한 명이 어떤 음식점이 맛있다고 추천하면, “아 그렇구나” (그리고 안감)두 명이 같은 음식점을 맛있다고 추천하면, “어떤 사람도 맛있다고 하던데..” (그리고 안감)세 명정도가 그 음식점을 맛있다고 추천하면, 그제서야 “거기 진짜 맛있나보네. 한번 가볼까” 라는 마음을 먹게 된다.매번 '불이아' 앞을 지나갈 때마다 각기 다른 사람들이 매번 같은 말로 “여기 훠궈맛집이야”라고 했다. 회사도 코앞인데, 이쯤 되면 한번 가보는게 예의다 싶었다. 가격대가 좀 있지만 금요일인지라 한 주 빡시게 일한 우리에게 셀프선물한다 쳤다.역삼역 7번출구로 나와서 그냥 앞만보고 걸어가다보면 나온다.실제 사진에서 가리키는대로 커피빈까지 쭈욱~~ 걸어가면 된다.커피빈을 지나 GS칼텍스에 가기 전, 오른쪽에 중국풍 건물이 하나 있는데 ‘弗二我’라고 써있다.훠궈. 중국식 샤브샤브를 파는 ‘불이아’다.찾아보니 불이아(弗二我)라는 이름은 '둘도 없는 우리' 라는 의미라고 한다!(워메 중국온줄 ㅎㅎㅎ)딱 들어가는 순간 뭔지모를 중국 그 특유의 향까지 난다.불이아의 대표 메뉴는 ‘불이아 정식(24000원)’소고기 정식과 양고기 정식과의 차이는 ‘소고기+양고기=불이아’ 라는 것.고기 기호에 따라서 선택하면 된다.우리는 소/양 가리지 않고 모두 좋아해 불이아 정식으로 택했다.18,000원짜리 점심 특선도 있는데, 고기 양이 너무 적어 패싱.먹고보니 선택 참 탁월했다는 생각이 든다.메뉴 선택이 끝났으면 소스를 제조하면 된다.간장을 베이스로 5-6개의 소스를 만들 수 있는데,가장 무난하게 간장+양파+고추를 섞어서 만들었다.근데 생각보다 육수가 짜서 소스를 찍어먹을 일이 없었던 게 함정.(채XX, 정XX 샤브샤브 육수를 생각하면 안된다)소스를 너무 그대로 남기고 나와 좀 죄송했다..ㅜㅜ꺄올~~분홍빛이 양고기, 빨간빛이 소고기다.육수 안에 들어가니 양인지 소인지 구분이 안됐다. 둘다 맛있었다.요 짬짜면 같은 반반의 육수가 훠궈의 백미하얀색은 ‘백탕’, 빨간색은 ‘홍탕’나는 원체 매운맛킬러라 단연 홍탕이 내 취향저격일 줄 알았는데, 이거 웬걸.홍탕은 향에 약한 내가 먹기에는 너무 셋다.같이 간 회사동료는 홍탕을 계속 먹다보니 혀가 얼얼해져서 “중국인처럼 말할 수 있을 것 같다”고 했다. 어어ㅓ어어럴어러러ㅓ어…..(개인적으로 같이 제공되는 어묵이 짱맛있어서 어묵으로 혀를 진정시켰다)회사에 돌아와서 불이아 추천해준 동료한테 “홍탕은 너무 향이 세다. 잘 안먹혔다” 했더니,자기는 홍탕 먹으러 불이아에 간다고 하더라 쩝... 같은 궁물인데 사람 따라 참 다르다 싶었다. 정식이라 밥이 나오는 줄 알고 기다리고 있었는데 다 먹어가도 소식이 없었다.확인해봤더니 정식이어도 생면 또는 수제비를 따로 시켜야 한다고.공평하게 생면1개, 수제비1개를 시켰다. (근데 수제비는 비추 ㅠ)딱 적절하게 배가 부른 양이었다. 불이아에서 식사를 마치고 돌아와서 어떤 곳이었는지 검색을 좀 해보니'중국에서 먹는 훠궈보다 맛있다'고 평가를 받는 곳이라고 한다.중국에서 먹어보질 않아서 그런가.. 그정도로 극찬을 할 곳이었던가 싶긴 하다만‘웩 훠궈 이제 안먹어’라는 생각이 들지 않은 걸 보니나 같은 훠궈 입문자한테는 나쁘지 않은 곳인 듯하다.불이아 맛집 평가는?(5점 만점에)불이아 역삼점은역삼역 7번출구에서 약 100미터 거리에 있어서 찾기가 쉽다!중국의 향신료를 즐기는 직장인들에게는  맛도 분위기도 저녁으로 딱일듯!(급 마무리를 하자면) 근무시간을 이용해서 2시간동안배부르게 먹고 모두다 씐나 해피프라이데이였습니당^^^^^^^^^^(좌측부터 현목님, 현주님, 현우님 모습)출처: https://blog.naver.com/urbanbaseinc 
조회수 2590

[아마존 성공 사례] 2. 일일 매출 1억의 기적!

안녕하세요 대한민국 셀러들의 성공적인 아마존 진출을 도와주는 컨설팅 회사이자 대행사인 컨택틱의 이이삭 대표입니다.아마존에서 만족할만한 성과를 거둔 업체들은 각각 특정한 시점에 ‘흐름’을 타는 게 통상적입니다. 여기서 ‘흐름’이라고 했을 때, 솔직히 어느 정도 운도 필요하지만, 그 운 자체를 발생시키기 위한 사전의 노력이 들어가지 않았다고 할 수는 없습니다. 그리고 무엇보다 제가 항상 강조하지만 애초에 ‘상품 및 시장’이 좋아야 이런 기회도 생깁니다. 오늘 소개해드릴 R사는 평소에 일일 판매량이 10~20개 수준이었지만 특정한 계기로 기존의 일일 판매량이 5~10개에 비해 일일 판매량이 1200개가 나왔습니다. 이 업체에게 무슨 일이 있던 걸까요? 아마존에서 매출을 증폭시키기 위해 해볼 수 있는 것들이 몇 가지 있습니다. 그중에 이 업체는 아마존의 ‘딜’을 활용하여 매출을 증폭시킨 경우입니다.아마존 딜 이란 무엇인가?아마존에서는 딜 종류가 3가지가 있습니다: Lightning Deal, Best Deal, Deal of the Day. 각각의 딜 종류마다 특징이 다르고 장단점도 다릅니다. 간단하게만 소개해드리자면 Lightning Deal은 승인이 된다면 약속된 기일에 2~4시간 동안 활성화되며, 그 시간 동안에 소진율을 눈으로도 화면에 볼 수 있습니다. 아래에 사진으로 보여드립니다:위와 같이 특정 lightning deal이 몇 % 정도 claim (소진) 되었는지 알 수 있으며, 언제 끝나는지도 나와있습니다. Lightning deal은 신청비가 발생하며, 어느 시즌에 신청하는지에 따라 신청 비용은 $150 ~ $500 정도 발생합니다. 아무래도 Q4 시즌에는 트래픽이 급증하기 때문에 신청 비용도 그만큼 상승하기 마련입니다. 가장 큰 단점은 본인이 원한다고 해서 lightning deal을 할 수가 없다는 것입니다. 아마존 시스템이 내 상품에 대하여 역제안이 들어와야 하며, 그때에서야 비로소 역제안 들어온 나의 특정 상품에 대해서만 lightning deal 신청이 가능합니다.Best Deal과 DOTD (Deal of the Day)는 신청 비용은 없지만, 아마존 코리아를 통해서만 신청이 가능한 ‘제한적인’ 딜 구좌입니다. 각 딜 종류마다 할인 조건과 자격조건 등이 다양합니다. 딜에 대한 자세한 포스트는 다른 칼럼에서 다루기 때문에 이 포스팅에서는 이 정도로만 소개하겠습니다.아마존 딜을 활용한 매출 증폭 사례R사는 자격조건이 가장 까다롭고 맞춰야 하는 할인율이 가장 높은 DOTD를 신청했고 승인까지 되었습니다. 이 업체는 평소 일일 판매량이 5~10개 수준이었으나, 이 하루 동안 1200개 정도의 상품이 팔렸으며 단 하루 동안 발생한 매출이 무려 대략 10만 불(1억 원)이었습니다.이 사례를 통해 제가 개인적으로 느끼고 여러분들께 말씀드리고 싶은 것은, ‘반응이 있는 상품은 어느 정도 판매량이 일어나야 반응이 있다는 판단을 할 수 있는 걸까?’에 대한 답변과, 그런 ‘반응이 있는 제품’을 대상으로 바라봐야 할 마음가짐과 행동지침입니다. 3개월, 6개월 동안 기본적으로 PPC도 해보고, 랭킹 작업도 해보고, 후기도 어느 정도 쌓였음에도 불구하고 일일 판매량이 꾸준하게 5~10개조차 나오지 않는다면, 이런 제품은 Off-Amazon 마케팅을 해도, 딜을 돌려도 반응이 좋지 않을 확률이 그만큼 높습니다. 하지만 만약 그렇게 꾸준하게 판매량이 받쳐준다면? 그럼 적극적으로 밀어볼 가치가 있습니다.그럼 내 상품이 내가 속한 시장에서 ‘반응’이 있다는 것을 어떻게 제대로 확인하고 확신을 가질 수 있을까요? 그리고 만약 밀어보겠다고 결정했다면 컨설팅이나 가이드 없이는 어렵고 막막하고 두려울 것입니다. 컨택틱에서는 1:1 컨설팅(자문) 서비스도 제공하고 있지만, 기초 지식과 아마존 판매에 대한 상식을 갖출 수 있도록 도와주는 아마존 기초과정과 심화과정이 준비되어 있고 글로벌셀러 창업연구소와 협력하여 여러분들께 배움의 기회를 제공하고 있습니다. 교육 후기들을 보시면 아시겠지만 처음에는 비용을 부담스러워하더라도 모두 매우 만족하며 강의 듣기를 잘했다고 얘기를 하고 있습니다. 무엇이든 혼자 공부해서 못할 것은 없다고 생각합니다. 하지만 그 시행착오와 자료를 찾아가며 공부하는 비효율적으로 소비된 시간보다 차라리 다소의 비용을 투자해서 아마존에 대한 전체적인 이해를 완벽하게 하는 강의를 듣는 게 시간적으로도 효율적일 뿐만 아니라 결국 시간이 돈이기 때문에 금전적으로도 여러분들에게 이익이 될 거라 확신합니다. 관심이 있으신 분들은 글로벌셀러 창업연구소에서 컨택틱과 함께하는 아마존 입문/기초/심화 교육과정들을 살펴보시고 신청해보세요. 가능하신 분은 가급적이면 오프라인 교육을 신청해주시고, 시간적인 여유가 없으시거나 거리가 멀어서 참석하지 못하시는 분들은 온라인 교육도 준비되어 있으니 온라인 교육에도 관심 가져주시기 바랍니다.오프라인 아마존 입문 과정오프라인 아마존 기초/심화 과정온라인 아마존 입문 과정그럼 오늘도 즐거운 글로벌 셀링 되세요!감사합니다.컨택틱  서울특별시 강남구 강남대로 62길 11, 8층 (역삼동, 유타워)   대표 전화: 02-538-3939   이메일: [email protected]   홈페이지: https://www.kontactic.com 네이버블로그: https://blog.naver.com/kontactic  카카오브런치: https://brunch.co.kr/@allaboutamazon
조회수 1184

중독적인 서비스의 2가지 비밀

사람들이 중독적으로 사용하는 제품/서비스를 만드는것은 모든 PM/마케터의 꿈이다. 생각해보라. 내가 만든 앱을 많은 사람들이 하루에도 수십번씩 사용하고, 지하철 이동중에, 화장실에서, 심지어 회의중에도 틈날때 마다 강박적으로 접속하는 서비스가 바로 내가 만든 제품이라는 생각은 상상만해도 흥분된다. 물론 모바일 게임분야에는 이런 중독성을 띄는 제품들이 도처에 널려있지만, 비 게임 영역에서는 이정도 급의 제품들이 많지 않은게 사실이다. 예를들어 주변에 'LoL에 중독됐다'는 사람은 쉽게 찾을 수 있어도, '카카오톡에 중독됐다'는 사람은 찾기가 쉽지 않다. 그만큼 어떤 서비스에 '중독됐다'는 상태는 아무 제품 영역에서나 달성 가능한 것이 아니라 해당 상태를 달성시키기 위한 특정 조건들이 있는데, 오늘 글에서는 그 2가지 비밀에 관한 이야기를 해볼까 한다.제품/서비스에 중독됐다는 것의 의미일단 특정 사용자가 어떤 제품/서비스에 '중독됐다'는 것의 의미를 명확하게 정의내릴 필요가 있다. 제품의 중독성을 어떻게 측정할 수 있을까? 유저 별 하루 평균 세션수를 측정해서 이게 하루에 20회 이상이면 중독됐다고 말할 수 있는건가? Day 30 리텐션이 60%이상을 꾸준히 유지하고 있으면 제품이 중독적이다 라고 말할 수 있을까? DAU/MAU로 측정되는 Stickiness가 항상 50% 이상을 유지하고 있으면 제품이 중독적인 것인가? (제품의 사용성을 측정하는 다양한 분석 지표에 관한 글은 이 전에 쓴 초기 스타트업의 모바일앱 지표 분석 방법론 글을 참고하도록 하자)물론 위와 같은 다양한 지표로 해당 제품의 중독성을 가늠해 볼 수는 있으나 중독된 상태 자체를 증명해 내지는 못한다. 내 제품을 우리 유저들이 정말 중독적으로 사용하고 있는지를 증명해내기 위해서는 위에 언급한 지표들과 함께 유저의 제품 사용 플로우를 함께 들여다 본 후에 다음 명제를 반드시 분석해야 한다.유저가 내 제품/서비스를 필요할때 접속하는가? 아니면 필요치 않아도 습관적으로 접속하는가?이 두가지를 명확하게 구분하는것은 제품이 중독적인가를 판단하는데 매우 중요하다. 예를 들어보자. 국민 메신저라 불리는 카카오톡의 유저 1명당 일 평균 실행횟수는 2016년 7월 App Ape 리포트 기준 거의 30회에 다다른다고 한다. 페이스북이 일 평균 실행횟수가 Verto Metrics의 2016년 9월 기준 11회 정도라고 하는데 카카오톡의 실행횟수가 월등하게 높은 수치임을 알 수 있다. (물론 두 데이터의 소스가 달라서 직접비교는 어렵다는걸 감안해야 한다.)이런 견지에서 카카오톡은 중독적인 서비스라고 말할 수 있는가? 본인은 그렇지 않다라고 주장하는 이유는 해당 앱 실행이 '습관적으로 접속하는게 아니라 필요에 의해서 접속하는것' 이기 때문이다. 사람들이 카카오톡을 사용하는 패턴을 관찰해 보면 누군가에게 메시지를 보내야 하거나 누군가에게 새로운 메시지 알람이 떴기 때문에 접속을 하지, 틈날때 마다 강박적으로 카카오톡을 먼저 켜서 대화를 탐색하고 메시지를 날리는 사람들은 그리 많지 않을 것이다. 즉, 이런 견지에서 내 제품/서비스가 중독적이다의 정의는 다음과 같이 내릴 수 있다.유저들이 내 제품/서비스를 높은 빈도로, 그리고 습관적으로 사용하고 있다.그렇다면, 이렇게 내 서비스를 습관적으로 사용하게 만드는 서비스들에는 그렇지 않은 제품들과 어떤 차이가 있을까? 이 비밀에 대해 제법 명쾌한 해답을 제시하고 있는 책이 하나 있다. 개인적으로 스타트업 하는 사람들이 무슨 바이블처럼 떠 받들고 있는 피터틸의 '제로투원'보다 백배는 더 도움이 되는 책이라고 생각한다. 바로 니르 이얄 (Nir Eyal)의 '훅 (Hooked)'이라는 책이다.개인적으로 제로투원보다 백배는 도움이 되는 내용이 많이 담겨져 있는 책이라고 생각한다.저자인 니르 이얄이 피터틸 처럼 직접 대규모 스케일업을 이뤄본 스타트업 유경험자는 아니고 오히려 학자에 더 가까운 사람이라 그런지 책의 개념에 나와있는 사례들은 사실 별로 공감되지는 않는다. 다만 해당 책에서 제시하고있는 핵심 개념, 즉 '사람들이 습관적으로 사용하는 제품들이 공통적으로 지니고 있는 속성'에 대해 아주 명쾌한 2가지 개념을 제시하고 있는 부분이 있어서 오늘 글에서 간단히 소개하고자 한다.첫째, 보상을 잘 던지는것 보다 중요한 건 보상을 원하는 열망을 잘 해소시키는 인터페이스를 만드는 것이다심리학 교과서에 단골처럼 출연하는 유명한 실험이 하나 있다. 바로 1940년대에 제임스 올즈 (James Olds)와 피터 밀너(Peter Milner)의 쥐 실험이다. 실험 내용은 다음과 같다.두 사람은 실험용 쥐들의 뇌에 전극을 심었고 이를 통해 쥐들이 대뇌 측좌핵 (nucleus accumben)이라는 조그만 부위에 스스로 약한 전기 자극을 가할 수 있게 했다. 그러자 이 쥐들은 얼마 안가 그런 자극에 중독되고 말았다. 쥐들은 음식과 물을 포기하고 심지어 전기가 흐르는 격자판을 통과해야 하는 고통을 감수하면서까지 자극 전달 레버를 계속 누르려 했다.몇년 후에 같은 내용의 실험을 사람에게도 실시했는데 동일한 수준의 결과가 나왔다. 즉, 두뇌에서 즐거움, 열망등과 같은 감정을 관장하는 중추를 발견한 순간이다. 이 둘의 실험에 의하면 그 뇌의 부분을 자극하는 어떤 기작이 존재하면 사람들이 미쳐서 중독될거라고 쉽게 판단해 버릴 수 있으나, 최근에 실시된 한 실험은 더 중요한 비밀에 관해 밝혀내고 있다.스탠퍼드 대학의 브라이언 넛슨 (Brian Knutson) 교수는 기능자기공명영상 기계를 사용해 사람들이 도박을 할 때 두뇌 혈류량에 나타나는 변화를 측정하는 실험을 실시했다. 실험 참가자들이 도박을 하는 동안 두뇌의 어떤 부위가 점점 활성화되는지를 살펴본 것이다. 그런데 보상 (이 경우, 도박으로 돈을 따는 것)을 받긴 하지만 그것이 기대했던 것일 때는 대뇌 측좌핵이 활성화되지 않는다는 놀라운 사실을 발견했다.위의 연구에서 주지해야 할 점은 바로 '우리의 행동을 유도하는 것은 보상 그 자체에서 느끼는 기분이 아니라 그런 보상에 대한 열망을 완화시키고자 하는 욕구'라는 사실이다. 무슨 말이냐면, 우리가 심리적으로 흥분된 상태를 경험하려면 특정 보상을 받고자 하는 열망이 필요한데, 중요한건 이 열망 자체를 제시하는것 보다 중요한게 열망을 완화시켜주는 인터페이스라는게 핵심이다.예를들어 틴더와 같은 데이팅 앱을 생각해 보자. 틴더 앱에서 우리가 원하는 보상은 명확하다. 바로, '맘에 드는 이성과 연결되는 것' 이다. 앱에서 특정 상대와 매칭되는 순간 그 자체가 우리에게는 보상이 되는 것이다. 그렇다면, 틴더는 그 보상만 계속 제공해 주면 유저들이 앱에 중독성을 띌까? 많은 사람들이 이 보상 자체에만 집중하는 경향이 있는데 더 중요한건 그 보상을 받고자 하는 열망이 해소되는 순간에 있다. 틴더에는 매칭이 되서 서로 대화를 나누는 순간이 바로 그것이다. 유저가 틴더에 계속 중독이 되려면 1) 'It's a Match!' 라는 보상을 주는 기작과 함께 2) 매칭이 되어 그 상대와 대화를 나누게 되어 내가 가지고 있던 열망이 완화되는 인터페이스가 잘 작동해야만 유저의 뇌의 대뇌 측좌핵을 흥분시키는게 가능해 지는 것이다. 즉, 유저가 아무리 매치됐다는 알림을 많이 받아도, 해당 상대와 대화로 연결되는 인터페이스가 잘 작동하지 않는다면 '뭐 매치되도 또 묵묵무답이겠지..' 라고 생각하면서 보상에 대한 열망이 완화되지 않고 스트레스로 쌓이게 되어 중독성을 잃게 되는 것이다.틴더가 중독성을 띄기 위해서는 It's a Match!라는 보상기작 보다 매칭 이후에 대화로 연결되는 보상에 대한 열망을 해소시켜주는 단계가 잘 작동해야 한다.반대로 페이스북의 경우를 보자. 페이스북에서 사람들의 중독성을 자극하는 보상기작은 무엇일까? 바로 이 지구본 아이콘에 버블로 달리는 Notification이다. 페이스북은 당신이 사회적으로 관심받고 있는 존재다 라는 보상을 노티피케이션으로 던져준다. 누군가 내 글에 라이크, 댓글 등을 달때라던지, 내가 단 댓글에 누가 또 댓글을 단다던지, '나'라는 존재에 사람들이 관심을 표현하는 모든 종류의 행동을 다 인터페이스화 해서 노티피케이션이라는 훌륭한 보상기작에 담아놓은 것이다.페이스북 중독의 핵심은 이 노티피케이션의 숫자 그 자체의 보상이 아니라, 바로 이 노티피케이션 숫자를 kill하는 순간, 즉 내 보상의 열망이 해소되는 순간에 있고, 페이스북은 이 인터페이스를 자연스럽게 설계해서 페이스북에 어느정도 시간투자를 하는 유저들이라면 누구나 보상 해소가 자연스럽게 이루어지도록 유도하고 있다.페이스북에 중독되는 마법의 순간은 노티피케이션 아이콘에 버블이 뜨는 순간이 아니라, 그 버블을 kill하면서 대뇌 측좌핵을 자극하는 순간에 있다.따라서, 본인 서비스에 유저들이 중독되게 만들고 싶으면 다음 3가지 개념을 꼭 고민해 봐야 한다. 1) 유저들의 어떤 열망을 자극하고자 하는지, 2) 해당 열망을 어떤 보상의 형태로 제공할 것인디, 그리고 가장 중요한 3) 보상에 대한 열망이 해소되는 인터페이스를 구현하는 것이다.둘째, 보상을 반드시 가변적으로 던져줘야 한다인간의 뇌는 '휴리스틱 (heuristic)'이라는 아주 훌륭한 인터페이스가 있어서 수많은 복잡한 감정이나 결정들을 최대한 효율적으로 처리할 수 있게 만든다. 이게 뭐냐면, 인간의 뇌에는 반복적인 절차나 경험을 그룹화해서 미리 저장해 놓는 인터페이스가 따로 있어서 어떤 일이나 감정이 반복적으로 발생하면 그에 대한 대처 역시 자동적으로 발생하도록 저장해 놔서 해당 자극이 발생할 때 마다 힘들게 사고처리를 하지 않아도 대처가 가능하도록 만들어놓은 아주 효율적인 시스템인 것이다. 직장에서 상사한테 깨질때 마다 습관적으로 담배피러 간다던지, 화장실 표지판의 색깔이 파란색이면 남자화장실, 빨간색이면 여자화장실일거라고 자동적으로 생각하고 파란색으로 들어갔다가 봉변을 당한다던지 하는 류의 행동이 모두 휴리스틱에 기반한 행동들이다.우리가 주목해야 하는 점은 바로 본인 서비스에서 제공하고 있는 보상이 반복적이거나 습관적인 패턴으로 제공이 되고 있으면 유저의 뇌에서는 이 자극을 휴리스틱 인터페이스로 처리할 가능성이 다분히 높아진다는 점이다. 즉, 위의 페이스북의 예시에서 노티피케이션의 버블 숫자가 내가 항상 앱에 접속할 때 마다 같은 숫자로 떠 있다던지, 틴더에서 It's a Match!라는 메시지가 너무 반복되는 패턴으로 뜬다던지 하면, 처음에는 해당 보상에 흥분하던 소비자가 점차 그 흥미를 잃고 해당 자극은 휴리스틱 인터페이스로 처리되어 더이상 대뇌 측좌핵을 자극하지 못하게 되는 것이다.하지만, 해당 보상이 최대한 간헐적으로, 예측하지 못하는 패턴으로 제공되면 오히려 유저가 해당 보상을 얻기 위해 더욱 열정적으로 달려드는 패턴을 보이는 경우가 많은데, 이 심리적 행동을 설명하는 아주 유명한 실험이 있다.1950년대에 스키너 (B.F. Skinner)라는 심리학자가 가변성이 동물의 행동에 미치는 영향에 관한 연구를 실시한 적이 있다. 그는 레버를 누를 때 마다 음식물이 나오도록 특수 제작한 상자 안에 비둘기들을 집어넣었다. 올즈와 밀너의 실험용 쥐와 마찬가지로 비둘기들은 레버를 누르는 것과 음식이 나오는 것 간의 인과관계를 학습했다. 다음 단계에서 스키너는 여기에 가변성을 추가했다. 비둘기가 레버를 건드릴 때 마다 음식물이 나오는 것이 아니라 무작위로 정한 횟수만큼 비둘기가 레버를 건드리면 기계에서 음식물이 나오도록 변화를 가한 것이다. 어떤 때는 레버를 누르면 음식물이 나오지만 또 어떤 때는 나오지 않았다. 스키너는 이런 간헐적 보상이 비둘기가 레버를 두드리는 횟수를 급격히 증가시킨다는 사실을 발견했다. 가변성을 추가하자 그가 의도했던 행동의 수행 빈도가 급증했던 것이다.이 스키너의 실험이 의미가 있는 것은, 보상기작을 최대한 간헐적이고 상대방이 예측하기 불가능한 패턴으로 제공하기 시작하면 해당 유저를 거의 미칠정도의 수준으로 중독시키는게 가능해 진다는걸 암시하고 있기 때문이다. 이걸 페이스북의 예시에 적용해 보자. 페이스북은 게시물 노출 알고리즘의 복잡함과 정교함을 통해 이 부분의 목표를 달성하고 있다. 많은 사람들이 페이스북 노출 알고리즘이 대략 이러이러할 경우 노출 확률이 높아진다 정도의 이야기는 하고 있어도 그 누구도 어떤 인풋과 조건값이 있을때 어떤 노출빈도가 형성되어 내 노티피케이션 버블을 만들어 내는지에 대해 알고 있지 못한다. 따라서 수 많은 유저들이 다양한 종류의 포스팅을 올리고 해당 글에 라이크가 얼마나 달리는지를 중독적으로 쳐다보고 있게 만들며, 언제는 라이크가 마구마구 달릴때도 있고, 또 어떤때는 내 예상보다 훨씬 적게 달릴때도 있게 만듦으로써 보상기작 자체를 간헐적으로 제공하고 있다. 이 간헐적 보상을 통해 페이스북은 해당 보상의 가치를 최대한 끌어올려서 유저로 하여금 레버를 미친듯이 눌러대는 비둘기 마냥 중독적으로 노티피케이션을 쳐다보게 만들고 있는 것이다.지금까지의 내용을 간단히 정리해 보면 다음과 같다.내 제품/서비스가 중독적이게 만들기 위해서는 우선 1) 유저가 내 서비스에서 제공하는 보상을 얻고싶다는 열망을 가지게 만들어야 하고, 2) 보상기작보다 중요한 건 보상을 완화시키고 싶은 열망을 해소시키는 인터페이스를 잘 구축해 놓는 것이며, 3) 보상을 반드시 간헐적으로, 예측 불가능한 패턴으로 던져줘야 한다.니르 이얄의 'Hooked' 책에는 이런 내용 외에도 사람들이 습관적으로 사용하게 만드는 서비스들이 공통적으로 지니고 있는 속성들에 대해 잘 정리되어 있으니 한번 읽어보면 많은 도움이 될 것이다. 다만, 앞서 말한바와 같이 저자가 학구파이다 보니 저자가 제시하고 있는 사례들이 크게 설득력 있진 않아서 다 읽고 나면 뭔가 뜬구름만 잡아대는 교과서같은 느낌을 받을 수도 있다. 하지만, 저자가 제시하는 개념 자체를 잘 이해해서 본인만의 사례, 또는 본인 제품에 대입해서 잘 고민해 본다면, 분명 '제로투원'보다 얻어가는게 백배는 많을거라는 본인의 말에 공감이 갈 것이다.** 본 글은 문돌이 PM의 마케터 따라하기 시리즈 입니다.** 1화 보기 - 초기에 할만한 ASO (앱스토어 최적화) 팁** 2화 보기 - 초보 PM이 알아야 하는 초기 모바일앱 분석 101** 3화 보기 - 스타트업 브랜딩: 내가 보는 나와 너가 보는 나의 일치** 4화 보기 - 홍보영상 직접 제작해서 수백만원 절약해보자** 5화 보기 - 바이럴루프, 중요한건 알겠는데 어떻게 적용할래?** 6화 보기 - 인스타그램 노가다 마케팅 101** 7화 보기 - 문돌이도 간지나는 HTML 이메일좀 보내보자** 8화 보기 - 인스타 마케팅 헛수고를 줄이는 10가지 마케팅 방법론** 9화 보기 - 초기 스타트업의 무료 마케팅 채널** 10화 보기 - 프리미엄병에 걸리지 말자** 11화 보기 - 초기 스타트업의 모바일앱 지표 분석 방법론글쓴이는 스팀헌트 (Steemhunt) 라는 스팀 블록체인 기반 제품 큐레이션 플랫폼의 Co-founder 및 디자이너 입니다. 비즈니스를 전공하고 대기업에서 기획자로 일하다가 스타트업을 창업하고 본업을 디자이너로 전향하게 되는 과정에서 경험한 다양한 고군분투기를 연재하고 있습니다.현재 운영중인 스팀헌트 (Steemhunt)는 전 세계 2,500개가 넘는 블록체인 기반 앱들 중에서 Top 10에 들어갈 정도로 전 세계 150개국 이상의 많은 유저들을 보유한 글로벌 디앱 (DApp - Decentralised Application) 입니다 (출처 - https://www.stateofthedapps.com/rankings).스팀헌트 웹사이트 바로가기
조회수 1029

이거 뭐 써먹을데가 있어야지..

규모는 대기업이라고 하기엔 뭐하지만 나름 카메라시장에서 제일 잘나가는 외국계 회사, 국내 대기업보다도 더 대기업 문화를 가진 회사에서 기획돌이로 일하고 있었다. 나름 신사업 담당이랍시고 이것저것 들쑤시고 다니면서 몇십억 돈드는 프로젝트도 터뜨려 보고 사장님 앞에서 당돌하게 이래서 뭐 5년후에 회사 남아 있겠습니까? 하며 직썰도 날리는 자신감 넘치고 좀 건방진 사원대리 나부랭이였다.그런데, 신사업을 담당하다 보니 자연스레 스타트업 동네에 놀러가는 일이 잦아졌고, 그들이 무대에서 멋있게 피칭도 하고 투자도 받고 인터뷰도 하면서 뭔가 본인이 하고싶은대로 다 해먹을 수 있는 저동네가 점점 부러워 지기 시작했다. 내 회사에서 뭐 하나 해보려고 하면 차장님 -> 부장님 -> 임원진들 -> 사장님 -> 다시 임원진들 -> 다시 부장님 -> 다시 임원진들 -> 다시 사장님 ... 이런 무한 트리를 반복하다 보면 내가 처음에 하려던건 수박이였는데 어느새 호박으로 바뀌어져 있는 경우가 많다보니 당연히 저 스타트업 형들이 얼마나 멋있어 보였겠는가.기획서 무한 루프에 한번 빠지면 빠져나올수가 없는 대기업 보고시스템그래서 과감하게 때려쳤다. 원래부터 한번 꽂히면 나중에 '아 이게 아니였는데...' 하고 후회를 하기 전에는 내 쿨해보이는 선택에 자아도취하던 성격이라, 나름 계획도 세우고, 그만두기 전에 팀도 꾸리고, 아이템도 (내 생각에는) 뭔가 있어보이는걸로 골라서 있어보이는 기획서도 만들고, 뭔가 이게 열라 심각한 문제를 해결하는 엄청 스마트하게 풀어내려는 아이템처럼 스토리도 잡고... 아무튼 회사 그만두기 1개월 전까지는 자신감도 충만했고 바로 막 무대에서 피칭도 하고 그럴줄 알았다.그러다가 1개월 직전 갑자기 같이 하기로 한 사람들의 마음이 바뀌고 팀이 와해되 버렸다. 회사에는 이미 '난 몇월 몇일부로 그만두겠소!' 하고 통보해놓은 마당에 이미 업질러진 물을 다시 담을 길은 없어 보였고, 또 그러기도 싫었다. 그때 내 생각은 (지금 생각하면 정말 바보같은 자아도취 마인드) 바로 이랬다.나 정도면 신사업도 이것저것 해봤고, 포샵으로 디자인도 할 수 있고 (파워포인트 디자인 하던걸 감히 디자인이라 불렀다...), IT쪽에도 나름 아는게 많고 (테크니들 기사를 열심히 읽던걸 감히 이렇게 생각했었더라...), 피칭도 잘 할 수 있고 (사장님, 임원들 앞에서 재롱떨던 피티실력을 감히 이렇게 평가했었더라...), 아무튼 나정도면 금방 개발자도 만나고 디자이너도 만나서 멋찐 팀을 꾸릴 수 있을꺼야!이렇게 생각했던게 정말 나의 엄청난 무지와 부끄러운줄 모르고 나대는 초딩들의 외침이였다는걸 느낀건 그리 오래걸리지 않았다. 회사를 그만둔 시점부터 열심히 이곳 저곳 스타트업 모임에 찾아다니고, 스타트업 이미 하고 있는 형들도 좀 찾아 다니고, 개발자 모임에 가서 열심히 아이템 설명도 하고 돌아다니는 시간이 길어질 수록 내가 가진 능력은 저기 길거리에서 나부끼고 있는 전단지 한장 딱 그정도의 역할밖에 이 바닥에서 할 수 있는게 없다는걸 받아들일때 까지 딱 두달밖에 걸리지 않았다.그 당시 스타트업 형님들이 나를 보면 아마 속으로 이렇게 생각하고 있었을꺼다그렇다. 내가 그때까지 해온 내 4-5년의 커리어라는건, 그냥 딱 3가지로 요약 가능한데 1) 보고, 2) 보고를 위한 기획서 작성, 3) 정치 및 의전. 그냥 이거 3개만 4-5년동안 줄창 해오던 거라는걸 인정하는데 그리 오래 걸리지 않은거다. 그나마 더 오래 걸리지 않은게 다행인건, 나는 대기업에서 좀더 전문가 보직에 있는 사람들 (재무, 회계, 영업, IT 등등)도 아니었기 때문일거다.그래서 나는 모든걸 다 인정하고, 내 무지를 깨달은 그 시점부터 최근에 정식으로 서비스를 런칭할때 까지 거의 1년 반의 시간동안 대학교에 다시 들어가는 심정으로 닥치는 대로 공부하며 시간을 보냈다. 다행이도 요즘은 유다시티, 유데미 등 맘만 먹으면 프로그래밍이나 디자인을 초보 수준으로 익힐 수 있는 길이 널려있기도 해서 나는 유데미에서 프로그래밍, UX기초, 스케치로 모바일 디자인하기 등등 앱이나 웹서비스 제품을 만들기 위해 꼭 필요한 기본기들을 착실히 공부해 나갔다.다행스러운건, 내 무지를 깨달을 즈음인 작년 여름, 아무 생각 없이 지푸라기라도 잡는 심정으로 나가본 해카톤에서 만나게 된, 그리고 지금은 고맙게도 이런 무지한 나와 같이 팀을 꾸리고 풀타임 스타트업을 같이 해주고 있는 만랩 풀스택 개발자를 만나게 된건 정말 행운 오브더 행운이었다. 현재 우리는 2016년 4월을 기점으로 BourbonShake (우리 개발자님이 좋아하는 술이 버번이라서...ㅎㅎ)라는 스타트업을 꾸리고 바크 (Bark)라는 앱을 서비스 하고 있다. (바크에 대해서는 나중에 자세히 소개할 예정.) 나는 나름 제품 디자인과 마케팅을 담당하고 있다. (하지만 이마저도 저 능력자 개발자님한테 맨날 갈굼당하면서 하고 있다.)앞으로 브런치를 통해서 나처럼 뭣도 모르고 이바닥 뛰어들었다가 고군분투 하고 있는 사람들과 다양한 이야기 및 노하우를 서로 나누고 싶다. 열혈강호의 주인공 처럼 (물론 그는 슈퍼 천재긴 하지만) 어쩌면 차라리 백지에서 시작하는게 더 원하는 그림을 그릴 수 있는 장점이 있는 것 처럼, 혹시나 나 같이 지금 회사에서 보고트리를 타는 업무를 하고 있는데 스타트업쪽의 커리어를 희망하는 사람들이 있다면 괜히 주눅들지 말고 과감하게 실행해 보라고 말하고 싶다. 글쓴이는 스팀헌트 (Steemhunt) 라는 스팀 블록체인 기반 제품 큐레이션 플랫폼의 Co-founder 및 디자이너 입니다. 비즈니스를 전공하고 대기업에서 기획자로 일하다가 스타트업을 창업하고 본업을 디자이너로 전향하게 되는 과정에서 경험한 다양한 고군분투기를 연재하고 있습니다.현재 운영중인 스팀헌트 (Steemhunt)는 전 세계 2,500개가 넘는 블록체인 기반 앱들 중에서 Top 10에 들어갈 정도로 전 세계 150개국 이상의 많은 유저들을 보유한 글로벌 디앱 (DApp - Decentralised Application) 입니다 (출처 - https://www.stateofthedapps.com/rankings).스팀헌트 웹사이트 바로가기
조회수 1093

[인터뷰] Humans of MEME, 그 두 번째 주인공을 만나다. - 누군가를 웃게 만들고 싶은 CS팀 루나의 이야기

안녕하세YO!미미박서의 사소하지만 특별한 이야기를 담아오는 Moth입니다!  본격적인 인터뷰에 들어가기에 앞서미미박스는 현재 '도와줘요 미미 SOS' 프로그램을 운영하고 있는 것을 알고 계신가요?바로 '도와줘요 미미 SOS'는 뷰티 고민 상담소인데요!매주 목요일 3시-5시 네이버 톡톡(채팅)에서 평소 가지고 있던 뷰티고민을 문의하면 모든 고객님들께 미미언니가 뷰티 솔루션을 드리고 있는 프로그램입니다! ↓↓↓ 도와줘요 미미 SOS 자세히 알아보러가기 ↓↓↓이처럼 미미박스는 고객의 입장에서고객 한 분 한 분의 고민을 해결하는 데에 도움을 드리고 더 좋은 경험을 할 수 있도록 노력하고 있습니다!현재 미미박스 판교 사옥에는 고객을 생각하는 회의실명으로 CUSTOMER 라는 공간도 따로 있을 정도랍니다!미미박스 회의실 CUSTOMER고객은 바로 미미박스의 중심!        ~(  ͡°  ͜ʖ  ͡° )~ 다시 본론으로 돌아와서..Humas of MEME는 탐험가 정신을 지닌 미미박서 분들의 가치관 혹은 삶을 살아가는 방식에 대한 이야기를 듣고자 진행되고 있는 프로젝트입니당 :)  이번 주에 저 Moth는가장 직접적으로 고객과 소통하고 있는 CS팀의 Luna를 만나보았습니다!Luna는 ‘해질녘 어느날…(아련)’ 머리 스타일을 가지고 있는 미미박스인데요!개성 있는 헤어스타일과 다양한 뷰티 제품 지식을 셥렵하고 있어서역시 코덕계의 성지, 미미박서! 라는 생각이 딱 들었습니당   바로 오늘 그 파!워!소!통!러! CS 팀 루나의 이야기가 궁금하시지 않으세용? 저는 매우매우 기대가 됩니다.(나는. 지금. 인터뷰가. 땡긴다.)그럼 그 두번째 주인공, LUNA를 만나볼까요?   Q. 뷰티 회사의 직원으로서 느끼는 ‘뷰티’가 아니라, Luna가 느끼는 ‘아름다움’ 이란 무엇인가요?A. 자기 자신을 사랑하는 거라고 생각해요. 제가 화장품에 관심을 갖고 좋아하게 된 계기이기도 하고 항상 즐거워 보이는 비결이기도 합니다(하지만 그로 인해 살을 못 빼는 치명적인 단점이 있다는 후문...).  어렸을 때에는 이해할 수 없었던 ‘나 자신을 사랑해야 다른 이에게도 사랑받는다는 말’을, 지금은 누구보다 공감하고 있어서 제가 사랑하는 모든 분들이 공감하시고 실행하실 수 있으면 좋겠네요! Q. 혹시 좋아하는 문장이나 문구 있으신가요?A. 어렸을 때 친구들이랑 모여서 모임이름이자 건배사로 썼던 단어인데요(웃음). 화.개.장.터! 입니다. 한명이 큰 소리로 화개장터! 를 선창하면, 다같이 화려한·개그를·장시간·터트리자! 라고 외치고 건배를 하곤했어요(웃음). 저는 누군가에게 도움이 되거나 좋은 사람이 되었을 때 만족하고 누군가를 웃게한 제 자신이 가장 좋거든요.  그러다보니 저런 웃긴 구호도 만들어서 놀고 그랬었네요. Q. 누군가에게 도움이 되는 존재이고 싶은 Luna 가 왜 CS팀에서 근무하고 계신지 단번에 이해가가네요! 혹시 그렇다면 ‘미미박스’ 뷰티 회사의 CS 팀에서 일하는 특별한 점은 무엇이 있을까요?A. 제일 먼저 생각나는 건, 아무래도 뷰티회사 직원이다보니 화장품을 포함한 뷰티제품을 많이 사고 써보고 관심있어 한다는 거죠! 덕분에 월급이 통장을 스쳐 지나가 버리지만.. ‘그래! 이건 내가 뷰티회사 직원이기 때문이지! 직업정신이다!’ 라며 죄책감을 잊을 수 있다는 장점이 있습니다(웃음).미미박스에서 일하면서 만족하는 건 저희 CS팀이 일반 고객센터처럼 단순 처리만 하는 게 아니라 CS팀으로서의 책임감과 자부심을 가지고 다각도로 고객들을 케어하려고 한다는 점이에요.어려운 이슈가 발생했을 경우에는 정해진 룰에만 따르는 것이 아니라 다같이 의견을 공유하고 가장 나은 처리를 할 수 있도록 하고 있습니다! 수동적이 아닌 주도적으로 일을 하고 있지요(뿌듯).고객의 불편함을 미리 방지할 수 있도록 대처를 하거나 더 나은 방법으로 고객께서 미미박스를 이용하실 수 있도록 사후관리도 하고있으며 무엇보다 고객들께 친근하게 접근하려고 노력하고 있습니다. Q. 어떻게 친근하게 접근하고 계신지 더 자세히 여쭤봐도 될까요?A. 예를 들면 저희는 고객이 제품에 대해 궁금해하시면 바로 자리를 박차고 일어나 제품을 준비해온뒤 통화하면서 제품을 발라보고 사용해보면서 경험을 공유하고 있어요.미미박스를 사랑해주시는 소중한 고객님들 한 분의 문의도 놓치고 싶지않기에 네이버지식인, 구글앱스토어, SNS, 고객센터전화, 1:1게시판으로 오는 문의를 모두 응대하고 있습니다. 더불어 소중한 미미박서님들의 문의도 저에게 슬랙(사내SNS)만 주시면 열심히 도와드리고 있습니다(아직 모르는 분들도 있으신거같아요! 내부 직원 문의는 루나에게 간단히 슬랙만 주셔도되고 가벼운 마음으로 찾아와주셔도 되어요!).사랑하는 저희 팀원들의 멋진 CS마인드도 특별하고 더불어 미미박스에는 타 부서에도 고객님을 생각하고 도와주시는 여러분들이 계셔서 많은 도움을 받을 수 있어서 더 멋지고 특별한 것 같아요.  고객과 미미박서 여러분들에게언제든 따뜻한 도움을 주고 계시는 Luna ❤︎실제로 루나는 다양한 뷰티 소식들을 미미박서분들께 공유해주시는 메신저 역할도 톡톡히 하고 계십니다>.<실제 근무하고 있는 루나의 모습! 루나의 책상에는 코덕을 증명하듯다양한 제품들과 향기가 가득했습니다..! (모뜨는 반성합니다_책상아 미안해)미미박서의 삶! 그리고 일! 을만나보셨는데 어떠셨나요?저는 인터뷰를 진행하면서 와- 미미박스에 이런 멋진 사람들이 많이 있구나! 라고 생각하고다음 인터뷰를 만날 생각에 참 기뻐용 허허.다음에는 NEW 미미박서 이야기를 NEW롭게 들려드리도록 하겠습니다!그렇다면 오늘은 ㅎㅎ루나의 건배사로 포스팅을 마치도록 하겠습니다!화!개!장!터!
조회수 1397

스타트업이 성공하는 1가지 이유?

(출처: MBC 무한도전 중에서)한창 스타트업의 길을 걷고 있는-ing형의 창업가 나부랭이가감히 이런 글을 남긴다는게아이러니하지만....(오지랖이 넓다 못해 참견쟁이인 필자 -.,-)간혹 여러 멘토님들이 지적하는스타트업이이러면 망한다, 이게 문제다 하는 글을 접하며과연 그 주장에 대한 근거에 대해 의문점이 생겼다.물론 다 맞는 이야기들이고매우 교과서적인 이야기들이다.뭔가 부족했으니까 망했겠지,뭔가 준비안되서 그랬겠지,뭔가 선택을 잘 못 했겠지.....벌써 주위에 여러 대표님들이자연인 혹은 다시 직장인으로 회귀하고 있다.(물론 또 한 번의 힘을 쥐어짜는 분도 계시고...)실패한 창업자에게 이유를 대는 것은 매우 쉽다.인력, 능력, 자금, 트렌드, 고객, 마케팅 등등이미 실패한 입장에서는 무얼 갖다대든다 맞는 이야기 같거든.역으로 물어보고 싶다.그럼 성공한 스타트업은이 모든 원인(조건)들을다 갖추었기 때문에 시장에서 성공하였는가.적어도 필자가 아는 범위에서는아.니.다.나름 잘 나가고 있다는스타트업 기업의 대표들도항상매출, 자금 수혈, 인력 부족,시장 트랜드의 변화 등에 대해고민하고 부족함을 호소하고 있다.(출처: KBS 1박 2일 중에서)1. 대표가 회사에 없고, 밖으로 나돌아서 망했다고?-> 사업에 따라서, 시기에 따라서회사안보다 밖에서 비지니스가 더 잘 이루어질 수 있다.2. 적절한 인력을 채용 못해서 망했다고?-> 대한민국의 중소기업 더 나아가서 중견기업까지모두 인력채용에 대해 매칭의 어려움과 투자대비 생산성에문제를 가지고 있다.(공무원과 대기업에 몰리는 현상이 괜히 있는게 아니다.)3. 고객의 니즈를 제대로 파악 못 해서 망했다고?-> 시장의 흐름은 빠르게 바뀐다. 거기다가 경쟁업체가이제는 국내만아니라 글로벌이다.일일이 다 파악하는데만 시간이 얼마나 소요되는가.그리고 고객의 취향을 저격해도, 곧 변덕을 부리기도 한다.물론 빠른 대처, 임기응변이 필요한건 다 안다.그래. 말은 쉽지.그거 제품/서비스에 반영하는데 들어가는 돈과 시간, 인력은?나열하면 끝도 없다.우리 좀 더 솔직해지자.창업하다보면 망할 수도 있다.진짜 능력이 미천하여,관리를 못해서,예측을 못해서망하는 기업이 수두룩하다.창업자가 "신"이 아닌 이상 완벽할 수 없잖아.그런데 성공한 창업자는 뭐 다 갖춰서 성공한건 아니잖아.부족한 가운데서 성공한 것은 완벽해서가 아니라부족함을 능가하는 뭔가가 있어서라는 말이 더 맞는거다.자금이 부족해서 힘든 스타트업은고객이든, 투자자든간에 그들에게 인정받을 그 때까지끝까지 동행해 준 동료(팀)으로 극복하기도 하는거고제품이 지금 당장 고객 니즈에 부합하지 않았다가시간이 지나서 고객 니즈에 맞아 떨어지는 타이밍이시기적으로 맞아 떨어져 성공하는 경우도 있고내세울게 창업자 하나 달랑 성실하다는거,적어도 사람하나는 꽤 괞찮아서거액의 투자받아 인력, 시설, 생산 등의 문제 해결하기도 하고(물론 이런 신데렐라 같은 경우는 매우 드문일이지만...;;)많은 성공스토리들에서 느낀 점은결국 완벽해서가 아니라"여기는 이쪽이 꽤 강하네"랄까?성공한 창업자에게는 참 관대하면서,실패한 창업자에게는 참 좁은 잣대로평가하는 글들은뭔가 그냥 구색 맞추기의 훈수거리가 아닐까?하다 못 해 동일한 기준으로 분석하고,피드백을 주는 것이 더 나은 복기가 아닐까?성공 가도를 달리고 있는 스타트업!사실 완전하게 성공한 스타트업이란 없다.최종적으로 Exit하지 않는 한,그냥 잘 진행하고 있는 스타트업 뿐이다.그리고 좀 잘 된 스타트업도 거기서 멈추지 않고,또 다른 도전과 영역에서형태만 다를 뿐이지 "스타트업" 인생은 계속 되는거니까.다만,필자는 소위말하는잘 나가는,본 받을만한 스타트업들은단 1가지가 다른 스타트업들보다다르다고 생각한다.그 한 가지가팀(멤버)든,자금이든,인적 네트워크든간에거기에 외부적인 타이밍과소위 "운"이라는 요인도절묘하게 맞아 떨어질때사업에 큰 변화와 목표 달성에한 발 더 앞서나가는게 아닐까.(출처: 구글, 노력한 사람과 안 한사람 중에서): 과연 잘 나가는 스타트업만이 문제해결을 위해 노력한걸까?모든 스타트업 기업들은다 그러한 차별성을 가지고 있다.그럼에도 실패하고, 폐업하고, 사라진다.막연하게 3년 버티면 잘될거라는 말따위에무작정 버티기하라는 식의 조언은창업자 입장에서는 근거없는 희망고문이다.우리가 발버둥을 치더라도확실한 한 가지는 붙잡고 발버둥쳐야하지 않을까?멘토들이 지적하는 부족한 부분들을무시하라는게 아니다.맞는 말들이고, 최대한 보완해야할 문제들이다.실패의 요인들을 최소화해야살아남을 가능성이 더 늘어나는 것도 사실이다.그렇다고,그거에 너무 몰입되어그나마 가지고 있는 장점을그냥 평범한 수준으로끌어내리는 우(愚)를 범하지 말자.누구에게든자신있게 자랑할 수 있는최고의 무기는 하나 꽉 잡고전쟁에 임해야 그나마 희망이라도 가질 수 있잖아.너무 팔랑귀가 되서이것저것 다 손대고,다 갈아엎고, 다 혁신이라는 이름으로다 바꾸어버리면...어느새이도저도 아닌 잡탕스런 회사가 되버린다.필자도 항상 두렵다.우리 회사라고 특별히 다른게 아니라언제든지 리스크는 존재하니까.최상의 선택을 하는 것보다,최악의 선택을 피하는 것이 더 낫다는 주의로좀 보수적이고, 조심스럽게회사를 운영하고 있다.필자를 멘토링해주시는많은 고마운 분들 중에서는"좀 더딘거 같아요. 속도를 더 내면 좋겠어요""지금 타이밍에 몰아 붙여야해요"라는 주문으로 필자를 푸쉬하기도 한다.멘토분들의 조언은 항상 감사하다.(출처: 구글, 감사합니다.)부족한 창업자에게길을 제시해주고, 보다 나은 선택을 위해피드백을 주시는 분이 많을 수록창업자가 볼 수 있는 시각은 더 넓고 깊어지니까.필자 역시 더 속도내고 싶고,더 욕심내고 싶지만,하고 싶어도 그렇게 하지 못하는 경우가 많더라.인허가를 받기 위해 단계별로 준비할 것들이 있고,내 욕심과 별개로 정해져 있는 프로세스와 규정들이 있다.왜 미리 준비 안 했냐고 물으신다면,그 전에는 또 먼저 수행해야할우선순위 미션들을 클리어하고 있었다.스타트업을 하는 창업자들은나름 그 분야에서 전문가인 분들이 많다.그 쪽 업계에 생태와 프로세스에 대해 어찌보면,두루 널리 알고 있는 컨설턴트보다는 좁겠지만,깊게는 더 잘 알고 있다.누구나 특허 준비해야한다, 인허가 준비해야한다,인력은 어떤 사람을 채용해 놔야한다라는 식의공통적이고 광의적인 멘토링은 쉽다.정작 제품/서비스에 필수적으로 수반되는검증/인증/제작 프로세스/핵심 기술에 대하여제대로 컨설팅 해줄 수 있는 것은그 분야에 정통한 경력자라던가, 현직자겠지.(출처: 구글, 다이어트 트레이너 빌리부트 독설어록 중에서)요즘은 멘토들의 홍수 시대라고 생각한다.많은 창업 관련 멘토들로 인해,시행착오도 줄이고,알지 못 했던 분야를 간접경험하며,시간과 비용을 줄이고 있다.그러나 너무나 두리뭉실한,원론적이고 이론적인 멘토링들은오히려 시간과 비용을 늘리더라.모든 멘토링이 절대적이고 옳은 것은 아니다.각자 사업은 다 다른 것이다.설령 같은 업종이라하더라도,회사에 따라,창업자에 따라 다 다른 색깔을 가지고 있고그것이 스타트업의 특징이다.획일화시키는 순간 그것이 더 큰 위험이 될 것이다.직원들은 채용할 때는 이것저것  따져보고, 고민하면서멘토들을 만날 때는 아무 필터링없이 다 받아들이고 있는 건 아닐까?멘토들이라고 다 유능하고, 다 전문적이지 않다.그들의 멘토링은 특정 분야, 특정 사이트에 관해인사이트가 있는거다.그러니까아주 많은 멘토링을 만나봐야한다.그리고 항상 멘토들이 사업에 대해 심사하고 살펴보듯우리도 멘토들을 심사하고 살펴봐야 한다.어디 매칭 프로그램이나 강연가서두어시간 감동과 공감을 받고나서"와~ 좋은 강연 감사합니다."하고 명함 하나 달랑 던져주고 자기만족에하루 보람찼다고 자기위안하지 말자.적어도 공감되고 감명 받았다면,메일도 보내고, 질문도 던지고피드백이 적절한지도 판별해야한다.필자가 열을 올리며 글을 쓰는 가장 큰 이유는절친한 대표의 업종 변경에 대하여,얼토당토 않은 분석을 해 주는 멘토의 이야기를 듣고힘이 빠져있는 모습에...무슨 기준과 무슨 근거로그 대표를 평가하는지에 대해의문이 들었기 때문이다.적어도옆에서 지난 1년 넘게 지켜본필자의 입장에서는그는 준비된 창업을 해서빠르게 미션을 달성해 나가고 있었고,직원들도 꽤 잘 챙겨주고, 팀웍도 좋았고,나름 자체 자금도 준비했었다.업종변경은 엉뚱하게도 내부가 아니라외부적인 요인이었다.지금은 새로운 아이템으로준비중이며, 밤낮으로 고생하고 있다.멋지고, 부럽고,꼭 배워야할 친구다.(사실 동갑내기지만...내겐 선생과도 같다)이 글은힘든 시기를 겪고 있는 스타트업 창업자 동지들과설령 한 번 실패했더라도, 주눅들지 않는존경하는 대표들을 위해 남긴다.#클린그린 #스타트업 #초기창업 #창업자 #고민 #경험공유 #인사이트 #조언
조회수 1088

알리바바에서 소싱할 때

안녕하세요 대한민국 셀러들의 성공적인 아마존 진출을 도와주는 컨설팅 회사이자 대행사인 주식회사 컨택틱의 이이삭 대표입니다.이전에는, 제조사와 거래할 때와 무역회사와 거래할 때의 장단점을 비교해봤습니다. 그렇다면 알리바바에서 소싱 할 때 제조사와 무역회사를 구분 짓는 방법이 무엇이 있을까요? 4가지만 기억하세요.1. 대놓고 물어본다너무 당연한 상식이라 이걸 보고 좀 당황스러울 수도 있다고 생각합니다. 하지만 사람은 대개 당연한 걸 무심코 넘기는 경향이 있다고 모두가 동의할 것입니다. 상대방이 제조사인지 무역회사인지, 대놓고 물어보는 게 어찌 보면 가장 깔끔하고 시원한 방법이 될 수 있습니다. 그리고 대부분의 경우, 이런 질문을 받았을 때, 망설임이나 질문을 우회하는 것 없이 직설적으로 ‘예 저희는 공장입니다’라고 답변하는 분들 중에 거짓말하는 사람은 굉장히 드물기 마련입니다. 만약 썩 시원치 않은 대답을 받을 경우, 예를 들어 ‘우리는 파트너십을 맺은 공장이 있다. 공장이나 다름없다. 맞다 우린 제조’유통’업자다.’ 등등, 일단 의심하고 보는 게 좋습니다. 수출 자격증이 있는지 물어보는 것도 아니고, 인허가 자료를 구비했는지 물어보는 것도 아니라, 단순히 제품을 직접 제조하는 제조사인지 물어봤을 뿐인데, 만약 본인이 정말 제조사 즉 공장이면 대답을 회피할 필요가 전혀 없기 때문입니다.2. 전시된 상품 라인을 검토한다이것도 사실 당연한 얘기지만, 정말 상대방이 제조사가 맞다면 상품 라인 (상품군)이 어느 정도 일관성이 있을 수밖에 없습니다. 식칼류에 특화되어있거나, 수건류에 특화되어있다거나, 이런 식으로 어느 특정 시장에 특화되어있다는 얘기이죠. 그럴 수밖에 없는 게, 한 ‘종류’의 상품을 제조하려면 그에 맞는 장비가 필요합니다. 하지만 제조에 필요한 장비 시설의 가격은 절대 만만하지 않습니다. 해당 공장이 대기업 수준으로 규모가 크지 않는 이상 한 공장에서 휴대폰 케이스도 제조하고, 베개도 제조하고, 식탁도 제조할 수는 없는 게 당연합니다.반대로, 정말 상식을 벗어난 다양한 상품군의 제품들이 알리바바 미니 몰 스토어에 전시되어있다면 해당 판매자는 공장이 아니라 무역 회사일 가능성이 매우 높습니다. 이런저런 공장과 연을 형성하고 그들의 제품들을 해당 무역회사의 알리바바 storefront에 전시해놓는 셈입니다.Photo by Hayes Potter on Unsplash3. 상품에 대한 구체적인 질문을 한다구체적인 질문을 물어보면 해당 분야에 대한 상대방의 지식수준이 여실히 드러나게 됩니다. 전문가 수준의 질문까진 필요하지 않더라도, 해당 분야에 주로 사용되는 소재나 규격, 부품, 건전지가 들어있다면 수명 시간 등에 대한 질문 및 용어를 미리 사전에 시장조사를 하면서 익히고, 상담하고 있는 상대방에게 전화나 채팅으로 실시간으로 물어봐야 합니다. 이메일로 물어보면 지식이 없던 사람도 구글링을 통해 금방 알아보고 어쨌거나 답변을 할 수는 있게 되기 때문에, 반드시 전화나 채팅으로 물어보셔야 됩니다. 그리고 질문을 받은 당사자가 즉시 대답을 하지 못하거나 당황해한다면 제조사라기보단 중간에 알선해주는 무역 회사일 가능성이 높다고 판단할 수가 있습니다.4. 직접 공장을 방문한다사실 여기까지 하는 것은 여러분께 큰 부담이 될 수 있습니다. 중국은 방문하려면 비자가 필요하고, 무엇보다 사업장을 비우고 외국 출장을 갔다 오는 것이기 때문에 시간적, 인력적, 금전적 투자가 발생하는 셈입니다. 하지만 그런 모든 것을 감수할 정도로 중요한 사안이면 당연히 방문을 하는 게 맞습니다. 그리고 방문하겠다고 했을 때 흔쾌하게 ‘OK’하는 분들은 공장을 직접 운영하는 제조사일 가능성이 높은 것은 당연합니다. 제조사 입장에서 여러분의 방문은 전혀 손해 볼 것이 없는 것이기 때문에 방문을 절대로 마다하지 않습니다. 만약 온갖 핑계를 대면서 (지방에 위치해있다, 요즘 바빠서 방문은 어렵다, 등등) 피한다면 분명히 무역회사가 본인의 돈벌이 수단이나 마찬가지인 ‘공장 인맥’을 숨기기 위함이니, 그런 분들은 무역회사라고 단정 지을 수 있습니다.Photo by Ant Rozetsky on Unsplash알리바바는 80% 정도가 무역회사라고 합니다. 20%의 실질적으로 공장을 소유하고 상품을 직접 제조하는 제조사를 찾기 위해서는 위 4가지 방법을 잘 기억해주셔서 알리바바에서 상담하실 때 요긴하게 사용하시면 금방 누가 제조사이고 누가 무역회사인지 구분할 수 있을 것입니다.컨택틱의 모든 교육은 파트너인 글로벌셀러창업연구소와 접수하고 진행합니다. 교육 신청은 아래 링크나 글로벌셀러창업연구소의 홈페이지를 통해 가능합니다.오프라인 아마존 입문 과정오프라인 아마존 기초/심화 과정온라인 아마존 입문 과정그럼 오늘도 즐거운 글로벌 셀링 되세요!감사합니다.컨택틱서울특별시 서초구 서초대로 356, 606호(서초동, 서초지웰타워)대표 전화: 02-538-3939이메일: [email protected]홈페이지: https://www.kontactic.com네이버 블로그: https://blog.naver.com/kontactic카카오 브런치: https://brunch.co.kr/@allaboutamazon유튜브 채널: https://www.youtube.com/c/kontactic
조회수 1582

RxJava2 함수 파헤치기!

Overview지난 글 Rxjava를 이용한 안드로이드 개발에서는 RxJava의 Android 연결 방법과 기본적인 사용법을 다뤘습니다. 이번 글에서는 RxJava의 강력하고 다양한 함수들을 살펴보고자 합니다. Android에서 복잡하게 구현되는 내용들을 단 몇 개의 함수로 처리할 수 있는 RxJava를 꼭 사용해보길 권합니다.1. just2. fromArray/fromlterable3. range/rangLong4. interval5. timer6. map7. flatMap8. concatMap9. toList10. toMap11. toMultiMap12. filter13. distinct14. take15. skip16. throttleFirst17. throttleLast18. throttleWithTimeout참고: 공통적으로 사용하는 구독(수신) 클래스는 아래와 같습니다.static class CustomSubscriber<T> extends DisposableSubscriber<T> { @Override public void onNext(T t) { System.out.println(Thread.currentThread().getName() + " onNext( " + t + " )"); } @Override public void onError(Throwable t) { System.out.println(Thread.currentThread().getName() + " onError( " + t + ")"); } @Override public void onComplete() { System.out.println(Thread.currentThread().getName() + " onComplete()"); } } 1. just파라미터를 통해 받은 데이터로 Flowable을 생성하는 연산자입니다. 최대 10까지 전달할 수 있고, 모든 데이터가 수신되면 onComplete() 수신됩니다. 기본적인 Flowable 생성자 함수로 볼 수 있으며 단순 작업에서 많이 사용합니다.public static void just() { //파라미터 값을 순차적으로 송신하는 Flowable 생성 Flowable<String> flowable = Flowable.just("A", "B", "C", "D", "E", "F"); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( A ) main onNext( B ) main onNext( C ) main onNext( D ) main onNext( E ) main onNext( F ) main onComplete() 2. fromArray/fromIterablefromArray, fromIterable 함수는 파리미터로 배열 또는 Iterable(리스트 등)에 담긴 데이터를 순서대로 Flowable을 생성하는 연산자입니다. 모든 데이터를 순차적으로 송신 후 완료됩니다. 반복적인 데이터 변환 작업 같은 경우 for 문 대신 대체할 수 있습니다. 결과를 보면 main Thread 에서 작업 결과가 나오지만, flatMap 을 사용한다면 별도의 Thread로 main Thread의 부하를 막을 수 있습니다.1. fromArray public static void fromArray() { //fromArray 배열로 파라미터를 전달 받는다. Flowable<String> flowable = Flowable.fromArray("A", "B", "C", "D", "E"); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( A ) main onNext( B ) main onNext( C ) main onNext( D ) main onNext( E ) main onComplete() 2. fromIterable public static void fromIterable() { List<String> list = Arrays.asList("A", "B", "C", "D", "E"); //fromIterable 리스트로 파라미터를 전달받는다. Flowable<String> flowable = Flowable.fromIterable(list); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( A ) main onNext( B ) main onNext( C ) main onNext( D ) main onNext( E ) main onComplete() 파라미터와 함수는 다르지만 동일하게 처리된다. 3. range/rangLongrange 함수는 지정한 숫자부터 지정한 개수만큼 증가하는 Integer 값 데이터를 송신하는 Flowable를 생성합니다. rangLong 함수는 range와 동일하며 데이터 타입은 Long을 사용합니다. 두 함수 데이터 송신을 마치면 onComplete를 송신합니다.1. range public static void range() { //range(int start, int count) //start : 시작 값 //end : 발생하는 횟수 Flowable<Integer> flowable = Flowable.range(10, 5); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( 10 ) main onNext( 11 ) main onNext( 12 ) main onNext( 13 ) main onNext( 14 ) main onComplete() 2. rangLong public static void rangeLong() { //range(int start, int count) //start : 시작 값 //end : 발생하는 횟수 Flowable<Long> flowable = Flowable.rangeLong(10, 5); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( 10 ) main onNext( 11 ) main onNext( 12 ) main onNext( 13 ) main onNext( 14 ) main onComplete() 4. interval지정한 간격마다 0부터 시작해 Long 타입 숫자의 데이터를 송신하는 Flowable을 생성합니다. 데이터는 0, 1, 2, 4 순차적으로 증가된 데이터를 송신합니다. Android 에서는 반복적인 작업인 TimerTask를 대신해서 interval로 간단하게 처리할 수 있습니다. UI 변경이 필요한 부분에서는 interval scheduler를 AndroidSchedulers.mainThread() 를 변경해 적용할 수 있습니다.public static void interval() { //(long time, TimeUnit unit, Scheduler scheduler) //time : 발생 간격 시간 //unit : 간격 시간 단위 //scheduler : 발생 scheduler를 변경하여 사용할 수 있습니다. // ex)AndroidSchedulers.mainThread() // - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 // 1초 간격으로 데이터 요청을 송신하다. Flowable<Long> flowable = Flowable .interval(1000L, TimeUnit.MILLISECONDS).take(10); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 1 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onNext( 5 ) RxComputationThreadPool-1 onNext( 6 ) RxComputationThreadPool-1 onNext( 7 ) RxComputationThreadPool-1 onNext( 8 ) RxComputationThreadPool-1 onNext( 9 ) 5. timertimer 함수는 호출된 시간부터 일정한 시간 동안 대기하고 Long 타입 0을 송신 및 종료하는 flowable을 생성합니다. interval이 조건까지 반복적으로 송신한다면, timer는 한번만 송신하고 종료됩니다.public static void timer() { SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy.MM.dd hh:mm ss"); System.out.println("현재시간 : " + simpleDateFormat.format(System.currentTimeMillis())); //(long time, TimeUnit unit, Scheduler scheduler) //time : 발생 간격 시간 //unit : 간격 시간 단위 //scheduler : 발생 scheduler를 변경하여 사용할 수 있습니다. // ex)AndroidSchedulers.mainThread() Flowable<Long> flowable = Flowable.timer(1000L, TimeUnit.MILLISECONDS); //구독을 시작한다. flowable.subscribe(value -> { System.out.println(" timer : " + simpleDateFormat.format(System.currentTimeMillis())); }, throwable -> { System.out.println(throwable); }, () -> { System.out.println(" complete"); }); } 결과 현재시간 : 2019.04.29 09:09 56 timer : 2019.04.29 09:09 57 complete 6. mapFlowable 에서 송신하는 데이터를 변환하고, 변환된 데이터를 송신하는 연산자입니다. 하나의 데이터만 송신할 수 있으며, 반드시 데이터를 송신해야 합니다. 혹여 송신되는 데이터가 null 을 포함하면 map 대신 아래의 flatMap 을사용하는 것이 좋습니다.public static void map() { Flowable<String> flowable = Flowable.just("A", "B", "C", "D", "E") //map(Function mapper) //mapper : 받은 데이터를 가공하는 함수형 인터페이스 //알파벳 값을 소문자로 변경하여 return 한다 .map(value -> value.toLowerCase()); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( a ) main onNext( b ) main onNext( c ) main onNext( d ) main onNext( e ) main onComplete() 7. flatMapflatMap은 map과 동일한 함수이지만, map과는 달리 여러 데이터가 담긴 Flowable을 반환할 수 있습니다. 또한 빈 Flowable를 리턴해 특정 데이터를 건너뛰거나 에러 Flowable를 송신할 수 있습니다.파라미터 mapper에서 새로운 Flowable의 데이터 전달이 아닌 다른 타임라인 Flowable로 작업하면 들어온 데이터 순서대로 출력을 지원하지 않습니다. 타임라인 Flowable(timer, delay, interval 등)에서는 가급적 사용을 피하거나, 순서에 지장이 없을 때 사용하는 것이 좋습니다.public static void flatMap() { Flowable<String> flowable = Flowable.range(10, 2) //flatMap(Function mapper, BiFunction combiner) //mapper : 받은 데이터로 새로운 Flowable를 생성하는 함수형 인터페이스 //combiner : mapper가 새로 생성한 Flowable 과 원본 데이터를 조합해 새로운 송신 데이트를 생성하는 함수형 인터페이스 //첫 번째 데이터를 받으면 새로운 Flowable를 생성한다. //take(3) : 3개까지만 발생한다. .flatMap(value -> Flowable.interval(100L, TimeUnit.MILLISECONDS).take(3), (value, newData) -> "value " + value + " newData " + newData); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( value 10 newData 0 ) RxComputationThreadPool-2 onNext( value 11 newData 0 ) RxComputationThreadPool-1 onNext( value 10 newData 1 ) RxComputationThreadPool-2 onNext( value 11 newData 1 ) RxComputationThreadPool-1 onNext( value 10 newData 2 ) RxComputationThreadPool-2 onNext( value 11 newData 2 ) RxComputationThreadPool-2 onComplete() 결과를 보면 각기 생성된 Flowable이 비동기식으로 송신 되기때문에 서로 다른 스레드에서 실행돼 데이터를 받는 순서대로 송신하지 않는다는 점을 주목하자 8. concatMap받은 데이터를 Flowable로 변환하고 변환된 Flowable을 하나씩 순서대로 실행해서 수신자에서 송신합니다. 다시 말해 여러 데이터를 계속 받더라도 첫 번째 데이터로 생성한 Flowable 의 처리가 끝나야 다음 데이터로 생성한 Flowable을 실행하는 것입니다.생성된 Flowable의 스레드에서 실행되더라도 데이터를 받은 순서대로 처리하는 것을 보장하지만, 처리 성능에 영향을 줄 수 있습니다.public static void concatMap() { Flowable<String> flowable = Flowable.range(10, 5) //map(Function mapper) //mapper : 받은 데이터를 가공하는 함수형 인터페이스 .concatMap(value -> Flowable.interval(100L, TimeUnit.MILLISECONDS).take(2) .map(data -> ("value : " + value + " data : " + data))); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( value : 10 data : 0 ) RxComputationThreadPool-1 onNext( value : 10 data : 1 ) RxComputationThreadPool-2 onNext( value : 11 data : 0 ) RxComputationThreadPool-2 onNext( value : 11 data : 1 ) RxComputationThreadPool-3 onNext( value : 12 data : 0 ) RxComputationThreadPool-3 onNext( value : 12 data : 1 ) RxComputationThreadPool-4 onNext( value : 13 data : 0 ) RxComputationThreadPool-4 onNext( value : 13 data : 1 ) RxComputationThreadPool-5 onNext( value : 14 data : 0 ) RxComputationThreadPool-5 onNext( value : 14 data : 1 ) RxComputationThreadPool-5 onComplete() 결과를 보면 생성된 Flowable 스레드와 데이터 순서대로 출력이 보장된다 것을 알 수 있다. 9. toListtoList는 송신할 데이터를 모두 리스트에 담아 전달합니다. 한꺼번에 데이터를 List로 가공해서 받기에 좋습니다. 하지만 많은 양의 데이터를 처리할 경우 버퍼가 생길 수 있고, 쌓은 데이터 때문에 메모리가 부족해질 수도 있습니다. 또한 수신되는 데이터는 하나이므로 Flowable이 아닌 Single 반환값을 사용합니다.public static void toList() { Single<List<String>> single = Flowable.just("A", "B", "C", "D", "E", "F") .toList(); // 구독을 시작한다. single.subscribe(new SingleObserver<List<String>>() { @Override public void onSubscribe(Disposable d) { System.out.println(Thread.currentThread().getName() + " onNext()"); } @Override public void onSuccess(List<String> strings) { //최종 완료된 리스트를 순서대로 출력한다. for (String text : strings) { System.out.println(Thread.currentThread().getName() + " onSuccess( " + text + " )"); } } @Override public void onError(Throwable e) { System.out.println(Thread.currentThread().getName() + " onError() " + e); } }); } 결과 main onNext() main onSuccess( A ) main onSuccess( B ) main onSuccess( C ) main onSuccess( D ) main onSuccess( E ) main onSuccess( F ) 10. toMaptoMap은 송신할 데이터를 모두 키와 값의 쌍으로 Map에 담아 전달합니다. 나머지는 toList의 특징과 같습니다. 송신되는 데이터 타입은 Map에 담아서 송신하는데 동일한 key에서 value는 마지막 데이터가 덮어 씁니다. 요청되는 값보다 결과 값이 적을 수도 있습니다. List 값을 손쉽게 key, value로 분리할 수 있는 함수이기도 합니다.public static void toMap() { Single<Map<Long, String>> single = Flowable.just("1A", "2B", "3C", "1D", "2E") //toMap(Fuction keySelector, Function valueSelector, Callable mapSupplier) //keySelector : 받은 데이터로 Map에서 사용할 키를 생성하는 함수형 인터페이스 //valueSelector : 받은 데이터로 Map 넣을 값을 생성하는 함수형 인터페이스 .toMap(value -> Long.valueOf(value.substring(0, 1)), data -> data.substring(1)); //구독을 시작한다. single.subscribe(new SingleObserver<Map<Long, String>>() { @Override public void onSubscribe(Disposable d) { System.out.println(Thread.currentThread().getName() + " onNext()"); } @Override public void onSuccess(Map<Long, String> longStringMap) { //최종 완료된 map을 순서대로 출력한다. for (long id : longStringMap.keySet()) { System.out.println(Thread.currentThread().getName() + " onSuccess( id : " + id + ", value " + longStringMap.get(id) + " )"); } } @Override public void onError(Throwable e) { System.out.println(Thread.currentThread().getName() + " onError() " + e); } }); } 결과 main onNext() main onSuccess( id : 1, value D ) main onSuccess( id : 2, value E ) main onSuccess( id : 3, value C ) 11. toMultiMap키와 컬렉션 값으로 이루어진 Map을 데이터로 변환하여 송신하는 함수입니다. 나머지 특징은 toList, toMap과 같습니다. toMap에서 중복되는 value를 관리하는 건 없었지만, value를 collection으로 관리하여 전달되는 데이터를 모두 수신할 수 있습니다.public static void toMultiMap() { Single<Map<String, Collection<Long>>> single = Flowable.interval(100L, TimeUnit.MILLISECONDS) .take(5) //toMultimap(Function keySelector, Function valueSelector) .toMultimap(value -> { //value가 홀수인지 짝수 인지 판단해서 key값을 리턴한다. if (value % 2 == 0) { return "짝수"; } else { return "홀수"; } }); //구독을 시작한다. single.subscribe(new SingleObserver<Map<String, Collection<Long>>>() { @Override public void onSubscribe(Disposable d) { System.out.println(Thread.currentThread().getName() + " onNext( " + d + " )"); } @Override public void onSuccess(Map<String, Collection<Long>> stringCollectionMap) { for (String key : stringCollectionMap.keySet()) { StringBuffer stringBuffer = new StringBuffer(); for (long value : stringCollectionMap.get(key)) { stringBuffer.append(" " + value); } System.out.println(Thread.currentThread().getName() + " onSuccess( id : " + key + ", value " + stringBuffer.toString() + ")"); } } @Override public void onError(Throwable e) { System.out.println(Thread.currentThread().getName() + " onError() " + e); } }); } 결과 main onNext() RxComputationThreadPool-1 onSuccess( id : 짝수, value 0 2 4 ) RxComputationThreadPool-1 onSuccess( id : 홀수, value 1 3 ) 12. filterfilter는 받은 데이터가 조건에 맞는지 판단해 결과가 true인 값만 송신합니다. 위의 just, fromArray, interval이 반복적인 케이스였다면, filter는 if문처럼 조건문의 역할을 할 수 있습니다. 반복문 함수와 조건문 함수를 같이 사용해 몇 줄 안에 for, if와 똑같이 구현할 수 있죠.public static void filter() { Flowable<Long> flowable = Flowable.interval(300L, TimeUnit.MILLISECONDS) //짝수만 통과한다. 3개만큼 .filter(value -> value % 2 == 0).take(3); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 13. distinct이미 처리된 데이터를 다시 볼 필요가 없을 때 사용하는 함수입니다. 송신하려는 데이터가 이미 송신된 데이터와 같다면 해당 데이터는 무시합니다. 이 함수는 내부에서 HashSet으로 데이터가 같은지 확인합니다.public static void distinct() { Flowable<String> flowable = Flowable.just("A", "a", "B", "b", "A", "a", "B", "b") //distinct(Function keySelector) //keySelector : 받은 데이터와 비교할 데이터를 확인하는 함수 //모두 소문자로 변환하여 알파벳 기준으로 데이터를 판단한다. .distinct(value -> value.toLowerCase()); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 main onNext( A ) main onNext( B ) main onComplete() 14. take1.taketake 함수로 지정된 횟수만큼 받은 데이터를 송신합니다. 지정된 횟수에 도달하면 완료를 송신해 처리 종료합니다.2.takeUntil지정된 조건까지 데이터를 송신하는 연산자입니다. 조건이 되면 완료를 송신해 종료합니다.3.takeWhile지정된 조건이 해당할 때만 데이터를 송신하는 연산자입니다.4.takeLast데이터의 끝에서부터 지정한 조건까지 데이터를 송신하는 연산자입니다.take 함수는 한 화면에 출력되거나 칠요한 데이터만큼 리스트에서 값을 하나씩 수신할 때 사용합니다. 예를 들어 화면에 데이터가 6개가 필요하면 take를 이용해 원하는 만큼의 데이터를 가져올 수 있습니다.Flowable.take(6) 또한 이후에 나올 skip 함수를 같이 사용하면 두 번째 화면에서 필요한 데이터를 6개 가져올 수 있습니다.Flowable.skip(6).take(12) 1. take public static void take() { // 100 밀리세컨드만큼 반복하며 총 5개를 출력후 종료한다. Flowable<Long> flowable = Flowable.interval(100L, TimeUnit.MILLISECONDS) .take(5); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 1 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 2. takeUntil public static void takeUntil() { // 100 밀리세컨드만큼 반복하며 값이 5가 될때까지 송신한다. Flowable<Long> flowable = Flowable.interval(100L, TimeUnit.MILLISECONDS) .takeUntil(value -> value == 5); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 1 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onNext( 5 ) RxComputationThreadPool-1 onComplete() 3. takeWhile public static void takeWhile() { // 100 밀리세컨드만큼 반복하며 값이 5가 아닐경우까지 송신한다. Flowable<Long> flowable = Flowable.interval(100L, TimeUnit.MILLISECONDS) .takeWhile(value -> value != 5); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 1 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 4. takeLast public static void takeLast() { //100밀리 세컨트만큼 반복하며 5개의 출력중 뒤에 2개만 송신한다. Flowable<Long> flowable = Flowable.interval(100L, TimeUnit.MILLISECONDS) .take(5) .takeLast(2); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 15. skip1.skip함수로 지정된 횟수만큼 받은 데이터 송신을 제외합니다. 지정된 횟수가 초과되면 나머지 데이터를 송신합니다.2.skipUntil지정된 조건까지 데이터 송신을 제외하는 연산자입니다. 조건이 되면 나머지 데이터를 송신합니다.3.skipWhile지정된 조건이 해당될 때만 데이터 송신을 제외하는 함수입니다.4.skipLast데이터의 끝에서부터 지정한 조건까지 데이터 송신을 제외하는 함수입니다.take와 반대의 기능을 갖고 있습니다. 보통 페이저나 리스트에서 paging을 처리할 때는 take와 skip을 혼용합니다.1. skip public static void skip() { //100 밀리세컨드만큼 반복하며 5번 발행하고, 처음 2개를 제외합니다. Flowable<Long> flowable = Flowable.interval(100L, TimeUnit.MILLISECONDS) .take(5) .skip(2); //구독을 시잔한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 2. skipUntil public static void skipUntil() { //300밀리 세컨드만큼 반복하며 5개를 발행하고, 1000 밀리세컨드 제외 후 송신합니다. Flowable<Long> flowable = Flowable.interval(300L, TimeUnit.MILLISECONDS) .skipUntil(Flowable.timer(1000L, TimeUnit.MILLISECONDS)) .take(5); //구독을 시잔한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-2 onNext( 3 ) RxComputationThreadPool-2 onNext( 4 ) RxComputationThreadPool-2 onNext( 5 ) RxComputationThreadPool-2 onNext( 6 ) RxComputationThreadPool-2 onNext( 7 ) RxComputationThreadPool-2 onComplete() 3. skipWhile public static void skipWhile() { //300밀리세컨드만큼 반복하며 5개를 발행하고, 데이터 3이 올때까지 데이터를 제외힙니다. Flowable<Long> flowable = Flowable.interval(300L, TimeUnit.MILLISECONDS) .skipWhile(value -> value != 3) .take(5); //구독을 시잔한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 3 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onNext( 5 ) RxComputationThreadPool-1 onNext( 6 ) RxComputationThreadPool-1 onNext( 7 ) RxComputationThreadPool-1 onComplete() 4. skipLast public static void skipLast() { //1000 밀리세컨드만큼 반복하며 5개를 발행하고 마지막 2개는 제외합니다 Flowable<Long> flowable = Flowable.interval(1000L, TimeUnit.MILLISECONDS) .take(5) .skipLast(2); //구독을 시작한다. flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 1 ) RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onComplete() 16. throttleFirst데이터를 송신하고 지정된 시간 동안 들어오는 요청을 무시합니다. 이 함수는 View의 Event 처리에서 많이 사용됩니다. 중복되는 처리를 막기 위해 최초 실행 후 일정 시간 동안 View의 클릭 이벤트나 API 이벤트를 막을 수 있기 때문에 비동기 처리와 화면에 직접적인 피드백이 발생했을 때 throttleFirst를 자주 사용하고 있습니다. //데이터 요청이 30 밀리초마다 5번 발생합니다. //데이터 요청 발생시 100 밀리세컨트 동안 들어오는 데이터 요청을 무시합니다. // — 0 — 1 — 2 — 3 — 4 interval 30 밀리초 마다 // — — -*- — throttleFirst 100 밀리초 무시 Flowable<Long> flowable = Flowable.interval(30L, TimeUnit.MILLISECONDS) .take(5).throttleFirst(100L, TimeUnit.MILLISECONDS); flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 0 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 17. throttleLastthrottleLast 함수는 데이터를 송신하고 지정된 시간 동안 들어오는 마지막 요청을 송신합니다. 이 함수도 throttleFirst처럼 반복적인 선택 이벤트 처리에 유용하게 사용할 수 있습니다. 간단하게 장바구니 카운트 변경을 요청할 때 마지막 변경 이벤트 데이터만 처리하면 되므로 값이 선택되고 일정 시간이 지났을 때 API를 요청해 리소스 낭비를 줄일 수 있습니다.public static void throttleLast() { //데이터 요청이 1 초 마다 6번 발생합니다. //데이터 요청 발생시 2 초 동안 들어오는 마지막 요청을 송신하다. // - 0 - 1 - 2 - 3 - 4 interval 1 초 마다 // - - -* - throttleLast 2 초의 마지막 값 송신 Flowable<Long> flowable = Flowable.interval(1, TimeUnit.SECONDS) .take(5) .throttleLast(2, TimeUnit.SECONDS); flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( 2 ) RxComputationThreadPool-1 onNext( 4 ) RxComputationThreadPool-1 onComplete() 18. throttleWithTimeoutthrottleWithTimeout 함수는 데이터를 송신하고 지정된 시간 동안 다음 데이터를 받지 못하면 현재 데이터를 송신합니다. 완료 시엔 마지막 데이터를 송신하고 종료됩니다.public static void throttleWithTimeout() { Flowable<String> flowable = Flowable.<String>create(emitter -> { emitter.onNext("A"); Thread.sleep(1000L); // 1000 밀리세컨드 슬립 // 500 밀리세컨드 동안 데이터 다음 데이터 요청이 없으므로 A 송신 emitter.onNext("B"); Thread.sleep(300L); // 300 밀리세컨드 슬립 emitter.onNext("C"); Thread.sleep(300L); // 300 밀리세컨드 슬립 emitter.onNext("D"); Thread.sleep(1000L); // 1000 밀리세컨드 슬립 // 500 밀리세컨드 동안 데이터 다음 데이터 요청이 없으므로 D 송신 emitter.onNext("E"); Thread.sleep(100L); // 100 밀리세컨드 슬립 emitter.onComplete(); //완료 요청 시 마지막 데이터 송신 후 종료 }, BackpressureStrategy.BUFFER) .throttleWithTimeout(500L, TimeUnit.MILLISECONDS); flowable.subscribe(new CustomSubscriber<>()); } 결과 RxComputationThreadPool-1 onNext( A ) RxComputationThreadPool-1 onNext( D ) main onNext( E ) main onComplete() ConclusionRxJava에서 많이 사용되고, 또 알고 있으면 좋은 함수들을 살펴봤습니다. 브랜디에서도 이 함수들을 응용해 그동안 다양한 기능을 구현했고, 복잡한 함수도 사용하고 있습니다. 지금까지는 Flowable로 송신과 수신이 1 : 1 로 진행되었지만, 다양한 수신자를 사용해 하나의 Flowable로도 다른 화면에서 여러 수신자를 등록하여 반복적인 작업을 할 수 있습니다. 덕분에 같은 작업을 코드 중복 없이 간단하게 구현할 수 있죠.다음 글에서는 2개 이상의 Flowable을 결합해 사용하는 방법과 Android View에서 RxJava를 응용하는 방법, 구독을 관리하는 방법 등 Android에서 유용하게 쓰는 방법들을 알아보겠습니다.글고재성 팀장 | R&D 개발MA팀[email protected]브랜디, 오직 예쁜 옷만
조회수 1705

잔디의 공식 모델, 그래픽 디자이너 Diane을 만나다.

축복받은 창가 자리에서 꾸준히 광합성을 하고 있다는 Diane편집자 주: 잔디에는 현재 40명 가까운 구성원들이 일본, 대만, 한국 오피스에서 일하고 있습니다. 국적, 학력, 경험이 모두 다른 멤버들. 이들이 어떤 스토리를 갖고 잔디에 합류했는지, 잔디에서 무슨 일을 하고 있는지 궁금해하시는 분들이 많았습니다.  이에 잔디 블로그에서는 매 주 1회 ‘맛있는 인터뷰’라는 인터뷰 시리즈로 기업용 사내 메신저 ‘잔디’를 만드는 사람들의 이야기를 다루고자 합니다. 인터뷰는 매 주 선정된 인터뷰어와 인터뷰이가 1시간 동안 점심을 함께 하며 다양한 이야기를 나누며 진행됩니다. 인터뷰이에 대해 궁금한 점은 댓글 혹은 이메일([email protected])을 통해 문의 부탁드립니다.‘맛있는 인터뷰’를 요청하니 바로 고기를 먹자고 했다. 이 곳은 어떤 곳인지 알려달라.이번 주 내내 ‘스테이크’라는 단어가 머리속에서 떠나지 않았다. 회사 근처 가성비 높은 스테이크 집을 찾은 결과, ‘리즈스테이크갤러리’를 발견했다. 하는 일이 디자인쪽이라 스테이크의 가성비 뿐만 아니라, 레스토랑 인테리어도 신경 써서 골랐다. 유리 지갑 직장인의 심금을 울리는 장소라 확신한다.스테이크는 사랑입니다.간단하게 자기소개 부탁한다.맛있는 인터뷰를 오매불망 기다렸다. 잔디에서 그래픽 디자인을 맡고 있는 Diane이다. 반갑다.그래픽 디자인? 구체적으로 하는 일을 무엇인가?못 믿겠지만 다 하고 있다. 일종의 분산 투자다. 한 분야만 깊이 파는 것보단 UI(User Interface), 일러스트레이터, 콘텐츠 이미지 제작 등 다양한 분야에 발을 담그고 있다. 사실 여러 가지 작업을 동시에 하는 게 더 재미있다. 같은 팀의 Jane과 인쇄 작업을 한 적이 있는데 시간 가는 줄 몰랐다. 내겐 나름 호시절이었는데, 디자인 팀에 인원이 하나, 둘 늘어나며 각자의 R&R이 명확해졌다. 업무가 분담돼 효율성은 높아졌으나, 경험할 수 있는 분야가 줄어들었다. 개인적으로는 안타깝다. 하지만 돌려 생각해보면 잔디가 성장하고 있다는 청신호이니 기쁜 마음으로 분산 투자를 접을 생각이다.디자이너를 만나면 꼭 묻고 싶은 질문이 있었다. 어떻게 미술을 시작하게 되었는가?중학교 2학년 때 미술 선생님이 매력적인 딜을 제시하셨다. 내가 그림을 그리면 교과서에 실어준다는 제안이었다. 선생님은 미술 교과서를 출판하는 곳에서 꽤 지위가 높으셨다. 열심히 그림을 그린 결과, 내 그림이 교과서에 실릴 수 있었고 이때의 성취감이 계속 그림을 그려야겠다는 결심을 하게 된 계기가 되었다.대단하다. 나도 그런 제안이 있었다면 지금쯤 Diane과 같은 팀에 있지 않았을까 싶다. 잔디는 어떻게 들어오게 되었는가?대학교를 졸업할 즈음, 산업체리크루팅(졸업을 앞둔 디자인 전공 학생들이 자신의 포트폴리오를 회사에 소개하는 프로그램이다 – 편집자 주)을 통해 잔디와 인연을 맺게 되었다. 포트폴리오가 괜찮으면 회사에서 2차 면접을 제안한다. 그 당시 떨리는 마음으로 내 포트폴리오를 소개했었는데, YB와 Jane이 스윽 다가와 명함을 주고 가셨다.그 당시 잔디에 대해 어떤 생각을 가지고 있었나?YB에게 처음 ‘잔디’에 대해 들었을 땐 ‘음~ 파릇파릇한 신생 기업이군!’이라고만 생각했다.YB에게 어떤 이야기를 들었는가?지금도 또렷하게 기억난다. 그대로 읊어보겠다. “우리는 멤버 한명 한명의 역량을 중요시합니다. 나영(잔디 안에서는 Diane이라는 닉네임으로 불리고 있다-편집자 주)님의 잠재력을 이런 좋은 기회에 살짝 보게 되었는데, 앞으로도 그 잠재력을 펼쳐나가는 모습을 볼 수 있었으면 좋겠습니다.” 이 말을 듣고 두근거렸다. 정말 잔디에서 일하고  싶게 만드는 멘트였다. ‘이 사람에게 인정받고 싶다’는 생각이 절로 들었다. 그리곤 근로 계약서에 도장을 찍고 Diane으로 살아가고 있다.산업체 리크루팅 관련해 꿀팁 아닌 꿀팁을 후배 분들에게 공유하고 싶다. 일반적으로 산업체 리크루팅은 여러 회사가 동시에 모여 진행된다. 그러다 보니, 각 회사의 인사 담당자의 태도를 통해 얼추 어떤 분위기인지 유추해볼 수 있다. “저기야”라고 부르는 회사, “해보세요”라고 명령하는 회사, “합격, 불합격 버튼 눌러야지~♪”라고 장난치듯 말하는 회사까지 다양하다. 그 중 “나영님”이라고 부른 회사는 잔디 뿐이었다. 김춘수 시인의 ‘꽃’처럼 잔디가 내 이름을 불러 주기 전까지 난 그저 하나의 디자인 노예에 지나지 않았다. 사실 “누구님”이라는 호칭이 낯간지러웠다. 하지만 이젠 익숙하다. 누구를 봐도 ‘~씨’보다는 ‘~님’이 편하다.잔디 1주년 파티에서 흥이 오른 Diane이 카메라를 보며 포즈를 취하고 있다.첫 직장으로서 잔디 어떤 것 같나? 가감없이 말해달라.후회보단 점점 더 잔디가 좋아지고 있다. 나보다 일찍 졸업한 친구들의 직장고난기에 폭풍 스트레스를 받고 있는 모습을 지켜보며, 회사란 곳은 매일 야근과 갈굼이 일상이구나라고 생각했었다. 하지만 잔디는 그렇지 않다. 팀에서 막내임에도 불구하고 내 의견이나 작업이 다른 팀원들의 그 것과 동일선상에서 다뤄지며 적용되는 건 경험해보지 못한 사람은 모를 것이다. 상당히 짜릿하다.같은 분야에 종사하고 있는 친구를 만나 회사 얘기를 하면 으레 욕에서 시작해 욕으로 끝난다. 에이전시 업무 특성 상, 좋은 디자인이 아닌 클라이언트가 맘에 드는 디자인을 해야 하니 불만족, 회의감이 많을 거라 생각한다. 한 친구는 B치킨 페이스북에 올라가는 광고 배너를 매일 만들며 치킨의 ‘치’자만 나와도 부들부들 떤다. 치킨을 먹지 않겠다는 절식 선언도 꽤 인상 깊었다. 반면, 난 그런 스트레스가 없다. 나를 위한, 그리고 우리를 위한 디자인을 하다 보니 좀 더 예쁘게 잘 만들고 싶은 마음이 크다.누가 보면 회사에서 사주한 줄 알겠다. 이제 다른 회사는 못 갈 것 같은데 어떤가?그렇다. 잔디에서스트레스 없이 편히 일하다 혹시라도, 정말 혹시라도 이직하게 된다면 암울할 것 같다. 이미 난 잔디의 문화에 완전 빠진 상태다.처음 스타트업에 간다고 했을 때 주변 반응은 어땠나?에이전시에 취직하면 이름만 대면 누구나 아는 브랜드의 포트폴리오를 만들 수 있다. 첫 직장으로선 안전하다. 반면, 스타트업은 ‘모 아니면 도’라는 주변의 반응이 있었다. 부모님도 처음엔 반신반의하셨으나, 잔디의 모습이 담긴 사진들을 보시고 이야기도 들으시면서 지금은 나보다 잔디를 더 좋아하신다.디자인 뿐만 아니라 남심을 사로 잡는 잔디의 광고/홍보 모델로도 활약하고 있다. 한국경제에 실린 잔디의 기사에서 Diane 사진을 보고 Hugo의 친구 분이 소개팅을 강력히 원했다고 들었는데 기분이 어떤가? 같은 여자로서 부럽다.한국 경제에 실린 기사 사진은 전문 포토그래퍼가 잘 찍어주셨다. 그리고 최근 집행되고 있는 잔디의 페이스북 광고의 경우, 광고 컷 촬영 초반 연기가 어색해 어려워 힘들었다. 하지만 나중에 라이브 된 광고 이미지를 보며 ‘내가 저런 표정도 지을 수 있구나’하고 감탄했다. 직장인의 비애를 리얼하게 연기한 광고가 실렸었는데, 직장인분들이 공감해주셨으면 한다. 광고 촬영을 계속 하다 보니, 점점 표정이 리얼해진다고 주위에서 칭찬해주고 계셔 힘을 내고 있다.페이스북 광고를 본 지인들의 반응은 어떤가?광고가 올라오는 대로 캡쳐를 떠 보내준다. 친구들이 덕분에 웃는다고 하더라. 왜 웃는지는 모르겠지만..나도 촬영할 때 옆에서 지켜봤었다. 광고 촬영할 땐 상당히 격정적이었는데, 막상 일할 때는 차분하더라. 사무실 밖의 모습은 어떤지 궁금하다.집에서 쉬면 우울하고 센치해진다. 그래서 차라리 밖에서 친구들을 만나 재미있는 곳을 찾아다닌다. 얼마 전에는 건대에 새로 생긴 ‘커먼그라운드’를 다녀왔는데 정말 좋더라. 아직 가보지 않았다면 꼭 가보길 추천한다.만약 회사에 출근했는데 1일 휴가를 선물로 받는다면 어떻게 보낼 것인가?힙합 콘서트를 보러 갈 것이다. 고등학교 1학년 때 처음으로 친구를 따라 힙합 콘서트를 갔었다. 당시, 친구들은 아이돌파와 힙합파로 나뉘어 있었는데 나는 아이돌의 상업적인 느낌이 싫었다. 반면 힙합의 가사 한 마디, 한 마디는 레알 자기 이야기라서 들을 수록 그 가수랑 친해지는 느낌이 있었다. 흥이 오르면 직접 트위터를 통해 메시지를 보내곤 했다.요즘엔 어떤 음악을 듣나?쇼미더머니, 언프리티랩스타 등의 프로그램을 통해 많은 크루들이 급부상하고 있다.  이들 중 저스트뮤직, 일리네어레코즈, AOMG 등의 레이블에서 나오는 음악을 고루 듣고 있다. 요즘에는 특히 스윙스, 기리보이가 속해 있는 저스트뮤직의 음악을 많이 듣는다. 이들이 언더에 있을 당시, 나만 알고 나만 좋아한다는 느낌이 있어 좋았는데, 요즘에는 이들이 너무 유명해져 오히려 아쉽다.이 집 빙수로 돈 좀 벌어봤어다음은 맛있는 인터뷰의 고정 코너 ‘어서 말을 해’이다. Mark의 질문은 ‘최근 3년 동안 당신에게 가장 행복했던 일은?’인데 뭐가 가장 행복했나?대학생 때 입시학원에서 1-2년 동안 아이들에게 미술을 가르쳤다. 내가 가진 걸 다른 사람에게 알려 줄 수 있다는 점이 굉장히 재미있었다. 입시생들에게 큰 의미인 ‘합격’이라는 단어에  내가 일조할 수 있다는 점은 무척 의미있었다. 나이 차이가 그리 많지 않아 제자라기 보단 동생 대하듯 가르쳤던 친구들인데 입시가 끝날 무렵 합격 기념 깜짝 파티를 열어주었다. 너무 행복한 기억이다.다음 인터뷰이에게는 어떤 질문을 남기고 싶나?회사에 여름방학이 생겨 30일 휴가 기회가 주어진다면 무엇을 할 것인가?그럼 Diane은 30일 휴가가 생기면 뭘 하고 싶은가?30일 내내 통영에 내려가 바다를 보며 지낼 거다. 유치원을 통영에서 다녔는데 집 밖에 나가면 보이던 항구와 바다 냄새가 아직도 생생하다. 해산물 먹방을 찍으며 푹 쉬고 싶다.나중에 꼭 이루고 싶은 꿈이 있다면?디자인하는 친구들과 함께 디자인 전문 회사를 차리고 싶다. 하루하루 열심히 경력도 쌓고, 돈도 차곡차곡 모은다면 언젠가 시작할 수 있을 거라 믿는다.#토스랩 #잔디 #JANDI #디자인 #디자이너 #그래픽디자이너 #그래픽디자인 #팀원소개 #팀원인터뷰 #팀원자랑 #기업문화 #조직문화 #사내문화
조회수 1641

HBase 설정 최적화하기 - VCNC Engineering Blog

커플 필수 앱 비트윈은 여러 종류의 오픈 소스를 기반으로 이루어져 있습니다. 그 중 하나는 HBase라는 NoSQL 데이터베이스입니다. VCNC에서는 HBase를 비트윈 서비스의 메인 데이터베이스로써 사용하고 있으며, 또한 데이터 분석을 위한 DW 서버로도 사용하고 있습니다.그동안 두 개의 HBase Cluster 모두 최적화를 위해서 여러 가지 설정을 테스트했고 노하우를 공유해 보고자 합니다. 아랫은 저희가 HBase를 실제로 저희 서비스에 적용하여 운영하면서 최적화한 시스템 구성과 설정들을 정리한 것입니다. HBase를 OLTP/OLAP 목적으로 사용하고자 하는 분들에게 도움이 되었으면 좋겠습니다. 아래 구성을 최적화하기 위해서 했던 오랜 기간의 삽질기는 언젠가 따로 포스팅 하도록 하겠습니다.HBaseHBase는 Google이 2006년에 발표한 BigTable이라는 NoSQL 데이터베이스의 아키텍처를 그대로 따르고 있습니다. HBase는 뛰어난 Horizontal Scalability를 가지는 Distributed DB로써, Column-oriented store model을 가지고 있습니다. 사용량이 늘어남에 따라서 Regionserver만 추가해주면 자연스럽게 Scale-out이 되는 구조를 가지고 있습니다. 또한, Hadoop 특유의 Sequential read/write를 최대한 활용해서 Random access를 줄임으로 Disk를 효율적으로 사용한다는 점을 특징으로 합니다. 이 때문에 HBase는 보통의 RDBMS와는 다르게 Disk IO가 병목이 되기보다는 CPU나 RAM 용량이 병목이 되는 경우가 많습니다.HBase는 많은 회사가 데이터 분석을 하는 데 활용하고 있으며, NHN Line과 Facebook messenger 등의 메신저 서비스에서 Storage로 사용하고 있습니다.시스템 구성저희는 Cloudera에서 제공하는 HBase 0.92.1-cdh4.1.2 release를 사용하고 있으며, Storage layer로 Hadoop 2.0.0-cdh4.1.2를 사용하고 있습니다. 또한, Between의 데이터베이스로 사용하기 위해서 여러 대의 AWS EC2의 m2.4xlarge 인스턴스에 HDFS Datanode / HBase Regionserver를 deploy 하였습니다. 이는 m2.4xlarge의 큰 메모리(68.4GB)를 최대한 활용해서 Disk IO를 회피하고 많은 Cache hit이 나게 하기 위함입니다.또한 Highly-Available를 위해서 Quorum Journaling node를 활용한 Active-standby namenode를 구성했으며, Zookeeper Cluster와 HBase Master도 여러 대로 구성하여 Datastore layer에서 SPOF를 전부 제거하였습니다. HA cluster를 구성하는 과정도 후에 포스팅 하도록 하겠습니다.HDFS 최적화 설정dfs.datanode.handler.countHDFS에서 외부 요청을 처리하는 데 사용할 Thread의 개수를 정하기 위한 설정입니다. 기본값은 3인데 저희는 100으로 해 놓고 사용하고 있습니다.dfs.replicationHDFS 레벨에서 각각의 데이터가 몇 개의 독립된 인스턴스에 복사될 것 인가를 나타내는 값입니다. 저희는 이 값을 기본값인 3으로 해 놓고 있습니다. 이 값을 높이면 Redundancy가 높아져서 데이터 손실에 대해서 더 안전해지지만, Write 속도가 떨어지게 됩니다.dfs.datanode.max.transfer.threads하나의 Datanode에서 동시에 서비스 가능한 block 개수 제한을 나타냅니다.과거에는 dfs.datanode.max.xcievers라는 이름의 설정이었습니다.기본값은 256인데, 저희는 4096으로 바꿨습니다.ipc.server.tcpnodelay / ipc.client.tcpnodelaytcpnodelay 설정입니다. tcp no delay 설정은 TCP/IP network에서 작은 크기의 패킷들을 모아서 보냄으로써 TCP 패킷의 overhead를 절약하고자 하는 Nagle's algorithm을 끄는 것을 의미합니다. 기본으로 두 값이 모두 false로 설정되어 있어 Nagle's algorithm이 활성화되어 있습니다. Latency가 중요한 OLTP 용도로 HBase를 사용하시면 true로 바꿔서 tcpnodelay 설정을 켜는 것이 유리합니다.HBase 최적화 설정hbase.regionserver.handler.countRegionserver에서 외부로부터 오는 요청을 처리하기 위해서 사용할 Thread의 개수를 정의하기 위한 설정입니다. 기본값은 10인데 보통 너무 작은 값입니다. HBase 설정 사이트에서는 너무 큰 값이면 좋지 않다고 얘기하고 있지만, 테스트 결과 m2.4xlarge (26ECU) 에서 200개 Thread까지는 성능 하락이 없는 것으로 나타났습니다. (더 큰 값에 관해서 확인해 보지는 않았습니다.)저희는 이 값을 10에서 100으로 올린 후에 약 2배의 Throughput 향상을 얻을 수 있었습니다.hfile.block.cache.sizeHBase 의 block 들을 cache 하는데 전체 Heap 영역의 얼마를 할당한 것인지를 나타냅니다. 저희 서비스는 Read가 Write보다 훨씬 많아서 (Write가 전체의 약 3%) Cache hit ratio가 전체 성능에 큰 영향을 미칩니다.HBase 에서는 5분에 한 번 log 파일에 LruBlockCache (HBase 의 Read Cache) 가 얼마 만큼의 메모리를 사용하고 있고, Cache hit ratio가 얼마인지 표시를 해줍니다. 이 값을 참조하셔서 최적화에 사용하실 수 있습니다.저희는 이 값을 0.5로 설정해 놓고 사용하고 있습니다. (50%)hbase.regionserver.global.memstore.lowerLimit / hbase.regionserver.global.memstore.upperLimit이 두 개의 설정은 HBase에서 Write 한 값들을 메모리에 캐쉬하고 있는 memstore가 Heap 영역의 얼마만큼을 할당받을지를 나타냅니다. 이 값이 너무 작으면 메모리에 들고 있을 수 있는 Write의 양이 한정되기 때문에 디스크로 잦은 flush가 일어나게 됩니다. 반대로 너무 크면 GC에 문제가 있을 수 있으며 Read Cache로 할당할 수 있는 메모리를 낭비하는 것이기 때문에 좋지 않습니다.lowerLimit와 upperLimit의 두 가지 설정이 있는데, 두 개의 설정이 약간 다른 뜻입니다.만약 memstore 크기의 합이 lowerLimit에 도달하게 되면, Regionserver에서는 memstore들에 대해서 'soft'하게 flush 명령을 내리게 됩니다. 크기가 큰 memstore 부터 디스크에 쓰이게 되며, 이 작업이 일어나는 동안 새로운 Write가 memstore에 쓰일 수 있습니다.하지만 memstore 크기의 합이 upperLimit에 도달하게 되면, Regionserver는 memstore들에 대한 추가적인 Write를 막는 'hard'한 flush 명령을 내리게 됩니다. 즉, 해당 Regionserver이 잠시 동안 Write 요청을 거부하게 되는 것입니다. 보통 lowerLimit에 도달하면 memstore의 크기가 줄어들기 때문에 upperLimit까지 도달하는 경우는 잘 없지만, write-heavy 환경에서 Regionserver가 OOM으로 죽는 경우를 방지하기 위해서 hard limit가 존재하는 것으로 보입니다.hfile.block.cache.size와 hbase.regionserver.global.memstore.upperLimit의 합이 0.8 (80%)를 넘을 수 없게 되어 있습니다. 이는 아마 read cache 와 memstore의 크기의 합이 전체 Heap 영역 중 대부분을 차지해 버리면 HBase의 다른 구성 요소들이 충분한 메모리를 할당받을 수 없기 때문인 듯합니다.저희는 이 두 개의 설정 값을 각각 0.2, 0.3으로 해 놓았습니다. (20%, 30%)ipc.client.tcpnodelay / ipc.server.tcpnodelay / hbase.ipc.client.tcpnodelayHDFS의 tcpnodelay 와 비슷한 설정입니다. 기본값은 전부 false입니다.이 설정을 true로 하기 전에는 Get/Put 99%, 99.9% Latency가 40ms 와 80ms 근처에 모이는 현상을 발견할 수 있었습니다. 전체 요청의 매우 작은 부분이었지만, 평균 Get Latency가 1~2ms 내외이기 때문에 99%, 99.9% tail이 평균 Latency에 큰 영향을 미쳤습니다.이 설정을 전부 true로 바꾼 후에 평균 Latency가 절반으로 하락했습니다.Heap memory / GC 설정저희는 m2.4xlarge가 제공하는 메모리 (68.4GB)의 상당 부분을 HBase의 Read/Write cache에 할당하였습니다. 이는 보통 사용하는 Java Heap 공간보다 훨씬 큰 크기이며 심각한 Stop-the-world GC 문제를 일으킬 수 있기 때문에, 저희는 이 문제를 피하고자 여러 가지 설정을 실험하였습니다.STW GC time을 줄이기 위해서 Concurrent-Mark-and-sweep GC를 사용했습니다.HBase 0.92에서부터 기본값으로 설정된 Memstore-Local Allocation Buffer (MSLAB) 을 사용했습니다. hbase.hregion.memstore.mslab.enabled = true #(default)hbase-env.sh 파일을 다음과 같이 설정했습니다. HBASE_HEAPSIZE = 61440 #(60GB) HBASE_OPTS = "-XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=70 -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps"GC log를 Python script로 Parsing해서 STW GC 시간을 관찰하고 있습니다. 지금까지 0.2초 이상의 STW GC는 한 번도 발생하지 않았습니다.그 밖에 도움이 될 만한 설정들hbase.hregion.majorcompactionHBase는 하나의 Region에 대해서 여러 개의 StoreFile을 가질 수 있습니다. 그리고 주기적으로 성능 향상을 위해서 이 파일들을 모아서 하나의 더 큰 파일로 합치는 과정을 진행하게 됩니다. 그리고 이 과정은 많은 CPU usage와 Disk IO를 동반합니다. 그리고 이때 반응 속도가 다소 떨어지게 됩니다. 따라서 반응 속도가 중요한 경우에는, 이 Major compaction을 off-peak 시간대를 정해서 manual 하게 진행하시는 것이 좋습니다.저희는 사용자의 수가 상대적으로 적은 새벽 시간대에 crontab 이 실행시키는 script가 돌면서 전체 Region에 대해서 하나하나 Major Compaction이 진행되도록 하였습니다.기본값은 86,400,000 (ms)로 되어 있는데, 이 값을 0으로 바꾸시면 주기적인 Major Compaction이 돌지 않게 할 수 있습니다.hbase.hregion.max.filesizeHBase는 하나의 Region이 크기가 특정 값 이상이 되면 자동으로 2개의 Region으로 split을 시킵니다. Region의 개수가 많지 않을 때는 큰 문제가 없지만, 계속해서 데이터가 쌓이게 되면 필요 이상으로 Region 수가 많아지는 문제를 나을 수 있습니다. Region 수가 너무 많아지면 지나친 Disk IO가 생기는 문제를 비롯한 여러 가지 안 좋은 점이 있을 수 있기 때문에, split 역시 manual 하게 하는 것이 좋습니다. 그렇다고 Table의 Region 수가 너무 적으면 Write 속도가 떨어지거나 Hot Region 문제가 생길 수 있기 때문에 좋지 않습니다.HBase 0.92.1 에서는 기본값이 1073741824(1GB)로 되어 있는데, 저희는 이 값을 10737418240(10GB)로 늘인 후에 manual 하게 split을 하여 Region의 개수를 조정하고 있습니다.hbase.hregion.memstore.block.multipliermemstore의 전체 크기가 multiplier * flush size보다 크면 추가적인 Write를 막고 flush가 끝날때까지 해당 memstore는 block 됩니다.기본값은 2인데, 저희는 8로 늘려놓고 사용하고 있습니다.dfs.datanode.balance.bandwidthPerSec부수적인 설정이지만, HDFS의 Datanode간의 load balancing이 일어나는 속도를 제한하는 설정입니다. 기본값은 1MB/sec로 되어 있지만, 계속해서 Datanode를 추가하거나 제거하는 경우에는 기본값으로는 너무 느릴 때가 있습니다. 저희는 10MB/sec 정도로 늘려서 사용하고 있습니다.dfs.namenode.heartbeat.recheck-intervalHDFS namenode에만 해당되는 설정입니다.Datanode가 응답이 없는 경우에 얼마 후에 Hadoop cluster로부터 제거할 것인지를 나타내는 값입니다.실제로 응답이 없는 Datanode가 떨어져 나가기까지는 10번의 heartbeat가 연속해서 실패하고 2번의 recheck역시 실패해야 합니다. Heartbeat interval이 기본값인 3초라고 하면, 30초 + 2 * recheck-interval 후에 문제가 있는 Datanode가 제거되는 것입니다.기본값이 5분으로 되어 있는데, fail-over가 늦어지기 때문에 사용하기에는 너무 큰 값입니다. 저희는 문제가 있는 Datanode가 1분 후에 떨어져 나갈 수 있도록 이 값을 15,000 (ms) 으로 잡았습니다.Read short-circuitRegionServer가 로컬 Datanode로부터 block을 읽어올 때 Datanode를 통하지 않고 Disk로부터 바로 읽어올 수 있게 하는 설정입니다.데이터의 양이 많아서 Cache hit이 낮아 데이터 대부분을 디스크에서 읽어와야 할 때 효율적입니다. Cache hit에 실패하는 Read의 Throughput이 대략 2배로 좋아지는 것을 확인할 수 있습니다. OLAP용 HBase에는 매우 중요한 설정이 될 수 있습니다.하지만 HBase 0.92.1-cdh4.0.1까지는 일부 Region이 checksum에 실패하면서 Major compaction이 되지 않는 버그가 있었습니다. 현재 이 문제가 해결되었는지 확실하지 않기 때문에 확인되기 전에는 쓰는 것을 추천하지는 않습니다.설정하는 방법은 다음과 같습니다. dfs.client.read.shortcircuit = true #(hdfs-site.xml) dfs.block.local-path-access.user = hbase #(hdfs-site.xml) dfs.datanode.data.dir.perm = 775 #(hdfs-site.xml) dfs.client.read.shortcircuit = true #(hbase-site.xml)Bloom filterBloom filter의 작동방식에 대해 시각적으로 잘 표현된 데모 페이지HBase는 Log-structured-merge tree를 사용하는데, 하나의 Region에 대해서 여러 개의 파일에 서로 다른 version의 값들이 저장되어 있을 수 있습니다. Bloom filter는 이때 모든 파일을 디스크에서 읽어들이지 않고 원하는 값이 저장된 파일만 읽어들일 수 있게 함으로써 Read 속도를 빠르게 만들 수 있습니다.Table 단위로 Bloom filter를 설정해줄 수 있습니다.ROW와 ROWCOL의 두 가지 옵션이 있는데, 전자는 Row key로만 filter를 만드는 것이고, 후자는 Row+Column key로 filter를 만드는 것입니다. Table Schema에 따라 더 적합한 설정이 다를 수 있습니다.저희는 데이터 대부분이 메모리에 Cache 되고 하나의 Region에 대해서 여러 개의 StoreFile이 생기기 전에 compaction을 통해서 하나의 큰 파일로 합치는 작업을 진행하기 때문에, 해당 설정을 사용하지 않고 있습니다.결론지금까지 저희가 비트윈을 운영하면서 얻은 경험을 토대로 HBase 최적화 설정법을 정리하였습니다. 하지만 위의 구성은 어디까지나 비트윈 서비스에 최적화되어 있는 설정이며, HBase의 사용 목적에 따라서 달라질 수 있음을 말씀드리고 싶습니다. 그래서 단순히 설정값을 나열하기보다는 해당 설정이 어떤 기능을 하는 것인지 저희가 아는 한도 내에서 설명드리려고 하였습니다. 위의 글에서 궁금한 점이나 잘못된 부분이 있으면 언제든지 답글로 달아주시길 바랍니다. 감사합니다.
조회수 3167

13. 내 깜둥이의 자위기구

개발자 시절 가장 힘든 시간은 변수명과 메소드명을 지을 때였다. 서비스나 회사 이름은 그보다도 더 힘들었고 그래서 그만큼 많은 시간을 할애했지만 모두 실패했다.  우리는 첫 서비스부터 지금까지 1번도 아니고 3번 그리고 회사 이름까지 하면 총 4번의 네이밍 실패를 겪었다.  정말 고민에 고민을 하고 지었는데도 말이다. 네이버 검색이나 구글링 또는 몇몇 사람들한테 물어보는 정도는 부족하다는 것을 알게 되었다. 특히 영어 단어를 이용한 네이밍이나 영단어들을 합치는 네이밍은 영어 잘하는 한국인이 아닌 현지인들의 검증을 거쳐야 한다. 그것도 연령대와 성별도 다르게 해서 여러 명으로부터 받아야 한다. 특정 연령층이나 특정성별 또는 특정 연령대에서 안 좋게 쓰이는 용어들도 있기 때문이다.1. 만땅5년 전 배터리 공유 서비스를 준비하면서 서비스 이름을 고민하던 시기였다. 수십 가지 이름들이 후보들이 나왔고 그중에 재미있는 느낌을 고른 것이 '만땅'이였다. 주유소에서 기름을 꽉 채울 때 쓰는 표현인데 젊은 친구들은 스마트폰의 배터리가 가득 찬 상태를 표현할 때 쓰기도 했었다.만땅이란 단어의 사전적 의미가 썩 좋지는 않았다. 또한 그 유래가 일본어라서 걱정이 되기도 했지만 주변 사람들에게 많이 물어보고 고민하고 내린 결정은 "정말 크게 문제가 되지는 않을 것 같다"였다. 약간은 어설프지만 귀여운 히어로 캐릭터와 함께 B급 감성으로 서비스를 친근하게 가져가자는 기획과도 어느 정도 맞아떨어졌다.< '만땅'은 그럭저럭? 버틸만 했다. >그렇게 첫 서비스 이름이 탄생했다. 몇몇 고객들로부터 서비스 이름이 조금 걸리긴 하네요. 라던가 기자분들에게 단어의 뜻에 대한 피드백을 받기도 했지만 서비스 본업에 지장이 있을 만큼의 안 좋은 피드백은 없었기 때문에 그럭저럭 버티면서 서비스를 진행할 수 있었다.2. 내 깜둥이의 자위기구 ( Mycoon 의 Plugger )만땅 서비스를 초기에 본엔젤스로부터 첫 투자를 받고 법인 설립 절차를 진행하던 시기 '회사 이름 지으셔야 해요."라고 강대표님으로부터 연락이 왔다. 회사 이름? 생각조차 하지 않았었는데. 아! 회사 이름도 우리가 직접 정하는구나 하고 신기해하던 시절이었다.서비스 이름은 정해졌지만 회사 이름을 "주식회사 만땅" 으로 하기는 좀? 그랬었다.  그래서 며칠 고민 끝에 나온 이름이 마이쿤이었다. 모바일 업계에서 거물이 되자라는 뜻으로 두 단어를 합쳤고 발음도 쉬웠다.Mobile + Tycoon = Mycoon나름 뿌듯했다. 그때 당시에는...그리고 시간이 지나 '만땅'앱의 2번째 버전인 충전장소의 위치정보를 공유하는 앱을 신규로 개발했고 이름을 Plugger로 지었다.  Plug + er을 합성해서 충전을 위해 플러그를 찾는 사람들이었다. 팀원들도 다들 괜찮다는 의견이었고 그렇게 세 번째 네이밍을 했다. 꾸준히 공부도 하는 사람? 끈질기게 선전하는 사람? 의 사전적 의미도 좋았다. 그리고 구글링도 해봤는데 별 특이한 점을 찾지 못했다.< 충전을 위해 플러그를 찾는 사람들? 뜻은 좋았다. > 문제는 미국을 건너가서 시작되었다. 2015년 1월 500 스타트업으로부터 투자를 받고 SF배치 참가 확정을 받게 된다. 노점상을 하면서 매일같이 버티던 우리에게는 정말 큰 성장의 기회가 찾아 온 것이다. 그렇게 국내 스타트업 최초로 500 스타트업 배치에 선정이 되었고 정말 많은 준비를 하고 팀의 절반인 5명이 미국으로 건너 가게 된다.15개 국가에서 건너온 35개 팀들과 함께 생활이 시작되었다. 같은 배치의 35개 팀이 첫날 간단한 인사들을 나누고 펍에서 다 함께 맥주를 먹던 중 한팀의 외국인 친구가 말을 건네 왔다. Plugger가 뭐냐? 자위기구를 만드는 하드웨어 제조 스타트업이냐고 물었다. 부족한 영어 실력 지만 아는 그 단어? 가 나왔고 나는 분명히 알아 들었다. 아 이게 무슨 소리인가 하고 그 친구에게 물었고 서로 오해를 풀었다. 그리고 그 친구가 폰으로 구글링을 해줘서 나에게 보여줬다.  검색어는 'Plugger for women'였다. 콘센트를 찾아서 플러그를 꼽는 동작은 하잖아 그래서 이 단어를 거기에도 쓰는 것 같다는 상세한 설명을 더해줬다. 여자들은 아마 이런 뜻으로 오해를 할 소지가 있다는 것이였다.망치로 한 대 맞은 기분이었다. 우리가 6개월 가까이 개고생을 하면서 만든 서비스의 뜻이 자위기구라니..다음날 전체 배치 인원들이 모여서 갑자기 팀 소개를 시켰다. 안되는 영어에 뭐라도 말하자 싶어서 어제 생각이 나서 말도 안 되는 콩글리쉬를 했다.어제 펍에서 한 친구가 자위기구를 만드는 스타트업이냐고 물었다.(미국인 친구들의 유머 코드를 모르겠지만 이 말을 하자마자 홀에 모였던 미국 친구들이 모두 다 빵 터졌다.)우리는 자위기구를 만드는 스타트업이 아니다. Plugger는 플러그를 찾는 사람들이란 뜻이고 우리는 충전을 할 수 있는 위치정보를 공유하는 앱을 개발하는 스타트업입니다. 한국에서 왔고 앞으로 잘 부탁합니다.소개가 끝나자  500 스타트업 CEO 데이브 맥클루어가 진심인지? 위로인지? 모르겠지만 스타트업은 수단과 방법을 가리지 않고 서비스를 알려야 하는데 Plugger 서비스는 그런 점에서 오늘  사람들에게 가장 각인을 잘 시켰다고 했다. 그뒤로 서비스 이름으로 남자멘토들과 여자멘토들이 심각하게 논의를 했고고 해당 단어가 일부? 여자들만 쓰는 단어이기 때문에 써도 된다는 결론을 내렸다. 그래도 내심 찜찜했다. 서비스 이름의 다른 뜻이 자위기구는 아니지 않은가?  자위기구의 충격이 가시기도 전에 다시 한번 충격적인 소리를 듣게 된다. 며칠이 흘렀고 몇몇 팀들과 좀 친해져서 인사 정도는 나눌 정도가 되었을 무렵 한 흑인 친구가 찾아와서 말을 건넸다. 너 회사 이름의 뜻을 알고 쓰고 있냐?  미국에서 서비스를 정식으로 할 거면 회사 이름을 바꾸는 게 좋겠어.라는 조언이었다. 한국 이름으로 마이쿤, 영어 표기로 Mycoon을 썼는데 Coon이 정말 안 좋은 단어인데 너희는 앞에 My까지 붙었다고... Mobile+Tycoon 이란 뜻이라고 내가 설명을 했지만 그 친구의 해석은 My + coon, 내 깜둥이라는 뜻이었다. < Tycoon>그렇게 우린 내 깜둥이의 자위기구(Mycoon 의 Plugger)가 되었다. 시간이 지난 지금 Plugger 서비스는 종료했고, 회사 이름은 Mycoon에서 Mykoon으로 변경을 했다. 그때 조금만 더 신경을 썼더라면 시간과 비용을 아낄 수 있었을 텐데 하는 후회가 된다. 3. Spoonme서비스를 종료했고 피벗팅 이후 새로운 서비스를 시작하면서 또 이름을 정해야 하는 시점이 있었다. 3번을 이랬는데 얼마나 더 심사숙고를 했겠는가? 목소리로 소통하는 오디오 서비스를 만들자고 결정을 했고,  한 팀원이 우리 서비스는 서로가 위로와 감성을 전하는 서비스 이기 때문에 영화 Her의 대사 중에 하나인 Spoon Me로 해보자는 의견이 나왔다. 나는 해당 영화를 봤었고 해당 대사가 나오는 예쁜 장면을 기억하고 있었다.네이버와 구글링을 했는데 참 따뜻한 표현이었고 서비스 취지에 맞았었다. 다시 한번 여러 외국인 친구들에게 물었는데 별 이상이 없었다.(이게 실수였다. 공부만? 잘했던 올바른 친구들에게만 물었고 성별은 이전의 Plugger 네이밍 충격으로 여자가 많았었다.)< 연인간에 뒤에서 백허그를 해달라는 표현으로 쓴다. 양지에서는...>신규 서비스의 이름은 그렇게 스푼 미-SpoonMe로 졌다.  사용자들도 이름이 좋다고 했고 우리도 어느 정도 만족을 했었다. 설마 또 이름 가지고 문제가 생길까? 그럴일 없어 이건 아름다운 영화 대사잖아...그러고 몇 달이 지나서 500 스타트업 멘토들이 한국을 찾아와서 같이 저녁을 먹을 기회가 있었다.서비스를 피벗 했고 열심히 새로운 서비스를 만들고 있다. 서비스 이름을 묻길래 SpoonMe 라고 했다. 그랬더니 또 몇몇 친구들이 뿜어대기 시작했다. 왜? 또? 설마? 야 영화에 나오는 대사잖아. 이게 왜 문제야? 재차 물었다. 4~5명의 남자 외국인 멘토들이 또 심각하게 논의를 시작했다. 이게 문제가 될 것인가? 말 것인가? 그래서 나온 결론은 안 쓰면 좋겠다 였다. 오해할 소지가 Plugger 보다 크다는 것이었다. 그 이유는 남자들끼리 대화할 때 특정체위를 표현하는 속어로 쓴다는 것이었다. 그 뒤로도 몇몇 외국인 친구들한테 똑같은 피드백을 받았다.< 이 그림을 누드로 생각해보자. 그게 스푼미 이다. > 아 이번에도 또 이름이?  베타 서비스 기간이었지만 비용을 들여서 도메인을 구입했고 각종 디자인과 SNS 그리고 앱에서 SpoonMe를 쓰고 있었다. 팀원들과 다시 한번 논의 끝에 이번에는 초반부터 정말 논란 없게 미리 변경하자는 의견을 가지고 Spoon이라는 이름으로 모든 것을 수정 했다. < 아직도 그 흔적이 남아 있다? 스푼의 안드로이드 팩키지명.>그렇게 4번째 네이밍을 실패하고 지금의 스푼이라는 서비스명을 정할 수 있었다. ASO와 SEO를 위해 라디오 단어를 추가 했다. 하지만 아직도? '스푼미'라고 부르는 초기사용자들이 남아 있을 정도로 네이밍은 한번 정해지면 그 인식을 변경하는데 많은 리소스와 많은 시간이 드는 것 같다.앞으로는 스푼 서비스가 지속적으로 성장해서 다시는? 네이밍 할 일이 없기를 바랄 뿐이다.#스푼 #Spoon #스타트업마케터 #마케터 #운영 #네이밍 #인사이트 #경험공유

기업문화 엿볼 때, 더팀스

로그인

/