스토리 홈

인터뷰

피드

뉴스

조회수 1528

CTO의 인간선언

아이오에서 일 한지 어느 덧 한 달 가까이 되어간다.이젠 나도 어느 정도 팀의 비즈니스 로직, 도메인, 문화, 사용하는 기술들이 조금씩 이해되기 시작하고 있다.그러자 이번엔, CTO이자 나의 멘토이며 사수인 미정님이, "직접 기능을 하나 TDD로 개발해서 Pull Request 해보라"는 미션을 주었다.API를 보고, 구글링하고, 기존에 미정님이 짰던 코드를 참고해서 만들어갔다.그럼에도 불구하고 제대로 작동하지 않는 코드가 있었다.혼자 해볼 수 있는 것은 다 해 본것 같은데도 해결법이 떠오르지 않아, 미정님에게 이런저런 문제가 있다고 설명하고 도움을 요청했다.미정님이 코드를 좀 보더니 해결했다. 미정님이 짰던 기존 코드에 오류가 있었고, 내가 그것을 참고해서 코드를 짰기 때문에 생긴 문제였다.그녀는 쓴 웃음을 지으며, “변형덕에 오류발견 했네, 잘했어.”라고 약간 주눅들어 말했고,나는 “아, 저는 미정님 코드는 완벽하다 생각하고 그걸 레퍼런스로 하고 코드를 짰는데, 그래서 오류를 못 찾았나봐요.”라고 대답했다.그러자 그녀는 갑자기 눈빛을 바꾸며 역정을 냈다. “그건 변형이 아직 엔지니어의 마인드를 못 갖췄다는 말이야!”예상치못한 임기응변에 순간 나는 움찔했고, 내게 유리했던 분위기를 뺐기고 말았다.그녀의 설명이 이어졌다.“세상에 실수 없는 사람은 없어! 엔지니어라면, 컴퓨터는 믿어도 사람은 못 믿는 다는 생각을 갖고 있어야 되!나는 선배가 짠 코드라도 안 믿어. 심지어 구글러가 짠 코드도 난 안 믿어!100%완벽한 코드는 없어.우리가 TDD를 하는 것도 실수나 오류를 최소한으로 줄이기 위해서지, 그렇게해도 오류없는 100% 완벽한 코드를 보장하지는 않아.그러니까 누가 짠 코드든 완벽하다고 생각하면 안 돼! 내 코드도 마찮가지고!”구구절절이 맞는 말이다.친절한 미정님은 스스로를 실수할 수 밖에 없는 인간으로 낮추면서까지, 엔지니어로서 가져야할 자세를 알려주셨다.진정한 살신성인의 멘토라고 아니할 수 없다.ㅜ친절한 박미정줄여서 친박.앞으로 친박이라 부르고 싶다.#스위쳐 #Switcher #개발자 #스타트업 #스타트업CTO #CTO #개발일지 #경험공유
조회수 5250

"캘린더앱은 돈이 되지 않아요"

지난 2년 내내 투자자 미팅에서 귀에 박히도록 들었던 소리."캘린더앱은 돈이 되지 않아요."맞다. 캘린더앱은 돈이 되지 않는다.지난 몇 년간 다수의 회사들이 출시했던 화제의 캘린더 앱들의 말로를 함께 살펴보자.  1,000만 달러를 투자받은 캘린더앱 - Tempo지평만 열고 2015년에 인수 후 종료.  모두에게 사랑받던 캘린더앱 - SunriseMS가 1억 달러(1천억 원)에 인수를 해 화제가 된 후1년 만에 또 종료(2016년).뭐 바다 건너 이야기는 너무 멀게 느껴질 수 있으니, 국내의 사정을 살펴보자.참고로 아래 4개의 서비스 모두 종료 관련 공식 보도자료를 내지는 않았기에 가볍게 블로그나 커뮤니티를 통해서만 확인이 가능하다(그조차도 없는 서비스는 출시 정보로 대체했다).2015년 9월 다음카카오(현 카카오), 다음캘린더 서비스 종료.2017년 6월, SKT 썸데이 캘린더 종료(2016년 출시, 2017년 종료).2018년 12월, 네이버 타르트 종료.(네이버의 경우 오랫동안 유지 중인 '네이버 캘린더'가 있긴 하지만 사실 신규 '일정 관리 앱'을 실험적으로 출시했었다)위 3개 서비스는 다소 생소할 수 있지만 아래 쏠캘린더는 대부분 한번 정도 들어본 적 있으리라 생각한다.위 서비스들 중 가장 많은 사용자를 확보했던 쏠캘린더도 결국 2016년 가을 종료. (쏠캘린더는 다음과 카카오 합병 전 카카오에서 출시된 서비스라 다음캘린더와 쏠캘린더는 다른 서비스였다)위의 4개, 아니 3개 회사가 캘린더 서비스를 종료하게 된 이유는 각기 다를것이고, 공식 보도자료는 없지만 업계 관계자 및 당사자 분들이 남겨놓은 몇몇 자료들을 통해 소소하게나마 내막을 엿볼 수 있었다.다음캘린더 서비스 개발 비하인드 스토리SKT 모바일앱은 왜 거의 다 '단명'할까 네이버 타르트 - 연구 종료 일지결국 그렇게 국내 현 캘린더 시장은 구글 캘린더, (기존)네이버 캘린더, iOS 기본 캘린더, 삼성 / LG 등 안드로이드 내장 캘린더, 4개 캘린더가 4등분하고 있으며 그 외에도 다양한 커스터마이즈 캘린더와 아웃룩이 작은 포션을 차지하고 있다(물론 어디까지나 국내의 이야기로 나라마다 상황은 다르다).커스터마이즈 캘린더를 쓰는 대부분은 구글 캘린더 또는 iOS 기본 캘린더 서버를 연동해서 사용하기에 사실상 자체 캘린더 서버를 운영하는 기업은 구글과 네이버, 그리고 애플뿐이다. 그런데 또 iOS 캘린더 유저의 상당수는 구글 캘린더를 연동해서 쓰기에 여러모로 얽히고설키고 복잡한 시장이다. 아 원래 하려던 얘기로 돌아와서, 여하튼 카카오와 SKT가 시도하다 접었고 네이버, 구글, 애플이 꽉 잡고 있는 이 시장에,2017년 대학생 5명이 또 하나의 캘린더 기반 서비스를 들고 뛰어들었다.(그렇다. 그 얘기 하나 하려고 이렇게 글이 길어졌다.)이름하야 '받아보는 캘린더 - 린더'. 때는 바야흐로 2017년 1월, 졸업을 앞둔 대학생 5명이 학교 강의실에 모여 창업 아이템을 구상하던 그 시절, 공동창업자 중 한 명이 '일정'을 아이템으로 서비스를 만들어보자고 의견을 던졌다.당시 그는 몇 주 전 교내 '캠퍼스 CEO'라는 창업 수업에서 '일정 관리 및 추천' 기능을 가진 서비스 기획서를 과제로 제출했던 상황이었고 팀의 리더였던 나는 그 제안을 듣고 허탈하게 웃으며 "그런 건 구글이나 네이버가 하는 겁니다"라고 단칼에 거절했다(원래 형 동생이었던 우리 팀은 팀빌딩 시점부터 존댓말을 썼다).비록 나 또한 학생이었지만 다수의 공모전, 해커톤, 회사 근무를 통해 서비스를 출시해본 경험이 있었고 서비스의 기획, 개발, 출시, 마케팅, 운영까지 이어지는 프로세스를 몇 번 정도 겪어본 입장에서 또 하나의 '캘린더' 앱을 출시하는 건 미친짓이라고 생각했다(솔직히 이제와서 말하자면 아직 뭘 몰라서 그냥 하는 말이겠거니 했다).그런데 당시 그가 했던 말 한마디가 우리를 움직였다."그러니까 우리가 해야죠"그의 논리는 이러했다."구글이나 네이버가 할 정도의 아이템이니까 시장이 큰 건 이미 증명이 됐고, 근성과 패기, 실행력으로 그들을 이기면 되는 거 아닙니까? 그게 스타트업 아니에요?"그때 말렸어야 했다.그때 설득되지 말았어야 했다.그때는 몰랐다.'일정'이라는 분야를 기반으로 사업을 기획하고, 운영하고, 확장한다는 것이 이렇게 외롭고 힘든 일이 될 줄은.  앞서 언급한 바와 같이 해외 사례라고는 하나 같이 다 종료된 서비스밖에 없었고 국내 시장은 해외의 그 사례들을 몇 년 후 따라가다 종료되는 수준에서 그쳤다.그래서 우리는 판을 새로 짜기로 했다.우리가 만들고자 한 서비스는 캘린더를 기반으로 하거나, 캘린더처럼 생겼는데, 캘린더 앱은 아니어야 했다.캘린더의 메인 기능인 일정을 '입력'하거나 '수정'하는 기능은 다 빼고, 사이드 기능 중 하나인 '구독'을 핵심으로 뒀다.캘린더도 문제였지만 이미 포화된 앱 시장도 문제였다. 새로운 앱들이 하루에도 수십 개씩 출시된지도 모른 채 사람들의 기억 속에서 잊혀지고 있던 상황이었다.단순히 앱을 통해 돌파구를 찾기보다는, 다양한 판로를 찾아보기로 했다.몇 번의 시행착오를 거쳐,2017년 하반기 즈음 우리가 앞으로 가져가야 할 방향성이 명확해지기 시작했다.카카오, 네이버, SKT 같은 회사의 기라성 같은 업계 선배들이 몇십억을 쓰고도 캘린더 서비스를 종료할 수밖에 없었던 데는 분명 이유가 있었다.우리의 전략은 치밀해야 했고, 2017년 말 아래와 같은 3개년 로드맵을 구상하게 되었다.일정 구독 서비스 린더 - 3개년 로드맵(2017.12)(로드맵에 대한 자세한 내용은 https://brunch.co.kr/@five0203/33 에서 확인할 수 있다)위 로드맵을 바탕으로 지난해 하반기 출시된 모바일앱, 즉 관심 일정 구독 플랫폼:린더의 다운로드 수는 40만, MAU는 18만을 돌파했고 지금도 가파르게 상승하고 있다.  한 달에 린더를 통해 일정을 확인하는 횟수(PV)는 700만 건이 넘었고 린더 내 링크를 통해 웹사이트로 이동하는 전환 횟수는 하루 1만 건을 넘어서고 있다.지난 30일 간 약 10여 건의 광고 및 제휴 문의가 있었고 그중 몇몇은 실행으로 옮겨졌다.린더의 장점은 그동안 광고로만 인식되어오던 이벤트 정보들이 '유용한 정보'로 전달된다는 것이다.누군가에게는 광고인 일정이, 누군가에게는 정보가 될 수 있다는 이유로 린더는 사용자에게 '광고 없는 앱'으로 인식되고 있다.물론 광고의 비중이 올라갈수록 네이티브 광고마저도 거부감을 일으킬 수 있기에, 우리는 일정을 모아 놓치지 않도록 도와주는 최초의 목적을 지속적으로 잊지 말아야 한다.  광고 플랫폼 기업 DMC미디어가 발표한 '2018 DMC리포트 종합 보고서'에 의하면 광고를 의도치 않게 실수로 클릭한 사용자는 28.9%에 그치며, 사용자 10명 중 7명은 노출되는 광고에 관심 및 의도를 가지고 클릭하는 것으로 조사되었습니다.문자, 페이스북, 카톡 플러스 친구 등 기존 채널에 대한 피로도가 높아지고 있는 현시점에서 린더가 경쟁력을 가지게 된 이유는 캘린더 유형의 정보 전달이 현재까지 '유용한 정보'라는 인식이 강하기 때문이라 볼 수 있습니다.위에서 언급한 바와 같이 이미 다양한 유형의 수익모델을 준비 중인 린더이지만 보다 장기적 관점에서 서비스 가치를 보존하기 위해 노력해야만 하며, 서비스 수익화에 대한 사용자의 거부감을 '너무 빠르게' 증가시키지 않아야만 사용자 이탈을 사전에 방지할 수 있습니다.이는 우리가 발생시키고자 하는 수익의 총합이 사용자에게 전달되는 가치의 총합을 섣부르게 넘어서는 안된다는 것을 의미합니다.- 19년 3월 주주서한 중 -아직 우리의 목표 MAU에는 한참 미치지 못한 현 상황에서도 밀려드는 광고 제의를 보며, 팀을 최소한으로 유지하고 서비스 운영 비용을 낮춘다면 향후 서비스의 지속과 생존, 즉 ROI를 맞추어 나가는 것은 어렵지 않을 것 같다는 확신이 생겼다(물론 ROI를 맞추는 것과 BEP를 맞추는 것은 차원이 다른 얘기라 BEP를 달성하신 모든 회사를 진심으로 존경합니다).하지만 성장하지 않고 머무르는 조직은 도태하는 조직이기에, 우리 팀은 앞으로도 여러 무모한 시도를 멈추지 않을 계획이다.  "캘린더앱은 돈이 되지 않아요" 공식적인 투자 라운딩을 3주 전 처음으로 시작하게 됐는데, 작년까지만 해도 귀에 박히게 들리던 이 이야기를 올해는 단 한 번도 듣지 못했다. 애초에 중요한 건 돈이 되는 게 아니었다. 사람들에게 필요한 서비스를 만들고, 그를 통해 새로운 가치를 창출하는 것. 그게 우리가 해야 할 일이었다.다수의 불편함을 소수의 기술력을 통해 해결하며, 그것을 지속&확대하기 위해 수익을 만든다.돈은 수단이지 목적이 아니다.긴 글을 마치기에 앞서 우리의 시작을 잊지 않기 위해, 2017년에 남겼던 감성 페북글 하나와 최근에 진행된 린더의 기업 협업 사례 하나를 남겨본다.2017년 7월(법인설립 1달 후, 기보 대출 받은지 일주일 후), SKT 썸데이 캘린더, 여름 문자 서비스 종료 소회그로부터 약 1년 후인 2018년 10월, SKT NUGU 스피커 x 린더 - 데이터 협업 진행
조회수 1568

도도 파이터 제작기

안녕하세요. 도도 파이터의 개발과 시각 디자인을 각각 담당한 스포카 크리에이터 박준규, 박지선입니다.우선, 도도 파이터에 관심 가져주시고 참여해 주신 분들께 감사의 말씀을 드립니다. 도도 파이터는 저희의 당초 예상을 훨씬 뛰어넘는 71명의 제출로 마무리되었습니다. 많은 분의 참여 덕분에 이벤트를 무사히 마칠 수 있었다고 생각합니다.이 글에서는 도도 파이터의 기획 의도와 제작과정, 기술적인 디테일에 대해서 다루어 보려고 합니다.기획 의도저희는 파이콘 한국에 2015, 2016년에 이어 이번 2018년까지 총 세 차례 후원사로 참여하였습니다. 저희는 매번 코딩 컨테스트를 열고 있는데 2015년에는 코드 골프1, 2016년에 코드 난독화2이벤트를 개최했습니다. 저희는 지난 이벤트들을 통해 파이콘 참가자들에게 오락거리를 제공하면서 재능을 발굴할 수 있었습니다그동안 다른 후원사들도 여러 가지 훌륭한 코딩 컨테스트를 열었습니다. 저희들은 이에 고무되어 2018년 파이콘 한국 참가를 결정하면서 새로운 코딩 컨테스트 이벤트를 만들어 보기로 했습니다.저희는 이번 코딩 컨테스트의 목표를 아래 세 가지로 잡았습니다.바이럴 효과가 있을 것사람의 눈을 사로잡을 수 있어야 할 것접근성 있고 직관적인 규칙을 제공할 것위의 점들을 고려해 봤을 때 인공지능 대전 격투게임의 아이디어는 비교적 자연스럽게 도출되었다고 생각합니다.유저 대 유저가 직접 경쟁하는 방식은 코드 골프나 난독화처럼 주최 측이 취합해서 평가하는 방식보다 훨씬 버즈를 만들기 쉽습니다.대전 격투 게임이라는 틀은 30년 넘는 세월 동안 거의 그대로 유지되어 왔기 때문에 수많은 사람들에게 익숙합니다. 그리고 두 사람의 대결을 가장 직관적으로 표현할 수 있는 포맷입니다.게다가 저희는 귀여운 마스코트 캐릭터도 가지고 있습니다. 귀여운 마스코트 캐릭터들이 투닥투닥 싸우는 모습을 누가 그냥 지나칠 수 있을까요.익숙한 장르이기 때문에 게임의 규칙 역시 큰 틀을 잡는 데 어려움이 없습니다.이런저런 다른 후보들도 있었지만 이러한 이유로 격투 게임을 만들자는 합의에 다다랐습니다.게임 디자인하지만 격투 게임은 직관적으로 보이는 외양에 비해 파고들기 굉장히 복잡합니다. 현존하는 대전격투 게임들은 수많은 캐릭터가 등장하고 캐릭터별 성능 차이와 상성 관계가 존재하며 대응 전략도 전부 제각각이기 때문입니다. 저희는 이러한 요소를 전부 배제하기로 했습니다. 그런 것들이 대전격투 게임의 본질을 관통하는 특성은 아니기 때문입니다. 그것들을 전부 벗겨내면 남는 본질은 심리전입니다. 상대방의 플레이 전략을 파악한 뒤에 정보를 취합하여 액션을 취하는 것이 대전격투 게임의 알파이자 오메가입니다. 저희는 이 게임을 턴제로 설계했는데, 보통 실시간으로 이루어지는 대전격투 게임을 턴제로 설계해도 말이 되는 이유가 여기에 있다고 생각합니다. 턴제로 만들어도 대전격투 게임의 본질이 심리전이라는 대전제가 깨지지 않기 때문입니다. 저희는 인공지능 대전으로 심리전의 특징을 살릴 수 있을 거라 보았습니다.여러 가지 시스템을 고려했으나 게임 디자인은 최소화된 형태로 수렴했습니다.플레이어는 뒤 또는 앞으로 한 칸씩 움직일 수 있다.공격 방식은 펀치와 킥이 있는데, 펀치는 숙여서 피할 수 있고 킥은 점프해서 피할 수 있다.심리전이 성립하기 위해서는 최소한의 상성 관계가 만족되어야 합니다.상대방의 공격을 무조건 맞는 대신 받는 데미지를 절반으로 줄이는 방어 액션이 있다.때로는 리스크를 지지 않는 안전한 선택지도 제공하면 좋을 것입니다.그 외에 게임 디자인 과정에서 여러 가지 시행착오가 있었습니다.처음에는 캐릭터를 움직인다는 개념이 없었습니다. 두 캐릭터들이 같은 위치에 서서 싸운다기보다는 가위바위보를 하는 모양에 가까웠습니다. 그래서 캐릭터 이동 액션을 추가했습니다.그런데 스테이지 크기에 제한이 없었습니다. 플레이어가 무한히 뒤로 갈 수 있었는데 한 대 때린 뒤에 끝날 때까지 뒤로 도망가는 파훼가 불가능한 전략을 쓸 수 있었습니다. 스테이지 크기에 제한을 두는 방식으로 해결했습니다.원거리 공격, 대쉬, 필살기 등등 여러 가지 세부적인 시스템을 고려했으나 시스템이 지나치게 복잡해질 것 같았고 무엇보다 제때 밸런스를 조정할 자신이 없어서 포기했습니다.시스템을 이렇게 만들어 보니 상대가 근접하면 가만히 서서 공격만 하는 에이전트가 승리할 확률이 가장 높았습니다. 이를 방지하기 위해 최근 다섯 턴 간 취한 액션이 한 종류라면 데미지가 1/3, 두 종류라면 2/3만 들어가도록 페널티를 주었습니다.이 조치만으로는 방어/회피 없이 공격만 해도 이기는 문제를 해결하지는 못합니다. 따라서 방어/회피에 성공할수록 다음 번의 공격력이 강해지는 시스템을 추가하여 적극적으로 방어/회피를 하도록 유도하였습니다.저희는 데미지 계산 공식을 공개하는 것을 주저했는데, 구체적인 공식을 공개하면 제출물의 성향이 한쪽으로 쏠릴 것을 염려했기 때문입니다. 저희는 최대한 창의적인 솔루션이 많이 나오길 바랐습니다. 하지만 지금 돌이켜보면 구체적인 수치를 공개한다고 크게 바뀔 것이 있었나 싶기도 합니다.시각 디자인처음엔 격투 게임이라는 설정만 있었지만, 시각적으로 풍부하게 표현하기 위해 더 디테일한 기획이 필요했습니다. 그리하여 도도 파이터 만의 세계관을 만들어 풀어보기로 했습니다. 설정을 초반에 정하고 나니 캐릭터부터 모든 디자인이 술술 풀려갔습니다. 왜 게임을 만들 때 초반에 세계관과 시놉시스를 세세히 기획하는지 알겠더군요.원래 실제 도도새는 마다가스카르 동쪽에 있는 모리셔스 섬 해안가에 주로 서식한 것으로 추정된다고 합니다. 모리셔스 섬에 도도새가 모여 마을을 이루고 있는 모습을 상상했고, 그곳을 배경으로 도도 파이터가 펼쳐집니다.야자수, 뜨거운 햇빛, 맑은 바다. 그리고 자영업자가 많은 평화로운 도도 포인트 마을. 손님을 위해 더 좋은 매장을 운영하려면 체력은 필수. 각자의 방식으로 체력을 기르던 매장 사장님들이 최고의 체력왕을 고르기 위해 도도 파이터라는 대회를 개최하게 됩니다. 과연 체력왕 사장님은 누가 될까요?노을이 아름다운 모리셔스 섬에 숨겨진 도도 포인트 마을Lean하게 캐릭터 디자인하기짧은 시간 내 게임을 완성하기 위해서 그래픽 리소스 제작 비용을 줄여야 했습니다. (인력 서포트도 있었습니다3) 기존에 잘 정리되어 있는 디자인 리소스들은 이런 상황에서 특히나 빛을 발합니다. 파이터는 포포(도도새 캐릭터)로 한정하고 동작 디자인은 거의 통일하기로 했습니다. 또한, 게임 특성을 고려해 기존에 디자인되어 있던 반측면 조형만을 활용했습니다.다만 사용자간 구분이 필요하기에 각 캐릭터별 특색을 넣었습니다. 게임에 등장할 포포들은 매장 사장님이므로 격투게임에 등장하면 흥미로울 만한 업종에 계신(?) 포포만을 모셨습니다. 그리고 각 업종에 어울리는 패션 아이템과 구별되는 성격을 배합해서 총 3종의 캐릭터를 완성했습니다.도도 파이터 대회에 참가한 포포 사장님들스시 장인 포포: 철두철미한 성격으로 묵직하고 독특한 풍미의 시그니처 스시를 주 무기로 사용합니다.학원 원장 포포: 성실히 학생들을 지도하며 평소에 칠판 지우개로 팔근육을 단련해왔습니다.볼링장 사장 포포: 걱정이 많지만 볼링을 사랑하며 즐깁니다.도도 파이터에서 캐릭터는 총 9가지의 액션을 취할 수 있습니다. 기본 틀은 동일하지만 캐릭터별 특색을 넣는 것만으로도 단조로움을 없앨 수 있었습니다. 공격하는 무기는 잔인하기 보다는 귀엽고 웃긴 방향으로 해 산뜻한 분위기가 되도록 했습니다. 만약 스시 장인 포포가 칼을 들고 있었다면 게임 분위기가 살벌했을 것입니다.캐릭터들의 다양한 모습구현 상세서버서버는 아래의 소프트웨어 스택을 사용하여 구현하였습니다.파이썬 3.6Flask 웹 프레임워크PostgreSQL 데이터베이스SQLAlchemy 데이터베이스 라이브러리그 외에 설정 관리에는 settei, 데이터베이스 마이그레이션은 alembic 등 여러 오픈 소스 프로젝트를 사용하고 있습니다.이상은 스포카에서 사실상 표준으로 사용하고 있는 소프트웨어 스택이기 때문에 스포카 개발팀이 비교적 능숙하게 사용할 수 있습니다. 덕분에 3~4주 남짓한 짧은 기간 안에 완료할 수 있었습니다. 개발 당시의 급박한 상태가 그대로 드러나는 퀄리티긴 하지만, 소스 코드는 여기에서 받으실 수 있습니다. PR이나 버그 보고는 두손 두발 다 들고 환영합니다.프론트엔드게임의 프론트엔드는 Unity 엔진을 사용하여 개발하였습니다. Unity는 WebGL 타겟 빌드를 지원하는데, 이를 통해 웹 브라우저 위에서 실행가능한 WebAssembly 바이너리로 빌드할 수 있습니다.매칭 기록을 재생해주기만 하면 되는 간단한 부분이기 때문에 처음에는 런타임 바이너리 용량만 수 메가바이트에 달하는 거대한 게임 엔진을 쓰는 것이 내키지 않았습니다. HTML5 Canvas를 직접 써서 만들까 했지만, 생각보다 손이 많이 가고 제때 끝낼 자신이 없었습니다. 다행히 Unity로는 빠른 작업이 가능했고 절약한 시간만큼 애니메이션 효과와 시각적 완성도에 조금 더 시간을 투자할 수 있었습니다. 빌드 용량이 크긴 했지만, 결과적으로는 좋은 결정이었다고 생각합니다.배포 인프라도도 파이터는 Docker로 빌드되며, 스포카의 프로덕션 서비스에 사용되고 있는 AWS ECS 클러스터 위에 배포됩니다. 기존 인프라를 활용하여 추가적인 지출을 최소화할 수 있었습니다.지금에서야 말할 수 있는 사실이지만 도도 파이터는 파이콘 행사 중에도 미완성 상태였습니다. 여러분들이 도도 파이터에 참가하고 계신 와중에도 개발자는 부스 한구석에서 부리나케 작업을 하고 있었습니다. 급박한 과정에서 Docker와 ECS가 있었기에 빠른 배포가 가능했습니다.샌드박싱웹 앱 위에서 임의의 파이썬 코드를 실행을 허용하면 필연적으로 공격의 위협에 노출됩니다. 따라서 저희는 악의적인 코드가 실행되지 않도록 하는데 많은 노력을 했습니다.에이전트 스크립트는 메인 서버 프로세스와 격리되어 실행됩니다. 이때subprocess모듈을 사용합니다.스크립트는 바로 실행되지 않고 러너 안에서 실행됩니다.이때 러너에서는 스크립트가 다른 파일을 열지 못하도록__builtins__.open()함수를 지웁니다.러너 프로세스는 제한된 유저 권한으로 실행됩니다. 혹여나 다른 파일을 불러올 수 있는 가능성을 OS 레벨에서 차단합니다.보안상의 이유로 에이전트는 허용된 모듈만 불러올 수 있습니다. 러너에서는 스크립트의추상 구문 트리를 분석하여 허용되지 않은 모듈을 불러오는지를 검사합니다. 이때ast모듈을 사용합니다.러너가 참조하는 모듈을 에이전트 안에서 참조하지 못하도록sys.modules를 비웁니다.실수 또는 DoS로 스크립트가 무한 루프를 도는 상황을 방지하기 위하여 3초가 지나도 스크립트가 완료되지 않으면 프로세스를 강제로 종료하는 역할도 합니다.서버는 Docker 컨테이너 안에서 격리되어 실행됩니다. 만약 잘못된 코드로 인해서 서버가 죽는 상황이 생기면 ECS 클러스터가 자동으로 복원해 줍니다.가장 마지막으로, 모든 실행되는 코드는 기록을 남깁니다. 만에 하나 이 모든 보호 조치들을 우회한다고 하더라도 어떤 GitHub 아이디로 로그인해서 무슨 코드를 실행시켰는지 기록을 남겨서 사후에 추적할 수 있도록 하였습니다.느낀 점들무엇보다 대회 진행에 아쉬움이 진하게 남습니다. 참가자들을 여러 조로 나눈 것은 수시로 조를 배정하고 결승전 이전에 조별 우승자를 미리 선정하기 위함이었는데, 결과적으로 최종 제출 기한이 끝난 뒤에 조가 배정되고 결승 중계 현장에서 조별 우승자가 정해졌습니다. 이로 인해 결승 중계 진행이 많이 늘어졌던 것 같아서 아쉽습니다.참가자와의 소통을 위한 피드백 창구가 없었던 점 또한 아쉽습니다. 몇몇 참가자 분들께서는 직접 부스로 찾아오셔서 문의하시기도 했습니다. 생각하지 않은 것은 아니었는데 다른 시급한 작업이 우선이라 엄두를 내지 못했습니다.예상보다 참가자들이 많아서 결승전 중계 때는 시간이 많이 밀렸습니다. 플레이백 속도를 조절할 수 있는 기능을 넣었어야 했다는 아쉬움도 남네요.처음에 우려했던 밸런스가 붕괴하는 상황은 다행히 발견되지 않았습니다. 승리에 유리한 전략은 어느 정도 경향성이 있는 것으로 보이나 게임의 밸런스가 망가진 수준까진 아니라고 판단하고 있습니다.마치며여기까지가 장장 4주에 달하는 도도 파이터의 제작 후기였습니다. 후속 포스팅에서 이번 파이콘 한국 2018 세션에서 제출된 출품작들을 분석하고 어떤 참신한 코드가 있었는지를 알아보도록 하겠습니다. 읽어주셔서 감사합니다.특정 목적을 달성하는 프로그램을 가장 짧은 길이로 작성하여 겨루는 경쟁 게임입니다. ↩창의력을 동원하여 어떤 목적을 달성하는 코드를 가장 알아보기 어렵게 작성하는 경쟁 게임입니다. ↩디자인 서포트를 해주신 안정빈 디자이너에게도 감사를 표합니다. ↩#스포카 #기업문화 #조직문화 #개발자 #개발팀 #프로젝트 #후기 #일지
조회수 1091

안드로이드 색상 투명도

제 깃헙블로그 https://heelog.github.io/about/ 에서 동시에 포스팅을 진행하고 있습니다.개발 관련 글을 보기에는 블로그를 통하시는 것이 더 좋습니다!안드로이드에서 색상을 표현할 때는 #AARRGGBB 형태로 표현한다. 앞의 AA 자리에 16진수를 이용하여 투명도를 표현해줄 수 있다. 범위는 0~255이다.0%~100% 투명도 값  100% — FF99% — FC98% — FA97% — F796% — F595% — F294% — F093% — ED92% — EB91% — E890% — E689% — E388% — E087% — DE86% — DB85% — D984% — D683% — D482% — D181% — CF80% — CC79% — C978% — C777% — C476% — C275% — BF74% — BD73% — BA72% — B871% — B570% — B369% — B068% — AD67% — AB66% — A865% — A664% — A363% — A162% — 9E61% — 9C60% — 9959% — 9657% — 9456% — 9156% — 8F55% — 8C54% — 8A53% — 8752% — 8551% — 8250% — 8049% — 7D48% — 7A47% — 7846% — 7545% — 7344% — 7043% — 6E42% — 6B41% — 6940% — 6639% — 6338% — 6137% — 5E36% — 5C35% — 5934% — 5733% — 5432% — 5231% — 4F30% — 4D28% — 4A28% — 4727% — 4526% — 4225% — 4024% — 3D23% — 3B22% — 3821% — 3620% — 3319% — 3018% — 2E17% — 2B16% — 2915% — 2614% — 2413% — 2112% — 1F11% — 1C10% — 1A9% — 178% — 147% — 126% — 0F5% — 0D4% — 0A3% — 082% — 051% — 030% — 00참고한 블로그: 커피한잔의 여유와 코딩#트레바리 #개발자 #안드로이드 #앱개발 #인사이트 #경험공유 #꿀팁
조회수 1260

Humans of TODAIT : CTO 유병한을 만나다

어느 화창했던 3월, ‘Humans of TODAIT’ 의 첫 주인공인 투데잇 CTO 유병한을 만나봤습니다. 투데잇 핵심엔진인 그의 이야길 함께 들어볼까요?Q. 자기소개 부탁드려요.안녕하세요! 투데잇에서 CTO를 맡고 있는 유병한입니다. ‘SW 마에스트로’라는 과정에서 대표님과 좋은 인연이 되어 투데잇의 전신인 투데잇브레이커부터 지금까지 열심히 개발중입니다. 안드로이드분야에 관심이 많아서 시작하게 되었는데, 차츰 기술 스펙을 확장해 나가면서 서버개발부터 최근엔 iOS 개발까지 맡고 있습니다.Q. ‘꿈을 향한 오늘, 투데잇’ 이라는 슬로건처럼 CTO님의 꿈에 대해 들을 수 있을까요?제겐 두가지 꿈이 있는데요, 먼저 투데잇이라는 서비스 자체에 대해선 전국민 앱으로 거듭나고 싶어요. 기존 교육관련 산업에서 우뚝 솟을 수 있는 서비스가 되고 싶은데요, 공부하는 사람의 입장에서 처음부터 끝까지 도움을 줄 수 있는 서비스를 제공하고 싶어요. 그래서 ‘저 사람이 일하는 투데잇은 일하기 좋은 회사다!’ 라던가 ‘성장하기 좋은 회사!’라는 인식을 주고 싶어요! 여러사람들을 심쿵!하게 만들고 싶습니다(웃음)음.. 그리고 제 개인적인 꿈으론 진짜 언젠간 해보고 싶은건데, 다큐멘터리 내셔널 지오그래픽급의 사진작가가 되고 싶어요.이래저래 심쿵하는 사람이 되고, 심쿵하게 만드는 서비스를 제공하고 싶습니다.Q. ‘개발자’로서의 시작은 어땠나요?음 제가 처음부터 개발자가 되고 싶단 생각은 안했어요. ‘개발’과 인연의 끈이라고 되짚어본다면, 아마 어릴 적에 접했던 나모웹에디터로 홈페이지 만들기?였던 것 같아요.그리고 수시를 과감하게 버리고 제가 즐겁게 할 수 있었던 컴공이나 관련 학과로 찾다보니 지금의 과에 입학하게 되었어요. 대학교와서도 다양한 학교 수업 중 개발 관련 수업을 맛보면서 ‘아 이게 나한테 맞겠구나!’ 싶어서 본격적으로 공부했어요.(Q. 앗, 그럼 ‘개발자’라는건 갑작스러운 전환이었나요? )그렇다고 해서 아주 갑작스럽진 않았어요. 학생때 사진찍는걸 즐겨서 색감에 대한 거라던가 화면에서의 구도에 대한 이해같은게 높았거든요. 학과에서 배웠던 다양한 편집툴들이 지금의 UI 센스에 발판이 되지않았나 생각해요.어느 순간 하나가 쓸데없던 적은 없었던 것 같아요. 자그마한 순간순간들이 지금의 저로 만든 것 같아요.Q. 본인이 맡은 업무에 대해 어떻게 접근하나요?일단 맡은 분야에 대해서도 그렇고 제가 욕심이 좀 많아요(웃음) 내가 잘하고 싶은 욕심, 가지고 싶은 욕심이 여러 힘든 과정을 이겨낸 원동력이 아닐까 생각해요.Q. 예를 들면 어떤 경험이 있나요? 조금 더 자세하게 듣고 싶어요!음.. 아 이건 좀 비밀인데 중학교때 사진을 찍게 되었는데 보통 그냥 똑딱이카메라쓰던 시절이었거든요. 그런데 DSLR이 너무 가지고 싶어서 조르기도하고 한푼두푼 모으기도해서 결국엔 DSLR을 손에 넣었어요. 되게 사소한것 같지만 나름 원하는걸 얻어낸 뜻깊은 추억이죠. 뭐든 전문가처럼 해야겠단 욕심이 강한 것 같아요.(Q. 오.. 그런데 책상에 책이 되게 많이 쌓여있네요? )책을 쌓아두는게 사실 좀 최근 관심이 가진 프로그래밍 언어라던지 관심이 가는거 위주로 가져다 놓긴 했어요. 아이폰 관련 서적이 몇개 있는데, (이제 세달 정도) 레퍼런스로 많이 찾아보기 위해서 책들이 상시대기하고 있어요. 2–3권. 스위프트라는 언어를 배우면서 기존의 코틀린 자바 스크립트 등 다양한 관심이 생겨서 , 언어들에 대한 욕구가 좀 큰 요즘입니다~(웃음)Q. 일을 하다보면 힘든 순간도 많았을 것 같아요.힘든 순간은 매순간인것 같아요(하하) 그래도 진짜 엄청 힘든 순간이 있었는데 제겐 ‘아버지’가 되게 큰 힘이 되주셨어요. 아버지께서 목사님이시거든요. 평생 부산에서만 사셨던 분이 산골 깊숙히 들어와서 농촌교회를 준비하시면서 힘든 부분이 분명 클텐데도, 지금은 사회복지기관까지 운영하시는 걸 보면 정말 대단하신 것같아요. 홀로 타지에서 모든걸 감내하셨던 부분이, 그리고 하고자 하는 일에 대한 끊임없는 열정을 많이 배워요.그런 아버지를 보고 감명받아서인지 저도 모르는 사이에 창업가 마인드가 생겼던 것 같아요. “ ‘내’가 능동적으로, ‘내’회사를, ‘내’회사에서, ‘내’회사를 위해 일하는, ‘내’일을 한다. ”라는 생각 자체가 아버지의 영향을 많이 받지 않았나싶네요.음 그리고 역시나 빼놓을 수 없는! 우리 투데잇을 사랑해주시는 유저분들이 정말 큰 힘이되요. 실은 투데잇브레이커 당시에 제가 이일을 시작하게 된 이유자체가 ‘이 서비스를 사용하는 유저들이 있다’란 거였거든요. 제겐 그분들이 제 모든 이유인것 같아요. 제 스스로가 성장할 수 있는 이유, 투데잇이 인정받을 수 있는 이유, 그 모든 이유의 근간이라고 생각해요.Q. 항상 좋은 리뷰만 있진 않았을 것 같아요. 혹시 가장 기억에 남는 리뷰 있나요?되게 오래전 리뷰인데, 많이 부족했던 투데잇을 보고 ‘대체 언제쯤 기능 업데이트 되냐, 3D게임 만드냐’라고 하셨던 리뷰가 가장 기억에 남아요. 순간은 되게 기분이 상하면서도 점점 더 잘해내고 싶단 의지가 생기더라구요. ‘내가 3D게임 개발하는 것도 아닌데, 이정도라니. 더 개발 좀 열심히 해야겠다.’하구요. 지금은 그분께 감사하죠.그때 당시만해도 투데잇이란 서비스가 되게 부족했을텐데도 끊임없이 애정해주시면서 기다려주신 유저분 중 한 분이니까요.좋았던 리뷰들은 정말로 셀 수 없이 많아요. 저희가 매주 리뷰를 함께 공유하는 자리가 있는데, ‘성적이 올랐다는 리뷰’부터, ‘투데잇 덕분에 공부 스타일이 또는 생활 습관이 바뀌었어요’, ‘지금 수험생활을 하고 있는데 힘을 얻고 있어요.’ 그리고 ‘합격소식’까지. 진짜 큰 힘이 되죠. 제가 어떤 무형의 무언가를 하고 있단게 현실에서 드러난다는게. 그게 정말 큰 힘이 되요.Q. 나에게 ‘기술’ 이란?저는 아까 말씀드렸던 것처럼 욕심이 좀 많은 편인데, 그 중 제일 욕심 많은게 바로 ‘기술’이예요. 이 분야에서 전문가가 되기 위해서 하나하나 하면 하나를 깊게 파는 스타일이예요.그래서 다양한 분야의 기술을 심도있게 잘하고 싶은 욕심이 있었는데, 투데잇을 개발하면서 그런 욕심을 부릴 수 있는 기회가 주어졌어요. 당시만 해도 당장 없는 개발팀원 자릴 메우기 위해 열심히 욕심부렸던게 지금의 이 자리에 앉게되지 않았나 생각됩니다.제게 기술이란건, 기술 자체가 가지고 싶은 그 무언가예요. 끊임없이 욕심을 내서 계속해서 닿고싶은 그런 존재?(웃음)Q. 오픈소스활동에서 핫하다는 이야기가 있는데요~오픈소스 활동이 아주 거창하진 않아요. 아직은 걸음마단계 수준이죠. 음 처음엔 제가 필요한 오픈 소스를 사용하면서 발견한 에러나 버그 부분에 대해 피드백을 드렸어요. 되게 간단한 부분이었는데 그쪽에서 긍정적으로 받아들여주셨어요. 그런 상호 피드백이 오가면서 관심을 갖게되었습니다.제트브레인스라는 회사에서 근무하시는 분의 피드백을 받는 과정이 오픈 소스활동을 통해 서로 교류할 수 있단 점이 매력적이었어요.활동을 하게된 결정적인 계기는, 다른 회사에 다니는 친구와 함께 깃허브에 올리고 IOS 개발 커뮤니티에 올렸더니 반응이 핫하더라구요. 큰 이슈는 아니지만, 사람들이 긍정적인 피드백을 해줘서 즐거운 순간이었죠.앞으로도 작은것부터 하나씩 해나갈 예정이에요. 큰 규모의 기술은 아니더라도, 투데잇의 ANDROID/IOS에 필요한, 하지만 불편함을 해소해줄 수 있는 라이브러리나 툴들을 만들어나가려고 생각을 하고 있구요. 기존에 투데잇 안에서만 쓰던 걸, 조금씩 정리해서 공유해나갈 생각입니다.Q. 안드로이드 앱 개발을 하면서 소프트웨어 아키텍쳐에 관한 고민이 있다던데, 어떤 고민을 하고계신지 들어볼 수 있을까요?지금 저희 나름대로, 기존에 있던 MVVM, VIPER라든지 그런 아키텍쳐들을 많이 보고 차용을 해서, 투데잇에도 적용을 해나가고 있는 중이에요. 직접 해보니 학교에서 책으로 배운 “프로그래밍 구조가~” 나 “아키텍쳐 구조가~” 에 대해 필요성을 뼈저리게! 몸소 부딪혀가면서 느끼는 중입니다.개발을 하다보면, 사소한 버그나 문제점을 많이 발견하게 되는데, 이를 어떻게 미리 테스트할지 또 어떻게 검증할지에 대해 고민을 하고 있어요. 그런데 기존 소스코드는 각각 다른 기능을 하는 코드가 한데 뭉쳐있어서, 이걸 분리해서 테스트하기에 용이한 아키텍쳐에 대해 개선 및 적용해나가고 있습니다.또 안드로이드와 아이폰 버전을 개발 중인데, 각각 플랫폼에 종속적인 부분을 빼놓고 두 버전 모두 동일한 구조를 가지고 갈 수없을까에 대한 고민 중인데요, 이러한 고민을 함께 하실 분들이 오셨으면 좋겠어요. 이상적인 구조를 향해서 말이죠. (웃음)Q. 현재 일하고 있는 팀원이 7명이나 된다고!네! 대표님과 단둘이 끌어왔던게 엊그제같은데, 벌써 7명의 투데잇팀으로 구성되었네요. (웃음) 사실 제게 투데잇팀은 그냥 공기같은 존재예요. 같이 있을 땐 중요성을 모르다가도, 누구하나 자릴 비우게 되면 그 느낌이 진짜 오묘해요. 서로가 서로를 너무 당연하게 자리하고 있다고 느끼고 있어서요.언젠가 한번 기호형님(COO)이 자릴 비운적이 있었어요. 아직 일한지 1년도 채 안되는데도, 옛날 옛적부터 알고 있던 사람처럼 그때 그 공허감이 되게 크더라구요.사실 좋을 땐 다 좋죠. 중요한건 일하면서 분명 좋지 않은 순간이 올텐데, 이때 서로 어떻게 커뮤니케이션을 하느냐 인것 같아요. 부정적 피드백에 대해 받아들이는 자세가 우리 팀의 가장 메리트라고 생각해요.지금 팀원들은 일에 있어서 피드백이 오갈 땐, 감정적인 건 잠깐 내려놓고, 객관적으로 앞으로 더 발전 방향에 있어서 뭘 어떻게 해야할지를 생각하는 태도를 보이거든요. 이 부분에 대해 ‘서로 핏이 잘 맞는다’라는 문장이 딱 맞는 표현 같아요.그래서 전 “같이 있으면서 어색하지 않은 그런 사이”가 좋아요. 물론 시간이 지나면서 서로 맞춰가는거겠지만, 왜 그런거 있잖아요. 함께 일을 해도 계속해서 어색한 사람이 있고 조금 풀리는 사람이 있는거. 그런 점이 저희 팀의 메리트라고 생각합니다.Q. CTO의 입장에서, 같이 일하고 싶은 개발자는 어떤 사람인가요?당연한 거겠지만, 일단 서로 존중해줄 수 있는 사람이면 좋겠어요. 아무리 비즈니스라지만 서로가 서로에게 예의와 매너가 갖춰진 사람을 원합니다.업무적으론, 뭔가 새롭게 배우는거에 대해 두려움이 없는게 좋은 개발자의 기본 자세라고 생각해요. 그래서 바로바로 과감한 도전 정신이 있는 사람! 그리고 제게 없는 재능을 가져서 서로가 상호 보완해나갈 수 있는 파트너면 좋겠어요.Q. 지원하고 싶은, 지원을 생각하는, 이 글을 보고있는 사람에게 한마디 부탁드려요!“만약에 지원을 하신다면, 마음을 단단히 먹어야할겁니다.”초반만 하더라도, 스타트업에 대한 환상이 있었어요. 이상적인 모습, 장밋빛 회사생활만을 꿈꿨거든요. 언론에서 소위 말하는 ‘젊은 창업가!’의 그 이면엔, 장밋빛을 현실화 하기위해 매일매일이 고난의 길이란걸 잊지 않으셨음 해요. 스타트업이란게 자신의 한계를 확인하는 과정이기 때문에, 같은 출발선에서 함께 발전하기 위해 달릴 준비가 되신 분을 환영합니다.또 자기 나름의 미션이 있고, 그걸 회사의 가치 성장에 일치시켜 나가면서 함께 실현해나가실 분을 모십니다!우리의 이상을 위해 함께 이 현실을 헤쳐나가실 분을 찾습니다!#투데잇 #팀원소개 #팀원인터뷰 #팀원자랑 #기업문화 #조직문화 #개발자 #개발팀 #CTO
조회수 1309

Event-Driven Programming

Overview마이크로 서비스 사이의 결합도를 낮추고 비동기적인 문제들을 처리할 때는 Event-driven 아키텍쳐가 유용합니다. 이번 글에서는 AWS에서 제공하는 SNS Topic을 이용해 Event-Driven을 알아보겠습니다. Event-Driven Programming프로그램의 제어 흐름이 이벤트의 발생에 의해 결정되는 컴퓨터 프로그래밍 패러다임입니다. publish/subscribe (이하 pub/sub)메시징서버리스 및 MSA에서 안정성 및 확장성을 높이기 위하여 사용되는 비동기 서비스 통신 방법입니다. 게시된 메시지를 다른 시스템에 비동기적으로 전달하고, Topic을 구독하는 모든 구독자는 모든 메시지를 받을 수 있습니다. 특히 게시자는 누가 구독하고 있는지 알지 않아도 되고, 구독자도 메시지의 출처를 알 필요는 없습니다. pub/sub 메시징 기본 / 출처: AWS Compute BlogAmazon SNS Topicpub/sub 방식의 메시징 서비스입니다. AWS의 여러 서비스들이 SNS에 이벤트를 게시할 수 있습니다. SNS Event Publishers / 출처: AWS Compute Blog위의 그림과 같이 구독자는 게시자 서비스에서 트리거된 이벤트에 응답해 필요한 작업을 진행합니다. 예시로 Elastic Transcoder 서비스에서의 Topic을 활용해보겠습니다. 네 가지의 순서를 거칩니다.1. SNS 토픽 생성2. Elastic Transcoder 등록Optional 항목인 Notification 영역에서 상태별 이벤트를 설정할 수 있습니다. On Completion Event에 위에서 생성한 Topic을 선택해 이벤트를 전달받도록 설정합니다. 3. SNS Topic에 구독자로 등록트랜스 코딩이 완료 후 처리할 프로세스를 가진 Lambda 함수 생성하여 위에서 생성한 SNS Topic에 구독자로 등록합니다. 현재 SNS Topic에서 제공하는 프로토콜은 HTTP, HTTPS, Email, Email-JSON, Amazon SQS, Application, AWS Lambda, SMS가 있습니다.4. 서비스 간 이벤트 전달출처: AWS Compute BlogSNS Topic으로 이벤트를 제공하는 AWS 서비스 중 하나를 살펴봤습니다. 이를 이용하면 마이크로 서비스 간에 이벤트를 전달하고 서비스의 분리 및 확장에 유용하게 사용할 수 있습니다.Conclusion오늘은 SNS Topic을 이용한 Event-Driven을 알아봤습니다. 다음 글에서는 마이크로 서비스에서 사용할 수 있는 AWS 서비스들을 다뤄보겠습니다.참고Event-Driven Computing with Amazon SNS and AWS Compute, Storage, Database, and Networking Services글이상근 팀장 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 1103

원하는 대로 뭉치는 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 데이터팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발자 #개발팀 #인사이트 #경험공유
조회수 4968

소스코드 리뷰에 대한 짧은 이야기...

개발자와 개발 조직에게 소스코드 리뷰는 필수적이다. 팀간의 협업과 대화를 보다 원활하게 만들어 주는 매우 필요한 절차이다. 슬랙과 같은 협업도구가 명쾌하게 의미 있게 활용되려면 개발팀 간의 소스코드 리뷰는 필수적으로 수행되는 것이 좋다.매우 당연한 이야기이지만, 소스코드 리뷰는 거북하고 불편하고 어렵고 힘들다. 그럼에도 불구하고 필수적인 이벤트가 되어야 하는 이유가 너무도 많다. 개발자들에게 코드리뷰에 대한 이슈를 설득하고 실제 행위를 발생시키는 것은 정말 어려운일이다. 더군다나 뜬금없이 코드리뷰 이야기를 회사나 팀리더에게서 갑자기 듣는다면 개발자는 매우 불편해 한다. 그것은 매우 당연한 반응이다. 그러므로, 가능하다면 팀 세팅 초기 시부터 이 소스코드 리뷰 문화는 만들어질 수 있게 노력하는 것이 최선일 것이다.초기에 세팅된다면 그 후에 들어오는 팀원들은 자연스럽게 그 문화에 익숙해진다. 이런 일련의 작업들은 결국 조직과 팀의 단결과 협력, 향후 유지보수에 매우 긍정적인 효과를 준다.매우 당연하지만 개발자들은 팀에 소속되고 빠져나가기를 반복한다. 이를 두려워하지 않는 방법 중에 가장 먼저 선택할 수 있는 것이 바로 코드 리뷰라는 행위다. 인수인계와 유지보수를 위해서 소스코드 리뷰를 각 단계별에 배치해두고, 그 시간을 투자하는 것을  아까워하지 않도록 하자.그렇다면, 소프트웨어의 본체인 소스코드를 타인이 리뷰한다는 것이 왜 어려울까? 그것은 소스코드는 언제나 완성상태가 아니라는 점 때문이다. 개발자의 생각은 무언가 다양한 변화를 예측하고 있고, 그 상세한 준비를 담고 있다. 언제나 소스코드는 완성 상태가 아니라, 변화되어야 하는 시간의 축을 담고 있기 때문이다.하지만, 소프트웨어 품질이 중요한 현재의 시점에서 본다면, 코드 리뷰라는 행위는 정말 필수 불가결한 행위에  해당한다고 생각한다.이런 필수적인 코드리뷰는 그 형태와 범위에 대해서 팀 내부에 잘 정의되어야 한다.그래서, 보통 이 코드리뷰를 어떻게 할 것인가에 대해서 조직이나 담당하는 사람의 경우에는 명쾌한 판단 기준이 있어야 한다. 그러한 ‘판단기준’을 가져야만 명확한  리뷰될 수 있다.이를 두고, 디자이너에게는 크리틱(critique-비평)이 있고, 개발자에게는 코드리뷰가 있다고 정의한다.좋은 비평을 받고 좋은 리뷰를 하려면 다음의 3가지 원칙이 필수이다.1. 리뷰는 언제나 상호 합의가 되어진 상황에서 진행되어야 한다.2. 리뷰어의 해당 결과물에 대해서 객관성을 가지고 서로 인지해야 한다3. 개발자 자신의 작업물에 대해서 정말 객관적으로 바라볼 수 있는 작성가가 선정되어야 한다.특히, 소프트웨어 코드는 정량적인 검토와 정성적인 검토를 구분해야 한다. 이 영역의 구분이 모호해지면, 리뷰는 그 방향성을 상실하게 된다. 그중에 특히, 정량적인 검토와 기본적인 규칙들은 가능한 자동화하고, 소스 형상관리 도구에서 기본적인 것들의 규칙들을 지키도록 권장하여야 한다. 최소한 이 정량적인 것만 자동화하고  규칙화해도 소프트웨어의 품질은 급상승한다.하지만, 코드는 논쟁을 발생시키고, 어떤 것이 우선적인지에 대해서 서술하기 매우 어렵다. 이러한 점은 정성적인 부분에 대해서 검토할 때에 고민하자.코드리뷰의 정도는 어느 정도 해주어야 하는가?그 전부터 주목하는 개발 방법론의 추세는 ‘테스팅’을 주로 하고, SRS와 같은 요구사항에 집중하기 보다는, TDD와 같은 방법으로 완성 산출물을 높이는 방법을 현재에는 주로 사용하고 있다.그것은 과거에는 요구사항을 통해서 결과물이 완성되는 SI성 개발이 주로였다면, 현재에는 요구사항은 계속 변화하고 버그 없는 결과물이 중요시되는 테스트를 얼마나 더 집중적으로 하느냐에 따른 웹서비스의 시대이기 때문에 그 방향성은 시대에 따라서 변화를 많이 하였다. 그래서, 슬프지만, 당장의 성과물을 위해서라면 코드리뷰보다는 테스팅에 집중하는 것이 더 효율적이다. 빠르게 고속 개발하고 테스트를 통해서 버그를 찾은 다음 수정하는 것이 ‘특정 기능들을 나열하고 기능을 만족하는 소프트웨어’의 경우에는 테스트 주도 개발 방법이 가장 적합하다고 할 수 있다.물론, 이러한 방향성이나 전체적인 틀에 대해서는 아키텍트가 잘 결정하여야 한다. 내가 속한 개발 결과물이 어떤 결과물이냐에 따라서 이 방법은 혼용되어져서 사용되어야 하기 때문이다.하지만, 이번 글의 주목적은 코드리뷰. SRS중심이건, TDD중심이건. 코드리뷰는 중요하다는 것을 강조하고 싶다. 특히, 코드리뷰는 ‘기능 나열’이 아닌, 어느 정도 이상의 복잡도나 코드 품질이 필요한 경우에는 필수적으로 수행하는 것이 매우 현명한 행동이다.물론, 코드리뷰 행위가 불필요한 업무들도 많다. 정해져 있는 단순한 업무를 수행하는 경우에는 굳이 할 필요 없다. 국내에서 SI를 하는 경우에는 대부분 코드리뷰가 필요 없는 업무를 하는 소프트웨어 개발자들이 절대 다수인 경우도 많이 보았다.일반적인 SI의 형태라면 워크 스루의 형태만 적합하다. 특정 도메인에 매몰되어 있고, 처리방법이 명쾌하기 때문에, 해당 경험들을 교환하는 것으로도 충분하기 때문이다. 그리고, 자동화된 테스트 수행방법을 최대한 갖추어두는 것이 가장 현명하다.그러므로, 코드리뷰는 어느 정도 솔루션이나 서비스 등을 고려하고 있는 곳에서 더욱 적합하다고 정의한다.코드리뷰는 특정 제품이나 서비스를 발전적으로 지향하고 있는 경우라면 필수적으로 선택해야 한다. 하지만, 일부 제품의 경우에는 발전적인 지향이 굳이 필요 없는 제품 라인업을 가진 경우에도 굳이 수행할 필요 없다.그 경우에는 선택적인 코드리뷰를 지향하면 된다. 비용상의 문제 때문에 굳이 코드리뷰를 억지로 진행할 필요는 없는 경우도 많다. 대부분의 소프트웨어 개발은 테스트 케이스를 잘 만들고, 통과시키는 것으로써 충분한 신뢰를 가지면 충분한 경우가 대부분이다.특히, 시장이 고착상태이거나, 특별한 변화의 폭이 없다면, 그 정도로 충분한 경우가 된다. 다만, 글로벌 서비스나 웹서비스 등의 지속적인 확장이 필요한 경우라면, 코드리뷰는 필수라고 할 수 있다.코드리뷰가 필요 없는 경우 체크리스트는 다음의 5가지 정도를 체크해보자.1. 특정 도메인만 다루는 팀이나 회사의 개발팀인가?2. 지난 2~3년 정도 솔루션이 크게 변한 것이 없으며, 향후로도 기업이나 팀에서 투자가 없을 예정이다.3. 현재 개발자들이 해당 솔루션에 대한 개발일을 5년 이상하고 있다.4. 기능 위주의 SI성 업무를 주로 처리하고 있으며, 복잡한 알고리즘은 존재하지 않는다.5. 비용과 일정상 개발팀에게 리소스 투여가 불가능하다위의 사례에서 1개 이상이라도 체크된다면, 코드리뷰는 성립하기 힘들다. 대부분 단념하고, TDD나 테스트 케이스를 가능한 많이 축적하여 소프트웨어 품질을 올리기를 권장한다.코드리뷰가 필요한 경우의 체크리스트도 다음의 5가지 정도를 체크해보자.1. 다국어와 시장이 다변화된 환경에서 소프트웨어가 구동되어야 한다.2. 코드의 복잡도가 높으며, 단순 기능 나열의 요구사항이 아니라, 소프트웨어 아키텍처가 별도로 구성되기 시작하였다.3. 사용자의 경험성을 증가하기 위하여 매우 많은 변화가 예측된다.4. 현재 개발 중인 서비스는 중단 없이, 지속적으로 발전되어야 하는 서비스이다.5. 목표 요구사항이 계속 변화하고 있고, 프레임워크를 지향하여 소프트웨어 품질의 요구사항이 매우 중요하다.위의 케이스에서 하나라도 해당이 된다면, 코드리뷰는 매우 효과적으로 소프트웨어에 의미 있는 결과물들을 얻어 내기 위한 좋은 방법이 된다.하지만, 다음과 같은 경우도 같이 고려하여야 한다.코드리뷰의 정도와 질에 대한 검토 리스트의 최소 체크리스트는 다음의 3가지이다. 물론, 이 정의는 조직 내의 아키텍트나 아키텍트 롤을 하는 사람이 결정하는 것이 좋다.1. 실험적인 코드인가?2. 1~2명 이상이 공동으로 작업하는 코드인가?3. 향후 버려질 가능성이 높은 코드인가?코드리뷰를 하지 않는 경우에는 해당 코드의 repository나 디렉터리를 완전하게 분리하고, 리뷰가 안된 코드를 명쾌하게 구분할 수 있어야 한다. 그리고, 그 정보는 팀 전체에게 공개되어야 한다.가장 첫 번째는 코딩규칙 가이드라인의 준수 여부를 체크하는 것이다.개발자들 간의 상호 중요한 것은 스타일 가이드이다. 하지만, 정말 지키기 어려운 것 또한 스타일 가이드라고 할 수 있다. 하지만, 스타일 가이드는 가능한 준수해야 한다. 하지만, 100% 준수하려는 것은 매우 비효율적인 상황을 만들 수 있다. 하지만, 이 경우에 최소한 리뷰어가 제시하는 기준이나 변경 방향에는 대부분 수긍하는 것이 가장 현명하며, 이 부분은 해당 팀의 가장 경험이 풍부한 사람이 리드하는 것이 좋다.그래서, 소프트웨어 개발에는 경험이 풍부한 아키텍트의 역할과 선임의 역할이 가장 중요하다. 소셜에서 이야기하는 가장 중요한 포인트는 이런 경험이 풍부한 선임 개발자가 있다면, 돈이 얼마가 들더라도 ‘개발팀’에 모셔야 한다! 가 정답일 것이다.아직까지 이 부분은 ‘공학’으로 해결할 수 없고, ‘엔지니어링’과 ‘경험’에 의존할  수밖에 없다.주석의 경우에도 ‘가독성’이 충 부한 코드에는 서술할 필요 없다. 이 부분에 대해서는 꾸준한 팀원들 간에 코딩 문화에 대해서  커뮤니케이션하면서 주석의 범위에 대해서 공론화하는 것이 현명하다. 그래서, 소프트웨어 개발은 대부분이 ‘커뮤니케이션’이고 ‘소통’이다. 그래서, ‘팀워크’이 가장 중요한 것이고. 변수의 명칭에 대해서도 ‘명확’하다는 선에서 합의해야 한다.테스트가 쉽지 않은 구조는 다른 문제를 야기한다. Junit과 같은 단위 테스트 도구로 손쉽게 정의가 가능한 구조가 아니라면, 변경해야 한다.코드리뷰 후에 분명하고 타당한 지적에도 고집이 세서 변화가 없는 경우에는 한두 번 이야기하고 더 이상 변화가 없다면, 포기하고. 해당 코드를 격리하여 관리하는 것이 현명하다.  팀원들 간에 감정이 상하는 것이 더 위험하다. 사람은 변하지 않는다 감정에 대한 다툼이나 기대를 할 필요가 없다.UI가 중요한 코드는 해당 코드들이 급변할 가능성이 농후하다. 처음부터 공을 들여서 추상화를 실현하지 않으면, 해당 코드 때문에 프로젝트가 심각해질 수 있다. 사용자에게 더 좋은 경험을 전달하려고 하면, UI코드는 계속 변화를 일으킨다.테스트 코드 여부? 로직에 대한 검토, 변수 네이밍 검토와 레이아웃에 대한 것들? 에 대해서는 다음과 같이 판단하고 체크해보자.코드리뷰는 대부분 ‘직관’에 의존한다. 그래서, 정말 어렵고. 경험이 풍부한 사람이 할  수밖에 없다. 다만, 이러한 코드 리뷰 시의 체크리스트 항목을 몇 가지 간단하게 정리할 수 있다. 최소한의 2가지는 꼭 지키자.코드 리뷰 시의 필수 내용 두 가지는 다음과 같다.1. 코드 검토는 1시간 이내에 끝낼 분량으로 검토한다.2. 코드는 200라인 이상을 한 번에 검토하지 마라이 기준이 어겨지면, 리뷰어는 제대로 된 리뷰를 하기 어려울 것이다.  그리고, 이러한 리뷰를 하는 동안 기능에 대한 검토 체크사항에 대해서 나열해 보면 다음과 같이 나열이 될 수 있을 것이다.1. 시스템의 요구사항이 제대로 반영되었는가?2. 시스템의 설계의 규격대로 구현되었는가?3. 과도한 코딩을 하고 있지 않는가?4. 같은 기능 구현을 더 단순하게 할 수 있는가?5. 함수의 입출력 값은 명확한가?6. 빌딩 블록들( 알고리즘, 자료구조, 데이터 타입, 템플릿, 라이브러리, API )등이 적절하게 사용되었는가?7. 좋은 패턴과 추상화( 상태도, 모듈화 )등을 사용해서 구현하고 있는가?8. 의존도가 높은 함수나 라이브러리 등의 의존관계에 대해서 별도 기술하고 있는가?9. 함수의 반환(exit)은 한 곳에서 이루어지고 있는가?10. 모든 변수는 사용 전에 초기화하고 있는가?11. 사용하지 않는 변수가 있는가?12. 하나의 함수는 하나의 기능만 수행하고 있는가?또한, 스타일과 코딩 가이드에 대해서고 검토하고 리딩을 해야 한다.1. 코딩 스타일 가이드를 준수하고 있는가?2. 각 파일의 헤더 정보가 존재하는가?3. 각 함수의 정보를 코드에 대해서 설명하기에 충분한가?4. 주석은 적절하게 기술되어있는가?5. 코드는 잘  구조화되어있는가? ( 가독성, 기능적 측면 )6. 헤더, 함수 정보를 도구로 추출해서 자동으로 문서화할 수 있는 구조인가?7. 변수와 함수의 이름이 일관되게 기술되어 있는가?8. 프로젝트의 가이드를 통한 네이밍 규칙을 준수하고 있는가?9. 숫자의 경우 단위에 대해서 기술하고 있는가?10. 숫자를 직접 서술하지 않고, 상수를 사용하고 있는가?11. 어셈블리 코드를 사용하였다면 이를 대체할 방법은 없는가?12. 수행되지 않는 코드는 없는가?13. 주석 처리된 코드는 삭제가 되었는가? ( 버전 체크가 되었는가? )14. 간결하지만 너무 특이한 코드가 존재하는가?15. 설명을 보거나 작성자에게 물어봐야만 이해가 가능한 코드가 있는가?16. 구현 예정인 기능이 있다면, ToDo주석으로 표시되어 있는가?가장 중요한 아키텍처에 대한 검토를 잊으면  안 된다.1. 함수의 길이는 적당한가? ( 화면을 넘기면  안 된다. )2. 이 코드는 재사용이 가능한가?3. 전역 변수는 최소로 사용하였는가?4. 변수의 범위는 적절하게 선언되었는가?5. 클래스와 함수가 관련된 기능끼리 그룹화가 되었는가? ( 응집도는 어떤가? )6. 관련된 함수들이 흩어져 있지 않는가?7. 중복된 함수나 클래스가 있지 않는가?8. 코드가 이식성을 고려하여 작성되었는가? ( 프로세스의 특성을 받는 변수 타입이 고려되어있는가? )9. 데이터에 맞게 타입이 구체적으로 선언되었는가?10. If/else구분이 2단계 이상 중접되었다면 이를 함수로 더 구분하라11. Switch/case문이 중첩되었다면 이를 더 구분하라12. 리소스에 lock이 있다면, unlock은 반드시 이루어지는가?13. 힙 메모리 할당과 해제는 항상 짝을 이루는가?14. 스택 변수를 반환하고 있는가?15. 외부/공개 라이브러리 사용하였을 경우에 MIT 라이선스를 확인했는가? GPL의 경우에는 관련된 영역에서만 사용해야 한다.16. 블로킹 api호출시에 비동기적인 방식으로 처리하고 있는가?당연하겠지만, 예외처리 관련 체크리스트도 제대로 검토해야 한다.1. 입력 파라미터의 유효 범위는 체크하고 있는가?2. 에러코드와 예외(exception)의 호출 함수는 분명하게 반환되고 있는가?3. 호출 함수가 어려와 예외처리 코드를 가지고 있는가?4. Null포인트와 음수가 처리되는 구조인가?5. 에러코드에 대해서 명쾌하게 선언하고 처리하고 있는가?6. switch문에 default가 존재하고, 예외처리를 하고 있는가?7. 배열 사용시에 index범위를 체크하는가?8. 포인트 사용시에 유요한 범위를 체크하는가?9. Garbage collection을 제대로 하고 있는가?10. 수학계 산시에 overflow, underflow가 발생할 가능성이 있는가?11. 에러 조건이 체크되고 에러 발생 시 로깅 정보를 남기는가?12. 에러 메시지와 에러코드가 에러의 의미를 잘  전달하는가?13. Try/catch 에러 핸들링 사용방법은 적절하게 구현되었는가?요즘 프로그램은 대부분 이벤트성으로 구동되지만, 시간의 흐름에 대한 체크는 프로그램의 뼈대를 이루게 된다. 이 부분에 대해서도 제대로 검토해야 한다.1. 최악의 조건에 대해서 고려하였는가?2. 무한루프와 재귀 함수는 특이사항이 아니라면 없어야 한다.3. 재귀 함수 사용시에 call stack값의 최댓값이 고정되어 있는가?4. 경쟁조건이 존재하는가?5. 스레드는 정상 생성, 정상 동작하는 코드를 가지고 있는가?6. 불필요한 최적화를 통해서 코드 가독성을 희생하였는가?7. 임베디드의 경우에도 최적화가 매우 중요하지 않다면, 가독성을 더 중요하게 해야 한다가장 중요한 검증과 시험에 대해서도 제대로 인지하여야 한다. 그리고, 테스트를 위해서 가능한 최대한 자동화를 하기 위한 방법들을 이용해야 한다.1. 코드는 시험하기 쉽게 작성되었는가?2. 단위 테스트가 쉽게 될 수 있는가?3. 에러 핸들링 코드도 잘  테스트되었는가?4. 컴파일, 링크 체크 시에 경고 메시지도 100% 처리하였는가?5. 경계값, 음수값, 0/1등의 가독성이 떨어지는 코드에 대해서 충분하게 경계하고 있는가?6. 테스트를 위한 fault 조건 재현을 쉽게 할 수 있는가?7. 모든 인터페이스와 모든 예외 조건에 대해서 테스트 코드가 있는가?8. 최악의 조건에서도 리소스 사용은 문제가 없는가?9. 런타임 시의 오류와 로그에 대비한 시스템이 있는가?10. 테스트를 위한 주석 코드가 존재하는가?간혹 등장하는 하드웨어에 대한 테스트도  마찬가지이다. 다음과 같은 기준들을 통해서 검토해야 한다.1. I/O 오퍼레이션 코드에 대한 테스트로 하드웨어가 정상적인 동작을 보장하는가?2. 최소/최대 타이밍 요구사항에 대해서도 하드웨어 인터페이스가 충족하는가?3. 멀티 바이트 하드웨어 레지스터가 read/write오퍼레이션 중에도 값이 바뀌지 않음을 보장하는가?4. 시스템이 잘 정의된 하드웨어 상태로 리셋하는 것을 S/W가 보장하는가?5. 하드웨어의 전압이 떨어지거나 전원이 차단되는 경우에 잘 처리하는가?6. 대기모드 진입 시와 빠져나 올 때에 시스템이 옳게 동작하는가?7. 사용하지 않는 인터럽트 벡터가 에러 핸들러에 연결되어 있는가?8. EEPROM손상(데이터 깨짐)을 막기 위한 메커니즘이 있는가? ( 쓰기 동작 중 powe loss)등구체적으로 코드리뷰를 하고자 한다면, 다음의 코드리뷰에 대한 기법과 적당한 방법을 다음과 같이 설명할 수 있다.이러한 코드 리뷰를 위한 몇 가지 방법들이 알려져 있다. 그것들을 몇 가지 정리하여 보면 다음과 같다. 코드 인스펙션은 가장 정형화된 기법으로 전문화된 코드리뷰팀을 통해서 구분하는 방법이다. 이 방법은 리소스가 풍부하고, 일정에 여유가 있는 경우에만 사용이 가능하다. 대부분 대기업이나 대형 포털에서 구현 가능한 방법이라고 할 수 있다. ( 이런 곳에 있다면 행복해 하자. ~.~ ) 하여간, 비용과 일정 등이 있다면 이 방법이 현명하다. 그리고, 코드리뷰에 대한 품질에 대해서 정량적인 보고와 구성을 만들어 낼 수 있다는 것은 코드 인스팩션의 가장 좋은 장점이다. 이 코드 인스팩션을 하기 위한 롤을 구분하면 다음과 같이 4가지 롤로 구분할 수 있다.1. ModeratorA. 실질적인 매니저로 팀 간의 인터페이스와 리소스, 인프라를 확보하고, 프로세스에 대한 정의와 산출물의 정리를 담당한다.2. ReaderA. 각 산출물을 읽고, 리뷰하고, 방향성을 제시한다. 보통, 지식이 많은 사람이 담당한다.3. Designer/CoderA. Reader의 지시에 따라서 코드를 검증하고 잠재적인 발견 등의 수정 방안을 만든다.4. TesterA. 진행 중인 코드와 권장 수정 코드에 대해서 검증한다.그리고, 코드 인스펙션은 다음과 같은 6단계로 진행된다.1. PlanningA. 계획 수립2. OverviewA. 교육과 역할 정의3. PreparationA. 인터뷰와 필요한 문서 습득, 툴 환경 구축4. Meeting(Inspection)A. 각자의 역할대로 수행5. ReworkA. 보고된 Defect 수정6. Follow-upA. 보고된 Defect가 수정되었는지 확인이러한 절차를 통해서, 코드 인스팩션이 수행되면, 상당히 명쾌한 리뷰가 진행되게 된다. 하지만, 일정과 비용 문제 때문에 이 작업은 대부분의 스타트업에서는 선택하기 어렵다. 그래서 사용하는 방법 중의 하나가 팀 리뷰이다.팀 리뷰는 일정한 계획과 프로세스만 따르는 방법으로, 코드 인스펙션보다는 좀 덜 정형화된 방법으로 진행한다. 보통은 일주일에 한번 정도 팀 리뷰를 수행하거나, 특정 모듈이나 기능이 완료되는 시점을 기준으로 테스트 결과를 가지고 리뷰를 하는 방법을 사용한다.또한, 위험하거나 의견이 필요한 경우에도 팀 리뷰는 유용하다. 일반적인 팀에서 사용하는 방법이다.하지만, 이 역시. ‘리뷰’에 대한 제대로 된 인식이 없다면, 적용하기 어렵다. 그래서, 가끔 사용되는 방법이고, 과거 국내 SI업체들이 주로 사용하던 방법 중의 하나가 ‘웍쓰로’이다.웍 쓰루(Walkthrough)는 단체로 하는 코드 리뷰 기법 중에 비정형적인 방법으로, 발표자가 리뷰의 주제나 시간을 정해서 발표하고 동료들로부터 의견이나 아이디어를 듣는 시간을 가지는 방법으로써 주로 사례에 대한 정보 공유나 아이디어 수집을 위해서 사용하는 방법이다.이 방법은 ‘특정 도메인’에 종속된 코드를 만들거나, 비슷한 SI성 형태의 업무를 수행하는 경우에 적합하다. 그래서, 국내의 SI업체에서는 적극적으로 사용되면 좋겠지만. 이 ‘시간’마저도 부정확하고, 갑을병정의 SI체게에서 ‘정보공유’나 ‘아이디어 수집’과 같은 커뮤니케이션이 자유롭게 일어나는 것은 매우 힘들다.이 웍 쓰루는 동일한 조직 내에서 동일한 목적의식이 분명한 팀에서나 활용이 가능한 방법이다. 웍 쓰루를 SI에서 시도한 경우에는 대부분 실패했거나, 목적의식이 다르기 때문에 불분명한 결론들이 대부분 도출되었다.대부분의 국내 스타트업이나 IT 전문기업들은 ‘리뷰’에 대해서 상급 관리자들이 제대로 허락을 해주지 않는다.대부분은 팀내에서 어떻게든 자체적으로 해보려고 한다. 그래서, 팀장의 권한 선에서 적절하게 리뷰를 하는 방법 중의 하나가 Peer review or over the shoulder review방법이다. 이 방법은 보통 2~3명이 진행하는 코드리 뷰로 코드의 작성자가 모니터를 보면서 코드를 설명하고, 다른 한 사람이 설명을 들으면서 아이디어를 제안하거나 Defect를 발견하는 방법이다.또한, 이 방법은 신입사원이나 인턴사원의 경우에 업무 이해도를 높이면서 해당 코드를 사용할 수 있는 수준으로 활용할 경우에 의미 있는 방법이다. 문제는 이 방법은 개발자의 인력 투입이 거의 두배 이상으로 증가하는 것으로써, 고품질의 영역을 개발하거나, 빠른 시간 안에 신입 개발자의 업무 이해도를 높이는 경우가 아니라면 시행하지 않는다.이렇게도 리뷰가 진행이 되지 않으면, Passaroud는 돌려 보기 방법을 사용한다. 이 방법은 원래 상세한 리뷰 방법은 아니다. 온라인이나 실시간성이 아니라, 리파지토리나 이메일 등을 사용하여 천천히 리뷰하는 방식에 해당하는데, 속도는 느리지만, 중요한 코드이거나, 제품의 기능 개선이 필요한 경우에는 아주 의미가 있다. 보통은 제품의 기능 개선을 위하여 사용하는 방법이다.이처럼 리뷰의 방법에는 다양한 방법이 있지만, 결론적으로는 어느 정도 개발 조직이 서로  커뮤니케이션하고, 목적의식을 통일하고, 적절한 시간 분배를 통해서 리뷰를 할 수 있는 시간을 만들어 내느냐가 리뷰의 핵심이라고 할 수 있다.리뷰를 통해서 소프트웨어의 품질을  끌어올리고, 개발자들과 소통하고, 방향성을 만들어 내며, 새로운 기능 개선 작업을 위해서 리뷰는 다양하게 활용된다. 어떤 관점으로 리뷰를 할 것이고, 어떤 관점으로 리뷰라는 프로세스를 개발 프로세스에 탑재할 것인가에 대해서 진지하게 고민하는 것. 그것이 아키텍트의 첫 번째 역할 아닌가 한다.
조회수 1190

테이블이냐, 컬렉션이냐, 그것이 문제로다!(KOR)

편집자 주 외래어 표기법에 따르면 ‘원어에서 띄어 쓴 말은 띄어 쓴 대로 한글 표기를 하되, 붙여 쓸 수도 있다.’고 규정하고 있다.(제3장 제1절 영어의 표기, 제10항과, 컴퓨터 전문어, 전기 전문어 등) 즉 ‘원칙’과 ‘허용’이 모두 가능하다는 의미다. 이를 바탕으로 여러 표기 용례를 참고한 결과, TableView는 ‘테이블뷰(원칙)’로 표기해야 하나, 본문에서는 독자의 가독성을 높이기 위해 ‘테이블 뷰(허용)’로 표기한다. 응용하여, CollectionView는 ‘컬렉션 뷰’로, TableViewCell은 ‘테이블 뷰 셀’ 등으로 띄어 쓴다. Overview앱에서 데이터를 사용자에게 보여줄 땐 여러 가지의 모습으로 나타납니다. 설정 앱처럼 목록으로 보여줄 때도 있고, 사진 앱처럼 그리드(grid) 형식으로 보여줄 때도 있습니다. 이처럼 데이터를 보여줄 때 많이 사용되는 뷰는 테이블 뷰(UITableView) 또는 컬렉션 뷰(UICollectionView)입니다. 각자 특징이 있기 때문에 앱의 성격에 따라 적절한 뷰를 사용해야 합니다. 왜냐하면 목록을 보여주는 디자인을 바꿀 때, 다시 개발해야 하는 수고를 덜 수 있기 때문입니다. 이번 글에선 각각의 뷰를 간략하게 알아보겠습니다. 목록 형식의 설정 앱과 그리드 형식의 사진 앱 스크린샷테이블 뷰(UITableView)단일 열에 배열된 행을 사용해 데이터를 표시하는 뷰입니다. 수직 스크롤만 가능하며, 테이블의 개별 항목을 구성하는 셀은 테이블 뷰 셀(UITableViewCell) 객체입니다. 테이블 뷰는 이 객체들을 이용해 테이블에 표시되는 행을 그립니다. 여러 행은 하나의 섹션 안에 구성될 수 있으며, 각 섹션은 헤더(header)와 푸터(footer)를 가질 수 있습니다. 섹션과 행은 인덱스 번호로 구별하는데, 번호는 0부터 시작합니다. 테이블 뷰는 plain과 grouped 스타일 중 한 가지의 스타일을 가질 수 있습니다. Plain 스타일은 보통 목록 스타일입니다. 섹션의 헤더와 푸터는 섹션 분리기(inline separators)로 표시되고 스크롤을 할 때 해당 섹션 안에 있는 콘텐츠 위에 나타납니다. Grouped 스타일은 시각적으로 뚜렷한 행 그룹을 표시하는 섹션이 있습니다. 섹션의 헤더와 푸터는 콘텐츠 위에 나타나지 않습니다. 아래와 같은 사진을 보시면 확연히 차이를 볼 수 있습니다. plain 스타일의 연락처 앱과 grouped 스타일의 설정 앱테이블 뷰의 많은 메소드들은 인덱스패스(NSIndexPath) 객체를 매개변수 또는 리턴 값으로 사용합니다. 테이블 뷰는 해당하는 행의 색인 인덱스와 섹션 인덱스 값을 가져올 수 있게 인덱스패스의 범주를 선언합니다. 또한 색인 인덱스와 섹션 인덱스 값을 가지고 인덱스패스를 만들 수 있습니다. 특히 여러 섹션이 있는 테이블 뷰는 섹션 인덱스 값이 반드시 있어야 행의 인덱스 번호로 구별할 수 있습니다.override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> AttractionTableViewCell {         // Table view cells are reused and should be dequeued using a cell identifier.         let cellIdentifier = "AttractionTableViewCell"              guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? AttractionTableViewCell else {             fatalError("The dequeued cell is not an instance of AttractionTableViewCell.")         }                 let attraction = attractions[indexPath.row]                 cell.attractionLabel.text = "\(indexPath.row). \(attraction.nameWithDescription)"         cell.attractionImage.image = attraction.photo                 cell.attractionImage.tag = indexPath.row                 attraction.indexPath = indexPath                 ...                 return cell     } 위의 코드는 데이터 소스(data source) 메소드로, 테이블 뷰의 특정한 위치에 셀을 추가합니다. 다시 말해, 이 메소드는 테이블 뷰가 ‘표시할 새로운 셀이 필요할 때마다’ 특정 행에 노출할 정보가 있는 셀을 만들고 리턴하는 걸 말합니다. 매개변수로 필요한 셀 객체의 행을 가리키는 indexPath 값을 전달합니다. 그리고 indexPath의 row 값을 이용해서 attraction이라는 배열 인덱스로 활용하고, 셀에 표시할 정보들을 설정합니다. 여기서 attraction 배열은 관광 명소들의 정보들이 담고 있는 배열인데, 1행은 첫 번째로 저장한 관광 명소, 2행은 두 번째로 저장한 관광 명소 등 순서대로 설정하도록 indexPath.row 값을 이용하는 것입니다. indexPath의 row 값과 배열의 인덱스 값은 0부터 시작하기 때문입니다. 해당 예제는 섹션이 1인 경우이기 때문에 섹션 인덱스 값이 없지만, 섹션이 여러 개 있다면 반드시 섹션 인덱스 값을 이용해서 설정해야 합니다.테이블 뷰 객체는 데이터 소스(data source)와 델리게이트(delegate)가 필요합니다. 데이터 소스는 UITableViewDataSource 프로토콜을 구현해야 하고, 델리게이트는 UITableViewDelegate 프로토콜을 구현해야합니다. 데이터 소스는 테이블 뷰가 테이블을 만들 때 필요한 정보를 제공하고 테이블의 행이 추가, 삭제 또는 재정렬할 때 데이터 모델을 관리합니다. 델리게이트는 화면에 보이는 모습과 행동을 담당합니다. 예를 들어 표시할 행의 수, 사용자가 특정 행을 터치했을 때, 행의 재정렬 등과 같은 것입니다.override func numberOfSections(in tableView: UITableView) -> Int {         // #warning Incomplete implementation, return the number of sections         return 1     }      override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {         // #warning Incomplete implementation, return the number of rows         return attractions.count     } 위의 두 소스는 데이터 소스가 필수적으로 구현해야 하는 메소드입니다. 하나는 섹션의 개수를 리턴하고, 또 하나는 한 섹션 안에 있는 행의 개수를 리턴합니다.테이블 뷰는 수정 모드에서 행을 추가, 삭제, 재정렬할 수 있습니다. 각 행은 테이블 뷰 셀에 연관된 editingStyle에 따라서 추가, 삭제, 재정렬을 할 수 있는데, 예를 들어 editingStyle이 insert라면 추가하는 메소드를 실행하고, delete면 삭제하는 메소드를 실행합니다. 행의 showsReorderControl 속성이 true라면, 재정렬하는 메소드를 실행할 수 있습니다.// Override to support editing the table view.     override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {         if editingStyle == .delete {             // Delete the row from the data source             ...                 // delete rows and attractions and reload datas             attractions.remove(at: indexPath.row)             tableView.deleteRows(at: [indexPath], with: .middle)             tableView.reloadData()         } else if editingStyle == .insert {             // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view         }     } 위 소스는 editingStyle이 delete일 때 셀을 삭제하고 테이블 뷰를 다시 로드하는 기능을 구현한 것입니다.테이블 뷰를 만드는 가장 쉽고 권장하는 방법은 바로 스토리보드에서 테이블뷰컨트롤러(UITableViewController)를 이용해서 만드는 겁니다. 런타임에 테이블뷰컨트롤러는 테이블 뷰를 만들고 델리게이트와 데이터 소스를 자기 자신으로 할당합니다.컬렉션 뷰(UICollectionView)컬렉션 뷰는 테이블 뷰에서 할 수 있는 모든 것을 할 수 있습니다. 섹션을 가질 수 있고, 인덱스패스 값을 이용해서 셀을 구별합니다. 이 셀들은 컬렉션 뷰 셀(UICollectionViewCell)의 서브 클래스이며 데이터 소스(UICollectionViewDataSource)와 델리게이트(UICollectionViewDelegate)가 필요합니다. 셀을 추가, 삭제, 재정렬하는 기능도 구현할 수 있습니다. 그렇다면 컬렉션 뷰와 테이블 뷰를 구분하는 특징은 무엇일까요? 바로 레이아웃입니다. 컬렉션 뷰는 여러 개의 열과 행으로 셀을 표현할 수 있습니다. 예를 들어, 그리드(grid) 형태로 아이템의 목록을 보여줄 수 있습니다. 그래서 수직 스크롤뿐만 아니라 수평 스크롤도 할 수 있습니다.스토리보드에서 디자인한 테이블 뷰 셀과 컬렉션 뷰 셀위 스크린샷에서 테이블 뷰와 컬렉션 뷰의 가장 큰 차이는 바로 셀입니다. 테이블 뷰에서는 하나의 열에 여러 행을 표시하는 형식이기 때문에, 셀의 모습을 행에 맞춰서 디자인합니다. 하지만 컬렉션 뷰는 열과 행을 만들 수 있기 때문에, 꼭 행의 모습이 아니더라도 다양한 모습으로 셀을 디자인할 수 있습니다. 컬렉션 뷰 셀의 가장 큰 특징이기도 하죠. 위처럼 셀을 디자인하고 앱을 실행하면 아래의 화면이 나타납니다.테이블 뷰와 컬렉션 뷰의 앱 화면 차이또한 컬렉션 뷰는 레이아웃 객체가 있습니다. 기존에 제공하는 flow layout을 사용해도 괜찮지만, 본인이 원하는 레이아웃 모양을 custom layout을 만들어서 사용합니다. 이를 담당하는 프로토콜은 UICollectionViewDelegateFlowLayout 입니다.func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {         let fullWidth = collectionView.frame.size.width - (self.CGFLOAT_INSET_WIDTH * 3) - (self.CGFLOAT_ITEMSPACING * 3)         let width = fullWidth/3         return CGSize(width: width, height: width + self.CGFLOAT_HEIGHT_ATTRACTIONCELL_DEFAULT)     }         func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {         return UIEdgeInsetsMake(self.CGFLOAT_LINESPACING_VERTICAL, self.CGFLOAT_INSET_WIDTH, self.CGFLOAT_LINESPACING_VERTICAL, self.CGFLOAT_INSET_WIDTH)     } 위 소스에서 collectionView(:layout:sizeForItemAt:) 메소드는 해당하는 셀의 사이즈를 설정하고, collectionView(:layout:insetForSectionAt:) 메소드는 섹션 안에 margin을 설정합니다.여러 모양의 셀을 이루어 하나의 뷰 화면을 구현할 수도 있습니다. 섹션마다 셀을 만들어 각각 다른 모습의 셀을 설정하고, 한 화면에 다양한 모습의 셀을 가진 뷰를 만드는 것입니다. 예를 들어, 헤더, 메뉴, 본문, 푸터 각각 셀을 만들어서 원하는 모양으로 만들고, 하나의 뷰 컨트롤러에 셀을 조합해서 한 화면에 나타나게 할 수 있습니다. 이 방법을 사용하면 자주 사용하는 셀을 재활용할 수 있습니다. 똑같은 헤더와 푸터 셀을 여러 번 만들지 않고 기존의 셀을 재활용하면 시간도 절약하고, 훨씬 깔끔한 소스를 만들 수 있을 겁니다.브랜디 앱 스크린샷 일부위의 스크린샷처럼 여러 화면에서 보여줘야 할 똑같은 뷰가 있을 때, 셀 xib 파일을 만들고 컬렉션 뷰에서 셀을 섹션별로 설정 및 사용하면 재활용하기 좋습니다.Conclusion지금까지 테이블 뷰와 컬렉션 뷰의 특징들을 살펴봤습니다. 한마디로 정리하면 테이블 뷰는 가장 간단한 목록을 만들 수 있습니다. 컬렉션 뷰는 다양한 모습의 목록으로 커스터마이징(Customizing)할 수 있습니다.그렇다면 우리는 어떤 것을 선택해야 할까요? 구현할 목록이 얼마나 복잡한지에 따라 선택은 달라집니다. 테이블 뷰는 간단하고 보편적인 목록을 만듭니다. 반면에 컬렉션 뷰는 특정한 모습의 목록을 만들 수 있습니다. 그래서 테이블 뷰는 목록이 간단하고 디자인 변경이 없을 때만 사용하길 권장합니다. 하지만 나중에 디자인이 바뀔 수도 있다면 컬렉션 뷰를 사용하는게 더 좋겠죠.Simple is the best! 간단하게 구현할 수 있는 건 테이블 뷰를 사용합시다. 테이블 뷰에서 구현하기 힘들다면 컬렉션 뷰를 이용해 개성 있는 목록을 마음껏 만들어봅시다!참고UITableView - UIKit | Apple Developer DocumentationUICollectionView - UIKit | Apple Developer Documentation 글김주희 사원 | R&D 개발1팀[email protected]브랜디, 오직 예쁜 옷만#브랜디 #개발문화 #개발팀 #업무환경 #인사이트 #경험공유
조회수 2187

프로세스 마이닝과 AI를 통한 프로세스 혁신

지난해 이세돌과 알파고의 대결 이후에 인공 지능 (AI)과 기계 학습은 국내에서 많은 대중들의 관심을 얻어 중요한 추진력을 얻었으며, 모든 산업 분야의 기업들이 해당 기술을 빠른 속도로 계속 적용하여 사용하는 비중이 더욱 높아졌습니다. 실제로 Gartner는 2022년까지 스마트 머신과 로봇이 고학년 전문직 분야를 대체할 수 있을 것으로 내다봤으며, 심지어는 인공지능이 경영자 CEO도 대체 가능할 것인지에 대한 논의도 일어나고 있습니다. 이것은 사람이 과거 경험에 의해서 의사 결정을 내리 듯이 인공 지능도 확보한 데이터를 기반으로 의사 결정 모델을 만들 수 있다는 유사성에 기반합니다.  인공 지능에 의한 의사 결정은 사람한테 종종 있을 수 있는 감정이나 개인적 이해관계 및 관례에 의해 불합리한 판단에서 벗어나 데이터의 의한 객관적 판단을 할 수 있다는 장점이 있습니다.여기서 중요한 것은 인공지능이 학습하기 위한 “데이터”입니다.  지금까지 머신러닝이 막대한 이미지, 음성, 영상 데이터를 축적한 후 해당 데이터의 특징을 추출하여 패턴을 학습하여 자연어 처리 등을 통해 사람처럼 인식하여 분류하거나 상황을 판단하였듯이 기업 내 여러 가지 업무 활동에 머신 러닝을 적용하기 위해서는 이와 마찬가지로 관련 데이터가 필요합니다.제조 분야의 공정 관리, 공공 서비스, 물류 공급망 관리 등 전통적인 기업 내 업무 프로세스는 인공 지능에 의한 자동화과 효율화를 통해 혁신이 필요한 분야입니다. 기존에 외부 협력 업체로부터의 납기 예측, 소요되는 자재 인력 등 리소스 산정, 생산 스케줄, 장비 파라미터 입력값 등은 사람에 의해 수작업으로 진행 시 몇 주에서 수개월 소요되었지만, 인공 지능과 기계 학습 기반의 솔루션 도움으로 정확하게 지속적인 추세를 인식하고 인간의 개입 없이 데이터 중심의 결정이 가능해집니다.지금까지 기업 내 축적된 엄청난 양의 데이터를 활용하여 여러 산업 분야에서 숨겨진 패턴과 상관관계, 이상 징후 및 불량 탐지, 고객 수요 예측 등이 시도되었습니다. 하지만 이러한 시도들은 기업 내 문제 요인을 파악하여 우선적으로 어떤 부분에 초점을 맞추어 개선을 해야 하는지 알아야 하므로, 기업 경영 활동 전반에 걸쳐 돌아가는 판세를 읽는 노력이 필요합니다. 하지만, 기업 내에서 이뤄지고 있는 프로세스는 충분히 복잡하여, 개별 단위 작업의 전문가들은 존재하겠지만, 각 개별 부서, 구성원, 시스템 간에서 발생하는 다양한 상호작용과 이에 따른 예외 상황이 존재하여 이를 파악하기가 쉽지 않습니다.프로세스 마이닝은 데이터 기반의 프로세스 분석을 통해 문제 부분을 파악하여, 실제 인공 지능이나 머신 러닝을 적용하여 개선할 부분을 찾을 수 있도록 도와줍니다. 그리고, 프로세스 개선을 위해 머신러닝을 적용하기 위해서는 앞서 말한 것처럼 “데이터”가 학습될 수 있는 형태의 기반을 제공합니다.아래 그림과 같이 이벤트 로그를 기반으로 프로세스 모델을 생성하고, 수집된 패턴들과 각 분기 단계에서의 주요 성과 지표들을 디지털화하여 인공지능이 이해할 수 있는 형태로 축적합니다 이렇게 축적된 프로세스 패턴 데이터를 가지고 알파고가 최적화된 다음의 한 수를 예측하듯이 프로세스 마이닝은 인공 지능 기술과 결합하여 과거 프로세스에 대한 이해뿐만 아니라, 현재 시점에서 앞으로의 프로세스를 예측하여 합리적인 의사 결정을 도와줄 것입니다.#퍼즐데이터 #개발팀 #개발자 #개발후기 #인사이트
조회수 1983

나는 이쁜 데일리룩을 보고 싶은걸? \w pose estimation

안녕하세요. 스타일쉐어 백엔드 개발자 김동현입니다.2018년의 스타일쉐어에서는 뷰티, 중고 그리고 데일리룩이라는 피드가 추가로 등장했는데요, 그중 제가 작업했던 데일리룩 피드를 만들게 된 배경과 개발 방향에 대해 공유드리고자 합니다.스타일쉐어 데일리룩#데일리룩 #ootd / 타자 치는 것은 귀찮아데일리룩에 관련된 스타일들만 뽑아내는 방법 중에 가장 간단한 방법은 텍스트로 분리해내는 방법이었을 것입니다.하지만 #데일리룩 #ootd는 사진이나 내용이 관계가 없더라도 들어가 있는 경우가 많았습니다.또한 위의 피드처럼 정성스러운 글을 써주는 유저도 많긴 했지만 자신의 데일리 로그를 남기면서 글을 작성하지 않는 경우도 더러 있었습니다.즉, 단순히 텍스트로만 구별해내기에는 이미지에 대한 질을 확신할 수 없었고, 텍스트가 주된 서비스가 아니다 보니 설명 없는 좋은 이미지들이 많았는데요.우리는 이 이미지들을 놓치고 싶지 않았습니다.그래서 결과적으로 텍스트 대신 이미지를 사용하는 방향을 선택하게 되었습니다.이미지로 어떻게 구별해낼까?다행히도 R-CNN의 높은 인식률과 Pre-Trained 된 모델의 label 중 person이 이미 학습되어있던 터라 별도의 Transfer Learning 없이 이미지 내에서 body parts가 있는지 없는지 찾아내는 것은 아주 어렵지 않았습니다.다만 문제가 있다면 body parts에 들어가는 모든 부분을 person이라고 예측하던 부분이었죠.예를 들자면 아래와 같습니다.다음과 같이 제가 사용한 모델에서는 body parts를 person이라는 라벨로 처리하고 있었습니다.단순히 R-CNN의 person 라벨만을 믿기에는 의도했던 데일리룩 외에도 너무나도 많은 것들이 데일리룩이라는 이름으로 필터링될 것 같았습니다.그래서 또 다른 필터가 하나 더 필요하다는 생각이 들었습니다.Pose EstimationBody Parts 중 우리가 원하는 부분이 사진에 있으면 좋겠다!라는 생각을 곰곰이 하다 보니 우연히 머릿속에 스쳐 지나가는 하나의 장면이 있었습니다.Source: http://graphics.berkeley.edu/papers/Kirk-SPE-2005-06/바로 3D 모델링 중에서 Motion Tracker 에 관련된 장면이었는데요. 이것을 Tracker가 아니라 이미지에서 stick figure를 뽑아낼 수 있으면 되지 않을까?라는 생각이 들었습니다.놀라운 딥러닝의 세계에는 이미 여러 명의 Stick Figure를 뽑아낼 수 있는 경지에 도달해 있었습니다.Source: https://github.com/ZheC/Realtime_Multi-Person_Pose_EstimationPose Estimation 딥러닝 모델을 사용하여 아래와 같은 결과물을 얻어낼 수 있었는데요.이미지 내의 Body Parts의 존재 여부를 알게 되었으니 우리가 원하는 Body Parts가 이미지 내에 있는지 검사할 수 있게 되었습니다.하지만 해당 모델이 마냥 가볍지는 않았기에 사용자의 업로드가 많은 순간에는 예측 Task가 밀리기 시작했습니다.그래서 아주 단순하지만, 효과적인 아이디어들을 적용하였는데요.pose estimation을 하기 전에 R-CNN을 돌린 후 person으로 예측된 bounding box가 있다면 pose estimation 모델을 돌리도록 했습니다.하지만 위의 필터를 통했음에도 원하는 결과물이 안 나오는 경우가 종종 있었는데요.바로 다음과 같은 경우입니다.생각보다 작은 사람의 stick figure도 잘 추출 내어서 해수욕장으로 떠나 찍은 사진 속의 저 멀리 있는 휴양객을 데일리룩으로 잡는 일이 종종 발생했거든요.그래서 위의 조건에 더불어서 person이라고 예측된 bounding box size가 전체 이미지 크기 대비 n % 이상의 크기 일 경우 Pose Estimation을 진행하자는 것이었죠.적당한 크기 이상의 데일리룩들을 뽑아내고 싶었고 사람이 너무 작아서 안 보이는 경우도 피할 수 있었습니다.빠른 분류 속도는 덤이었고요.덕분에 유저들이 올린 콘텐츠 중 데일리룩이라는 범주에 속하는 콘텐츠를 잘 뽑아낼 수 있었습니다.아래는 위의 과정을 거쳐서 Pose Estimation까지 처리되어 데일리룩 사진이라고 판별된 이미지입니다.이다음으론 무엇을 더 해볼 수 있을까요?사진 속의 자세를 알 수 있게 되었으니 좀 더 재밌는 것을 할 수 있을 것 같은데요.예를 들면 K-Means를 적용하면 비슷한 모습의 데일리룩들만 모아볼 수도 있고 스타일쉐어 유저들이 자주 찍는 자세 라던가 유저 별 자세 선호도 등등 재밌는 것들을 할 수 있을 것 같습니다.날 따라 해 봐요 같은 것도 해볼 수 있겠네요 :)같이 해보지 않을래요?아직도 재밌는 것들이 많이 남은 스타일쉐어 에서는 더 많은 것을 하기 위해 개발자분들을 모시고 있습니다 :)백엔드 개발자라고 해서 백엔드 개발에만 국한되지 않고 하고 싶은 것들을 해도 된다, 할 수 있다고 이야기해 주는 회사라고 생각합니다.스타일쉐어를 좀 더 알고 싶으시다면 여기를 눌러 주세요 :)#스타일쉐어 #개발팀 #개발자 #백엔드개발 #개발인사이트 #경험공유 #후기
조회수 1079

블록체인 진짜 하나도 모르는 디자이너의 독학일기(2)

1편에 이어 2편을 작성하기까지 참으로 많은 시간이 걸렸답니다. 물론 내용이 어려워서 이해하는 데 시간이 걸린 것도 있고... 어려운 만큼 귀차니즘이 강해져서 미루고 미룬 이유도 있지요.1편에선 블록체인이 왜 발생했는가! 에 대해서 말했어용. 혹시라도 못 보신 분들은 링크를 타고 슝 한 번 더 보고 와주시면 좋을 것 같습니다.https://brunch.co.kr/@roysday/199짧게 줄이자면, 결국 신뢰의 문제 때문이예요. 내가 널 뭘 믿고??? 라는 명제죠. 단순히 너와 나의 사이뿐만 아니라 정부나 기업 등이 해커나 서버폭발 등으로 탈탈 털리는 일을 보면서 우린 두려워진 거예요. 은행을 믿을 수 있어?? 보험사를 믿을 수 있어?? 국민연금 겁나 떼가는데 나중에 받을 수는 있는거야?? 등등...그래서 우린 누구도 깰 수 없고 변하지 않고 삭제도 되지 않는 강력한 '장부'를 만들고 싶었던 거예요. 그래서 생각해낸 가장 좋은 방법이 바로 다수에게 뿌리는 거였죠. 하지만 우린 이런 궁금증이 생겨요. 다수라구??...누가 참여하는데?? 내 컴퓨터엔 블록체인 같은 게 없는데??사실 이 부분을 이해하기가 진짜 어려웠어요. 아니 페이스북에 투표참여나 주식시장같이 '내가 이걸 산다! 투표한다! 동의한다! 클릭~!' 이런 식의 동작이 없잖아요. 그런데 어떻게 내가 동의를 했는지 안했는지 내 장부에 뭐가 언제 어떻게 기록된다는 거야??....는 궁금증이 생기는 거죠.그래서 오늘은 이 과정을 쉽게 정리해보려고 해용 :) 혹시 틀린 부분이 있다면 꼭!! 댓글로 남겨주세요!!1. 컴퓨터에게 말을 걸어보자.지금 컴퓨터를 켜고 이렇게 외쳐보세요. "윙가르디움 레비오싸."네, 아무일도 일어나지 않았어요. 혹시 무슨 일이 일어나셨다면 소름이네요. 컴퓨터는 마법주문이나 우리의 감정이나 목소리나 표정을 인식하지 못해요.(물론 요즘엔 이걸 가능하게 만들고 있어요. 놀라워요. 하지마 마법주문은 좀 시간이 걸릴 것 같아요.) 일본은 일본어를 쓰고 중국은 중국어를 쓰고 스페인은 스페인어를 써요. 컴퓨터는 2진법을 써요. 얘네들은 0 아니면 1이라는 원시적인 언어를 쓰고 있어요. 물론 인간도 아주아주 오래전엔 2진법으로 언어를 말했어요. 쿼스랜드는 원시인들은 'a(아)'와 'o(오)' 만을 사용해서 숫자를 표현했다고 해요. 아, 오, 아오아, 오아오아..등으로 말이죠. 컴퓨터는 이처럼 0와 1로 이루어진 신호들을 통해 소통해요. 그러니 우리가 컴퓨터에게 말을 걸고싶다면 2진법으로 0과 1을 마구마구 적어줘야 해요.2. 컴퓨터의 언어를 만들었졍.근데 0과 1로만 말을 걸다보니 도대체 눈이 아프고 헷갈려서 너무 어려운 거예요. 그래서 규칙을 만들었어요.A = 100 0001B = 100 0010C = 100 0011D = 100 0100...이런식으로 알파벳이나 기호, 한글 등등을 컴퓨터가 이해할 수 있는 신호와 대응시켰어요. 그래서 나온 게 컴퓨터 언어죠. 오늘 날 코딩이라고 불리는 그것들은 결국 컴퓨터의 말로 이렇게해라 저렇게 해라 명령을 내리는 거예요. 컴퓨터는 그 명령에 의해 이런저런 일들을 처리해요. 이걸 누르면 = 저 페이지로 넘어가게 해.이곳을 채우면 = 다음 칸을 적을 수 있게 해.여길 클릭하면 = 파란색으로 바뀌게 만들어줘.등등 뭔갈 하면 = 결과가 등장하는 거죠. 신기하죠? 네 저도 신기해요. 이렇게 명령어를 입력하면 결과가 짜짠.3. 규칙을 만들 수 있게 되었엉.컴퓨터는 논리에 의해서 움직여요. 뭔가를 누르면 - 계산하고 - 0이면 안하고, 1이면 해요. 사실 되게 단순하게도 '한다/안한다' 로 명확하게 움직여요. 이렇게 명확하기 때문에 사람의 목숨을 담보로 하는 수많은 것들을 만드는 거예요. 비행기도 그렇고, 인공위성, 놀이기구, 자동차 등등... 컴퓨터가 기분따라 오늘은 왠지 일하기 싫어서 땡깡이나 부려버리면 그냥 다 죽는 거잖아요. (물론 가끔 파랗게 질려서 멍청댕청해질 때가 있긴 하지만...)결정장애가 없는 특성 때문에 컴퓨터는 한 번 규칙을 정해주면 그렇게 계속 움직여요. 이런 점에서 보면 인간과 컴퓨터의 가장 큰 특징 중 하나가 '갈등' 이 아닐까 싶어요. 결정장애가 있으신 분들은 엄청 인간적인 매력을 지니신 거예요. 블록체인은 '규칙'이예요. 변하지 않고 계속 그대로 움직이는 규칙이죠.규칙을 컴퓨터에게 명령하는 거예요. 이렇게 하면 이렇게 처리해!~ 알았지? 하고 명령하는 거죠. 이 코드(=명령어)를 누가 짜요? 그렇죠 그걸 블록체인 회사에 있는 개발자님들이 만드는 거예요. 그러니 어떤 블록체인 코드가 만들어지면 처음엔 그 회사 컴퓨터에만 있을 거예요. 4. 사람들을 모아보쟈.명령어를 만들긴 만들었는데, 여튼 이제 돈을 벌어야 하잖아요. 회사니까. 많은 사람들이 우리가 만든 블록체인을 이용해줬으면 좋겠어요. 그래서 사람들을 모아야겠단 생각을 했어요. 사람들에게 막 알리기 시작했어요.블록체인은 다수의 사람들이 이용해야 의미가 있어요. 꼴랑 2명만 쓰고있으면 그 중 한명의 컴터만 털어버려도 장부를 조작할 수 있잖아요. 하지만 수백, 수천만명이 블록체인에 참여하고 있다면 얘기가 달라지죠. 그 많은 사람들의 컴터를 한꺼번에 해킹할 순 없으니까요. 그래서 사람이 많으면 많을수록 블록체인은 튼튼해져요.5. 블록을 만들면 보상을 줄께!가장 단순하고 간단한 방법은 누군가가 블록을 만들도록 하는 거예요. 블록체인은 블록이 우르르르 붙어있다는 소린데, 그 블록이란 건 사실 눈에 보이는 택배박스가 아니라 손으로 적는 기록과 같아요. 롤링페이퍼 아시죠? 딱 그런 느낌인거예요. 돌아가면서 나의 기록을 블록으로 만들어서 열차놀이를 하는거죠. 그리고 블록을 만들면 그에 대한 보상으로 무언갈 주는 거예요! 대부분 그 보상이 바로 암호화폐와 같은 것들이예요. 우린 이걸 '채굴한다.' 라고들 하죠. 열심히 노동했으니 보상을 주는 거예요.6. 블록을 어떻게 만들어? 채굴!그럼 어떻게 블록을 만들까용. 음 생각해봐요. 누구나 그냥 노트북만 있어도 블록을 만들 수 있다면 물론 순식간에 블록들이 엄청나게 만들어져서 온세상 온누리에 우리 블록체인이 아름답게 꽃피긴 하겠지만....'보상'을 줘야하는 걸 생각해보면 소름이 돋을 거에요. 더군다나 화폐의 가치가 있는 것을 만드는 데 아무나 10초만에 만들 수 있다고 하면 이건 복사기에 지폐를 위조해서 그냥 마구 쓸 수 있는 것과 비슷해요. 그래서 블록을 만드는 과정은 어려워야 해요. 개발자들은 그래서 사람들이 엄청 고민을 해야만 풀 수 있는 문제를 명령어로 만들었어요. 그리고 그걸 풀면 블록이 완성되고 보상을 받는 거예요. 물론 종이와 펜으로 푸는 건 아니예요. 인터넷에 떠돌아다니는 '이거 풀면 아이큐150 이상임' 이런 문제와 비슷하긴 하지만....이건 사람이 직접 푸는게 아니라 컴퓨터가 푸는 거에요. 예전에 막 그래픽카드가 없어서 난리가 났다..PC방에서 그래픽카드만 훔쳐갔다더라..이런 뉴스가 한참 떴었잖아요. 맞아요. 마치 영화에나 나올법한 슈퍼컴퓨터같이 엄청나게 엄청난 컴퓨터들을 잔뜩 가져다놓고 계산을 시키는 거예요. 사람은 그냥 엔터만 누르고 가만히 있으면 돼요. 고생은 컴퓨터가 하니까요. 컴퓨터는 미친듯이 계산을 해요. 모터가 탈 정도로 고생을 하죠. 그리고 마침내 문제가 풀리면 짜잔!!! 블록이 완성되었어요!! 물론 블록이 완성이 되었는 지 어쩐지는 눈으로 보지 못해요. 하지만 문제가 풀면 블록이 생기도록 명령어를 짜놓았으니 생겼을 거예요. 컴터는 명확하니까요.(항상 이걸 전제로 해요.) 그리고 약속된 보상이 생겨요. 나에게 암호화폐가 뾱! 생겼어요. 빗썸이나 코인원같은 거래소에서 현금으로 바꿀 수 있도 있어요. 7. 쉬운 방법도 있어요.이렇게 수십대의 컴퓨터와 첨단 장비들이 있어야만 블록을 만들 수 있는 건 아니예요. 일반인들도 블록을 만들 수 있어요. 다만 쉬운 만큼 보상이 굉장히 작겠죠. 단순한 예로 '스팀잇'을 들 수 있어요. 스팀잇은 겉보기엔 브런치같이 그냥 주절주절 글이나 쓰는 플랫폼처럼 보이지만...사실 그건 훼이크예요. 스팀잇에 글을 쓰는 것 자체가 사실 블록을 만드는 것과 같아요. 그래서 그 보상으로 스팀을 주는 거예요. 그래서 정확히 얘기하면 '글을 쓰니 돈을 주더라!!' 가 아니라..'블록을 만드니 보상을 준다!' 가 맞는 거예요. 블록을 만드는 방식이 '콘텐츠' 일 뿐이죠.이처럼 블록을 만드는 방식은 결국 개발사가 정하기 나름이예요. 여행사진을 500장 올릴 때마다 블록을 생성하자! 라고 규칙을 만들면 그렇게 만들어져요. 그리고 보상을 받는거구요. 기부를 하면 블록이 만들어지게 하자! 라고 할 수도 있고하루에 1km씩 뛰어다니면 블록이 만들어지게 하자! 라고 할 수도 있어요.심지어 성인사이트에서 결제를 하면 블록이 만들어지게 할 수도 있어요. 실제로도 있더라구요.규칙은 만들면 되니까요. 그래서 다양한 프로젝트들이 만들어지고 블록체인 회사들이 각자 자신만의 방법으로 사람들을 모으고 있죠. 8. 하지만 사람들은 그 사실을 잘 몰라요.스팀잇에 접속해보신 분이 계신가요?? 사실 그곳은 능력자들 천지라서 다들 블록체인을 어느정도 알고 있는 사람들이 많지만.. 또 많은 사람들은 그런거에 상관없이 그냥 돈 준다니까 가입해서 글을 쓰고 있기도 해요. 사람들은 이게 블록인지 뭔지도 몰라요. 그냥 보상준다니까 열심히 뭘 쓰고 있는거에요.내가 블록을 만드는 걸 눈으로 볼 수도 없고 손에 잡히지도 않아요. 이 모든 건 그냥 컴퓨터가 처리하고 인터넷상에 떠돌아다니는 전기신호로만 존재할 뿐이예요. 우리는 겉으로 드러난 것들만을 보죠. 그래서 수많은 블록체인 회사들이 예쁘고 쉽고 접근하기 좋은 웹페이지를 만들거나 플랫폼을 만들어서 이런저런 활동을 하게 만드는 거예요. 사실 블록체인이 정말 널리고 널려서 이제 공인인증서 등등이 필요없어지게 될 지도 몰라요. 지금도 공인인증서는 폐지수순을 밟고 있고 은행의 인증절차도 간편해지고 있잖아요. 중요한 건 우린 그냥 '우왕 편하다~~' 라는 것만 인지할 뿐 이게 왜 편해졌는지는 관심이 없어요.맞아요. 우린 알게모르게 블록을 만들고 있을 수도 있어요. 당신의 컴퓨터에서 말이죠. 이미 당신은 블록체인에 참여한 거예요. 당신도 장부에 뭔가를 기록했고, 그 블록체인에 참여한 철수란 사람이 그 후에 또 뭔가를 적으면 당신의 컴퓨터에서도 그걸 인식할 수 있어요. 그래서 당신은 철수를 모르지만 당신의 컴퓨터는 철수를 알고 있어요.  이 때문에 P2P거래도 별 인증절차없이 이루어질 수 있는 거예요. 당신의 컴퓨터는 철수를 믿고있거든요. 정리해보면 블록체인은 규칙이예요. 코드로 이루어진 일종의 어떤 규칙이죠. 이걸 블록체인회사에서 만든다음자기들이 어느정도 지분을 가져가요. 자기들이 만들었으니 좀 가지고 있어야 할 거 아니예요. 주로 암호화폐의 형태겠죠.그리고 또 어느 정도는 채굴자들을 모아서 채굴을 시켜요. 대부분은 장비가 충만하신 전문채굴자님들이겠죠. 이 분들은 적극적으로 블록을 만들어내고 많은 보상을 가져가요. 이 때의 보상도 대부분 암호화폐겠죠.나머지는 쪼끄마한 우리들이에요. 우린 그게 뭔진 잘 모르지만 그냥 재밌으니까 막 활동을 해요. 그러면서 블록들을 만들어내요. 우리도 블록체인을 튼튼하게 만드는 역할을 해주었으니 일종의 작은 보상들을 받아요. 이것도 암호화폐겠죠.이렇게 블록체인에 참여하는 컴퓨터수가 많아지면서 블록체인은 더 튼튼해지고 견고해져요. 그리고 겁나 빠르고 편해서 많은사람들이 쓰게 된다면....그게 추후엔 어떤 핵심플랫폼이 될 수도 있겠죠?...다들 그걸 꿈꾸고 열심히 블록체인 코드를 만들고 있는 거예요.여기서 궁금한 게 생겼어요. 그럼... 이런 블록체인 회사들은 돈을 어떻게 버는 걸까요???.... 생각해보면 개발비용이나...홍보나 인건비나..얘네들도 돈이 필요할 텐데 당장 가상화폐는 돈이 안되요. 이제 갓 태어난 화폐는 가치가 거의 없을 거예요. 그러니 마구 가상화폐를 만들어서 팔아도 그건 의미가 없어요. 이분들의 수익은 도대체 어디에서 나는 건지 그게 궁금해졌어요.그래서 3편에선 블록체인 회사들은 뭐 먹고 사는건지 알아보도록 하겠어요 :)어휴 힘들어..이제 저도 규칙에 의해서 자야겠어요.새벽2시가 되면 = 잠을 자라.(규칙)

기업문화 엿볼 때, 더팀스

로그인

/