스토리 홈

인터뷰

피드

뉴스

조회수 1857

스켈티인터뷰 / 스켈터랩스의 잡학다이너마이트 변규홍 님을 만나보세요:)

Editor. 스켈터랩스에서는 배경이 모두 다른 다양한 멤버들이 함께 모여 최고의 머신 인텔리전스 개발을 향해 힘껏 나아가고 있습니다. 스켈터랩스의 식구들, Skeltie를 소개하는 시간을 통해 우리의 일상과 혁신을 만들어가는 과정을 들어보세요! 스켈터랩스의 잡학다이너마이트 변규홍 님을 만나보세요:)PART1. About Skelter Labs사진1. 스켈터랩스의 소프트웨어 엔지니어, 변규홍 님Q. 간단한 자기소개를 부탁한다.A. 이름은 변규홍. 스켈터랩스에서 소프트웨어 엔지니어로 일하며, 컴퓨터에게 열심히 한국어를 가르치고 함께 배우고 있다. 대충 20년 전부터 컴퓨터 공부를 시작해서 컴퓨터 관련된 일이라면 사족을 못쓰는 덕후이기도 하다.Q. 현재 스켈터랩스에서 어떤 업무를 맡고있는가.A. 스켈터랩스의 인공지능 대화 엔진 개발 팀인 헤르메스(Hermes)에서 흔히 ‘챗봇’이라 부르는 인공지능 대화 엔진을 만들고 있다. 우리가 만드는 인공지능 대화 엔진은 ‘챗봇을 만들고자 하는 사람들이 누구나 쉽게 챗봇을 만들도록 돕는 편리한 사용'을 목표로 한다. 때문에 비개발자도 이해하기 쉽도록 효율적이고 간편한 UI와 구조로 개발하고 있다. 거기서 나는 어떻게 하면 컴퓨터가 사람이 하는 말을 더 잘 알아듣고 잘 대답할 수 있는지 연구하고 있다. 어떤 처리를 해야하는지, 언어의 어떤 패턴을 인식하는지 등 ‘자연어 처리(Natural Language Processing,NLP)’ 혹은 자연언어처리라고 불리는 기술 전반에 대한 연구를 진행하고 있다.Q. 자연어 처리라는 부분이 생소하다. 언어의 분석이나 처리에 대한 얘기를 더 해줄 수 있나.A. 챗봇 위주로 설명해 보자. 우리가 한국어 문장을 컴퓨터나 스마트폰에 입력할 때, 특히 채팅할 때는 문장의 변화가 심한 편이다. 띄어쓰기를 실수할 수도 있고 급식체같은 축약어를 사용하기도 한다. 같은 의도를 담은 문장이 아주 다르게 표현되는가 하면, 비슷한 문장이 어순이나 표현 한 두 가지만 바뀌어도 전혀 다른 뜻이 되기도 한다. 이러한 인간의 언어를 컴퓨터가 잘 알아들을 수 있도록 분석하고 처리하는 것이다. 입력된 문장에서 어떤 부분이 명사고 어떤 부분이 동사인지를 찾거나, 문장 속에서 어떤 형태소에 집중해야 하는지 분석한다. 그리고 은행 계좌나 전화번호처럼 규칙에 맞는 숫자가 다양하게 입력될 수 있는 경우를 찾아내기도 한다. 이런 과정을 거쳐 사람이 어떤 의도를 갖고 입력한 문장인지, 어떤 정보가 담겨있는지 식별해낼 수 있다.Q. 들어보니 기술에 대한 지식뿐만 아니라 언어학에 대한 조예가 필요한 분야로 보인다.A. 맞다. 이 분야를 전산학(컴퓨터공학)에서는 ‘자연언어처리’라고 하고 언어학에서는 ‘전산언어학(Computational Linguistics)’ 혹은 ‘계산언어학’이라고 한다. 학제 간 학문으로서의 성격이 강한 분야다. 초창기에는 언어학자들이 찾아낸 인간 언어의 구조, 규칙을 컴퓨터공학자 / 전산학자들이 프로그램으로 구현하는 연구가 많았다. 그러다가 애초의 예상보다 인간의 언어 구조가 훨씬 더 복잡하다는 것을 인식한 이후부터는 인간의 언어에서 규칙성을 찾는 과정도 통계적 방법 등을 통해 컴퓨터의 힘을 빌리게 되었다. 최근에는 요즘 화두인 머신러닝 기법을 적극적으로 적용하면서 연구 트렌드가 조금씩 바뀌고 있다. 다양한 규칙에 따라 문장을 분석하기보다, 빅데이터로 정리된 방대한 언어생활 자료를 컴퓨터 스스로 학습하여 문장 속에서 필요한 정보를 찾아내는 식으로의 전환이랄까. 하지만 여전히 좀 더 좋은 결과물을 내려면 언어학에 대한 지식과 규칙성에서 찾아낸 정보들이 필요한 것도 사실이다. 그래서 스켈터랩스에서는 규칙 기반 기법들과 머신러닝 기법 모두를 하이브리드 형태로 결합하여 대화 엔진을 개발하고 있다.Q. 아무리 다양한 형태로 기법을 결합하여 사용하더라도, 엔지니어가 언어학에 대해 연구하기는 쉽지 않아 보인다. 언어학을 별도로 공부하거나 혹은 언어학에 대한 관심을 이전부터 가지고 있었는지.A. 언어학이라기보다는 사실 나는 대학교에서 문학 동아리 활동을 오랫동안 했다. 자연스럽게 다양한 활동을 통해서 문학에 대한 얘기를 하다 보니 언어에 대한 관심도 꽤 높았던 것 같다. 무엇보다 구글코리아의 번역기 개발팀에서 인턴을 하며, 컴퓨터로 인간의 언어를 다루는 것이 굉장히 흥미롭다고 생각했고 꾸준히 관심을 이어왔다. Q. 구글 코리아 인턴 경험이 규홍님에게 여러모로 지대한 영향을 끼친 것으로 알고 있다. 그 얘기를 듣고 싶다.A. 대학에 처음 입학했을 때, 사실 실망감이 더 컸다. 합리적인 의사소통은 막혀있었고, 당시 학교의 학사제도 개편으로 인해 여러모로 시끄러운 상황이었다. 그러던 차에 마침 학교에 구글코리아에서 캠퍼스 리쿠르팅을 왔는데, 선배 중 한 명이 ‘왜 구글은 한국에서 인턴을 채용하지 않습니까' 라고 꽤나 당돌한 질문을 던졌다. 그렇게 구글 코리아 인턴 채용이 열려 면접 기회를 얻게 되었다. 당시 내 이력서에는 대학교 입학 후의 경력이라고는 연극동아리 공연 이력이 전부였기 때문에 일종의 두려움도 컸다. 하지만 일본어로 된 만화책을 컴퓨터에 넣으면 한국어로 번역된 만화책이 튀어나오게 하고, 컴파일(COMPILE) 사의 게임 중 미처 한국어로 번역되지 못한 게임들을 컴퓨터가 알아서 번역해 즐길 수 있게 하는, 그런 컴퓨터 프로그램을 직접 만들고 싶다는 꿈이 더 컸다. 마침 나의 면접관들도 구글 코리아 번역기 개발팀 분들이었다. 그렇게 구글 코리아 번역기 개발팀 인턴으로 입사하게 되었고, 그때의 경험이 나의 꿈의 실현 가능성에 대한 일종의 확신을 주었다.Q. 스켈터랩스에는 어떻게 입사하게 되었나A. 인턴 할 당시의 구글 코리아 사장이 지금 스켈터랩스 창업자, 조원규 대표님이다. 그리고 구글 코리아 면접관이었던 분이 우리 팀의 테크 리더(Tech Leader)를 맡고 있는 이충식 님이기도 하다. 작년 충식 님으로부터 어려운 문제를 풀어야 하는데 같이 한번 풀어보자는 연락을 받았다. 그 문제가 너무 어려울 것 같아서 답장을 망설이고 있었다. 그러다 이전 직장에 대한 염증과 새로운 일에 대한 호기심 등의 마음으로 충식님을 다시 만나 뵈니, 스켈터랩스에서 내가 어렸을 적 꿈꾸던 챗봇을 만들고 계셨다.Q.  스켈터랩스에서의 업무는 이전에 일했던 혹은 알고 있는 다른 개발자의 업무랑 어떻게 다른가. A. 사실 인공지능을 기반으로 한 스타트업에는 뛰어난 사람들이 많은 것 같다. 그러나 스켈터랩스가 다른 회사와 다른 점은 ‘내 동료가 누구인가'에 대한 인식의 범위가 조금 더 넓다는 점이다. 가령 디자이너는 디자이너끼리, 기획자들을 기획자끼리만 협력하고 부서에 따른 책임이나 업무 범위에 대해서 선을 긋는 문화가 흔히 있지 않나. 어떤 직장들은 수직적인 위계 구조를 강요하고 모든 걸 서류로 보고하게 만들기 때문에 일의 효율이 떨어지기도 한다. 그러나 스켈터랩스는 팀 간에, 직무 간에 서로의 업무 영역을 자로 재듯 규정하지 않고 넘나들며, 좀 더 활발한 소통을 추구한다. 덕분에 ‘하나의 공동체'라는 인식을 자연스럽게 가질 수 있다. 서로와 함께 일한다는 것에 대해 우리 스스로 가지는 자긍심도 대단하다. 사내에는 지인을 신규 입사자로 추천하는 채용 제도가 있는데, 그간 내가 일해왔던 회사 중 우리 회사만큼 열심히 지인들에게 추천하는 회사도 없었다. 사실 내가 일하는 회사가 별로면 친구에게 추천도 못 하지 않겠나. 그만큼 서로 만족하고, 자부심을 가지고 일한다는 것을 방증하는 면모인 것 같다.또한 스켈터랩스는 불필요한 서류 업무를 배제하는 대신, 아주 엄격한 코드 리뷰 시스템을 가지고 있다. 내가 과거에 근무했던 회사들은 많은 경우 상대적으로 지금 당장 작동하는 코드를 만들어 내는 것에 집중했다. 물론 이러한 방식이 때로는 실용적이다. 그러나 기능이 잘 작동되는지만 살피다 보니, 숨겨진 버그(Software Bug)가 남겨지고 이것이 뒤늦게 발견되어 더 큰 문제를 일으키기도 했다. 때로는 버그의 존재를 코드 작성자만이 알고 있기도 했다. 이렇듯 단기간 눈앞의 기능에만 집중하다가 코드의 품질이 저해되는 방식으로 개발이 진행되어 언젠가는 다시 수정해야 하는 일거리가 남겨지는 것을 ‘기술 부채(Technical Debt)’라고 부른다. 스켈터랩스의 코드 리뷰 문화는 사소한 영역까지 기술 부채를 남기지 않는다. 궁극적으로는 짧은 기간 완성도 높은 프로그램을 만들 수 있게 해주는 문화다. 엄격한 코드 리뷰가 가능한 것은 스켈터랩스의 개발자 역량이 높기 때문이기도 하다. 개발자들이 모두 기술에 대한 근본적인 이해와 최신 기술에 대한 섭렵을 두루 갖추었기에 타인이 작성한 코드도 바로 이해할 수 있다. 수준 높은 동료와 함께 일하며 피드백 받고 성장할 수 있다는 것은 회사의 굉장한 강점이라고 생각한다.사진2. 규홍 님과 다른 팀원 간의 코드 리뷰 모습.Q. 코드 리뷰 문화가 유익하기도 하지만, 일종의 압박감도 있을 것 같다. A. 압박감으로 여겨본 적은 없다. 한국 사회에서 개발자의 커리어에 대한 얘기를 나누다 보면 자연스럽게 ‘회사 일을 하다 보니 공부할 시간이 없어서 최신 기술을 알지 못해 뒤처진다.'라는 볼멘소리가 나온다. 그러나 스켈터랩스에서는 개발자 모두가 엄격한 코드리뷰를 거치는 과정에서 자연스럽게 더 나은 성능의 코드, 동료가 더 잘 이해할 수 있는 코드, 예상치 못한 예외 상황을 고려하는 코드를 작성하는 법을 실시간으로 배우게 되고, 때로는 그 과정에서 자연스럽게 코드 리뷰자가 제안하는 최신 기술에 대해 공부하고 습득하며 실력을 늘려나간다. 덕분에 코드 리뷰를 마치고 나면, 다음에 어떻게 해야 개선된 코드를 짤 수 있을지에 더 집중할 수 있고 실제로도 더 나은 코드를 작성할 수 있게 된다.물론 이런 문화가 신규 입사자로서는 다소 답답할 수 있을 것 같다. 나 또한 초반에는 ‘굳이 이런 디테일까지 다 잡아가며 이렇게 리뷰를 남겨야 할까'라는 생각을 해본 적도 있다. 그러나 스켈터랩스와 함께하는 시간이 점점 길어질수록, 꼼꼼한 리뷰로 기술 부채를 최소화하는 것이 팀 전체에도, 나의 성장에도 도움이 된다는 걸 느낀다.Q. 아무리 뛰어난 개발자가 있더라도 코드를 작성하는 사람은 한 명인데, 이를 함께 리뷰하다보면 작성된 코드를 이해하지 못하는 경우가 발생하지는 않나.A. 물론 그럴 수 있다. 때문에 스켈터랩스에서는 코드의 공동 소유, 공동 이해 개념을 깊이 이해하고, 잘 지킬 수 있게 만든다. 나만 이해할 수 있는 코드를 작성하면 장기적으로 다른 개발자들의 수정과 응용이 어려워진다. 그래서 스켈터랩스에서는 각 프로그래밍 언어별로 코딩 스타일 가이드를 준수할 것을 권장하고, 코드 리뷰 이전에도 가이드 준수 여부를 점검하는 도구를 활용하고 있다.Q. 스켈터랩스를 자랑한다면.A. 스켈터랩스는 아직 성장 중인, 그래서 ‘함께 만들어 갈 여지가 많은 회사'다. 나는 개인적으로 대기업부터 창업 초창기 단계의 스타트업까지 다양한 회사를 경험했는데, 이러한 과정에서 구성원 한 명 한 명이 회사의 문화와 기술적 원칙을 만들어가는데 얼마나 큰 영향을 주는지를 느꼈다. 스켈터랩스는 다양한 배경을 가진 개발자와 서로 영감을 주고받으며 함께 성장해가는 곳이다. 개발자 직군의 동료들과 비개발자 직군의 동료들이 끊임없이 소통하며 시행착오와 함께 점점 더 나은 기업문화를 만들어가고 있다. 그리고 실제로 이런 문화가 완성도 높은 프로그램을 만드는 데에 긍정적인 기여를 하고 있고, 현재는 성공 경험을 조금씩 안겨주고 있는 단계다. 역량 있는 인재들과 최신의 기술을 활용하여 새로운 결과물을 창출하는 것에 관심 있는 이들이라면 입사를 추천하고 싶다.#스켈터랩스 #사무실풍경 #업무환경 #사내복지 #기업문화 #개발팀 #팀원인터뷰 #팀원소개 #팀원자랑
조회수 1910

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

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

[인공지능 in IT] 네가 내 마음을 알아?

지난 2018년 3월, 고용노동부는 10월부터 발효되는 '감정노동자 보호법 개정안'을 통과시켰다. 해당 개정안은 고객의 폭언이나 폭력으로부터 스트레스를 받는 감정노동자의 인권과 업무의 질을 개선시킬 사업주 조치를 의무화하는 내용을 담고 있다. 감정노동이란, 고객을 응대하며 자신의 본래 감정과는 상관없이, 업무상 정해진 감정 표현을 연기하는 것을 일상적으로 수행하는 노동을 말한다. 예로 콜센터, 백화점 안내, 텔레마케터 등이 있다.< 감정노동자 보호를 위한 5개 금융업법 개정안 주요 내용, 출처: 동아닷컴 >이제 정부는 감정노동자의 '적응 장애'와 '우울증' 등을 업무상 질병으로 인정한다. 세계보건기구(WHO)에서 정의한 건강은 '육체적, 정신적, 사회적, 영적으로 안녕한 상태'다. 즉, 감정노동자들은 육체뿐만 아니라 정신적, 사회적으로 고통받을 수 있다는 것이다. 그들은 자동으로 저장된 말을 내뱉는 음성 안내기가 아니고, 일반 사람들처럼 똑같이 울고 웃는 사람이다. 그렇지만, 아직까지 국내에서 심리상담에 대한 정서적인 장벽은 높고, 상담 받을 수 있는 인프라도 잘 갖춰지지 않다. 감정노동자들이 실질적인 상담 도움을 받기는 어렵다는 의미다.감정노동 소식 뒤, 국내 인공지능 기술 업체 중 한 곳이 심리상담 서비스를 출시했다는 기사를 접했다. 전문 심리 상담사들이 축적한 수많은 상담 시나리오 데이터를 수집하고 구축해, 개별적이고 정확한 서비스를 제공한다는 것이 취지다. 또한, 통화 목소리를 기반으로 이를 감정 데이터로 변환시켜 정신 건강에 대한 정보와 스트레스 관리 등을 위한 맞춤형 콘텐츠를 제공하는 것이 목적이다. 정확도는 알 수 없지만, 인공지능이 인간의 감정을 인지하고 생활에 도움을 줄 수 있다는 사실만으로도 큰 의미가 있다고 생각한다.사실 필자는 몇 년 전까지 매 순간 변하는 복잡한 인간의 감정은, 인간 고유의 것이라고 생각했다. 인간은 자신의 감정을 알지 못할 때도 있고, 긍정적인 감정과 부정적인 감정을 주체하지 못하기도 한다. 아직 우리 스스로 감정에 대해 확실하게 정의할 수 없고, 통제할 수 없다. 하지만, 그럼에도 불구하고, (앞서 언급한) 심리상담 서비스처럼 여러 분야에서 기계가 인간의 감정을 이해하고, 심지어 감정 표현을 돕는 연구는 거듭되고 있다.기계와 감정의 접목은 2000년대 이전부터 시작되었다. 1995년 MIT의 피카드(Rosalind Picard) 박사가 처음으로 감성컴퓨팅이라는 용어를 사용하며, 인간의 감성을 분석하고 해석하는 기술 개발을 시작했다. 감성 컴퓨팅은 인간이 느끼는 바를 인지, 해석, 처리할 수 있는 시스템을 설계하기 위한 인공지능 기술을 연구하고 개발하는 분야다. 감정 인식은 상상 이상으로 복잡하고, 아직까지 정확하게 구현하기 힘든 어려운 기술이지만, 조금씩 그 영역을 확장하며 다양한 분야에서 사용되고 있다.아무래도 사람의 감정을 드러내는 표면적인 수단 중 가장 눈에 띄는 것이 표정일 것이다. 얼굴에 드러나는 인간의 감정은 안면 근육의 움직임을 통해 여러 표정으로 나타나기 때문이다. 여기에 영상 처리 기술을 활용하면, 기계가 인간의 감정을 분류할 수 있다. 이를 기반으로 한 감정인식은 다음의 과정으로 이루어진다.먼저 영상이나 이미지 안에서 얼굴 영역을 찾는다. 일반적으로 스마트폰 카메라 앱에서 많이 볼 수 있듯, 네모 박스 형태로 얼굴을 인식한다. 그리고 해당 박스 안에서 눈, 코, 입 등 랜드마크라고 불리는 특징점들을 찾는다. 이어서 각 특징점을 바탕으로 각각의 위치나 배치를 파악하는 프로세스를 거친다. 마지막으로 학습을 거쳐 사람의 표정을 인식할 수 있다.일반적으로 감정 쪽을 연구하고 기술을 개발하는 업체 대다수는 이러한 딥러닝 방식을 적용한다. 그리고 미리 지정한 각각의 감정 메트릭에 사용자의 표정을 맵핑하는 식으로 결과값을 도출한다. 하나 주의해야 할 점은 표정과 비교하는 감정이라는 결과값을 '확률(%)'로 산출한다. 예를 들어, 눈썹을 찌푸리고 눈이 커지면서 입을 벌리고 있으면, 감정은 '화남 95%, 놀람 20%, 슬픔 5%...' 등으로 표현하는 방식이다.< EMOTION>이외에도 톤, 크기, 템포 등 감정 변화에 따라 변하는 목소리를 분석하는 음성 인식 기술이나 몸의 특정 움직임을 분석해 감정 상태를 인지하는 동작 인식 기술 등이 있다. 특히, 음성 인식은 CS(고객 응대) 영역에서 빛을 발할 수 있다. 실시간으로 고객의 감정을 분석해 소통방식을 바꾸거나, 그들의 구매 패턴을 예측하는 데 도움을 준다.최근에는 페퍼를 비롯한 가정용 휴머노이드 로봇이 여럿 출시되면서, 감정인식 기술의 적용사례를 쉽게 찾아볼 수 있다. 이들 로봇들은 인간과 대화할 때 억양이나 표정을 인식하며, 심지어 때로는 인간의 감정을 예측하고 묻기도 한다. 물론, 아직까지 우리의 머리 속에는 기계라는 생각 때문에 상호간 자연스러운 대화나 감정을 전달하기 어렵다. 하지만 문자, 음성, 시각 등 현재도 여러 영역에서 인공지능 기술은 발전을 거듭하고 있다.< 핸슨로보틱스(hansonrobotics)의 휴머노이드 로봇 소피아(Sopjia), 출처: 핸슨로보틱스 >인간의 감정이라는 것은 하나의 영적인 매개체가 아닌, 복합적인 것이다. 결국 각 영역별 인공지능 기술이 고도화될수록 감정 인식에 적용할 수 있는 기술 또한 정교해진다는 것을 의미한다. 언젠가는 기계가 인간의 말상대가 되어주고, 함께 어려운 문제에 대해 의논할 수 있는 단계까지 이르지 않을까? 감정 노동자의 마음을 어르고 달래는 로봇이 등장할지도 모를 일이다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 1647

워크인사이트 프론트엔드 개발환경

조이코퍼레이션은 오프라인 고객 분석 서비스인 워크인사이트를 만들고 있습니다. 워크인사이트는 스마트폰 신호를 통해 매장 방문객의 출입 및 체류 패턴을 측정하고 분석합니다. 분석된 데이터는 웹 대시보드를 통해 한 눈에 파악하기 쉬운 형태로 매장에 제공됩니다. 매장들은 이 대시보드를 보고 중요한 판단과 의사 결정을 내리기 때문에 대시보드는 보기 쉬워야 하고 쓰기 편해야 하며 무엇보다 아름다워야 합니다. 조이의 빅데이터 기술을 통해 분석된 데이터를 매장에 효과적으로 전달하기 위해 프론트엔드 기술에 많은 노력을 기울이고 있습니다. 이 글에서는 조이의 대시보드를 만들기 위해 사용하고 있는 기술과 개발 환경 그리고 기술적인 관점에서 고민하고 있는 부분들을 간략하게 공유하고자 합니다.그림1. 대시보드 화면사용하는 기술AngularJS: AngularJS를 기본 프레임워크로 사용하고 있습니다. AngularJS는 SPA (Single Page Application) 형태의 웹 애플리케이션을 빠르게 개발할 수 있도록 도와주는 MVC 프레임워크입니다. 조이에서는 현재 프로덕션 버전인 1.3.x를 사용하고 있습니다. 대시보드는 사용자의 이벤트에 따라 동적으로 데이터를 변경해야하는 애플리케이션적 요소가 많기 때문에 AngularJS의 양방향 데이터 바인딩의 유용함을 느끼고 있습니다.D3.js: 다양한 그래프를 아름답게 보여주기 위해서 D3.js를 사용합니다. D3.js는 데이터 시각화를 위한 자바스크립트 라이브러리로, HTML/CSS/SVG 등의 웹 기술을 이용해 그래프를 그릴 수 있습니다. 자유도가 매우 높아서 생각할 수 있는 많은 형태의 그래프를 그릴 수 있으며 부드러운 전환이나 애니메이션도 추가할 수 있습니다. 다만 초기 학습 비용이 높고 신경쓰지 않으면 너저분한 코드가 양산될 수 있다는 단점도 있습니다.CoffeeScript: 자바스크립트를 더 깔끔하고 효율적으로 사용할 수 있도록 Compile to JS 언어를 사용하는데, 여러 선택 사항 중 CoffeeScript를 사용하고 있습니다. CoffeeScript는 문법적 간결함 덕분에 타이핑을 줄이고 빠르게 코드를 작성할 수 있습니다. 특히 클래스와 클래스 상속 등을 문법적으로 지원하기 때문에 OOP적인 설계를 할 때 도움을 받았습니다. 하지만 자바스크립트와는 다른 새로운 문법을 익혀야하고 그마저도 일관성이 떨어지는 문제가 있습니다. 또 특별한 신경을 쓰지 않으면 가독성이 안 좋은 코드를 작성하기 쉽습니다. 조이에서는 Lint 툴과 코드 리뷰를 통해 코딩스타일을 엄격히 제한하고 있습니다.개발 환경빌드 및 배포: Bower와 npm(Node Package Manager)을 이용해서 패키지를 관리합니다. 빌드 시에는 JS Minify & Uglify, HTML/CSS 최적화, CoffeeScript Lint를 통한 코드 품질 검증, Karma를 이용한 테스트 수행 등의 과정을 거치며 이 모든 빌드 과정은 Grunt를 사용하여 자동화하고 있습니다. 빌드가 끝난 파일들은 AWS (Amazon Web Service)의 S3 저장소로 배포하고 있습니다. 배포 과정 역시 Grunt의 task로 자동화되어 있습니다.코드 관리: 모든 코드는 Jenkins로 통합되어 자동화된 테스트를 통과해야 합니다. 모든 커밋은Gerrit을 통해 다른 엔지니어의 리뷰를 거쳐야만 머지를 할 수 있습니다. 따라서 모든 코드는 적어도 둘 이상의 엔지니어가 이해하고 있습니다. 같은 코드에 대해 더 좋은 설계가 있는지 논의하면서 함께 코드를 발전시켜 나갑니다. 더 좋은 설계가 발견될 때마다 수시로 리팩토링을 진행합니다.프로젝트 관리: 디자이너와 엔지니어 그리고 기획에 참여하는 데이터 분석가 등은 Trello를 이용해 태스크와 이슈를 관리합니다. 일주일을 한 번의 스프린트로 보고 매주 월요일에 일을 분배하고 금요일에 회고를 합니다. 이 과정에서 엔지니어도 기획에 능동적으로 참여할 수 있으며, 어떤 데이터를 어떤 형태의 그래프로 보여주어야 효과적인지를 함께 고민할 수도 있습니다.그림2. 트렐로를 이용한 프로젝트 관리지속적으로 고민하는 부분성능 이슈: 대시보드에는 많은 수치 데이터를 다룹니다. API 서버로부터 하나의 큰 JSON 데이터를 받아서 시간별/일별/요일별/날씨별/최고기온별/평일휴일별 방문객 정보, 방문전환율/체류전환율/구매전환율 등의 지표를 그리기 위한 데이터로 가공합니다. 여기에는 계산량이 적지 않기 때문에 성능에 대한 고민을 많이 하게 됩니다. 연산 로직을 더 간단히 하거나 더 적게 Draw/Redraw 하는 방법을 고민하고 응답성을 향상시키기 위해 Async하게 연산하는 등의 고민을 합니다. 설계: 대시보드는 빠르게 업그레이드됩니다. 기능이 추가되고 변경됨에 따라 그에 맞는 좋은 설계도 계속해서 변합니다. 수시로 진행하는 리팩토링이 좋은 설계를 만든다고 생각합니다. 따라서 리팩토링에 쓰는 시간을 아까워하지 않습니다.테스트: 테스트는 매우 중요합니다. 특히 버그로 인해 잘못된 데이터가 보여지는 것은 용납될 수 없습니다. 그래서 데이터를 가공하는 로직에 대한 테스트는 엄격하게 수행됩니다. 설계 단에서도 테스트하기 쉬운 코드를 작성하려고 노력합니다.최신 기술: 조이의 프론트엔드 팀은 최신 기술에 민감합니다. Gulp, Angular 2.0, EcmaScript6, TypeScript, React와 같은 자바스크립트 최신 기술들에 관심을 갖고 그들의 기본 철학이나 장단점들을 파악하려고 노력합니다. 때때로 우리에게 더 잘 맞는 기술이 등장하면 과감하게 적용하기도 합니다.맺음말조이는 임베디드 기술과 빅데이터 기술을 보유한 기술 회사입니다. 그러나 프론트엔드 기술 역시 그 못지 않게 중요하게 생각하고 있습니다. 말뿐이 아니라 며칠 전에는 OKKY 자바스크립트 컨퍼런스에 후원을 하고 좋은 자바스크립트 개발자들을 만나기 위해서 부스를 차리기도 했습니다. 앞으로도 프론트엔드 기술 관련 컨퍼런스에 후원도 하고 기여도 계속 할 계획입니다.저도 조이에서 엔지니어로 일하면서 훌륭한 동료 엔지니어들과 함께 많은 성장을 했습니다. 무엇보다 기술적인 욕심과 의욕이 넘치는 분위기 속에서 일하는 것 자체가 즐겁고요. 혹시 이 글을 읽고 위와 같은 고민을 공유하고 폭풍 성장을 함께 할 멋진 자바스크립트 개발자가 있다면 이 글을 읽어보시길 바래요 :)그림3. OKKY 자바스크립트 컨퍼런스 부스#조이코퍼레이션 #개발팀 #개발자 #개발환경 #업무환경 #기업문화 #조직문화
조회수 2378

전산팀의 홍일점, 김민서 개발자

안녕하세요 써티입니다!벌써 4월 중순, 벚꽃 흩날리는 봄이에요.비욘드펀드는 오늘도 상품 두개나 오픈했어요!오늘의 인터뷰 주인공은전산팀의 홍일점! 김민서 개발자입니다.입사 4개월차 신입이지만맡은 몫을 완벽히 해내고 계신 민서님:)사내인터뷰를 거부하며 3주간 저를 피해다니셨지만............ 언주역 태양빌딩에서 나의 인터뷰를 피할 수 있는 자 아무도 없으리.재밌는 이야기 들어볼까요?1. 안녕하세요 민서님. 전산팀의 유일한 여자 개발자이시네요. 현재 맡고 있는 일을 간단히 설명해주세요.일단 전산팀은 부장님, 과장님, 대리님, 저까지 총 4명인데요. 저는 비욘드펀드 홈페이지 프론트엔드를 맡고 있습니다.2. 프론트엔드가 뭔가요? (역시 개발자 인터뷰가 젤 어렵;;)음….홈페이지 구성할 때 프론트엔드와 백엔드가 있는데요. 프론트엔드는 브라우저로 보이는 기능들을 만드는거고 백엔드는 프론트엔드가 기능을 제대로 할 수 있도록 해주는 거거든요. 지금 백엔드는 과장님이 하고 계시고요. 제가 하는 일은 사용자들이 비욘드펀드 홈페이지에 들어갔을 때 보이는 모든 것들이라고 생각하시면 됩니다.3. 여기가 첫 직장이시라고 들었어요. 어떻게 오게 되셨어요?비욘드플랫폼에 합류하기 전에 한국정보기술연구원(Kitri) 산하 학원에서 웹/어플리케이션 과정을 공부하고 있었는데요. 추천 채용이 들어와서 면접을 보게 됐어요.4. 그러면 전공도 공대쪽이겠네요? 혹시…. 공대 아름이?+_+여대였어요……………………(절망) (역시 여대나온 써티도 함께 웁니다)서울 모 여대에서 컴퓨터학과를 졸업했습니다^^5. 면접 보고 어떠셨어요? P2P금융이라는 산업에 대해서는 알고 계셨었나요?잘 몰랐어요. 금융회사의 개발자가 되라라고는 상상도 못했죠. 사실 스타트업에서 일한다는 생각 자체를 해본 적이 없어요. 아는 분이 스타트업에 다니셔서 제안을 받아본 적은 있지만 진지하게 고려해보지 않았었거든요. 항상 일이 많은 전산팀...... ㅠㅠ 태양빌딩 3층에서는 커피를 양손에 들고 전산실로 걸어가는 그녀의 모습을 종종 발견할 수 있다.6. 오, 그런데 비욘드플랫폼에는 합류를 하신거네요?처음에는 회사소개에 ‘카드론’, ‘대부업’ 같은 단어가 나오니까 걱정이 좀 됐었어요. 사실 아직도 P2P금융이 일반인들에게는 많이 알려져 있지 않잖아요. 더구나 저처럼 금융에 대해서 잘 모르는 사람들은 더더욱 들어본 적이 없고요. 친구들에게 ‘여기 어떤 것 같아?’라고 물어봐도 다들 가지말라고 하더라고요ㅎㅎ그런데 홈페이지 들어가보니까 깔끔한 분위기가 맘에 들었어요. 트렌디한 회사 같다는 느낌? 대표님도 삼일회계법인 임원 출신의 대단한 분이라서 믿고 입사를 하게 됐어요.7. 그래서 P2P금융에는 관심을 좀 갖게 되셨어요?아니요. 돈이 없어요ㅋㅋㅋㅋㅋㅋㅋ 농담이고요. 비욘드펀드 상품이 좋은건 알겠는데 개발자다 보니 솔직히 완벽히 상품을 이해하진 못했어요. 지금은 사회초년생이라 투자할만한 돈은 없지만 목돈이 생기면 P2P로 재테크해볼 생각입니다.8. 비욘드펀드가 이제 좀 커나가고 있는데, 어떤 회사가 됐음 좋겠어요?비욘드펀드라고 말했을때 ‘거기 믿을만하다!’라는 평을 들을 수 있는 그런 회사가 됐으면 좋겠습니다. (사내 복지 쪽으로는 아침을 주면 좋겠…)9. 일적으로 목표가 있다면?솔직히 아직 잘 모르겠어요. 그게 문제라고 생각하기도 하면서도… 이제 4개월차 개발자니까 한창 고민할 때라고 생각해요. 예전에는 모호하게 알던 것들이 이제 조금 구체적으로 다가와요. 점점 더 디테일하게 알아가면서 깊이 공부하고 싶은 부분들이 생기는 것 같아요. 일단은 비욘드플랫폼에서 주어진 일을 열심히 해나가는 것이 목표입니다.10. 마지막으로 민서님이 제일 좋아하는건?누워있는거요. 주말에 약속 잡는 친구들이 제일 싫어요. 완전 집순이거든요. 그래서 우리 회사 휴게실에 있는 영롱한 오렌지색의 이케아 빈백이 너무 탐나요. 나중에 사려고요.민서님이 좋아하는 휴게실 빈백(옆)에서 진행된 즐거운 인터뷰!요즘 비욘드펀드가 상품출시를 활발히 하다보니 민서님이 많이 바쁘신 것 같은데, 화이팅입니다:)#비욘드플랫폼서비스 #비욘드펀드 #개발자 #인터뷰 #팀원 #팀원소개 #팀원인터뷰 #사내문화 #조직문화 #기업문화
조회수 1465

린더를 만들고 있는 이유 2.0

본문은 2017년 8월 작성한 린더를 만들고 있는 이유 1.0 의 후속편입니다.히든트랙이 해결하고자 한 문제히든트랙팀은 '린더'라는 일정을 받아보는 경험을 만들어가고 있습니다. 2018년 4월 기준 약 16만명의 사용자가 린더를 통해 일정을 받아보고 있으며, 린더가 존재하기 전 사람들을 일일히 자신들이 필요로 하거나 궁금한 일정들을 검색하여 확인해야만 했습니다. 우리가 문제를 해결한 방식은 매우 간단합니다. 매번 필요할 때마다 검색해봐야 했던 일정을 우리가 대신 기록하여 그것을 받아볼수 있도록 제공 하는것, 다시 말해 다수가 공통적으로 안고 있던 귀찮음을 소수의 노력으로 해결하고자였으며 이와 같은 문제 해결 방식은 명함 수기 입력 앱 - 리멤버 또는 전단지 모음 앱 - 배달의 민족이 접근한 방식과 유사합니다.첫 번째 선택, 캘린더 기반 일정 구독 ( https://linder.kr/ )일정을 받아보는 경험은 모바일앱, 챗봇, AI 스피커 등 다양한 방식으로 구현될 수 있습니다. 그중에서도 히든트랙팀이 선택한 첫 번째 방식은 이미 다수가 활용중인 캘린더 앱의 구독 기능을 활용한 것입니다. 스마트폰 기본앱인 캘린더를 하나의 정보 전달 채널로 활용함으로써 거부감 없이, 낮은 진입장벽으로 출시 반년 만에 15만명이 넘는 사용자를 확보할수 있었습니다.캘린더 기반 일정 구독의 한계하지만 캘린더를 기반으로 한 일정 구독에는 명확한 한계가 몇 가지 있었습니다. 1) 구독 캘린더의 특성상 리마인더 기능이 매우 제한적이었으며  2) 각 플랫폼 별 다른 동기화 시간으로 인해 실시간 업데이트가 불가했습니다. 3) 또한 기존 캘린더에 입력되어있던 개인 일정과 받아보는 일정이 혼재되어 분류가 어려웠으며 4) 일정을 삭제하거나 메모를 입력할 수 없었습니다.캘린더의 한계를 극복할 수 있는 자체 앱 제작 ( http://bit.ly/2EB41TW )이에 히든트랙팀은 지난 2017년 말 진행한 다수의 유저 인터뷰를 바탕으로 2018년 1월부터 약 3개월 간 일정을 받아보는 경험에 최적화된 모바일 앱을 개발하였습니다. 모바일의 핵심은 필요한 일정을 정확한 시점에, 검색 없이도 쉽게 받아 볼 수 있는데 초점을 두고 있습니다.린더 : 받아보는 캘린더 - Google Play 앱play.google.com 일정을 받아보는 경험에 대한 사용자와 이해 관계자히든트랙팀이 캘린더 기반의 일정 구독자와 모바일앱 사용자 모두에게 공통적으로 제공하고자 하는 것은 사용자가 자신에게 필요한 일정을 보다 쉽고 확실하게 소비할 수 있도록 돕는 것입니다. 사람들에게 필요한 일정은 아이돌 스케줄부터 화장품 세일, 학사일정에서부터 마트 휴무일까지 다양한 분야에 존재합니다. 일정을 받아보는 경험을 만들어가는 과정에서 우리가 일반 사용자 외에도 고려해야 할 나머지 두 종류의 이해 관계자는 일정을 공급하는 공급 파트너와 유통을 돕는 유통 파트너가 있습니다.망하기 딱 좋은 일정 데이터 생산 비즈니스일정을 받아보는 경험을 만들어가는 과정은 여느 타 서비스에 비해 매우 소모적입니다. 일정 데이터는 리뷰(왓챠)나 댓글(크리마), 연락처(리멤버) 등 과는 다르게 데이터의 휘발성이 매우 강하며 변동성 또한 매우 크기 때문에 다수의 기업들이 기피하는 데이터 형태라고 볼 수 있습니다. 일례로 2016년부터 2017년 중순까지 운영되었던 SKT의 Someday(썸데이)는 내부 조직장 교체와 비효율적인 ROI로 서비스가 종료된 바 있습니다.같은 실수를 저지르지 않기 위한 일정 데이터 서비스 전략 로드맵히든트랙팀은 2017년 1월부터 다수의 일정 관련 서비스 개발을 진행해왔으며 이 과정에서 습득한 노하우를 바탕으로 일정 데이터 생산 및 공급망을 구축할 수 있는 3단계 계획을 세우게 되었습니다.STEP.1 린더 파트너스 - 데이터 공급 파트너 확보캘린더 기반 일정 마케팅 솔루션 '린더 파트너스'는 해외 eCal, CalendarX, Eventable 등 다수의 캘린더 마케팅 업체를 벤치마킹하여 국내 인터넷 환경에 맞추어 최적화시킨 아시아 유일의 캘린더 마케팅 솔루션 입니다. 2018년 3월 기준 롯데자이언츠, 두산베어스, 수원삼성FC, 아디다스 코리아 등 20여 개의 데이터 공급 파트너를 확보한 린더 파트너스를 기반으로 히든트랙팀은 공식적인 데이터 공급 파트너를 확보함과 동시에 데이터 생산을 위한 초기 자본을 조달할 수 있게 되었습니다. 파트너스 영업은 현재 영업팀을 주축으로 이루어지고 있으며 2018년 말까지 현 20여 개의 파트너를 50여 개 수준으로 늘리는 것을 목표로 하고 있습니다.STEP.2 린더 모바일앱 - 일반 사용자 확보린더 파트너스를 통해 확보한 자금과 일정 생산력을 바탕으로 모바일앱 데이터의 정확도와 품질을 향상하고 사용자 중심의 서비스를 구축합니다. 기업 친화적인 린더 파트너스와는 다르게 린더 모바일앱은 오로지 일반 사용자를 위한 서비스로서 사용자 친화적인 인터페이스와 일정 콘텐츠 소비 경험을 핵심으로 합니다. 다수의 일반 사용자를 확보함으로써 제보 기능(크라우드소싱)을 활용하여 데이터의 정확도와 유저별 선호 캘린더 데이터를 파악할 수 있게 됩니다.  2018년 4월 안드로이드/iOS 앱 출시가 예정되어 있으며 2018년 연말까지 5만 이상의 MAU 확보를 목표로 하고 있습니다.STEP.3 린더 데이터헙 - 데이터 유통 파트너 확보글의 서두에서 언급한 바와 같이 일정을 받아보는 경험은 단순히 캘린더나 모바일앱 외에도 다양한 방식으로 제공될 수 있습니다. 확보한 데이터 공급 파트너와 일반 사용자 제보를 바탕으로 일정 데이터량과 품질을 향상하고, 더 나아가서는 보유한 유저 Pool을 바탕으로 사용자들의 선호도를 사전에 파악할 수 있게 됩니다. 이러한 다양한 종류의 데이터를 기반으로 현재 스피커 및 기타 AI 서비스를 제공 중인 네이버, 카카오, 삼성, SKT, KT 등의 유통 파트너를 대상으로 영업을 진행, 협력을 통해 다양한 방식으로 사용자들에게 일정 정보를 전달할 수 있게 됩니다.히든트랙의 3가지 비즈니스 모델위 언급한 3단계의 전략 로드맵을 통해 히든트랙은 3가지 수익창출 기회를 확보할 수 있습니다. 1) 캘린더 마케팅 솔루션 - 린더 파트너스의 Enterprise SaaS 형태 공급 및 데이터 관리 용역을 통한 수익2) 린더 앱 내 확보한 사용자 선호도를 바탕으로 일정 기반의 마케팅 광고주들에게 제공하여 창출하는 수익 3) 그리고 유통 파트너들에게 일정 데이터를 제공하는 대가로 받는 데이터 판매 및 용역에 대한 수익 이 바로 그 3가지 입니다.'린더' 하다 = 일정을 받아보다다각적인 비즈니스 모델과 단계가 존재하지만 결과적으로 이를 통해 확보한 매출의 재투자와 회사의 방향성은 하나로 일원화 될 수 있습니다. 그것은 바로 사람들의 소중한 일정을 놓치지 않도록 도와주는것. 자동차 네비게이션과 같이 서비스가 삶에 완벽히 녹아들어 그것이 부재하던 시절의 삶을 상상할 수 없게 되는 것이야 말로 가장 높은 수준의 서비스 구현이라 할 수 있습니다. 과거에 지도에만 의존하여 길을 찾던 시절 소수의 사람들이 네비게이션의 가능성을 보고 그것을 만들어왔던 것처럼, 사람들이 린더를 통해 그들의 소중한 일정을 놓치지 않도록 도와주는 것이 우리의 최종 목표입니다.#히든트랙 #챗봇 #기술기업 #개발자 #개발팀 #인사이트 #경험공유
조회수 2934

웹 플러그인 개발기 - iframe의 재발견

채널 웹 플러그인을 개발하며 겪은 문제들과 우리 팀의 해결책을 소개합니다. 채널 웹 플러그인은 SDK의 형태로 고객사 웹사이트에 붙어서 고객이 매니저와 대화할 수 있는 인터페이스를 제공합니다. 이 글을 쓰고 있는 당시 약 2300개의 채널이 개설되었고, 하루 약 180만 명의 일반 유저가 웹사이트에 붙은 저희 플러그인을 보고 있습니다.플러그인은 고객사 웹사이트 (이하 호스트 웹사이트라고 함) 의 HTML 도큐멘트에 붙어서 실행됩니다. 이 말은 실행 환경 (자바스크립트, CSS, DOM 환경 등) 을 우리가 컨트롤하지 못한다는 것을 의미합니다. 이것이 일반적인 웹서비스와 플러그인 개발의 가장 큰 차이점이고 사실상 많은 이슈들은 이 차이로부터 기인합니다. 또 이것에 대응하기 위해 프레임워크의 선택부터 개발, 배포에 이르기까지 훨씬 신경 써야할 부분이 많았습니다. 이 글에서는 그 중 호스트 웹사이트와의 실행 환경 공유에 따른 문제들을 자바스크립트와 CSS로 나누어 나열하고 iframe 을 이용하여 해결한 과정에 대해 설명하겠습니다.채널 홈페이지에 웹 플러그인이 붙은 모습1. 자바스크립트와 관련된 이슈1-1. 네임스페이스 공유에 따른 충돌 문제브라우저에서 자바스크립트는 글로벌 네임스페이스를 공유합니다. 이 속성 때문에 플러그인에서 window 를 접근해서 수정한다던가 글로벌로 객체를 정의해서 사용하면 호스트 웹사이트에 영향을 미칠 수 있습니다. 이 문제는 코딩할 때 아래 항목을 주의하는 정도로 큰 비용 없이 방지할 수 있습니다.플러그인의 최상위 네임스페이스를 만든다.(ex. window.CHPlugin)플러그인에서 사용하는 모든 객체는 최상위 네임스페이스 아래에 정의되도록 한다.(ex. window.CHPlugin.outObject)window 객체에 접근할 때는 수정하거나 추가하는 부분이 없도록 주의한다.(ex. [removed] = function(){}와 같은 코드는 사용하면 안 됨. 기존에 [removed] 이벤트가 날아감)사용하는 라이브러리들 중에 window에 바인딩하는 것이 없는지 체크하고 있으면 직접 수정하여 모듈화한다. (ex. lodash는 기본적으로 window 에 _ 객체를 생성함)이건 사실 플러그인이 아니더라도 주의해야하는 거죠..1-2. 에러로 인한 오동작 가능성더 어려운 문제는 바로 예측하기 어려운 오동작의 가능성이 있다는 것입니다. 호스트 웹사이트에서 동작하는 자바스크립트에서 에러가 날 경우 플러그인의 동작에도 영향을 미칠 수 있으며, 반대로 플러그인에서 에러가 발생해서 호스트 웹사이트의 코드 실행을 멈출 수 있다는 것입니다. 양방향으로 영향을 미칠 수 있는 것이죠. 특히 후자의 경우는 우리의 실수로 고객사의 서비스에 피해를 끼칠 수 있으니 쉽게 넘길 문제는 아닙니다.아이디어 1: try/catch를 적절히 처리한다?이를 해결하기 위해 가장 쉽게 생각할 수 있는 방법으로는 호스트 웹사이트 쪽에서 try/catch를 적절하게 처리하도록 가이드를 하는 방법입니다. 예를 들어 플러그인 코드의 바깥 쪽에 try/catch처리를 하고 호스트 웹사이트의 자바스크립트에도 적당하게 처리를 하면 되지만 이 방법은 현실적으로 어려움이 있습니다. 우리의 타겟 고객사들은 일반 쇼핑몰들이고 이들은 대부분 개발자가 없거나 쇼핑몰 빌더를 이용해 만들어진 사이트들이기 때문에 개발력이 없는 경우가 많습니다. 또 설사 개발력이 있다 하더라도 플러그인을 붙이기 위해 가이드할 것이 너무 늘어나는 문제가 있죠.아이디어 2: 자바스크립트 실행 순서를 강제한다?생각해볼 수 있는 또 다른 방법은 호스트 웹사이트의 코드와 플러그인 코드의 실행 순서를 명확히 정해서 한 방향의 영향이라도 차단하는 것입니다. 예를 들어 플러그인 코드가 호스트 웹사이트의 코드보다 항상 먼저 실행되도록 고객사에게 가이드한다면 우리의 코드는 항상 문제 없이 실행될 것이고 호스트 웹사이트에서 에러가 발생하더라도 영향을 받지 않을 것입니다. 하지만 이 방법 역시 마음에 들지 않았는데요 양방향의 영향을 모두 차단하지는 못하기 때문입니다. 그리고 더욱 큰 문제는 플러그인은 한 번 실행되고 끝나는 단순한 스크립트가 아니라 계속해서 실행이 되는 애플리케이션이기 때문에 사실상 소용이 없습니다.2. CSS와 관련된 이슈채널 웹 플러그인은 UI도 포함합니다. 플러그인의 DOM이 호스트 웹사이트에 붙어있기 때문에 플러그인의 스타일을 정의하는 CSS도 호스트 웹사이트에 Inject 되어야합니다. 호스트 웹사이트의 CSS와 플러그인의 CSS가 같은 스코프에 존재하기 때문에 우리가 의도한 스타일이 제대로 표현되지 않을 가능성이 있습니다. 실제로 이 문제는 런칭 초기에 우리를 가장 괴롭혔던 문제입니다. 쉽게 생각해볼 수 있는 방법은 아래와 같습니다.플러그인의 CSS에 네임스페이스를 둔다.(플러그인 CSS가 호스트 웹사이트 CSS에 주는 영향을 차단함)CSS 의 우선순위를 이해하고 플러그인 CSS의 우선순위가 항상 높도록 처리한다. (CSS Specificity 링크 참조)하지만 위처럼 처리하더라도 모든 경우에 대해 해결이 되는 것은 아닙니다. 주된 이유는 우리가 개발을 할 때 모든 CSS 속성을 정의하지 않기 때문입니다. 플러그인에서 정의하지 않은 속성을 호스트 웹사이트에서 사용한다면 호스트 웹사이트의 스타일이 적용될 것입니다. 또 특수한 경우이긴 하지만 만약 호스트 웹사이트에 !important 가 적용되어 있다면 그 속성이 덮어씌워지게 됩니다.!important는 사용하지 맙시다..ㅜ아이디어: 스타일 Normalizing?여기에서 의미하는 Normalizing은 모든 DOM 엘리먼트에 가능한 모든 CSS 속성의 기본값을 정의하는 것을 의미합니다. 크로미움을 기준으로 모든 CSS 속성 목록은 이 곳을 참조하시면 됩니다. 이것을 바탕으로 normalize.css를 만들어 적용했습니다.이 방법을 적용한 이후로는 스타일이 오버라이딩되는 문제는 어느 정도 해결되었습니다. 물론 !important에 대한 대응은 여전히 되지 않지만요. 그런데 예상하지 못한 부작용이 발생했는데 첫번째는 디버깅할 때 크롬 인스펙터가 도저히 사용하지 못할 정도로 느리다는 것입니다. 두번째는 CSS가 inheritance 가 안 되고 기본 엘리먼트 셀렉터의 우선순위가 높아서 직접 코딩해야하는 CSS가 2~3배는 길어지는 불편함입니다. 위 두 이유로 개발 피로도가 상당히 높아져서 머지 않아 다른 방법을 알아보게 되었습니다.3. iframe 도입위에 나열한 문제들을 해결할 수 있는 아이디어로 iframe을 리서치하게 되었습니다. 사실 iframe은 최근 웹서비스에서는 잘 사용하지 않기도 하고, 보통은 사용하지 않는 것을 권장하기도 하죠. 따라서 저희 팀에서도 처음에는 고려사항이 아니었는데요 우리와 유사하게 채팅 인터페이스를 제공하는 인터콤에서 iframe 을 적용한 것으로부터 아이디어를 얻어왔습니다.원래 목적에 맞게 사용하지 않으면 독이 됩니다.iframe은 HTML 도큐멘트 안에서 또 다른 도큐멘트를 임베드합니다. iframe 내에 있는 도큐멘트는 호스트 도큐멘트와 자바스크립트 스코프가 분리되어 있고, CSS가 적용되는 스코프 역시 분리되어 있습니다.이런 속성 때문에 위에 나열한 문제들을 원천 차단할 수 있습니다. 자바스크립트 스코프가 분리되어 있기 때문에 글로벌 네임스페이스에 접근해도 호스트 웹사이트에는 전혀 영향이 없고, 자바스크립트의 에러로 인해 다른 쪽 자바스크립트까지 실행을 멈추는 오동작을 막을 수 있습니다. CSS 역시 Normalizing 을 하지 않더라도 호스트 웹사이트와 플러그인은 완벽히 분리가 됩니다.4. iframe 의 단점iframe을 도입하여 1, 2번에 나열한 문제들은 해결했지만 그에 따른 작은 문제들도 발생했습니다. 첫번째는 iframe도입 시 가장 먼저 고민해야할 부분인데 바로 3rd-party cookie 문제입니다. iframe 안에서 로드되는 도큐멘트는 3rd-party 컨텐츠로 인식합니다. IE에서는 기본 설정이 3rd-party cookie 허용을 하지 않기 때문에 쿠키를 사용해서 인증을 구현한 경우 문제가 될 수 있습니다.두번째는 도큐멘트가 분리됨에 따라 발생하는 코딩상의 여러 불편함들입니다. 여기에서는 범위를 벗어나 더 자세하게는 설명하지 않겠지만 도큐멘트가 분리되니 조금 더 신경써야할 것들이 있었습니다.저희 팀의 경우 쿠키 인증 방식이 아닌 토큰 형태의 인증도 지원을 하고 있었기 때문에 첫번째는 크게 문제되지 않았고 두번째 문제도 얻는 이득에 비하면 불편함을 감수하는 편이 훨씬 좋다는 판단이 들어서 도입을 결정했습니다.마무리플러그인 개발을 시작할 당시에 우리 팀은 웹 SDK 형태의 프로젝트 개발 경험이 없었습니다. 리서치를 해도 플러그인 개발과 관련된 아티클이나 리소스 그리고 보일러플레이트 프로젝트도 많지 않았습니다. 프레임워크, 아키텍쳐를 선택하는 것부터 프로젝트를 구성하는 것부터 개발, 배포 및 운영에 이르기까지 일반적인 웹서비스를 개발할 때와 조금 다른 고민들을 해왔던 것 같습니다. 앞으로 저희가 해 온 고민을 공유하려고 합니다. 저희와 같은 플러그인, SDK 형태의 제품을 개발하고 계신 분들에게 도움이 되었으면 좋겠습니다.#조이코퍼레이션 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 2386

Activation Function

Activation Function(활성함수)인공신경망을 공부하다보면 활성함수(activation function)라는 것을 만나게 됩니다. 대부분의 분들은 처음 공부를 시작할 때, 저와 마찬가지로 활성함수는 그냥 이런 거구나 하신 뒤에 넘어가고 있을 거라 생각합니다. 하지만 딥러닝을 좀더 공부하다보면 어떤 활성함수를 사용했는지, 혹은 사용하지 않았는지로 인해 다양한 문제가 발생하곤 합니다. 특히 요즘 핫한 deep neural network 에서는 활성함수가 어떤 것인가에 따라서 vanishing gradient 문제로 인해 학습의 정도가 달라지기도 합니다. 이러한 이유에서 이번 포스팅에서는 활성함수를 자세히 이해해보도록 하겠습니다.인공신경망이 사람의 신경구조를 모방하여 만들어졌다는 사실은 다들 알고 계실겁니다. 인공신경망의 가장 기본 개념은 단일 퍼셉트론에서 출발했습니다. 관련된 포스팅에서도 설명했지만 퍼셉트론은 여러 개의 신호가 들어오면 이를 조합하여 다음으로 신호를 보낼지 말지를 결정합니다(0 또는 1). 이것을 발전시킨 feed forward multiple layer neural network는 하나의 단일 뉴런에 여러 신호가 들어오면, 다음 뉴런에 보낼 신호의 강도를 결정하게 됩니다. 즉, 단일 퍼셉트론이 multi layer perceptron으로 발전해나가는 과정에서, 뉴런은 신호의 전달유무가 아닌 전달 강도를 정하게 되었습니다. 이때 전달하는 신호의 세기를 정하는 방법이 활성함수입니다.많은 분들은 대표적인 활성함수로 sigmoid를 떠올리실 것입니다. 활성함수의 개념을 잡기에는 이만큼 좋은 함수가 없기 때문입니다. 그럼 우선 활성함수의 가장 기본적인 개념을 sigmoid를 통해 알아보도록 하죠. 그 전에 여러분의 이해를 돕기 위해 로지스틱 회귀분석에 대해 먼저 알아보겠습니다.로지스틱 회귀분석(logistic regression)로지스틱 회귀분석은 generalized linear model입니다. 정확히 말하자면 generalized linear model이라는 큰 개념의 여러 케이스 중 하나라고 볼 수 있겠네요. 로지스틱 회귀분석의 목적은 독립변수의 선형결합으로 종속변수인 ‘어떠한 사건이 발생할 확률’을 알고자 하는 것입니다. 어렵죠..? 쉬운 예시를 하나 들어보겠습니다.우리는 어떠한 연구를 통해 1일 흡연량과 폐암 발생 여부의 관계를 알고싶습니다. 이때 가장 쉬운 방법은 1일 흡연량{x}과 폐암 발생확률{p(y)}이 선형 관련성이 있다고 보고, 선형 회귀 분석(linear regression)을 시행하는 것입니다. 그 결과, p(y)=0.02x+0.1<math>p(y)=0.02x+0.1</math> 이라는 식이 도출되었다고 생각해보죠. 이 식은 담배를 전혀 안 피우는 사람은 10%의 확률로 폐암에 걸리고, 하루에 담배를 1개비씩 더 피울 때마다 폐암에 걸릴 확률이 2% 증가한다는 의미입니다. 표면적으로 보았을 때는 꽤나 합리적으로 보입니다. 하지만 과연 이 식을 실제 예측에 활용해도 전혀 문제가 없을까요? 예상하셨겠지만, 그렇지 않습니다.담배는 한 갑에 20개비가 들어있고, 3갑이면 60개비가 들어있습니다. 따라서 하루에 담배를 3갑 피우는 사람은 0.02∗60+0.1=1.3<math>0.02∗60+0.1=1.3</math>, 즉 130%의 확률로 폐암에 걸린다는 결론이 도출됩니다. 이는 확률의 공리에 어긋나는 결론입니다. 따라서 과거의 수학자들은 선형이라는 이해 및 계산이 쉬운 방법을 그대로 유지하면서 확률의 공리에 어긋나지 않는 방법을 찾고자하였고, 다양한 방법들 중 가장 보편적으로 사용하게 된 방법이 로지스틱 함수를 연결함수로 사용한 로지스틱 회귀분석입니다.로지스틱 함수는 아래와 같이 생겼습니다.g(x)=ex1+ex<math>g(x)=ex1+ex</math>이것을 연결함수로 적용한 generalized linear model, 즉 logistic regression의 수식은 아래와 같은 형태가 됩니다.P(y|x)=eβx1+eβx<math>P(y|x)=eβx1+eβx</math>위 식을 이용하면 비로소 선형이라는 직관적인 성질을 띄면서, 결과값의 범위가 0~1로 제한되어 확률값의 예측에 사용할 수 있는 회귀식이 도출됩니다. 이 때, 위에 사용한 로지스틱 함수가 바로 우리가 활성함수로 사용하는 sigmoid function입니다. 따라서 sigmoid를 활성함수로 사용할 경우, 필연적으로 로지스틱 회귀분석과 관련이 있을 것이라고 예상할 수 있습니다. 둘 간의 관련성을 아래 그림을 통해 알아보겠습니다.여러분의 이해를 돕고자 hidden layer가 없는 가장 단순한 형태의 feed forward neural network 형태를 그려보았습니다. 위 그림을 수식으로 나타내볼까요?P(Y|X)=exp(∑2i=0wixi)1+exp(∑2i=0wixi)=11+exp(−∑2i=0wixi)<math>P(Y|X)=exp(∑i=02wixi)1+exp(∑i=02wixi)=11+exp(−∑i=02wixi)</math>즉, 위처럼 sigmoid를 활성함수로 사용한 간단한 neural network는 logistic regression과 일치합니다. 물론 계수(weight) 추정 방법은 통계학에서 기존에 행하던 방법과는 차이가 있지만, 결과적으론 비슷한 값이 추정될 것입니다. 우리는 이 그림을 통해 아래와 같은 직관을 얻을 수 있습니다.input과 weight를 곱해서 더하는 과정은 linear combination(선형 결합)이다.인공신경망의 학습은 각 뉴런에 곱해지는 ‘weight’라는 모수(parameter)를 추정(estimate)하는 과정이다.이제 눈치 채셨나요? Sigmoid를 활성함수로 사용하는 multi layer perceptron neural network의 hidden layer의 각 뉴런은 로지스틱 회귀분석을 하는 것과 정확히 일치합니다. 따라서 학습 과정에서 각 layer의 weight라는 모수를 학습을 통해 추정하는 것입니다.mlp 적용그럼 이제 위에서 배운 로지스틱 회귀분석을 mlp에 적용해보겠습니다. 우리는 단층 퍼셉트론 에서 아래와 같은 그림을 보았습니다.위처럼 선형으로 깔끔하게 분류가 가능한 문제는 활성함수가 계단함수인 단층 퍼셉트론으로도 충분히 해결할 수 있습니다. 하지만 아래와 같은 경우는 문제가 달라집니다.이러한 분류 문제는 선형으로는 불가능하며, 비선형적인 분류를 하여야 합니다. 이처럼 우리가 원하는 비선형의 분류를 하기 위하여 크게 두 가지가 필요합니다.1개 이상의 hidden layer(2개 이상의 뉴런을 포함하여야 함)비선형의 활성함수먼저 비선형의 활성함수가 필요한 이유부터 간단하게 생각해보겠습니다. 만약 활성함수가 비선형이 아니라면, 각 뉴런의 결과값은 선형결합의 선형결합이 됩니다. 따라서 아무리 multiple layer를 쌓는다고 하여도, 결과적으로 출력값은 입력값들의 선형결합이 됩니다. 즉, 층을 여러 개 쌓는 의미가 퇴색되는 것입니다.다음으로 hidden layer와 뉴런의 갯수에 대한 정의가 왜 필요한지 생각해보겠습니다. 위에서 언급하였듯이 logistic regression은 generalized linear model입니다. 여기서 ‘linear model’에 주목해주세요. 즉, logistic regression도 결국은 선형 모델이라는 것입니다. 왜일까요? Logistic regression을 이항분류 문제(결과의 범주가 0 또는 1)에 적용하여, 결과값이 특정값 이상이면 1로 분류한다고 생각해보겠습니다. 이것은 결국 기존의 단일 퍼셉트론에서 활성함수로 sigmoid를 사용한 뒤, 다시 계단함수를 적용한 것과 같습니다. 비록 우리가 sigmoid라는 비선형의 활성함수를 사용했지만, 로지스틱 함수의 지수를 풀어내면 결국 선형 결합의 결과값에 대한 분류이므로 우리가 원하는 비선형의 분류를 할 수 없습니다. 따라서 위와같은 문제를 해결하기 위하여, 비선형의 활성함수를 쓰되, 다수의 뉴런을 갖는 hidden layer를 사용하는 것입니다. 이 때, hidden layer의 뉴런 갯수가 늘어날 수록 좀더 비선형으로 데이터에 적합한 분류가 가능해지지만 overfitting 문제가 발생하게 됩니다. 따라서 hidden layer의 뉴런 갯수를 과제마다 적절히 지정해주는 것이 중요합니다.activation function의 종류마지막으로 activation function의 종류 및 특징에 대해 정리해보겠습니다.1. Sigmoid functionBy Qef (talk) - Created from scratch with gnuplot, Public Domain, Link<특징>수식 : σ(wx+b)=ewx+b1+ewx+b<math>σ(wx+b)=ewx+b1+ewx+b</math>범위 : (0,1)시그모이드 함수는 완전히 값을 전달하지 않거나(0) 혹은 완전히 전달한다(1)는 특성 때문에 실제 인체의 뉴런과 유사하다고 생각되어 널리 사용되었으나, 현재는 점차 사용하지 않는 추세입니다. 그 이유는 아래와 같습니다.Vanishing Gradient :sigmoid 함수는 뉴런의 활성화 값이 0 또는 1에 매우 가깝다면(saturate), 해당 편미분 값이 0에 매우 가까워지는 특성이 있습니다. 인공신경망의 back propagation에서 가장 일반적으로 사용되는 gradient descent의 경우 chain rule을 이용하는데, 이 과정에서 0에 매우 작은 값이 계속 곱해진다면 그 값은 0으로 점점 더 수렴합니다. 즉, 학습의 결과가 back propagation 과정에서 전달되지 못하고 이에 따라 weight 값의 조정이 되지 않습니다. 이것은 학습의 과정뿐만 아니라, 초기 weight 값을 임의로 줄 때에도 문제가 됩니다. f=σ(wx+b)<math>f=σ(wx+b)</math> 를 통해 확인해보죠. 만약 w의 값이 매우 커서 σ(wx+b)<math>σ(wx+b)</math>의 값이 1에 매우 가까워 진다면, weight값은 초기 값에서 크게 변하지 않고 학습이 되지 않을 것입니다. 그럼 우리의 신경망 모델의 정확성도 감소하겠죠. 이것이 vanishing gradient problem입니다.중심값이 0이 아니다 :Sigmoid function의 결과값은 그 중점이 0이 아니며, 모두 양수입니다. 이 경우 모수를 추정하는 학습이 어렵다는 단점이 있습니다. 하지만 이것은 다른 방식으로 모델 내에서 극복이 가능하기 때문에 vanishing gradient 에 비해 큰 문제는 아닙니다.2. tanh function<특징>수식 : tanh(x)=e2x−1e2x+1<math>tanh(x)=e2x−1e2x+1</math>범위 : (-1,1)tanh(hyperbolic tangent) function은 sigmoid 처럼 비선형 함수이지만 결과값의 범위가 -1부터 1이기 때문에 sigmoid와 달리 중심값이 0입니다. 따라서 sigmoid보다 optimazation이 빠르다는 장점이 있고, 항상 선호됩니다. 하지만 여전히 vanishing gradient 문제가 발생하기 때문에 대안이 등장하게 됩니다.3. Relu(Rectified Linear Unit)<특징>수식 : y=max(0,x)<math>y=max(0,x)</math>범위 : (0,∞<math>∞</math>)Relu는 위 그림처럼 선형그래프를 한 번 꺾은 형태입니다. 이 간단한 함수는 오랫동안 인공신경망의 발목을 잡던 vanishing gradient 문제를 해결했습니다. 하지만 여전히 장점과 단점이 존재합니다.장점기존의 sigmoid, tanh에 비해 converge되는 속도가 빠릅니다. 이것은 그래프의 형태가 선형이고, saturate problem이 발생하지 않기 때문으로 보여집니다.x값이 0을 기준으로 선형발현/미발현 이라는 간단한 형태이기 때문에 상대적으로 연산량이 많은 exponential을 사용하지 않아, 컴퓨터의 연산에 대한 부담을 줄여줍니다.단점“dying Relu problem”이 발생합니다. 만일 학습 과정에서 weight가 특정 뉴런이 activate되지 않도록 바뀐다면, 해당 뉴런을 지나는 gradient도 0이 됩니다. 따라서 training 과정에서 해당 뉴런이 한 번도 발현하지 않게 될 수도 있습니다. 심한 경우에는 네트워크 전체 뉴런의 40%가 죽어있는 경우도 발생한다고 합니다(출처 : http://cs231n.github.io/neural-networks-1/). 이것을 막기 위해서는 learning rate를 크지 않게 조절하는 것이 중요합니다. 또 다른 해결 방안으로는 leaky relu와 같은 activation function을 사용할 수도 있습니다.정리이번 포스팅을 통해 우리는 activation function이 무엇이고, 왜 필요한 것인지 알아보았습니다. 또한 어떠한 activation을 어떻게 사용해야하는지도 배웠습니다. 제가 위에 소개한 것 이외에도 다양한 activation function이 있으므로, 한 번쯤 찾아보며 공부해보시면 좋겠습니다.
조회수 1064

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

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

샌프란시스코 테크 업계 인터뷰 2: Bleacher Report, Udemy, Intuit

이 포스팅은 2개의 글로 구성된 시리즈 중 2번째 글입니다. 이전 글을 읽으려면 “샌프란시스코 테크 업계 인터뷰 1: Facebook, Fivestars”로 이동하세요.  안녕하세요, 스포카 프로덕트 매니저 옥지혜입니다.  제품을 담당하는 팀이 일하는 방식은 제품 그 자체에 영향을 줍니다. 어떠한 기능을 어떤 주기로 사용자에 배포할 것이냐에 대한 결정을 하는 과정이기 때문입니다. 그뿐만 아니라 정성적인 차원에서 새로운 기능을 개발하거나 운영하는 일 등을 조직이 어떻게 평가하느냐에 따라 작업자의 업무 만족도와 작업물의 품질에도 영향을 미칩니다.  구태의연한 말이지만 테크 업계에서 일하는 방식에 있어 정답은 없습니다. 제품과 조직은 끊임없이 변화하고 이에 맞추어 일하는 방식도 바뀌어야 하므로 지난해에 불합리하다고 여기던 방식이 올해는 검토해 볼 만한 것이 될 수도 있습니다. 일하는 방식 그 자체도 협의를 거쳐 지속적으로 개선하는 과정이 필요합니다.  일하는 방식과 함께 제품과 조직마다 프로덕트 매니저의 역할과 권한도 바뀝니다. 비즈니스에 제품이 기여하는 정도에서부터 조직 내 이해관계자와의 관계까지 제품과 조직의 모든 요소가 프로덕트 매니저가 일하는 방식에 영향을 미칩니다. 스포카 프로덕트 매니저의 경우, 서비스 백로그 관리의 역할도 담당하기 때문에 유동적으로 일하는 방식에 따른 결과는 제품에 다시금 반영됩니다.  이번 샌프란시스코 테크 업계 인터뷰는 위와 같은 가정하에 ‘스포카는 앞으로 어떤 방식으로 일할 것인가’라는 질문에 대한 참고할 사례를 수집하기 위하여 진행하였습니다. 닭과 계란 문제일 수 있지만, 이것은 ‘스포카는 어떤 제품을 만들고자 하는가’하는 고민과 맞닿아 있습니다.  인터뷰는 총 5회에 걸쳐 아래의 PM 분들과 진행하었습니다. 흔쾌히 인터뷰에 응해 주신 모든 분께 감사드립니다. 각 인터뷰이와 나눈 이야기 중 인상적이었던 부분을 발췌하여 2개의 포스팅에 걸쳐 공유하겠습니다. Stephanie Shum(Director Product Management at Facebook)   David Park (Refereum COO)Michael Hsu (Product Manager at FiveStars)Chris Nguyen (VP Product at Bleacher Report)홍성철 (Product Manager at Udemy)정대영 (Product Manager at Intuit)    Chris Nguyen (VP Product at Bleacher Report)        현재 담당하고 있는 팀은 어떻게 구성되어 있나요?  C: 초기에는 직무 단위로 팀을 구성하였다. 현재는 전략에 맞도록 제품 단위의 스쿼드로 구성을 변경했다. 제품 팀은 전체적으로 디렉터 2명, 시니어 PM 2명, 주니어 PM 2명과 디자이너 7명으로 구성되어 있다. PM 1명 당 디자이너 1.5명의 비율을 유지하려고 한다. 보다 구체적인 수준으로 아이디어를 디벨롭하기 위해서이다. 엔지니어는 50명 규모로까지 충원하는 것을 목표로 하고 있다.  PM은 팀에서 어떤 역할을 하나요?  C: 스프린트를 안정적으로 운영하기 위해서 말 그대로 할 수 있는 일은 모두 도맡아서 했다. 점차로 팀이 커지면서 제품과 팀이 어떤 우선순위를 가지고 움직일지 트래킹하는 데에 집중하려고 노력했다. 우선순위를 지킬 수 있도록 스프린트를 계획하고 계획대로 일이 진행될 수 있도록 챙기는 역할에 집중했다. 실제 배포를 위한 역할이 이와 같다면, 서비스 전략 관점에서는 중요한 결정사항이 타당했는가에 대하여 결정 이후에도 자주 점검했다. 또 제품 팀의 KPI를 정확하게 측정하고 제품 팀에서 하는 모든 일이 KPI를 달성하였는지 검토했다.  PM으로서 제품 팀에 동기부여를 어떻게 하나요?  C: PM의 가장 중요한 역할 중 하나는 ‘왜 이 일을 해야 하는가’에 대하여 끊임없이 설명하는 것이다. 목표와 이를 달성하기 위해 해야 하는 일을 문서화하고 이것이 실제로 팀에서 할 수 있는 일이라는 것을 다양한 방식으로 팀에 전파한다. PM이 주로 조직과 제품에 대한 다양한 정보를 취득하게 되므로 팀 내에 이를 지속적으로 공유하는 것 역시 중요하다. (운영 업무에 대한 동기부여는 어떻게 하나요?) 서비스가 성장하고 시간이 흐를수록 기술 부채가 쌓이기 마련이다. 신규 기능에 대한 요구사항과 기술 부채 삭감을 위한 작업의 무게를 맞추는 역할도 PM의 몫이다. 팀에서 담당하는 가시화되지 않는 업무를 지적하여 마땅한 보상을 받게 하는 것이 좋은 방법이라고 생각한다.    홍성철 (Product Manager at Udemy)        PM의 역할 중 무엇이 가장 중요할까요?  홍: PM은 완성도 있는 제품을 제때 배포할 수 있는지가 가장 중요하다. Udemy의 경우, 서비스에 기술적인 오류가 있을 때 책임을 PM이 지게 하여 제품의 기술적인 영역에 집중하도록 유도한다. PM은 제품의 연 단위 목표를 수립하고 분기 단위로 쪼개진 목표를 실제로 달성할 수 있도록 2주 단위 스프린트를 운영하는 사람이다. (제품 팀이 목표지향적으로 일하기 위해 어떤 장치를 두나요?) 모든 기능의 제안은 원 페이지 기획서로 시작한다. 이 기획서에 해당 기능을 왜 지금 만들어야 하는지에 관해서 설명하게 한다. 이외에도 반드시 팀 비전과 목표에 각각의 기능이 어떻게 기여하는지도 적도록 요청한다. 기능을 제안하는 모든 팀은 이 문서를 작성하여 그것을 기반으로 백로그 조정을 진행한다.  유관부서 요구사항의 우선순위 조율과 디벨롭에 있어서 팁이 있나요?  홍: 기능을 제안한 배경이 되는 문제를 명확하게 정의해야 불필요한 커뮤니케이션을 줄일 수 있다. 아울러 특정 기능의 진행 우선순위를 높이면서 다른 기능의 우선순위가 내려간다는 점을 강조하여야 한다. 모든 커뮤니케이션의 기본은 그것이 협상의 성격을 띤다는 점이다. 개발 팀과의 커뮤니케이션도 협상이다. 이를테면 커뮤니케이션 스킬이 뛰어난 프로그래머와 협업하는 경우, 어떠한 예외 케이스가 있는지와 이에 대하여 대응할 때 검토할 수 있는 옵션을 제시할 수 있어 효과적으로 일할 수 있다. 개발 팀 외부 조직은 제품의 기술적인 영역에 직접 관여할 수 없다. 따라서 어떤 프로그래머가 개발 팀의 리더인지에 따라 협의 결과에 큰 차이를 가져올 수 있다.  컴퓨터 공학에 대한 사전 지식의 유무 또는 한국인이라는 점이 샌프란시스코에서 PM으로 일하는 데 영향을 미친다고 생각하나요?  홍: 재학 중에 시스템 디자인 엔지니어링을 배웠다. PM으로서의 업무 경험이 쌓이면서 테크니컬 배경 유무에 따른 차이가 갈수록 작아진다. 경력 초반에 개발 팀의 업무에 공감할 수 있는 범위와 정도의 차이에 영향을 주었고 시간이 갈수록 차이가 작아졌다. 모바일 앱 시장 초기 단계에는 빠른 출시가 중요하므로 공학 배경이 있는 사람을 업계에서 선호했다. 시장 성숙도가 올라가면서 현재는 트렌드가 바뀌었다. 샌프란시스코에 일하는 한국인 PM은 MBA 출신이 대다수이고 다양한 문화적 배경을 가진 사람이 업계에 많으므로 이 또한 크게 문제는 되지 않는다. 적극적인 태도와 뛰어난 업무 능력이 있다면 적응하는 데에 어려움은 없다고 생각한다.    정대영 (Product Manager at Intuit)        기능에 대한 요구사항은 어떻게 발굴하나요?  정: 발의하는 주체에 따라 크게 2가지 카테고리로 구분할 수 있다. 외부에서 발생하는 요구사항의 경우, 사용자의 제안 또는 리서치를 통해 발굴할 수 있다. 내부에서 발생하는 요구사항의 경우, 사용자 관점에서 서비스 개선사항을 직접 찾아낸다. 이후에 프로젝트를 만들고 프로토타이핑하여 A/B 테스트를 진행한다. 제품 팀 - PM, 디자이너, 엔지니어 - 모두 개선사항을 찾는 과정에 참여한다. 제품의 목표는 탑다운으로 제시될 수 있으나 실제 액션 아이템에 대한 결정은 실무 단에서 가장 비즈니스 임팩트를 줄 수 있는 기능을 정한다. 기존 백로그의 우선순위에 영향을 주는 기능 요구사항이 있을 경우, 명확한 기준을 근거로 투명한 의사결정을 거쳐 우선순위를 결정한다. 이는 모든 요구사항이 협상 과정이라는 것을 강조한다는 점에서 유의미하다.  사내에서 제품 팀 또는 제품에 대한 피드백은 어떻게 받나요?  정: 모든 임원진이 참석하여 제품에 대한 피드백을 주는 미팅이 있다. 서비스에 대한 내부 피드백을 정확하게 받을 수 있는 계기가 된다. 이 회의를 통해 전략 미팅이 시작되기도 하며 구체적인 프로젝트 협의를 진행하는 미팅이 이어지기도 한다. 각기 다른 제품을 담당하는 PM이 모두 모이는 미팅도 있다. 미팅 이전에 어떤 피드백을 받고 싶은지에 대해 사전 요청을 하기도 한다. 반드시 ‘애자일’ 하게 일하는 방식이 옳다고는 생각하지 않는다. 방법론보다는 데이터 기반의 피드백과, 일반적인 경험에 대한 언급보다는 명확하고 직관적으로 상대방에게 구체적인 피드백을 주는 것이 중요하다.  제품 팀이 목표에 집중할 수 있도록 PM으로서 어떤 역할을 하시나요?  정: 비즈니스 목표와 제품 팀의 목표가 서로 연관되어야 하는 것은 당연하다. 다만 기술 부채 문제처럼 비즈니스 목표에서 포함하지 않는 제품 팀의 목표가 있을 수 있고, 이 또한 협상의 대상이다. 기술 부채의 범위와 정도에 따라 서비스 자체에 영향을 미칠 수 있기 때문이다. 이러한 문제를 해결하기 위해서 Hack day를 운영한다. 제품 팀이 특정 문제를 해결하기 위해, 정해진 시간 동안 다른 업무를 진행하지 않고 그 문제에만 집중할 수 있도록 유도하는 방식이다. 또한 PM은 업무 우선순위를 정함에 있어 신규 기능과 기존 기능 버그 패치를 함께 조율한다. 제품의 퀄리티는 제품 팀 또는 개발 팀만의 책임이 아니고 전사의 책임이다. 테스트와 클린업의 중요성에 대해 전사적인 공감대 형성이 필요하다.    총 5회에 걸친 인터뷰를 통해 얻을 수 있는 인사이트를 요약 하자면 다음과 같습니다. 비즈니스 목표와 제품 팀 목표가 연관될 수 있도록 업무 방식을 관리해야 한다.   요구사항 간의 우선순위를 조율하는 것은 협상의 과정이다. 협상의 주된 기준은 비즈니스 임팩트에의 기여도이며 기술 부채와 같이 가시화되지 않는 기준도 PM이 검토하여 반영해야 한다.제품 팀 자체도 제품이다. 팀원의 피드백을 취합해서 효과적인 동시에 행복하게 일할 수 있도록 업무 방식을 개선해 나가야 한다.  스포카에서는 위와 같은 인사이트를 기반으로 스포카 크리에이터(스포카 제품 팀)의 업무 방식을 지속적으로 개선하고 있습니다. 스포카 크리에이터는 우선 서비스 품질 차원의 기술적인 목표를 관리합니다. 동시에 제품이 비즈니스에 어떻게 기여하는지를 확인하고 보다 큰 임팩트를 낼 수 있는 기능을 탐색합니다. 이 결과로 제품에서 발생하는 매출 지표 혹은 이에 기여하는 부가 지표를 관리합니다. 아울러 제품 팀 외 유관부서의 요구사항을 취합하는 채널을 일원화하고, 스프린트를 구성하는 회의에서 이를 발의받아 우선순위를 정합니다. 이러한 협의체는 스포카 크리에이터가 가장 효과적으로 비즈니스와 제품에 기여할 수 있도록 업무를 조율하는 역할을 합니다.  마지막으로 스포카 크리에이터는 분기 단위로 동료 간 리뷰 및 조직장과의 면담을 거쳐 팀의 컨디션을 체크합니다. 피드백을 통해 각 팀원은 보다 성장할 수 있는 기회를 확인할 수 있습니다. 조직 차원에서는 각 팀원이 비즈니스 또는 제품의 목표에 대해 얼마나 공감하는지를 확인하고 기여하고자 하는 업무를 파악하여 팀이 보다 효과적으로 일할 수 있도록 조직 구성을 변경하기도 합니다.  스포카 크리에이터는 개인의 성장이 팀의 성장으로 이어지고 이는 곧 제품의 경쟁력과 연결된다고 믿습니다. 스포카와 함께 성장하실 수 있는 분은 언제나 환영합니다.
조회수 2026

Circle CI에서 rbenv를 이용해서 Ruby 2.2와 CocoaPods 0.39 버전 사용하기

최근 Circle CI에서 Ruby 버전을 2.3으로, CocoaPods 버전을 1.0으로 업그레이드함에 따라 발생하는 빌드 문제를 rbenv를 이용해서 해결한 경험을 공유합니다. 최종적으로 완성된 Gemfile과 circle.yml 파일은 마지막 섹션에서 확인하실 수 있습니다.1. CocoaPods 1.0지난 2015년 12월에 CocoaPods 1.0.0 베타 버전이 처음 공개되었습니다. CocoaPods이 1.0 버전으로 업그레이드되면서 굉장히 많은 변화가 있었는데요. 가장 큰 변화는 DSL입니다. 추상 타겟Abstract Target과 타겟 상속Target Inheritance이 새롭게 소개되면서, 0.39 버전까지 자주 사용되던 link_with 및 :exclusive => true와 같은 구문이 제거되었습니다.이에 따라 기존에 사용하던 Podfile이 CocoaPods 1.0 버전과는 호환되지 않는 문제가 발생했습니다. 이를 해결하기 위한 가장 좋은 방법은 새로운 DSL을 사용하여 Podfile을 다시 작성하는 것이지만, 꽤 많은 서드파티 라이브러리를 사용하는 StyleShare의 경우 새로운 DSL을 적용하여 빌드하면 각종 문제로 인해 빌드가 정상적으로 이루어지지 않았습니다. 4년동안 유지되고 있는 프로젝트이다보니, 레거시 Objective-C 코드와 라이브러리, 그리고 새로운 Swift 코드와 라이브러리가 혼용되어 사용되는 것도 원인 중 하나일 것입니다.따라서 StyleShare에서는 CocoaPods 0.39 버전을 사용하기로 결정을 했습니다. 하지만 최근 Circle CI에서 CocoaPods 버전을 공식적으로 1.0 버전으로 업그레이드하면서 빌드가 깨지기 시작했습니다. Circle CI 환경에서 CocoaPods 0.39 버전을 사용하려면 어떻게 해야 할까요?▲ ㅠㅠ2. Bundler를 이용해서 Gem 관리하기Bundler는 Ruby로 작성된 라이브러리들의 버전을 관리해주는 강력한 도구입니다. CocoaPods에서 Podfile에 의존성을 기재하듯, Bundler에서는 Gemfile에 의존성을 기재합니다.source 'https://rubygems.org' gem 'cocoapods', '~> 0.39' $ gem install bundler 명령어를 사용하면 Gemfile에 기재된 의존성 라이브러리들을 설치해줍니다. 이렇게 설치된 CocoaPods을 사용할 때에는 $ pod COMMAND 대신 $ bundle exec pod COMMAND 명령어를 사용해야 합니다.$ gem install bundler $ bundle install --path vendor/bundle $ bundle exec pod --version 0.39.0 3. Ruby 2.3과 CocoaPods 0.39Bundler를 사용해서 CocoaPods 0.39 버전을 사용하기만 하면 모든 문제가 해결될 줄 알았습니다. 하지만 더 큰 삽질이 남아있었는데요. 바로 Ruby 2.3 버전이 CocoaPods 0.39 버전과 호환되지 않는 것이었습니다.$ bundle exec pod install Updating local specs repositories Analyzing dependencies 신나게 $ bundle exec pod install 명령어를 실행하니, 의존성을 분석하는 듯 싶다가 갑자기 에러를 주르륵 뱉습니다. 에러 로그의 #### Error 항목을 보면 에러 메시지가 나와있습니다.NoMethodError - undefined method `to_ary’ for #이 에러 메시지로 CocoaPods GitHub 저장소의 이슈를 검색해보면 꽤나 많은 이슈가 올라와 있습니다. 이 이슈들을 보면, 모두 Ruby 버전이 2.3이라는 공통점이 있습니다. Ruby 버전을 2.2로 내렸더니 문제가 해결됐다는 댓글들도 굉장히 많고요. Circle CI의 Ruby 버전을 2.2로 낮추면 문제가 해결될 것 같습니다.Circle CI 문서 내용에 따라 circle.yml에 Ruby 버전을 기재해봅시다.machine: ruby: version: 2.2.5 그러나 Circle CI의 OS X 컨테이너에서는 Ruby 버전 변경을 지원하지 않는다고 합니다.▲ ㅠㅠ (2)4. rbenv를 이용해서 Ruby 2.2 사용하기그러다가 알게된 것이 바로 rbenv입니다. rbenv를 사용하면 여러개의 Ruby 버전을 깔끔하게 관리할 수 있게 됩니다. rbenv는 Homebrew를 사용해서 쉽게 설치할 수 있습니다.$ brew install rbenv rbenv는 ~/.rbenv 디렉토리에 안에 여러 Ruby 버전을 설치하고 관리합니다. rbenv를 설치한 뒤 가장 먼저 할 일은 환경변수 $PATH를 설정해주는 것입니다. $PATH에는 $HOME/.rbenv/shims와 $HOME/.rbenv/bin 경로가 포함되어있어야 합니다.4.1 환경변수 설정하기Circle CI에서는 환경변수를 설정하는 편리한 인터페이스를 제공합니다. 하지만, Circle CI에서 실행되는 각 명령어는 별도의 쉘에서 실행됩니다. 그말인 즉슨, 각 명령어가 실행되기 직전에 새로운 쉘이 실행되고, $PATH 환경변수를 덮어쓰는 .bash_profile이 실행된 후 명령어가 실행된다는 뜻인데요. 이렇게 될 경우 $PATH 환경변수의 가장 우선순위는 항상 /usr/local/bin이 가지게 됩니다. 그리고 같은 이유로 $ export FOO=bar와 같은 명령어도 사용할 수 없게 됩니다.1고민을 하다가 생각해낸 방법은 바로 .bash_profile의 내용을 변경(!)하는 것입니다. 그렇게 되면 우리가 원하는 $PATH를 항상 우선순위로 둘 수 있게 됩니다. 아래와 같이 환경변수를 설정하는 명령어를 .bash_profile의 가장 아랫줄에 삽입하도록 설정했습니다.machine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile 4.2 rbenv에 Ruby 2.2 설치하기그 다음으로 할 일은 원하는 Ruby 2.2 버전을 설치하는 것입니다. $ rbenv install -l을 사용해서 설치 가능한 모든 Ruby 버전을 조회할 수 있고, $ rbenv install 2.2.5 명령어를 사용해서 2.2.5 버전을 설치할 수 있습니다.$ rbenv install -l Available versions: 1.8.5-p113 1.8.5-p114 1.8.5-p115 1.8.5-p231 ... $ rbenv install 2.2.5 이렇게 설치된 버전은 두 가지 방법으로 사용될 수 있습니다. 한 가지 방법은 시스템 전체에서 사용하는 것이고, 다른 한 가지 방법은 프로젝트 단위로 사용하는 방법입니다. 시스템 전체에서 사용하려면 $ rbenv global 2.2.5 명령어를, 프로젝트 단위로 사용하려면 $ rbenv local 2.2.5명령어를 사용합니다.global 명령어를 사용해서 Ruby 버전을 선택하면 ~/.rbenv/version 파일에 선택된 버전이 기록됩니다.$ rbenv global 2.2.5 $ cat ~/.rbenv/version 2.2.5 local 명령어를 사용하면 현재 디렉토리의 .ruby-version 파일에 선택된 버전이 기록됩니다.$ rbenv local 2.2.5 $ cat .ruby-version 2.2.5 local 명령어로 선택된 Ruby 버전은 global 명령어로 선택된 Ruby 버전보다 우선순위가 높습니다. $ rbenv version 명령어를 사용하면 현재 선택된 버전을 확인할 수 있습니다.$ rbenv version 2.2.5 (set by /project/path/.ruby-version) Circle CI에서는 편의를 위해 global 명령어를 사용해서 Ruby 버전을 선택하도록 했습니다.dependencies: pre: - brew update - brew install rbenv - rbenv install 2.2.5 - rbenv global 2.2.5 4.3 Bundler 다시 설치하기rbenv를 사용해서 새로운 Ruby 버전을 설치했기 때문에, Circle CI 시스템에서 제공하는 Gem도 다시 설치해야 합니다. 우리는 Bundler로 Gem 의존성을 관리하기로 했으므로, Bundler만 재설치합니다.$ gem install bundler --no-ri --no-rdoc $ rbenv rehash $ gem install 명령어를 실행한 후에는 $ rbenv rehash 명령어를 실행해서 executable 경로들을 재설정해주어야 합니다.4.4 ~/.rbenv 경로 캐싱하기rbenv를 사용해서 Ruby를 설치하는 과정이 굉장히 오래 걸립니다. 이 경우, Circle CI에서 제공하는 캐싱 기능을 사용해서 이 과정을 한 번만 하고 건너뛸수 있게 됩니다.dependencies: cache_directories: - ~/.rbenv 위와 같이 circle.yml를 설정해주면 컨테이너 실행시 ~/.rbenv 디렉토리가 캐시로부터 설정됩니다. 캐싱된 디렉토리를 사용하는 경우 Ruby 버전이 미리 설치되어있기 때문에 $ rbenv install시에 --skip-existing 옵션을 추가해주어서 캐싱된 버전을 재설치하지 않도록 합니다.5. 마치며최종적으로 완성된 Gemfile과 circle.yml 파일은 다음과 같습니다.Gemfilesource 'https://rubygems.org' gem 'cocoapods', '~> 0.39' circle.ymlmachine: pre: - echo "export PATH=\$HOME/.rbenv/shims:\$HOME/.rbenv/bin:\$PATH" >> .bash_profile - echo "export RBENV_SHELL=bash" >> .bash_profile xcode: version: 7.3 dependencies: cache_directories: - ~/.rbenv pre: - brew update - brew install rbenv - rbenv install 2.2.5 --skip-existing - rbenv global 2.2.5 - gem install bundler --no-ri --no-rdoc - rbenv rehash - bundle install --path vendor/bundle override: - bundle exec pod --version - bundle exec pod install https://circleci.com/docs/environment-variables/#custom ↩#스타일쉐어 #개발 #개발자 #개발팀 #후기 #일지 #인사이트
조회수 17246

iOS 10 웹뷰에서 LSApplicationQueriesSchemes 에 등록되지 않은 URL scheme으로 앱 열기

미국 현지 시각으로 9월 13일 런칭된 iOS 10 버전에서는 보안과 관련된 여러가지 정책의 변화가 생겼습니다. 그 중, 문서화가 잘 되어있지 않아1 곤란했던 정책의 변화는 바로 웹뷰에서의 custom URL scheme을 통한 앱 열기에 관련된 것입니다.문제 발견StyleShare 앱 내 스토어에서는 웹뷰를 통한 결제 방식을 사용하고 있습니다. 결제 프로세스는 다음과 같습니다. 웹뷰로 개발된 KCP 결제 페이지에서 주문 정보를 모두 작성한 후, 카드 결제 버튼을 선택하면 웹뷰에서 각 은행의 결제 앱을 실행하게 됩니다. 실행된 앱에서 사용자가 결제 정보를 입력하여 결제를 완료한 뒤 StyleShare 앱으로 돌아오면 결제가 완료되는 방식입니다. 발견한 문제는 바로 은행 결제 앱이 실행되지 않는 치명적인 문제였습니다.문제 원인웹뷰로 작성된 KCP 주문서는 아마 [removed].replace('myapp://hello/world')와 같이 custom URL scheme을 사용해서 결제 앱을 실행하도록 개발되어 있을 것입니다. 웹뷰의 URL이 변경될 경우 iOS가 이를 먼저 알아채고 설치된 앱에 등록된 URL scheme을 확인해서 앱을 실행하도록 하는데요. iOS 10 에서 변화가 생긴 곳이 바로 이 부분이라고 판단됩니다.iOS 9 버전에서 처음으로 LSApplicationQueriesSchemes 라는 Info 항목이 소개되었습니다. URL scheme을 사용해서 외부 앱을 열 경우, 특별한 제한이 없던 기존 방식에서 화이트리스트에 등록된 scheme만 열 수 있도록 보안 정책이 강화된 것인데요. 이 정책이 처음 소개된 iOS 9 버전에서는 웹뷰에서 URL scheme을 사용해서 앱을 열 경우 경고창을 통해 사용자에게 확인하는 과정만 추가되었을 뿐 정상적으로 작동하였습니다. 하지만 iOS 10 버전에서는 화이트리스트에 등록되지 않은 경우, 웹뷰에서는 무조건 차단하는 정책으로 변경된 것으로 보입니다.해결 방법애플에서 권장하는 해결 방법은 아마도 Info.plist의 LSApplicationQueriesSchemes 항목에 사용하고자 하는 URL scheme들을 등록하는 방법일 것입니다. 하지만, StyleShare 스토어는 KCP라는 PG사를 통해 각 은행의 결제 앱에 연동하는 구조로 되어 있습니다. 즉, KCP에서 새로운 결제 수단을 추가하거나, 각 은행사에서 앱 URL scheme을 변경/추가/삭제할 경우 각각에 대응해서 새로운 릴리즈를 해야 하는 것입니다. 더 심각한 것은 각 은행사에서 사용하는 URL scheme들이 문서화가 제대로 이루어지지 않거나 파편화되어있다는 점입니다.따라서, StyleShare에서는 웹뷰에서 custom URL scheme 요청이 발생하는 경우, 네이티브 코드에서 직접 앱을 실행하도록 하는 방법을 사용했습니다.UIWebViewDelegate를 사용하는 경우 func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { if let url = request.url, url.scheme != "http" && url.scheme != "https" { UIApplication.shared.openURL(url) return false } return true } WKNavigationDelegate를 사용하는 경우 func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { if let url = navigationAction.request.url, url.scheme != "http" && url.scheme != "https" { UIApplication.shared.openURL(url) decisionHandler(.cancel) } else { decisionHandler(.allow) } } 혹시 이 부분에 대한 문서화가 어디에 되어있는지 아시는 분은 [email protected]로 연락주시면 감사하겠습니다. ↩#스타일쉐어 #iOS #모바일 #개발자 #개발 #앱개발 #꿀팁 #인사이트

기업문화 엿볼 때, 더팀스

로그인

/