Ringster's Techblog

Tech, Mobile, Internet

Rewriting Cheezburger Saved My Life – Ben Huh

leave a comment »

한동안 블로그 포스팅을 쉬었다. 여러가지 이유가 있었지만 일단 한번 멀어지니 다시 손이 잘 안가게 되는 것이 사실이라,억지로라도 글을 하나 써야겠다는 생각이 들었다. 기술적인 포스팅이나 생각을 정리하여 포스팅하는데는 시간이 걸리기에 복귀글(?)로 Cheezburger의 CEO인 Ben huh님의 기업가 정신 관련 포스팅을 번역해 보았다. 작년쯤 읽어야겠다고 생각하고 스크랩 해둔 글인데, 한동안 미루다 보니 방치되어 잊고 있다가 작업목록 정리중에 다시금 발견했다.

기업가들의 성공 스토리는 영웅담처럼 미화되기 마련이고, 어두운 면에 대한 언급은 거의 하지 않는다. 대부분 불굴의 의지와 영감과 실행력으로 모든것을 이겨내는 사람들로 묘사되지만, 실제로 발을 담궈보면 그렇게 간단히 치부하기에는 너무도 많은 어려움들이 있는 것이 사실이다. 많은 어려움 중에서도 정신적인 흔들림은 창업자를 궁지로 몰아넣는데, 비슷한 느낌을 느끼고 있던 차에 해당 글을 읽으며 많은 힐링이 되었다. 작년에 읽었다면 아무런 느낌이 없었을지도 모르겠건만 지금 이 글을 읽게 된 것이 어떤 운명이 아니었나 하는 생각도 하게 된다.

각설하고, 원문 번역은 다음과 같다.


제 이름은 벤 허, 엔터테인먼트 회사인 Cheezburger의 CEO이자 설립자입니다. 2007년에 회사를 시작해 고양이 사진들이 온라인 상에서 유명해지게 만들었습니다. 지금은 여러 유머 사이트를 운영 중입니다. 그리고 오늘 우리는 iOS 앱을 내놓았습니다. 이 순간이 매우 자랑스럽지만, 지금부터 할 이야기는 앱에 대한 이야기는 아닙니다.

저는 이 앱이 나오기까지의 모든 이야기를 여과하지 않고 말하려 합니다. 사람들을 즐겁게 하기 위해 디자인된 앱이고 개발과정도 특별하진 않지만, 저는 이 제품의 이야기가 기업가 정신에 대한 이야기가 될 것이라 믿습니다. 저에게는 앱을 내놓는 과정이 부활과도 같았습니다.

기업가들은 대부분 새로운 제품의 행복하고, 자랑스러운 면만을 공유합니다. 축하하는 동안은 정직할 때가 아니라는 듯이 내내 우리를 따라다니던 실패들은 제쳐둡니다. 모든 신제품에는 고통스러운 역사가 있는대도 말입니다.

Cheezburger는 2007년 제 아파트에서 ICHC를 시작으로 웹 사이트들을 사모으는 너저분한 원맨 스타트업으로 시작되었습니다. 몇 달 후 웹사이트 명단이 커지기 시작했고, 팀은 시애틀에 있는 작은 방으로 사무실을 옮겼습니다. 우리는 Know Your Meme나 FAIL Blog와 같은 meme 관련 웹사이트를 사거나, 만들어가며 확장했습니다.

우리는 유머 왕국을 완성할때까지 계속해서 확장하고 더해 나갔습니다. 우리는 lean 했지만 자원이 풍족했고, 새로운 아이디어를 테스팅 하는대도 뛰어났습니다. 우리는 빠르게 커졌습니다.

2011년 Cheezburger는 30만 달러라는 놀라운 자금을 첫번째 펀딩으로 유치하게 됩니다. 그 돈으로 Cheezburger는 가내수공업을 벗어나 미디어의 관심속에 엄청난 벤쳐 펀딩의 시기를 맞이하게 됩니다. 우리는 투자금을 제 비전에 따라 유치했습니다: 모든 사람이 그들의 유머감각을 뽑낼수 있는 곳을 만들자는 비전말입니다. 단순히 새로운 소재들을 뽑아내는 것이 아니라, 유저들이 재미있는 아이디어들을 불편 없이 표현할 수 있는 플랫폼을 운영해야 했습니다.

돈이 쏟아져 들어오며, 저는 길을 잃었습니다. 결국 저는 인생에서 3년의 시간과 수백만달러를 낭비했습니다.

오직 지난 4달이 우리가 실제 새로운 앱을 만들기 시작한 때입니다.

간단히 말해서, 우리는 우리가 뭘 하고 있는지 몰랐습니다. 우리는 수 년동안 광고를 유치하고, 티셔츠와 책을 팔고, 심지어 리얼리티쇼 까지 출현해 수익성이 있었습니다. 하지만 은행에 넣어둔 투자금은 우리에겐 새로운 것이었습니다. 더 중요하게는, 워드프레스 사이트를 만들고 인수하던 우리를 컨텐츠 플랫폼 회사로 변신시키는 것 또한 새로웠습니다. 우리는 인원을 3배로 늘렸습니다.

하지만 초기 투자자가 빠져나간 후, 우리의 30만 달러는 4만 달러가 되었습니다. 벤처캐피털 기준에는 적은 돈이지만 우리는 현금속에서 유영하는것 같이 느꼈습니다. 그러나 우리는 돈을 잃어가며, 당황하게 됩니다.

2011년의 과다 고용 몇달 후 저는 우리의 CTO와 이야기를 나눴습니다.

나: 우리 프로덕트 릴리즈 페이스는 어떤가요?

CTO: 인원 고용하느라 너무 바빠서, 아무것도 만들지 못하고 있습니다.

저는 할말이 없었습니다.

그때가 CEO가 강제로 끼어들어 직원들의 우선 순위를 바꿔놓을 순간이었습니다. 새로운 사람들을 고용하는 이유는 빠르게 변화하고 경쟁적인 환경에서 새로운 기능과 향상을 좀 더 빠르게 하기 위한 것이었습니다.

우리가 코드를 작성하지 않는다면, 우리는 수백달러를 모닥불에 던져놓는 셈이었죠. 항공사가 이렇게 말하는 것을 상상해 보십시오. “우리는 새로운 비행기를 사는데 너무 바빠서, 모든 비행편을 취소하기로 마음먹었습니다.”

끼어들어 중재하기보다, 저는 우리 팀을 위한 변명을 만들었습니다: 이익은 아직 적정 수준으로 상승하고 있었습니다. 머뭇거림은 일시적이었죠. 우리가 데려온 사람들은 우리를 다음 레벨로 데려다 줄 것입니다. 우리는 모두가 고용된 이후 한번에 따라잡을 생각이었죠.

2012년, 몇달의 지연 끝에 우리는 모든 사이트를 우리의 플랫폼으로 옮겼고, 유저들은 그것을 싫어했습니다.

유저들은 그들이 익숙하던 여러 기능들의 부재에 대해 불평하기 시작했습니다. 팀의 불일치는 점점 심화되었습니다. 톱 경영진들은 해고되거나 회사를 그만두었습니다. 제가 데려온 사람들은 저를 다음 레벨로 데려다 주지 못했습니다.

늦은 2012년 저는 새로운 CRO인 Amber Dunn을 AllRecipes로 부터 영입했습니다. 그녀는 재능이 있고, 함게 일하는 사람들로부터 존경받고 사랑받는 사람이었습니다.

그리고 그녀는 난소암을 가지고 있었습니다.

그녀의 암은 비밀이 아니었습니다. 저는 그녀가 정기적인 치료를 받으면서 암을 제어하며 정상적인 삶을 살고 있기에 고용했습니다. 그녀는 새로운 팀을 모으고 재조직하는데 도움이 되었습니다. Amber는 재미있는 이미지를 공유하고 리믹스하는 플랫폼 대신 미디어 회사를 세우는 전략을 세웠습니다. 그녀는 우리가 우리의 강점을 살리길 바랬습니다: 우리의 유저들은 충성스러웠고, 많은 트래픽을 가지고 있었으며, 수익과 투자로 인한 몇백만 달러를 가지고 있었습니다. 우리는 플랫폼 대신 재미있는 사이트를 구성하여 그들에게 광고를 파는데 집중해야 했습니다.

Amber의 제안을 들었을때, 유머 플랫폼을 만드려는 이미 망쳐버린 기회에 대한 생각이 떠올랐습니다. 아마 내가 틀렸을지도 모르겠구나. 그래서 저는 그녀의 아이디어를 받아들였습니다. 저는 이런 변화에 대해 이사진을 설득하기도 했습니다.

누구나 코미디 마스터가 될 수 있는 곳을 만드려던 제 꿈은 미뤄둬야만 했습니다.

우리는 2013년 높은 기대와 함께 시작했습니다. 우리는 경험있는 미디어인 몇몇을 고용했습니다. 우리는 일류 세일즈 팀을 여러 도시에 세웠습니다. 우리는 계획적으로 투자모드로 돌아섰습니다.

그때 Amber가 병원에 실려갔습니다. 그녀의 암이 좀 더 심해져 있었습니다. 회사는 혼돈에 빠져들었습니다. 저는 충분한 에너지와 열정과 제품 아이디어가 있었으나, 나머지 반 – 어떻게 미디어 전략을 세우고 광고를 팔지 – 은 알지 못했습니다. 4월, 우리는 병원에 있는 Amber를 포함한 회사의 1/3을 해고했습니다. 우리는 그녀가 나갈때 기분이 상하지 않도록 신경썼습니다. 하지만 그 어떤것도 병원에 있는 말기 암환자인 한 아이의 엄마를 해고했다는 사실을 기분좋게 할 수는 없었습니다.

Amber Dunn은 남편과 어린 딸을 남겨두고 몇 달 후에 임종을 맞이했습니다. 때때로 저는 그녀의 삶을 단축시킨대 책임이 있는지 생각하곤 합니다.

Cheezburger 이야기는 거기서 끝날수도 있었습니다. 해고 이후 재능있는 직원들이 회사를 떠났습니다. 하지만 감사하게도, 많은 직원들이 남았습니다. 사기는 끔찍했고, 저는 비참했습니다. 투자자 중 한명인 Brad Feld의 재촉에 따라 CEO 코치를 만나기 시작했습니다.

코치들은 당신의 기분을 낫게 만들지는 못합니다. 그건 그들의 일이 아닙니다. 그들은 당신을 좀 더 잘 볼 수 있게 해줍니다. 모든 것을 망쳐버렸다고 느껴지고 그것을 크게 외치는 것 말고는 다른 대안이 없을 때 말입니다. 저는 제 코치인 뉴욕에 있는 Jerry Colonna의 소파에 앉아, 처음으로 나 자신과 다른 사람에게 자신의 깊은 공포를 인정했습니다.

“뭘 해야 될지 모르겠습니다.”

“아마도 제 회사에 알맞은 CEO는 제가 아닌것 같습니다.”

“제가 Amber를 죽였는지도 모르겠습니다.”

공포를 이해하기 위해 저는 공포를 받아들이고, 공포가 저를 삼키게 두었습니다.

저는 제가 상실속에 빠져있다는 것을 깨달았습니다. – 나의 플랫폼을 갖겠다는 실패한 시도에 대한 후회, 투자자들의 돈을 낭비한 것에 대한 죄책감, Amber의 쇠락에 일조했다는 불안감. 저는 제 회사를 객관적으로 보는 것에 어려움을 겪고 있었습니다.

그리고 회사안에서 어떤 일이 벌어졌던간에 아직 수백만의 사람들이 우릴 사랑한다는 사실은 바뀌지 않았다는 것을 깨닫기 시작했습니다. 우리는 세계 여러곳의 사람들을 행복하게 만드는 것을 계속하기 시작했습니다. 제 방향상실은 일시적인 퇴보였을 뿐이었습니다. 하지만 그것을 일시적으로 두기 위해선 의기소침해질 수 없었습니다. 저는 실망감을 이겨내야 했습니다.

2001년 첫번째 스타트업이 실패했을때, 저는 우울증과 자살에 대한 생각들과 싸워야 했습니다. 2013년 여러가지 상황들이 나빠 보였지만, 저는 전과 같이 어둡고 도움받을 수 없는 상황으로 돌아가지 않기로 자신과 약속했습니다. 많은 기업가들에게 삶과 비즈니스는 같은 것입니다 – 이는 자아를 파괴하는 위험입니다. 당신이 정말 당신과 당신의 비즈니스가 하나이고, 비즈니스의 실패가 당신을 파괴하고 성공이 끝없는 보상을 준다고 믿는다면 말이죠. 하지만 어떠한 결과도 그런 희생을 보증하지 못합니다.

저는 제 실패를 껴안으며 저의 두 정체성을 떼어놓기 시작했습니다. 저는 해고에 대해 공개적으로 토론했습니다. 공개적인 실패는 당황과 고립을 동반합니다. 당신은 부정적인 흐름의 타겟이 됩니다.

지인이나 타인들은 당신을 괴짜, 사기꾼, 날강도와 같이 부릅니다. 당신은 모든 세계의 경제적, 사기 저하, 사회적 잘못에 대한 희생양이 됩니다.

한번 공개적으로 실패를 밝히고 나면, 당신은 하나의 선택만 남게됩니다: 나아가는 것입니다. 저는 사직하는 것을 고려했으나 그러지 않기로 했습니다. 제 잘못을 바로잡고 버텨내는 것이 제 직원들과 투자자들에게 할 수 있는 최소한이라 생각했습니다.

세번째로 새로운 팀을 조직했습니다. 저는 Cheezburger를 플랫폼으로 만들어 모든 사람들이 유머감각을 펼칠 수 있는 곳을 만드려고 하는 초기 아이디어로 돌아갔습니다. 2013년 8월, Scott Moore를 사장겸 COO로 고용했습니다. 초기의 비전으로 돌아가는 것은 어려웠습니다. 첫번째로, 저는 투자자들에게 돌아가 더 많은 돈을 투자받아야 했습니다. 그리고 저는 지금의 팀에게 플랫폼 아이디어는 추구할만한 가치가 있는 것이고 저는 믿을만한 리더라는 사실을 납득시켜야 했습니다. 우리는 가능성을 본 새로운 경영진을 고용해야만 했습니다. 그리고 이번에는 좀 더 잘 위임해야만 했습니다. 쉽지 않았죠.

동정심을 사기 위한 이야기가 아닙니다. 저는 결단을 내렸고 그것을 사랑했습니다. 저는 기업가가 그들의 비전을 약간의 운을 가지고 현실로 만들수 있는 기회를 얻을 수 있는 나라에 사는 것을 감사하게 생각합니다. 미국에서 여러해의 고생과 불확실성이 따름에도 투자자들은 나같은 이민자에게 재미있는 앱을 만들라며 수백만 달러를 줍니다. 물론 모든 이야기의 끝에서는 당신은 스스로를 보여주거나 계속 시도해야합니다.

여러 몸부림을 통해 모바일 세계에서 미디어 논제가 어떻게 될지에 대해 보고 듣고 다듬었습니다. 저는 Matt Galligan 과 Arsenio Santos와 함께 저널리즘 회사인 Circa를 공동 설립했습니다. 이는 제 논제에 대한 첫번째 테스트가 될 것입니다. Cheezburger 앱은 제 전투에서의 피와 살이 될 것입니다. 이 앱에 깔려있는 철학은 CEO로서의 지난 3년간 제가 배운 교훈을 나타냅니다.

1. 소비는 배움이다.

 기업가로서 배운 거의 모든 것은 다른 사람들이 일하는 것을 보면서 배운 것입니다. 유사하게, 우리는 유저들이 우리가 매일 실어나르는 유머들의 홍수에 영감을 받기를 바랍니다. 유저들은 그들의 친구의 피드 프로필과 좋아하는 사이트들을 Cheezburger 네트워크에서 볼수 있습니다 – 우리의 사이트와 우리의 유저들은 동등하게 취급됩니다. 많은 컨텐츠를 넉넉히 소비함으로써 사람들은 어떻게 다른 사람들을 웃길수 있는지 배우게 됩니다.

2. 리믹스는 협동이다

 모든 아이디어는 비판이나 협동에 대해 열려있어야 합니다. 창의적이 되기 위해서, 우리는 다른 사람들의 아이디어를 우리 자신의 것으로 통합해야 합니다 – 저는 이것을 제가 점점 위임을 잘하게 되어가며 배웠습니다. 앱에서 우리는 다른 이미지나 GIF를 한번에 리믹스할수 있게 함으로써 이런 원리를 삽입했습니다. 우리는 친구들에게 영향을 받고 우리 또한 친구들에게 영향을 줄수 있게 했습니다. 리믹스는 아름답고, 진화하는 공동체 입니다. 우리는 그것을 포용했습니다.

3. 마찰은 죽음. 속도는 승리.

  마찰은 꿈을 갉아먹습니다. 속도는 모든 비즈니스에서 큰 이점입니다. 저희와 유저들은 아이디어로부터 최대한 빨리 시작하는 것을 원했습니다. 우리는 유저들이 앱의 컨텐츠에서 원하는 것이 우리 회사의 관심사가 아니더라도 그들이 원하는 것들은 무엇이든 하게 해주었습니다.

바깥세상에서, 오늘날의 많은 테크 기업정신은 몇 메가바이트로 이루어진 간단한 기능들과 같이 보입니다. 당신은 프로젝트에 깔린 거대한 비전에 대해 들을지도 모르겠습니다. 아주 가끔 당신은 지저분한 전체 스토리에 대해 알게 될 것입니다. 이 개인적인 모험을 공유함으로서, 저는 당신이 제가 이 앱을 제가 원하던 미래를 형상화 – 모두를 위한 재미있고, 행복한 세상 – 한 것이라 할때 유머를 던져줬으면 합니다.

비록 초기 비전이 종종 실패하고 무시되더라도, 기업가들은 제품이 세상으로 뛰어드는 순간을 위해 피를 흘립니다. 3년간의 출혈 끝에, Brad 는 저에게 말했습니다. “이제 속죄는 끝내도 된다네.”

이 앱의 릴리즈는 저의 부활과도 같은 것이며, Cheezburger의 모두가 열심히 일했기에 가능했습니다. 저는 그들이 매우 자랑스러우나 아직 많은 것들이 남아있습니다. 제가 원하는 것은 더 많은 앱을 만들고 더 많은 릴리즈를 하는 것이니까요. 아무도 당신에게 성공을 약속하지 못합니다. 제가 할수 있는 것은 계속 시도하는 것뿐입니다.


원문보기

https://medium.com/backchannel/rewriting-cheezburger-saved-my-life-76fa09404916

Written by Ringster

2015/05/29 at 5:58 오후

IT 회사들의 Stack 엿보기, Stackshare

leave a comment »

여러 굵직한 IT 회사들이나 스타트업들은 어떤 기술을 이용하고 있는지 궁금할 때가 있다.
구글링을 하거나 Quora와 같은 사이트를 찾다보면 어렵지 않게 찾아볼 수 있긴 하지만, 그래도 그 작업 자체가 번거롭긴 하다.

웹서핑을 하다가 이런 정보들을 모아놓은 사이트가 있는 것을 발견했는데, 주소는 다음과 같다.

http://stackshare.io/

Stackshare

사이트에 들어가보면 위와 같이 여러 Tech company들의 Tech stack, Utilities, DevOps, Business tool 들에 대한 정보들이 나온다. 자세한 정보가 나열된 것은 아니지만 각각의 회사들이 어떠한 툴들을 사용하고 있고, 어떤 툴이 어떤 용도로 널리 쓰이는지에 대해서 훑어보기는 편리하다.

사이트 로그인을 하지 않아도 이런 정보를 볼 수 있기는 하지만, Github 계정으로 가입할 수 있게 만들어놓은 점이 특이해서 가입을 해보았다. 가입하자마자 자신의 Stack을 share할 수 있게 해주는 페이지로 연결되는데, 이런식으로 스타트업이나 테크 기업들의 Stack을 수집하고 있는 것 같다.

사이트에 대해 좀 더 알아보니, Stackshare 자체도 하나의 스타트업으로 이미 펀딩도 받은 상태였다. 비즈니스 모델이 어떻게 되는지 자세히는 찾아보지 않았으나 굵직한 회사들의 Stack들을 소개하는 위쪽 공간에 영세 스타트업의 Stack을 소개해주는 광고(?) 비스무리한 배너가 출력되는 것을 보니, 스타트업에 어떤 기술 스택을 적용할지 고민하는 사람들이나 이에 관심있는 사람들을 끌어들이고, 여기에 소규모 스타트업들이 노출 될 수 있는 공간을 제공하려는 것 같다.

골드러시 시절엔 금캐는 사람들보다 청바지 만드는 사람들이 돈을 더 벌었고, 지금의 실리콘 밸리는 부동산 소유주들이 상당한 재미를 보고 있다고 한다. 남들은 다 황금을 쳐다보고 있을 때, 황금을 캐는 사람들의 니즈를 찾아 발빠르게 서비스를 제공하는 Stackshare와 같은 회사들이 더 재미를 볼 지는 지켜볼 일이다.

Written by Ringster

2015/03/13 at 3:30 오후

모바일 인터넷에 게시됨

Tagged with , , ,

Layout XML의 Background 이미지에 할당된 메모리 즉시 반환하기

with one comment

앱을 제작하는데 있어 Layout XML의 Background로 이미지를 포함시키는 작업은 상당히 빈번하게 이루어진다.

public class MainActivity extends ActionBarActivity {
    private Button launchBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        launchBtn = (Button) findViewById(R.id.button);
        launchBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(MainActivity.this, SecondActivity.class);
                startActivity(i);
                finish();
            }
        });
    }
}

위는 액티비티를 생성하고 Launch 버튼을 클릭하면 다음 액티비티가 실행되는 간단한 코드이다.
실행 결과는 다음과 같다.

xml_activity

Background로 포함된 이미지가 OOM을 유발한 만큼 크지 않은 이상 위와 같이 정상 실행된다.
여기서 문제는 아래의 화살표 부분에서 첫번째 Activity를 종료시키고 두번째 Activity를 실행했음에도 첫번째 Activity의 background XML에 할당된 이미지가 계속 메모리 공간을 점유하고 있고, 이 메모리가 언제 반환될지 알 수 없다는 것이다.
memory_monitor

이는 이미지가 커서 많은 메모리를 점유하고 있거나, 다음 Activity에서 메모리가 많이 필요한 작업을 할 경우에 OOM을 유발시킬 수 있는 요인이 될 수 있는데, 이를 간단히 해결하는 방법은 다음과 같다.

@Override
    protected void onDestroy() {
        super.onDestroy();
        findViewById(R.id.rootView).setBackground(null);
        System.gc();
    }

memory_monitor2

OnDestroy에서 Activity가 destroy될 때 View의 Background를 null로 설정하고 명시적으로 gc를 호출했다.
이로써 두번째 Activity가 시작될 때 첫번째 Activity의 XML에 할당된 메모리를 회수했음을 확인할 수 있다.

Written by Ringster

2015/03/10 at 6:55 오후

안드로이드 개발에 게시됨

Tagged with , , ,

Technology Entrepreneurship (Lecture 4~8, 마무리하며)

leave a comment »

Lecture 4. From idea to Opportunity

1) Technology는 Introduction, over exposure, parody/remix, equilibrium과 같은 Lifecycle을 가짐.
처음 발견되어 널리 퍼지게되면, 누구나 다 과도하게 사용하게 되고, 이후 이에 대한 패러디나 재발견 등을 거쳐 다시 평형 상태를 찾는다.

2) 팀을 구성할때는 누가  ‘A Player’고, 어떤 스킬셋을 가지고 있느냐가 다가 아니다. 어떤 목표를 가지고 있고, 어떻게 전념할 것인지 정확히 정의해라.

Lecture 5. Legal Aspects of Startups

1) 누가 공동창업자이고, 어떻게 지적 재산권을 분배할 것인지, 어떻게 주식이 분배될지 등 가능한 한 모든것을 문서화하라.
이러한 것들이 초창기에 문서화되지 않으면, 후에 충돌이 발생하게 된다.

2) 지적재산권(IP)에 대해서는 매우 조심해야 한다. 기존 고용주와 깔끔하게 갈라서고 싶고, 그들의 축복을 받으며 떠나고 싶다면 말이다. 하지만 기존 고용주와 일하고 있는 동안에는 스타트업에 대한 일을 해서는 안된다.

3) 어떻게 주식을 분배하고, 퇴직자 연금처리리 등에 대한 대화를 해라. 이러한 것들은 돈이 연관되어 있지 않을 때 이야기 하는 것이 훨씬 쉽다.

4) 다른 나라에 있는 공동 창업자나 이민 문제는 불행히도 매우 까다롭다. 법의 지역성 때문에 가이드라인을 잡기 힘들어진다. 분명히 모두가 한곳에 있다면 훨씬 쉬워질 것이다. 이를 피하는 방법이 몇가지 있긴 하지만, 복잡성을 증가시키고, 시간을 들여야하며 창의력을 발휘해야 한다. 몇몇 나라들이 다른나라보다 좀 더 쉬운편인데,  예를 들어 캐나다는 스타트업 비자를 가지고 있다.
미국은 조금 느린편이지만 무엇인가 대책을 마련하긴 할 것이다.

5) 기업 설립이나 지적재산권에 대해 변호사와 상담해야 하는지 궁금해지기 시작했다면, 그래야만 한다. 좋은 변호사를 찾는 가장 좋은 방법은 같은 지역에 있는 다른 창업자들에게 물어보는 것이다. 그들은 누가 함께 일하기 좋은지 말해줄 것이며, 좋은 스타트업 변호사들은 비용 지불을 펀딩을 받을때까지 연기해 줄 것이다. 종종 변호사들은 펀딩을 받기 쉽도록 도와주는데, 이를 위해선 당신의 스타트업이 리스크를 감당할만한 장래 유망한 스타트업이라는 것을 확신시켜야 한다.

6) 지적재산권(IP)을 보호하기 위한 몇가지 방법이 있다. 기업 비밀(Trade secrets), 상표(Trademarks), 특허(patents), 저작권(Copyright)이다. 좋은 변호사는 당신의 비즈니스 타입에 따라 어떤 선택을 해야하는지 도와줄 것이다. 투자자들은 때때로 지적재산권이 보호되는지 보곤하는데, 바이오테크를 제외한 기업가에게는 마켓에 대한 빠른 접근과 비즈니스 모델을 제대로 만들고, 효과적으로 실행하는 것이 최고의 보호방법이 된다.

7) 돈을 받거나 투자를 받기전에는 언제나 변호사와 상담하라. 특히 친구나, 가족, 엔젤투자자들이 돈을 주기 전에 말이다. 초창기에 한 실수들은 나중에 돈을 투자받기 어렵게 만든다.

Lecture 6. Customer Development and Lean Startups

1) Entrepreneurship은 Balancing Act
– optimistic/pessimistic, flexible/persistent : 너무 긍정적이면 현실을 파악하기 어렵고, 너무 비관적이면 사업을 시작하기가 쉽지 않다. 너무 유연하면 Customer development가 힘들고, 너무 경직되어 있으면 잘못된 컨셉에 너무 묶여 있게된다.

2) Startup process는 Unknown을 known으로 바꾸는 작업
– 가설을 설정하고 시험하며, 가설이 맞는지 확인하고 틀렸을 경우 pivot이 필요
– Customer가 원하는 것은 엔지니어 팀이 무엇을 만들고 싶어하나와 일치하지 않는다. (엔지니어 팀은 sexy한 프로덕트를 만들어내고 싶어하고, customer가 필요로 하는 것은 sexy한 프로덕트가 아니다. 실제 고객을 접하는 것이 중요하다.)

3) Lean/Fat startup에 대한 논쟁
– Ben Horowitz : Lean Startup 모델에서는 customer market fit을 찾은 후 go fat을 하라고 말한다. 하지만 이 모델에는 문제점이 있다. 첫번째로 Market fit을 정확히 알 수 있다고 가정한다. (Ipod의 경우 밀리언 셀러가 되는데 2년이 걸렸고, Iphone의 경우에는 3일이 걸렸다. Market fit을 정확히 어떻게 알 수 있나?) 두번째로는 Market fit을 이루면 그 상태가 계속될 것이라고 가정한다. (브라우저 시장의 예를 들면 MS가 윈도우에 익스플로러를 끼워팔면서 기존 브라우저 시장이 뒤엎어 지기도 했다. Market fit이  유지될지는 알 수 없다.) 마지막으로는 Market fit을 이룰때까지 경쟁이 없을 것이라는 가정을 한다.  경쟁자들은 기다려주지 않고 빠르게 움직인다.
– Fred Wilson : Double amount of cash가 창업가의 Exit 확률을 높여주지 않는다. 스타트업의 value를 이루는 것은 아이디어나 프로덕트 팀의 quality, 운 등 여러 요소이고, 자금은 그 중 하나의 요소일 뿐이다. go fat을 빠르게 가는 것은 도움이 되지 않는다.

Lecture 7. Entrepreneurship in Emerging Economies

1) 중국에서의 Entrepreneurship 환경 – 펀드 레이징 관련
– Seed money 구하기 힘들다, 은행에서 대출을 통해 초기 자금을 구하기도 어렵다.
비즈니스가 일정 궤도에 오른 후에도 중국에서의 펀드레이징은 창업자와의 관계를 중시하고 이는 펀드레이징을 받기 힘들게 만든다. 큰 돈은 Guanxi(꽌시)를 가지고 있는 사람들에게 가고, 대부분의 창업자들의 경우 Diao si이므로 (연줄도 없고, 돈도 없는 일반 가정 출신의 가난한 젊은이를 나타내는 중국어 슬랭) 펀딩을 받는 것은 매우 어렵다. 그래서 비즈니스를 운영하기 위해서는 현금흐름을 만들거나 친구들에게 돈을 빌려야 한다. VC와의 Term sheet에 사인을 하더라도 돈을 바로 받을 수 있는 것이 아니고, 실제적인 관계 형성을 하기까지 오랜 시간을 기다려야 한다. 이 와중에도 Commitment 이슈등이 생기면 언제든지 일이 틀어질 수 있고, 이는 펀딩을 더 어렵게 만든다.
2) 중국에서의 Entrepreneurship 환경 – 정부 및 그 외 관련
– 정부 관련 문제들은 피할 수 없다. 베이징 쪽은 좋지 않고, 그나마 상하이쪽의 정부관료들은 생산적이다.
그 외에도 사기나, 부패와 같은 것들과 싸워야 한다.

중국 Startup Entrepreneur(YingYi) 인터뷰 링크
https://vimeo.com/74811163
https://vimeo.com/74812478
https://vimeo.com/74811164

Lecture 8. Entrepreneurial Marketing and Sales

1) 사람들이 어떻게 물건을 사게 만드나?
– 확실한 value proposition을 가질 것
– Demand creation 실험을 할 것
– Influencer를 찾을 것
– Bowling pin strategy를 이용할 것


연초에 계획했던 Technology Entrepreneurship 강의를 드디어 끝마쳤다. 중간에 약간 강의가 밀리기도 하고, 팀 프로젝트도 조금 소홀히 하긴 했지만, 어찌됐든 마무리를 지었다.

이론적인 내용들도 많았지만 Lean/Fat 스타트업에 대한 논쟁과 중국의 스타트업 환경 및 창업자 인터뷰 부분은 재미있게 들었다. 중국의 “꽌시” 문화와 그 때문에 스타트업 생태계가 받는 영향에 대한 창업자의 인터뷰를 통해 그러한 환경에서도 꾸준히 도전하는 중국의 Diao si들의 열망을 볼 수 있었다.

스타트업의 주요 키워드 중 하나인 Lean Startup도 하나의 관점일 뿐이라는 깨달음 아닌 깨달음도 얻었다. 주변에서 다들 Lean Startup이나 MVP를 외치고 있다보면, 그것이 마치 진리인 양 생각하게 되버린다. 장하준의 경제학 강의를 읽고 경제학에도 여러 관점과 접근법이 있고 각각의 한계가 명확하다는 사실에 충격을 받고, (Freakonomics와 같은 책을 재미있게 읽었던 나로서는 속았다는 기분도 약간 들었다.) 넓은 관점을 가져야 겠다고 생각한 것이 얼마 전인데 벌써 이러는 것을 보면 아직 갈 길이 멀다.
Lean Startup이 아니면 뭔가 잘못된 방법으로 스타트업을 하고 있는 것처럼 여겨지는 분위기와는 별개로, 각 방법론의 장단점을 정확히 알고 사용하도록 해야겠다.

마지막으로 강의를 마무리하며 Heidi Roizen의 인터뷰를 들었다. 실리콘 밸리의 Legendary connector라고까지 불리는 무게감과는 달리 편안하고, 밝고 유머러스한 분위기로 시종일관 인터뷰를 지속 하는 모습에 좋은 인상을 가지게 되었다. 간단히 인터뷰에 대한 느낀 점과 감사 인사를 메일로 적어 보냈는데, 몇시간 뒤 답장이 왔다. 긴 답장은 아니었지만 예상도 못한 답장에 대단한 사람이구나 하는 생각을 다시금 했던 것 같다.

Written by Ringster

2015/03/08 at 7:02 오후

Android Studio로 버전코드/버전네임 관리하기

with 5 comments

PlayStore에 등록된 앱은 VersionCode와 VersionName의 두가지 속성을 가지고 있다.
VersionCode는 정수값을 이용하는데, 플레이 스토어 내부적으로 상위 버전을 구분하는데 사용되고, VersionName은 플레이 스토어에서 사용자에게 보여주기 위한 값으로 사용된다.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.android.example"
    android:versionCode="0"
    android:versionName="0.0.0.0">

보통 AndroidManifest.xml에 위와 같이 정의하여 사용하는데, 안드로이드 스튜디오에서는 Gradle scripts의 Build.gradle(Module:app)에 정의된 아래 값에 의해 manifest에 정의된 값이 무시된다.

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.android.example"
        minSdkVersion 14
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

자동화된 빌드 툴을 쓰지 않고 일일히 버전코드와 버전네임을 관리하는 것은 귀찮은 일인데, 이럴때 간단하게 버전 코드를 업데이트 해줄 방법은 다음과 같다.


apply plugin: 'com.android.application'
import java.util.regex.Pattern

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.android.example"
        minSdkVersion 14
        targetSdkVersion 21
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}


task('increaseVersionCode') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def pattern = Pattern.compile("versionCode=\"(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcher = pattern.matcher(manifestText)
    matcher.find()
    def versionCode = Integer.parseInt(matcher.group(1))
    def manifestContent = matcher.replaceAll("versionCode=\"" + ++versionCode + "\"")
    manifestFile.write(manifestContent)
}

task('incrementVersionName') << {
    def manifestFile = file("src/main/AndroidManifest.xml")
    def patternVersionNumber = Pattern.compile("versionName=\"(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+)\"")
    def manifestText = manifestFile.getText()
    def matcherVersionNumber = patternVersionNumber.matcher(manifestText)
    matcherVersionNumber.find()
    def majorVersion = Integer.parseInt(matcherVersionNumber.group(1))
    def minorVersion = Integer.parseInt(matcherVersionNumber.group(2))
    def pointVersion = Integer.parseInt(matcherVersionNumber.group(3))
    def buildVersion = Integer.parseInt(matcherVersionNumber.group(4))
    def mNextVersionName = majorVersion + "." + minorVersion + "." + pointVersion + "." + (buildVersion + 1)
    def manifestContent = matcherVersionNumber.replaceAll("versionName=\"" + mNextVersionName + "\"")
    manifestFile.write(manifestContent)
}

tasks.whenTaskAdded { task ->
    if (task.name == 'generateReleaseBuildConfig' || task.name == 'generateDebugBuildConfig') {
        task.dependsOn 'increaseVersionCode'
        task.dependsOn 'incrementVersionName'
    }
}

default config의 versionCode/versionName를 삭제한 후, Build.gradle에 위와 같이 task 구문을 추가해 주면 빌드 시마다 Manifest의 VersionCode가 +1씩 증가하게되고, VersionName은 0.0.0.0 (Major.Minor.Point.Build 버전) 순으로 형성되어 빌드 시마다 빌드버전이 +1씩 증가된다.

public class MainActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PackageInfo pInfo = null;
        try {
            pInfo = getPackageManager().getPackageInfo(
                    this.getPackageName(), 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        int versionCode = pInfo.versionCode;
        String versionName = pInfo.versionName;

        TextView versionCodeTextView = (TextView) findViewById(R.id.versionCode);
        versionCodeTextView.setText("VersionCode:"+Integer.toString(versionCode));

        TextView versionNameTextView = (TextView) findViewById(R.id.versionName);
        versionNameTextView.setText("VersionName:"+versionName);

    }
}

매니페스트 상에서도 바로바로 업데이트 되는 것을 볼 수 있지만 위와 같이 버전명과 버전코드를 호출해서 확인도 가능하다.

Written by Ringster

2015/03/06 at 4:33 오후

Android Studio Getter/Setter prefix 설정법

leave a comment »

클래스의 멤버 변수나 스태틱 변수 이름 명명 시 mVariable, sVariable과 같이 접두사를 이용하는데,

안드로이드 스튜디오에서는 Getter/Setter의 prefix를 설정하는 방법을 몰라서 Getter/Setter 자동 생성시

getmVariable, setmVariable과 같이 메소드 명이 생성되어 손이 두번 가곤 했다.

접두어 설정 방법은 메뉴에서 File -> Other Settings -> Default Settings 에 들어간 후 Code Style -> Java

이후 Default에 있는 Code Generation의 Name Prefix를 Field : m, Static Field : s로 설정해 놓으면 된다.

Written by Ringster

2015/03/03 at 4:51 오후

SporTracker 제작 후기 (2) – Amazon Web Service, Elastic Beanstalk 사용기

with 2 comments

SporTracker를 제작하며 개인 기록을 저장할 간단한 서버가 필요했다.
AWS EC2에는 어느 정도 익숙한 편이지만, 일일히 EC2 인스턴스에 DB를 설치하고 웹서버를 설정하고 다시 앱과 연동하는 것은 간단히 빠르게 구현해 업로드 하려던 프로젝트의 취지에 맞지 않았다.

그래서 눈을 돌리게 된 것이 Elastic Beanstalk다. 콘솔을 통한 몇번의 클릭만으로도 Auto Scaling이 지원되는 서버를 쉽게 설정할 수 있고, mysql을 지원하는 RDS를 통해 DB 로그 보기나 DB 백업등의 관리를 손쉽게 가능하게 해준다. Cloud watch와 연동하여 여러 조건에 대해 이메일 알람을 받는것도 쉽게 설정할 수 있으며, 자체적인 버전 관리 기능도 가지고 있다.

어플리케이션 배포는 콘솔을 통해 zip 파일을 올리는 것으로도 가능하고, 이와 더불어 git을 통한 퍼블리싱도 가능하다.
나의 경우에는 Beanstalk-CLI (링크)를 설치하고, 파이썬과 boto 인터페이스(링크)를 설치 한 후 git을 통해 beanstalk 서버에 직접 업로드 하는 방식을 사용했는데, 설정도 간편하고 git을 통해 푸시하는 방식은 익숙하다 보니 어렵지 않게 이용할 수 있었다.

DB에 접속할 때, php의 경우

      $dbhost = $_SERVER['RDS_HOSTNAME'];
      $dbport = $_SERVER['RDS_PORT'];
      $dbname = $_SERVER['RDS_DB_NAME'];
      $dsn = "mysql:host={$dbhost};port={$dbport};dbname={$dbname}";
      $username = $_SERVER['RDS_USERNAME'];
      $password = $_SERVER['RDS_PASSWORD'];


      $dbh = new PDO($dsn, $username, $password);

와 같이 접근하면 DB 핸들러를 얻을 수 있다.
그 이후에는 다른 서버에서 작업할때와 별반 다른점이 없는데, 다만 고생했던 점은.. DB 테이블의 인코딩을 UTF-8로 설정하고, 앱에서도 제대로된 인코딩 값을 보내주는데 DB에서 계속 한글이 깨지게 출력되어 알고보니 RDS DB의 기본 encoding 설정이 utf-8이 아닌 latin1으로 되어었었다.

문제는 이 설정값은 Beanstalk에 의해 생성된 인스턴스에 접근해서 my.cnf 파일을 수정해도 바꿀 수가 없다는 것인데, 온갖 방법으로 시도해봐도 영 바뀌지가 않아 고생하고 있다가 결국 해결책을 찾아냈다.

AWS관리 콘솔에 들어가서 RDS 대쉬보드에 들어가 Parameter charset을 UTF-8로 적용한 그룹을 생성하고, RDS 인스턴스 중에서 Elastic beanstalk가 생성한 인스턴스에서 instance action를 선택, 이후 modify -> Database options 하위에서 해당 Parameter group을 적용한 후 RDS 인스턴스를 재부팅하면 된다.

이후 다시 DB에 접속하여 show variables like ‘c%’를 쳐보면

character_set_client utf8
character_set_connection utf8
character_set_database utf8
character_set_filesystem utf8
character_set_results utf8
character_set_server utf8
character_set_system utf8
character_sets_dir /rdsdbbin/mysql-5.5.40b.R1/share/charsets/
collation_connection utf8_general_ci
collation_database utf8_general_ci
collation_server utf8_general_ci
completion_type NO_CHAIN
concurrent_insert AUTO
connect_timeout 10
위와 같이 캐릭터 셋이 utf8로 적용된 것을 확인할 수 있다.
아마존에서는 RDS의 파라미터 값을 바꾸는 것을 권장하지 않아 이런식으로 파라미터를 잠가 놓았다는데, 기왕이면 utf-8로 설정해주지 latin1이라니.. 그 탓에 Elastic beanstalk를 포기하고 EC2 인스턴스를 그냥 하나 생성할까도 고민했었다.
Elastic Beanstalk를 처음 사용해본 탓에 생각보다 고생했지만, git을 이용한 빠른 배포와 빠른 서버 설정에는 이만한 서비스가 없는 것 같다. EC2 인스턴스를 설치해 웹서버를 설치하고, DB를 설치해 권한 및 원격 접속을 설정하고, 여러 로그들을 관리하고, Auto Scaling을 적용하는데는 너무 많은 손이 간다.
간단한 서버의 배포를 위해 이 모든것을 설정하는데, EB를 이용하면 5분이 채 걸리지 않는다. (나처럼 헤매지 않는다는 가정하에..)
aws_management
또한 위에 보이는 AWS Console와 같이 공식적으로 지원되는 앱을 통해 모바일에서도 쉽게 서비스의 상태를 파악하고, 관리 가능하다는 것은 5분도 걸리지 않는 노력에 비해 충분한 메리트가 있다.
더구나 Free tier에서 이용 가능하므로 이 모든 것을 이용하면서도 비용이 청구되지 않는다. (서비스 트래픽이 증가해 Auto Scaling이 되지 않는 이상, Auto Scaling 되더라도 기본 설정은 t1.micro 4대까지 이므로 적절히 한달 가동시간 750시간을 넘기지 않게 잘 관리해주면 된다.)
서비스가 사용자가 몰리게 되면서 트래픽이 증가하게 되면 Elastic Beanstalk의 사용에서도 불편함을 느낄테지만, 간단한 서비스를 작성해 런칭하고, 반응을 보는데는 적합한 서비스다. Twitch가 Beanstalk를 사용해 개발되었으니, 생각만큼 소규모 서비스에만 적합한 서비스도 아니다. 사실 백엔드에 대한 복잡한 고민 없이 아이디어와 서비스의 질 자체에 집중하고 싶다면 Beanstalk가 좋은 선택이 될 것이라 생각한다.

Written by Ringster

2015/03/02 at 5:30 오후

쉐어보드

쉐어메이트에 관한 모든 것

jamesjungkuelee's biotech story

Biotech, entrepreneur, life

Communications as Ikor

All about Corporate Crisis Communication

미스타표, 즐기며 배우며.

표철민의 생각과 배움, 여러 정제되지 않은 이야기들. 성장기 그 자체.

VentureBeat

News About Tech, Money and Innovation

Open API, Cloud, DevOps 와 eBook

Open API, eBook, Cloud, DevOps

Economics of almost everything

Tech, Mobile, Internet

cylee

Tech, Mobile, Internet

gorekun.log

고어쿤로그

Google Developers Korea 블로그

Tech, Mobile, Internet

Android Developers Blog

Tech, Mobile, Internet

최피디의 앱스 개발기

기술, 앱스, SNS, 창업

D2 Blog

Tech, Mobile, Internet

All of Software

Tech, Mobile, Internet

Platum

Startup's Story Platform

김동호의 스타트업 이야기

한국신용데이터, 아이디인큐, 그리고 기업가정신