스토리 홈

인터뷰

피드

뉴스

조회수 2025

Interview - Android App Developer 박형일님

크래커나인 팀에서는 사용자의 의견을 적극 반영하기 위해서 안드로이드 개발자 박형일님의 크래커나인 사용기 인터뷰를 해보았습니다.개발자 박형일님본인 소개를 부탁 드려요~저는 에이치나인에서 안드로이드 개발 파트를 담당하고 있는 박형일 입니다. 개발 경력은 12년 정도 됐구요.에이치나인에 입사한지는 4년 정도 됐습니다. 주로 외주 안드로이드 앱 개발 업무를 하고 있습니다.개발일을 꽤 오래 하셨네요. 시니어 개발자들은 코드를 직접 작성하는 것을 선호 하시는 것 같던데, 형일님은 어떠신가요?저도 코드를 직접 작성하는 것을 선호 하는 편입니다. 툴에서 생성되는 코드를 별로 신뢰하지 않아요. 제가 원하는 대로 안 나온다는 느낌을 많이 받거든요.그럼 크래커나인의 첫인상은 어떠셨나요? GUI 로 부터 코드를 생성해 주는 툴인데..처음엔 아이디어는 괜찮은데, 이게 과연 제대로 된 코드를 생성 해 줄까? 라는 의심이 들었죠. 꼭 사용 해 보고 싶은 프로그램은 아니었어요.크래커나인을 사용하신지는 얼마나 되셨죠?올해 6월쯤에 처음 접하여 2달 정도 된 같아요.어떤 프로젝트에 적용 해 보셨나요?회사에서 회의실 예약 시스템이 필요하다고 해서 회의실 예약 앱을 만들었어요.그 때 처음 사용 했죠. 공식 프로젝트가 아니라 디자이너 없이 웹에서 무료로 사용할 수 있는 Sketch 파일로 된 디자인 샘플을 받아서 혼자서 만들었어요.앱을 구성하는 화면은 대략 5~6개 정도로 간단한 프로젝트여서 가능 했죠. 지금은 외주 과제를 하고 있는데, 크래커나인을 사용 해서 하고 있어요.외주 같으면 주로 파워포인트로 작성된 GUI 가이드라인 문서를 보고 개발 하잖아요. 크래커나인을 사용하기 전에는 디자이너와 무엇을 통해서 개발에 필요한 디자인 정보를 얻으셨어요? 에이치나인에 있으면서 거의 대부분 GUI 가이드라인 문서를 보고 개발 했죠. 최근에 다른 프로젝트 팀에서 GUI 가이드라인 문서 없이 제플린을 쓰더라구요. 그래서 그것도 조금 써봤어요.제플린과 같은 기존의 유사 서비스와 비교해서 크래커나인은 어땠나요?GUI 가이드라인 문서를 보면서 개발을 하다 제플린을 써보니까 너무 편리하더라구요. 문서에서 원하는 정보 찾는게 불편했거든요.그래서 사실 처음 크래커나인을 사용 했을 때는 제플린과 큰 차이를 못 느꼈어요.근데 프로젝트를 진행 하다 보니 크래커나인의 코드 생성 기능이 있어서 좀 더 편리하다고 느껴지는 순간이 오더라구요. 제플린을 보고 개발 할 때는 코드나 수치를 직접 입력하다 보니 실수를 할 때도 있었고, 여전히 XML 작성하는 수고로움이 남아 있었거든요.근데 크래커나인의 레이아웃 코드 생성 기능을 사용해서 나온 XML 코드가 100% 는 아니지만 70~80%는 작업을 안해도 될 수준이더라구요. 그래서 XML 작성하는데 들이는 시간이 많이 줄어 들었어요.크래커나인을 익히는데 어렵지는 않으셨어요?타 서비스를 사용한 경험이 있어서 많은 부분 기능을 따로 매뉴얼로 보지 않아도 파악이 됐는데요.사용하는데 크게 문제는 없었던 거 같아요. 직관적으로 파악이 안 되는 기능은 사용하지 못한 것 같지만 따로 매뉴얼은 찾아보지 않았습니다.Cracker9의 어떤 기능이 가장 편리하셨나요?당연히 레이아웃 코드 자동 생성 기능이었습니다.손으로 직접 코딩 하지 않고 View들의 관계를 맺으면 자동으로 View의 관계와 속성을 xml 코드로 생성해주는 기능이 개발하는 데에 상당히 많은 도움이 되었습니다.Cracker9을 사용하면서 불편했던 점이나 개선했으면 하는 부분이 있었나요?Asset 이름이나 리소스(문자열, drawable) 이름이 해쉬값이나 text1, text2 이런 식으로 되어 있어 나중에 다 변경을 해 주어야 되었습니다. 이 부분은 개선이 되었으면 좋겠습니다.※ 위의 내용은 Cracker9 0.9.5 에서 개선되었습니다.Cracker9의 정식 버전으로 출시가 되면 사용할 의향이 있으신가요?네, 사용할 것 같아요. 가격만 너무 비싸지 않으면 전 무조건 사용하겠습니다.App을 만들거나 디자이너와 소통해야 하는 다른 개발자들에게 알려주고 싶은 Cracker9 사용 Tip이 있다면 알려주세요~디자이너가 텍스트나 이미지 단위로 View를 만드는데요. 개발자가 원하는 모든 View를 만들진 않기 때문에 Custom Layout 활용은 필수입니다.Custom Layout을 잘 활용하시면 원하시는 레이아웃 작업이 모두 가능합니다. 그리고, 오른쪽에 Tree Structure 패널이 있는데요.View의 트리 구조 순서로 레이아웃 xml 코드가 생성되기 때문에 어떻게 코드가 만들어질지 예상할 수 있어요. 물론 View의 순서나 부모/자식 관계는 마우스 드래그로 편집할 수 있습니다.마지막으로 Constraint Layout의 관계를 맺을 때, View가 작으면 정확하게 클릭하여 작업하기 어려울 수 있는데요. 당연하지만 View를 확대해서 연결 지으면 쉽게 작업할 수 있습니다.마지막으로 Cracker9에게 한 말씀해주세요~저는 안드로이드 App을 개발하면서 레이아웃 작업은 초반에 하는 시간 잡아먹는 노가다 작업이라고 생각을 했는데요.레이아웃을 자동으로 생성해주는 Cracker9을 사용하면서 더 이상 노가다라는 생각을 하지 않게 되었습니다. 아직은 Beta 버전이라 부족한 부분이 보이지만, 개선될 것이라고 믿고 계속 사용할 거 같아요.앞으로 발전하는 모습 기대하겠습니다 파이팅!#에이치나인 #디자이너 #개발자 #협업툴 #크래커나인 #솔루션기업 #팀원인터뷰 #기업문화 #조직문화 #팀원자랑
조회수 1436

반복적인 모니터링 프로세스 구축

IT 서비스에 장애가 발생 할 경우 모니터링 프로세스는 장애를 찾는 것으로 끝나지 않습니다. 장애를 발견하는 것은 모니터링 프로세스의 시작 점이며 최종적으로 모니터링을 통해 장애의 근본 원인을 찾아낼 수 있어야 합니다. 그리고 찾아낸 원인들은 예측과 추론에서 확인까지 이르는 하나의 프로세스로 정착되어 다시금 모니터링 과정에 포함되어져야 합니다. 이렇게 서비스를 운영하는 과정에서 근본적인 장애를 찾기 위해 모니터링을 어떻게 이해해야 하는지 알아보겠습니다. 우리가 모니터링 해야 하는 지표어플리케이션 지표(WORK METRICS)- 처리량 지표(THROUGHPUT)- 성공 지표(SUCCESS)- 에러 지표(ERROR)- 성능 지표(PERFORMANCE)시스템 지표(RESOURCE METRICS)- 가동률(UTILIZATION)- 포화상태(SATURATION)- 에러 지표(ERROR)- 이용률(AVAILABILITY)이벤트(EVENTS)- 코드 변경(CODE CHANGES)- 경고 알림(ALERTS)- 규모 변경(SCALING EVENT)- 기타(ETC)IT 서비스를 운영하는 과정에서 발생하는 문제의 근본원인을 추적하기 위한 모니터링 데이터는 크게 3가지로 나눌 수 있습니다. 어플리케이션 지표(Work metrics)서비스의 흐름(트렌젝션)을 측정하여 시스템의 최상위 레벨의 이슈를 보여줍니다. 시스템 지표(Resource metrics)이용률, 상태, 에러 또는 시스템 의존적인 리소스의 이용률을 수량화합니다.이벤트(Events)코드변경, 내부 경고, 확장 이벤트와 같이 드물게 발생하는 불연속적이 이슈를 보여줍니다.일반적으로 IT 모니터링의 핵심 이슈는 어플리케이션 지표를 통해 확인할 수 있습니다. 하지만 다른 지표들 또한 어플리케이션의 지표에서 나타난 문제의 원인을 찾기 위한 중요한 요소이기 때문에 같이 모니터링 해야 합니다. 시스템 지표를 통한 모니터링인프라스트럭쳐는 대부분 시스템의 자원으로 구성됩니다. 최상위 수준에서 유용한 작업을 하는 각각의 시스템들은 다른 시스템들과 연동하기도 하는데요. 예를 들어, 여러분의 아파치 서버가 MySQL 데이터베이스를 자원으로 사용하여 요청을 처리하는 작업을 지원할 수 있습니다. 연관된 작업을 따라 들어가보면 MySQL은 제한된 커넥션 풀을 관리하기 위한 리소스를 가지고 있고 MySQL이 실행되는 서버의 물리적인 리소스 레벨에서는 CPU, Memory, Disk 같은 지표를 보게 됩니다.어플리케이션이 서비스를 제공하는 데 있어서 각각의 리소스가 그 작업을 지원한다면 우리는 장애가 발생한 경우에, 필요한 원인을 얻는 좋은 방법을 시스템을 통해서도 찾아볼수 있습니다. 이런 프로세스를 만들어 간다면 시스템에서 발생한 경고를 통해 장애의 원인을 체계적인 조사하는데 도움이 될 것입니다. 1. 최상위 어플리케이션 지표에서 시작하기첫번째 해야 하는 질문은 "발생한 장애를 설명할 수 있는가?" 이다. 처음부터 문제를 명확하게 정의하지 못하면 이슈를 분석하기 위해 파고들어가야 하는 시스템 패스를 잃어버릴 확률이 높다.다음으로 문제가 있을 것으로 보여지는 최상위 시스템의 작업 지표를 검사해라. 이 지표들은 종종 문제의 원인을 알아내거나 또는 적어도 추적해야 하는 방향을 알려 줄 것이다. 예를 들어 성공적으로 진행된 작업의 성공율이 한계치 이하로 떨어졌다면 에러 지표를 찾아보고 반환된 에러의 형러의 타입을 살펴봄으로써 문제의 방향을 찾아나갈 것이다. 반면에, 대기시간이 길고 외부 시스템에 의해서 요청된 작업처리량이 매우 높다면 시스템 과부하로 인한 문제일 확률이 높다. 다만 와탭의 어플리케이션 분석 서비스를 사용한다면 약간 방법을 달리해도 된다. 와탭의 성능 분포도(어플리케이션 히트맵)와탭의 어플리케이션 성능 분포도를 통해 문제가 발생한 트랜잭션을 드래그하여 선택하게 되면 실제 어플리케이션에서 발생하는 스탭들을 추적하여 문제 해결에 바로 도달할 수도 있다. 하지만 더 복잡한 형태의 장애라면 시스템의 리소스 정보를 찾아봐야 합니다.  2. 리소스 찾아보기최상위 work metrics를 조사하여 문제의 원인을 알수 없다면, 다음으로 시스템이 사용하는 리소스(물리적인 요소 뿐만 아니라 시스템의 리소스 역할을 하는 소프트웨어 또는 외부 서비스)들을 조사합니다. 해당 리소스가 높다면 리소스를 사용하는 하위 Application 지표를 찾아보는 방식으로 찾아나갑니다. 와탭의 데시보드(CPU, MEMORY)3. 변경 내용 찾아보기다음으로 지표에 연관된 경고와 다른 이벤트들을 살펴봅니다. 문제가 발생하기 직전 코드가 릴리즈 되었거나, 내부 경고가 발생하고나 다른 이벤트가 등록되었다면 문제와 연관된 부분을 찾아봐야 합니다. 4. 수정하기 (잊지 말기)문제의 원인을 찾았다면 문제의 원인이 되는 상태를 수정해보고 증상이 사라지는 것을 확인합니다. 증상이 더이상 나오지 않는다면 향후 유사한 문제를 피하기 위해 시스템을 어떻게 변경할지 고민해야 합니다.  서비스가 중단된 상황이 오면 1분이 중요합니다. 문제를 찾는 속도를 높이기 위해 눈앞에서 벌어진 상황에 대한 높은 집중력을 유지하면서 대쉬보드를 상황에 맞춰 재 조정합니다. 최상위 어플리케이션 데쉬보드와 각각의 서브시스템들을 위한 대시보드를 하나씩 설정합니다. 시스템 대시보드는 시스템 지표의 하위 시스템의 키 메트릭스와 함께 어플리케이션 메트릭을 확인 할 수 있어야 합니다. 이벤트 데이터도 이용가능한 상황이라면 연관 분석 차트에서 관련된 이벤트가 올라가 있어야 합니다. 와탭의 알림 서비스정리하기   서비스에 장애는 무조건 발생하지만 우리는 모니터링을 통해 빠르게 해결 할 수 있습니다. 이를 위해 표준화된 모니터링 프로세스를 만들고 대시보드로 연관관계를 만들어 놓는다면 문제를 빠르게 추적 조사할 수 있습니다. 가능하면 모든 지표는 어플리케이션 지표에서 부터 찾을 수 있도록 대시보드를 구성합니다.인프라스트럭처를 통해서도 문제를 분석할 수 있습니다. 시스템에 대해 대시보드를 설정하고 주요 지표들을 올려놓아야 합니다. 문제의 원인을 조사하는 것은 증세가 나타나는 최상위 시스템에서 부터 시작합니다. 문제가 되는 리소스가 발견되면 문제를 발견하고 수정할 때가지 리소스에서 발견되는 패턴을 조사하고 적용시키는작업을 반복해야 합니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 1477

스푼 라디오 안드로이드 개발자 Yong을 소개합니다!

 정말 좋아하는 일을 하면, 주말 또는 정해 놓고 쉬는 날이 없습니다. 어디선가 호탕한 웃음소리가 나면 백발백중 'Yong'의 웃음소리라는 것을 안다. 듣는 다른 이 또한 웃게 만드는 매력적인 웃음의 소유자 안드로이드 개발자이자 클라이언트팀의 리더 용을 지금 소개합니다.호탕한 웃음의 원천이요?"저는 기본적으로 일을 즐겁게 하자 라는 생각으로 일을 합니다. 함께 웃으면서 일하면 서로 함께 기분이 좋아지잖아요! 그게 저의 호탕한 웃음의 원천인 것 같습니다. 다른 분들께 매력적으로 보인다는 것은 처음 알았네요 :) 그리고 저는 원래 웃음이 많은 사람입니다"듣고 싶은 당신의 스푼 라이프클라이언트팀이 궁금합니다."클라이언트 팀은 세 파트로 나뉘어있습니다. IOS, AOS 그리고 Web입니다. 저희 팀은 다른 많은 부서들과 긴밀한 협업을 통해 제품에 대한 틀을 정의하고 프로그래밍이라는 구현 작업을 통해 제품을 만들어 사용자들에게 가치를 전달하고 있습니다. 저희는 사용자들에게 제품을 이용하는 편의성을 제공하며 사용자 상호 간의 소통의 창구적인 역할을 하게 됩니다. 또한, 사용자들의 다양한 행위를 통해 스푼은 사용자들에게 재미, 감동, 그 이상의 의미를 전달합니다. 결과적으로 사용자들이 인식하고 보고 느끼는 모든 것이자 스푼의 가치를 전달하는 최종적인 결과물이라고 할 수 있겠습니다. 그리고 저는 현재 팀에서 클라이언트 팀 리더이자 안드로이드 개발을 담당하고 있습니다."개발자 그리고 팀 리더가 되기까지"저는 원래 전공이 하드웨어 분야였습니다. 사실 원대한 꿈은 없었지만 제 스스로가 이공계에 마땅한 사람이라는 것은 알 고 있었어요. 하드웨어와 소프트웨어 가리지 않고 무언가를 개발하는 것을 좋아한다는 걸 알았거든요. 제가 진로를 선택했을 땐 안드로이드 개발이 구현되기 전이었어요. 그래서 서버랑 클라이언트(윈도우)이 둘 중에 진로를 선택해야 했었고 첫 회사에서 UI 쪽으로 업무를 시작하게 되었어요. 사실 애초 UX/UI에 관심이 많았고 적성에 맞다는 걸 느꼈어요. 제가 만든 제품을 누군가가 사용하는 것을 육안으로 보고 싶었거든요. 개발은 정말 보람된 일이자 저에게 자부심이기도 합니다.개발자로서 코딩만 하다가 팀 리더가 되어보니, 리더가 정말 힘든 일이라는 것을 알았어요. 어쩌면 코딩보다 더 어려운 일인 것 같아요. 상대방을 이해하고, 또 이해시키고 공감해야 하니까요. 제가 일을 하면서 가장 행복할 때는, 함께 한다는 느낌을 받을 때인 것 같습니다. 예를 들어서 아이디어 회의를 할 때 모두가 같은 마음으로 함께 이루어간다고 생각이 들 때가 가장 뿌듯하더라고요."함께 일하고 싶은 사람 저는 솔직한 사람을 좋아합니다. 본인의 생각을 진솔하게 이야기하고, 공감대를 잘 형성할 수 있는 사람이요. 결국 일은 사람과 사람이 함께 하니까요.  알고 싶은 Yong의 이야기나를 표현하는 한마디 - '바람'저는 자유로운 사람이 되고 싶어요. 바람처럼 유유자적하면서, 무언가 하고 싶은 것이 있을 때 자유롭게 즐길 수 있으며, 구속받지 않는 삶을 살고 싶습니다.나만의 스트레스 해소법"제가 게임을 정말 좋아해요. 거의 모든 온라인 게임은 다 했던 것 같아요. 와우, 블리자드, 배그, 오버워치 등등 정말 많이 했는데 사실 지금은 잘 안 하는 것 같아요. 예전에 마케팅팀 테드랑 주말마다 함께 온라인에서 만나서 게임을 했었는데 테드가 결혼하고 저도 아이와 함께 시간을 보내다 보니 점점 게임을 안 하게 되더라고요. 게임을 왜 좋아하냐고요? 일단 재미있잖아요! 그리고 스트레스 푸는데 아주 좋아요. 게임에 몰두하고 나면 잡생각이 없어지거든요. 게임도 개발과 비슷해요. 온전히 집중해서 하지 않으면 모든 게 틀어지거든요. 게임은 집중력 향상에도 굉장히 좋습니다!"개발은 '예술'과 같아요 "주말에 집에서 일하는 이유요? 일이 많아서나 해야 해서 하는 것은 아니에요. 단지 자유롭게 하고 싶을 때 하는 편입니다. 좋아하고 즐거운 일이니까요! 개발은 하나의 예술이라고 생각합니다. 화가가 요일을 정해놓고 그림을 그리지 않는 것처럼 개발자도 똑같아요. 좋아하는 일을 한다면 그건 일이 아니라고 생각이 들거든요. 저에게 개발은 그렇습니다. 제게 개발은 재미있는 하나의 예술과 같아요"Yong은1. 사진, 그림, 음악 등 예술에 관심이 아주 많습니다!(피아노 독주회, 전시회에 종종 가신다고 합니다. 특히나 클래식과 재즈를 좋아합니다)2. 가리는 음식은 없지만, 한식류를 좋아합니다!팀원들이 Yong을 한마디로 표현한다면?Edward Jung 曰: 웃지만 무서운 관리자 - “언제나 웃음으로 대하시지만 내가 웃는 게 웃는 게 아니야라고 느껴짐…”Julia Na 曰: 행복한 리더 - "호탕한 웃음소리가 트레이드 마크. '행복하세요'라고 말하며 팀원들에게 긍정기운을 전파합니다."Michael Chung 曰: 따뜻한 마음을 가진 개발자 - “팀원들 하나하나 직접 챙기기 때문”Roy Choi 曰: 온화한 아버지 - "개발 실력은 기본, 팀원들을 챙기며 일정 조율 및 커뮤니케이션 능력까지 겸비한 그는 클라이언트팀의 아버지"Raymond Hong 曰: 허허실실 웃음 가득 리더 - "꼼꼼히 팀원과 프로젝트를 챙기기 때문"
조회수 1091

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

웹 플러그인 개발기 - 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 형태의 제품을 개발하고 계신 분들에게 도움이 되었으면 좋겠습니다.#조이코퍼레이션 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 1288

MySQL에서 RDS(Aurora) 로 이관하기

안녕하세요. 스티비팀 서버 개발자 이학진 입니다. 저희는 최근 서비스에서 사용 중이던 MySQL DB를 RDS로 이관하는 작업을 진행하였습니다. 무엇 때문에 이관을 결정하게 되었는지와 어떻게 이관을 진행하였는지에 대해 글을 써보도록 하겠습니다.배경stibee.com은 작년 11월에 정식 오픈한 새내기 이메일 마케팅 서비스 입니다. 사실 오픈 초기부터 얼마전까지만 해도 AWS EC2의 m4.large 인스턴스 하나로 운영되던 서비스였습니다.(사실 웹+API 서버 1대, 메일발송서버 1대)그리고 이 싱글 인스턴스에 무려 6개의 서버, mysql 1개, kafka 1개, redis 1개가 돌고 있었습니다. 그럼에도 불구하고 cpu사용률은 20%를 넘지 않았습니다.하지만 최근 사용자도 점점 늘어났고, 네이버에서 메일 수신정책을 변경하면서 메일발송서버에 대한 요청이 급증했습니다.스티비에서 네이버로 대량메일을 발송했을 때 해당 메일의 본문 링크를 자동검사하는 것을 발견했는데요, 따라서 네이버로부터 비정상적으로 많은 요청이 들어오고 있었습니다. (어떤 기준으로 이런 검사를 하는 것인지 정확한 정책은 아직 모릅니다. 담당자분 이 글을 보신다면 연락주세요. 친하게 지냈으면 합니다#슬로워크 #스티비 #개발 #서버개발 #개발환경 #MySQL #인사이트
조회수 2348

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이 있으므로, 한 번쯤 찾아보며 공부해보시면 좋겠습니다.
조회수 2678

MOIN 안드로이드 개발자를 소개합니다

영화 같은 일들이 매일같이 벌어지는 요즘 모두들 안녕하신가요?해외송금 스타트업 모인에게 최근 새로운 변화가 생겼습니다.안드로이드 개발자가 합류했습니다.어떤 분인지 지금부터 소개 해드리겠습니다 ^^안드로이드 개발을 해주실 효찬님!- Professional Experience -2015.01~2016.10 kt R&D 연구개발센터 전임연구원2013.07~2015.12 kt R&D 연구개발센터 연구원2013.03~2013.06 kt R&D 연구개발센터 인턴- Education -2006.03~2013.08 고려대학교 컴퓨터통신공학부 학사2001.09~2005.05 Jakarta International School▶ 모인에서 어떤 일을 담당하고 계신가요?총체적인 안드로이드 개발과 웹 서버를 보조하는 일을 맡고 있습니다.▶ 개발자가 되겠다고 한 계기가 궁금합니다. 개발자로서 이력에 대해 간략히 설명해주시겠어요? 특정한 계기가 있어서 개발자가 되겠다고 한 건 아니었어요. 고등학교 시절, 컴퓨터 게임 하면서 막연히 나도 게임을 만들어 보고 싶다고 생각했고 그래서 관심은 가지고 있었죠. 친구들 이름 넣어서 RPG를 만들어보기도 했는데, 생각해보면 스토리 만들기가 재밌었던 거 같아요. 그러면서 자연스럽게 어떻게 하면 컴퓨터 개발할 수 있나 생각도 해보게 됐고, 책도 뒤적여보게 됐습니다. 이런 생활이 고2때까지 이어졌어요. 그런데 마땅히 공부할 수 있는 방법이 없어서 대학가서 해야겠다 생각했습니다. 대학 와서 본격적으로 컴퓨터공학을 공부하면서 재미를 느끼게 됐어요.▶ 그 중에서도 안드로이드 개발을 선택하게 된 이유는 뭐였을까요?예전에 KT에 있을 때, 안드로이드 개발 프로젝트를 맡으면서부터입니다. 원래 이 분야에 대해 전혀 몰랐는데 회사에서 3일간 안드로이드 개발 교육을 받고 해보라는 지시를 받게 된거죠. 막상 해보니 재밌었어요. 특히 이 시기가 2014년 초였는데, 당시에는 안드로이드가 워낙 인기 있는 분야여서 더욱 할만하겠다는 생각을 하게 됐습니다. 효찬님이 선보인 안드로이드 앱 (왼부터)가계부투게더, 메모캐스트, 돈테크 ▶ 본격적으로 모인에 들어오게 된 이야기를 들어보고 싶습니다. 어떻게 모인을 알게 되셨나요?이전 회사에서 늘 입버릇처럼 ‘스타트업을 하고 싶다’는 말을 하고 다녔습니다. 생각해보면 제가 굉장히 밉상이었을텐데 주변 회사분들이 응원을 많이 해주셨어요. 정말 좋으신 분들입니다. (하하) 지인 추천으로 원티드를 알게 됐어요. 저는 초기 단계에 있는 스타트업에 가고 싶었는데 쉽게 찾기는 힘들더라고요. 이후 설립한지 1년도 안 된 ‘모인’을 찾게 됐습니다. 회사에 대해 이것저것 찾아보고 한 번 만나서 이야기해보면 좋겠다는 생각이 들어 대표님을 만났어요. 대표님과 만나 이야기를 나누어 보니 같이 일하고 싶었습니다.  ▶ ‘스타트업을 하고 싶다’는 말을 입버릇처럼 하셨다고 했는데, 특별한 계기가 있었나요?대학 때, 그래픽 프로그래밍 관련 Term Project를 수행했던 적이 있었어요. 이 때 친구들과 밤을 새면서도 웃고떠들며 프로젝트를 해낸 게 제겐 정말 좋은 경험이었습니다. 친한 친구들과 같이 일을 하면 힘든 업무도 웃으면서 즐겁게 할 수 있다는 생각이 들었어요. 앞으로도 좋은 사람들과 같이 즐겁게 일할 수 있으면 좋겠다는 생각을 가지게 되었죠. 스타트업에서 근무하면 일과 동시에 좋은 조직문화를 만들어나갈 수 있을 거라고 생각했어요.  ▶ 개발자로서 자신 있는 영역이 무엇인가요?두루 다룰 줄 안다는 게 제 장점일 수 있겠네요. 그래서 스스로 찾아가면서 어떤 서비스든 개발할 수 있다는 자신이 있습니다. 하지만 역시 한 분야에 대한 전문성은 좀 부족하지 않나 생각해요. 안드로이드에 더더욱 집중해보려고 노력한 이유이기도 합니다. 앞으로도 저만의 차별점을 발굴하는데 계속 노력을 기울일 생각입니다. 효찬님이 가장 애착간다는 원피스 '상디'▶ 개발 외 관심 있는 영역이 무엇인가요?개발 외적으로는 조직 문화에 관심이 많습니다. 제가 개인적으로 일본 만화 ‘원피스’를 좋아해요. 루피 해적단을 보면 개개인이 발전하면서 동시에 팀이 강해지는 모습을 볼 수 있거든요. 어떠한 모험도 할 수 있을 정도로 강해지죠. 루피 해적단 같은 조직을 꿈꿉니다. 어떻게 보면 제가 꿈꾸는 조직 문화가 담겨있다고도 할 수 있죠.특히, 배트맨을 보면 악당이 배트맨 지인을 인질로 잡으면 배트맨은 지인을 구하러 가죠. 하지만 원피스에서는 악당이 루피 친구들을 인질로 잡으면 루피는 친구를 구하러 가지 않아요. 다만, 친구가 함정에서 알아서 잘 나올거라 믿습니다. 그리고 악당을 쓰려트려야 하는 자신의 역할을 수행하는 데 충실해요. 동료를 믿기 때문에 가능한 자세라고 생각해요. 제 나름대로 ‘믿음의 리더십’이라고 혼자 정의해봤어요. (웃음) 대신 내 능력은 스스로가 키워나가야 하죠. 이렇게 각자 자신의 일에 최선을 다하는 사람들과 함께 큰 꿈을 이루는 게 지금 제게 마지막으로 남아 있는 순수한 이상입니다.▶ 더 키워나가고 싶은 역량이 있나요?역량이라기 보다는 제가 만든 작품을 Developing 해나가고 싶어요. 발전가능성이 없는 서비스는 더 이상하고 싶지 않습니다. 내가 만든 앱을 상용화 시키고, 고객들이 반응하는 걸 직접 보고 싶어요. 더불어 서비스 개선에 필요한 역량은 지속적으로 키워나가려고 합니다.장효찬 개발자에게 '함께 일하고 싶은 사람'이란?#온정 #진솔 #파이팅 ▶ 출근한지 일주일도 안됐지만 (웃음) 모인에 대한 첫인상은 어땠어요?정말 아직 1주일도 안됐는데…. (웃음) 대기업에 있다 와서 그런지 소위 ‘젊음의 열정’이라고 하죠? 다들 파이팅 넘치는 모습이 좋았습니다. 그러면서 동시에 나 잘났다고 으스대지도 않고, 특히 대표님 같은 경우는 능력도 있으신데, 겸손하기까지 해서 반했어요. 무언가를 물어보면 설명도 친절하면서 꼼꼼하게 해주시구요. 팀워크가 좋을 거 같다는 긍정적인 예감이 들었어요. 사람 뽑는 데 신중하시다는 대표님을 믿으며, 앞으로도 잘 부탁드립니다.  ▶ 앞으로 어떤 개발자가 되고 싶으신가요? 모인에게도 한마디 해주세요.개발 PM(Project Manager)에 관심이 많습니다. 사실 앱 구현보다 뼈대를 구축하는 일이 더 중요하다고 생각해요. 저는 이 부분이 개발에서 30% 혹은 그 이상을 오롯이 혼자 차지하고 있다고 생각해요. 그러기 위해서는 리소스나 구현한 코드를 어떻게 관리할까, 어떤 부분을 어떻게 더 추가를 해서 연동시킬 수 있을까 등을 서비스 앱 전체를 보고 관리할 줄 알아야 하죠. 이 역할이 국내에서는 중요하게 다뤄지는 거 같지 않아 안타깝습니다. 대부분 보이는 것에만 관심을 가지고 제품이 어떤 제질로 만들어졌는지는 큰 관심을 가지지 않는 추세거든요. 저는 이러한 부분을 중요시 여기는 개발자가 되고 싶습니다. “저를 버리시면(?) 아니됩니다 (웃음)”- 장효찬이 꼽은 인생 명언 -“Do what you love. Everything else is secondary”by. Steve Jobs#모인 #MOIN #개발자 #개발팀 #안드로이드개발자 #안드로이드 #팀원 #팀원소개 #팀원인터뷰 #인터뷰 #기업문화 #사내문화 #조직문화
조회수 1379

샌프란시스코 테크 업계 인터뷰 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이 검토하여 반영해야 한다.제품 팀 자체도 제품이다. 팀원의 피드백을 취합해서 효과적인 동시에 행복하게 일할 수 있도록 업무 방식을 개선해 나가야 한다.  스포카에서는 위와 같은 인사이트를 기반으로 스포카 크리에이터(스포카 제품 팀)의 업무 방식을 지속적으로 개선하고 있습니다. 스포카 크리에이터는 우선 서비스 품질 차원의 기술적인 목표를 관리합니다. 동시에 제품이 비즈니스에 어떻게 기여하는지를 확인하고 보다 큰 임팩트를 낼 수 있는 기능을 탐색합니다. 이 결과로 제품에서 발생하는 매출 지표 혹은 이에 기여하는 부가 지표를 관리합니다. 아울러 제품 팀 외 유관부서의 요구사항을 취합하는 채널을 일원화하고, 스프린트를 구성하는 회의에서 이를 발의받아 우선순위를 정합니다. 이러한 협의체는 스포카 크리에이터가 가장 효과적으로 비즈니스와 제품에 기여할 수 있도록 업무를 조율하는 역할을 합니다.  마지막으로 스포카 크리에이터는 분기 단위로 동료 간 리뷰 및 조직장과의 면담을 거쳐 팀의 컨디션을 체크합니다. 피드백을 통해 각 팀원은 보다 성장할 수 있는 기회를 확인할 수 있습니다. 조직 차원에서는 각 팀원이 비즈니스 또는 제품의 목표에 대해 얼마나 공감하는지를 확인하고 기여하고자 하는 업무를 파악하여 팀이 보다 효과적으로 일할 수 있도록 조직 구성을 변경하기도 합니다.  스포카 크리에이터는 개인의 성장이 팀의 성장으로 이어지고 이는 곧 제품의 경쟁력과 연결된다고 믿습니다. 스포카와 함께 성장하실 수 있는 분은 언제나 환영합니다.
조회수 1207

장애를 가장 빠르게 알아내는 액티브 트랜잭션

IT 서비스는 장애가 발생할 수 밖에 없습니다. 현대의 서비스는 지속적으로 커지고 복잡해지고 있습니다. 이를 해결하기 위한 MSA 구조는 장애의 규모를 줄여줄수 있지만 장애는 여전히 발생합니다. 그렇기 때문에 최근 애플리케이션 운영은 장애의 규모를 줄이고 장애를 빠르게 해결하는데 집중하고 있습니다.  그런데 이미 오래전부터 장애를 빠르게 해결하는 문화를 가진 지역이 있습니다. 바로 우리가 살고 있는 대한민국 서울입니다. 2000년에 엔터프라이즈의 IT 서비스가 태동될 때, 경험많은 해외 IT 기업들이 5년이 걸릴것이라 예상하는 ERP 시스템 통합을 한국의 기업들은 2년에서 3년만에 이뤄내는 기적(IT 지옥의 시작)을 이뤄냅니다. IT 기술이 전혀 없던 나라에서 빠르게 엔터프라이즈 IT 서비스들을 만들어 나가다보니 많은 문제들이 생겼습니다. IT 엔지니어의 혹사도 문제였지만 급하게 만들어진 IT 서비스들을 운영하는 것도 쉽지가 않았습니다. 2000년 중반의 어렵던 프로그래머의 삶을 대표하는 이미지이 때, 국내에 APM(Application Performance Mangement, 애플리케이션 성능 관리) 솔루션들이 혜성처럼 나옵니다. APM 솔루션을 통해 서비스 장애 원인을 알아낼 수 있었기 때문에 국내 엔터프라이즈 서비스를 운영하던 기업들에게 APM 솔루션은 단비와 같았습니다. 그리고 국내 APM 솔루션들은 해외 솔루션들과 비교되는 몇몇 특징을 가지고 있었는데, 그 중 하나가 실시간 어플리케이션 분석이였습니다. 그 중에서도 대표적인 실시간 분석 기능이 액티브 트랜잭션입니다. 액티브 트랜잭션애플리케이션 성능 분석 솔루션은 종료된 트랜잭션을 분석하는 기술입니다. 고객의 요청에서 응답까지의 과정을 트랜잭션이라고 합니다. 이렇게 완료된 고객의 요청을 하나 하나 분석하면 애플리케이션의 성능을 알아낼 수 있습니다. 그리고 액티브 트랜잭션은 종료되기 전의 트랜잭션을 분석하는 것입니다. 아직 완료되지 않은 트랜잭션을 분석하기 때문에 액티브 트랜잭션은 장애를 가장 빠르게 볼 수 있는 선행지표가 됩니다. 이해를 돕기 위해 아래에 벤더별 액티브 트랜잭션을 보여드립니다. 제니퍼소프트의 Active Service트랜잭션의 요청건수, 진행건수(Active Service), 완료건수가 상단에 나옵니다. 하단에는 다양한 방법으로 진행건수Active Service)를 보여주고 있습니다. 액셈의 Active Transaction트랜잭션의 요청건수, 대기건수(Active Service), 완료건수가 상단에 나옵니다. 하단에는 대기건수만(Active Transaction)를 보여주고 있습니다.와탭랩스의 Active Transaction트랜잭션의 진행건수를 원형으로 보여주고 있습니다. 와탭의 서비스는 대용량 분석을 위해 기존의 이퀄라이즈를 원형으로 보여주는 특징을 가지고 있습니다. 액티브 트랜잭션은 서비스를 오픈하는 과정에서 큰 효과를 보입니다. 아직 서비스가 완벽하지 않은 상태에서 부하 테스트를 하게 되면 서비스에 락이 걸리면서 트랜잭션이 연속으로 홀딩되면서 서비스 전체가 다운되기도 하는데, 이렇게 되면 종료된 트랜잭션으로는 분석이 불가능하기 때문입니다. 장애 상황에서의 액티브 트랜잭션장애 상황이 되면 일반적으로 액티브 트랜잭션의 양이 증가하게 됩니다. 아래는 와탭의 성능추이에서 볼수 있는 엑티브 트랜잭션의 건수를 표현하는 지표입니다. 평소 액티브 트랜잭션이 10건 이하였다면 아래와 같은 상황은 장애 상황일 확률이 높습니다. 마무리애플리케이션 성능을 분석하는 기준은 트랜잭션입니다. 데이터 분석 기준으로는 종료된 트랜잭션을 추적하는 것이 가장 중요합니다. 하지만 액티브 트랜잭션은 선행지표로서의 의미와 함께 종료된 트랜잭션으로 분석할 수 없는 상황을 알아낼 수 있는 중요한 지표이기도 합니다. 여러분이 사용하는 애플리케이션 성능 분석 도구가 있다면 액티브 트랜잭션 지표도 잘 활용하시기 바랍니다. #와탭랩스 #개발자 #개발팀 #인사이트 #경험공유 #일지
조회수 1195

[인공지능 in IT] AI, 넌 나만 바라봐

기술 회사 마케터로서, 특히 인공지능이라는 고도화된 기술을 다루는 회사에서 지내다 보면 참 재미있는 일이 많다. 기본적으로 엔지니어들이 다루고 있는 기술 컨셉과 역사는 물론, 가끔 코드도 공부해야 한다. 반강제적으로 (기술을 배우며) 성장하는 기분이다. 긍정적으로 생각하면, 비(非)엔지니어로 누릴 수 있는 특별한 혜택이지만, 여러모로 힘든 것도 사실이다.가장 고달픈 점이라면, '기술'이라는 눈에 보이지 않는 무형의 자산을 매력적으로 보일 수 있도록 설명하고, 이를 매출까지 연결하는 과제를 풀어야 하는 점이다. 앞서 언급한 기술 공부도 빼놓을 수 없다. 지금 다루고 있는 인공지능은 깊게 들어갈수록 끝이 없는데, 기술이라는 것은 나날이 변화하고, 익숙해졌다 생각하면 새로운 친구를 데리고 등장한다. 정말 환장할 노릇이다. 어찌되었건, 훌륭한 동료들과 함께 고도의 기술을 다룰 수 있는 환경을 축복이라 생각하며, 매번 마음을 다잡는 중이다.현재 필자는 인공지능 기술을 '팔고' 있다. 하지만, 정작 인공지능 기술을 '활용'하는 것은 또 다른 이야기다. 실제로 한번도 인공지능을 적용한 마케팅 솔루션을 다뤄보지 못했고, 엔지니어에게 요청한 경험도 없다. 아직까지 (회사는) 'B2B' 모델에 집중해, 굳이 제품을 사용하는 최종 소비자에게 맞춰 나갈 필요도 없다. 다만, 모바일 앱이나 가정용 기기 등 개인 사용자가 사용할 수 있는 제품을 팔아야 한다고 가정했을 때, '어떤 기술을 적용해야 (인공지능을) 타겟에 맞춰 설명할 수 있을까'라는 고민은 꼬리표처럼 따라 다닌다.< 마케팅에도 인공지능을 이용할 수 있지 않을까? >마케팅에는 굉장히 많은 이론이 있다. 'STP', '4P', 'MOT', 'SWOT' 등…. 나열하면 정말 끝이 없다. 이 모든 이론과 전략의 공통된 목표는 하나다. 소비자가 원하는 것을 정확히 파악해 (제품 또는 서비스를) 판매하는 것이다. 말이 쉽지 마케팅 전문가이든, 소프트웨어 엔지니어이든, 아직 모두가 고민하고 풀고 있는 어려운 문제다. 소비자들은 도대체 어떤 것을 원하는 것인지 도무지 정답이 없다. 그리고 필자는 여기에 한가지를 더 고민한다. (인공지능 기술 개발 업체 마케터로서) '인공지능을 활용해 정답을 찾아내는 방법은 없을까?'라고 말이다.현재 인공지능 기술로 접근할 수 있는 가장 근접한 해답은 '개인화'다. 다만, 지금도 많은 기업이 개인화 전략을 사용한다. 하지만, '개인화(Personalization)'와 '맞춤화(Customization)'라는 차이가 있다. 인공지능 기술 측면에서, 개인화는 고객이나 기술을 사용하고 있는 대상을 일부 집단으로 이해하지 않는다. 하나하나를 '개별적인 사람'으로 인식한다. 그 사람의 출퇴근 경로나 주로 방문하는 식당은 물론, 좋아하는 음악 장르, 구매 제품에서 얻고자 하는 가치, 더 나아가 감정 상태까지 개인마다 다른 특성을 정확하게 파악할 수 있어야 한다.반면에 맞춤화는, 개인화에 따른 결과 혹은 비슷한 특성을 가진 집단의 요구와 요청에 기반한다. 때문에 맞춤화는 반드시 개인화를 동반할 필요가 없다. 때문에 사용 집단을 대상으로 필요, 요구, 혹은 수요를 만족시키는 것을 주로 의미해 1명의 개인에게 불필요한 정보를 전달할 수 있다.지금과 같은 인공지능 기술이 없던 시절에도 방대한 양의 데이터를 활용한 마케팅 자동화로 고객에게 상품 관련 메세지를 전송하는 프로모션은 존재했다. 하지만, 이제는 마케팅 자동화에 인공지능이라는 살을 붙여 '개인화'와 '예측 분석'을 시도할 수 있도록 바뀌었다.아주 간단한 예를 들어보자. 필자는 축구를 좋아하고, 그중 아스날이라는 팀을 좋아한다. 여기에 리그 개막은 한달 정도 남은 여름에 시작된다고 가정하자. 기존 일반적인 마케팅 솔루션을 적용한 기업은 필자의 검색 히스토리, 혹은 현재 필자가 직접 입력한 개인정보와 비슷한 그룹의 다른 고객 데이터를 이용해 상품을 추천한다. 때문에 그저 현재 할인판매 중인 '긴팔 리버풀 유니폼'을 추천할 수 있다. 하지만, 인공지능을 적용해 개인화 정보를 활용하면, 이미 필자 이메일로 '반팔 아스날 유니폼 구매 링크'와 지난 시즌 아스날 유니폼을 20% 할인 가격에 구매할 수 있는 프로모션 정보를 추천할 수 있다. 이렇듯 각 개인에게 꼭 맞는 정보라면, 소비자도 자연스레 지갑을 열 수밖에 없다.명심해야 할 것은 '추천'과 '스팸'은 한 끗 차이라는 사실이다. 개인에게 '필요한 정보'는 추천이고, '일반적인 쓸데없는 정보'는 스팸이라는 것을 기억해야 한다.이호진, 스켈터랩스 마케팅 매니저조원규 전 구글코리아 R&D총괄 사장을 주축으로 구글, 삼성, 카이스트 AI 랩 출신들로 구성된 인공지능 기술 기업 스켈터랩스에서 마케팅을 담당하고 있다#스켈터랩스 #기업문화 #인사이트 #경험공유 #조직문화 #인공지능기업 #기술기업
조회수 3709

린더를 만들고 있는 이유 3.0

지난 토요일 매우 더웠던 어느 여름밤, 관심일정 구독 서비스: 린더가 앱스토어 라이프스타일 16위에 올랐다.물론 출시에 맞추어 마케팅을 진행하다 보면 초기에 순위 상승 효과가 다소 있기 마련이고, 요즘 같은 시대에 앱스토어 순위 좀 올랐다고 그게 그리 큰 대수냐랴고 말하는 사람도 있겠지만서도, 이 앱을 스토어에 올리기까지의 험난했던 과정을 누구보다도 잘 아는 사람으로서 비록 잠깐이지만 한여름밤의 꿈 같았던 이 과정과 결과를 글로 간직하고 싶었다.모든 스타트업, 아니 작은 중소기업이 그렇겠지만 우리는 매우 소수의 인력으로 구성되어있고, 그 소수의 인원 하나하나가 정말 많은 일을 담당하고 있다. 관심일정 구독 서비스: 린더는 다소 독특한 서비스 구조 특성상 사업 초기부터 B2B, B2C 모두를 대상으로 운영이 되고 있으며, 하루하루 예상치 못한 새로운 일들의 연속이 이어진다. 혹자는 이를 도전적이고 진취적인 경험이라 포장할 수도 있겠지만, 당장 어제는 한 번도 해본 적 없는 B2B SEO 작업을 하다가 오늘은 또 ASO 전문가가 되어야 하는 우리 당사자들 입장에서는 이러한 일련의 과정이 매우 가혹할 수밖에 없다.린더를 만들어 가는 과정에서 정말 많이 다퉜다(물론 앞으로도 많이 다투겠지만). 앞서 말한 가혹한 과정 속에서 여유를 가지고 서로가 서로를 대하기는 쉽지 않았기에, 당장 회사가, 서비스가 몇 달 후에도 계속 존재할지 아무도 모르는 상황에서 희망을 품고 모두가 함께 서비스의 미래를 바라보기는 정말 쉽지 않았다. 하지만 그 다툼의 근간에는 제품에 대한 기대와 열망이 있었다는 것을 모두가 알고 있었고, 기능 하나하나 쉽게 양보하지 않았지만 결국 하나의 공통된 목표 하에 조금씩 타협해나갈 수 있었다. 그렇게 우리는 현재 '린더'라는 이름을 달고 세상에 태어난 총 5개의 서비스를 운영하고 있다.'린더웹'으로 불리우는 기본 캘린더 연동 서비스는 작년 6월에 출시되어 현재까지 약 20만 명의 사용자를 확보하였고, 올해 4월, 7월에 각각 출시된 '린더안드로이드앱'과 '린더iOS앱'은 현재까지 총 2만여 다운로드와 1만 MAU를 확보하였다. 이 과정에서 우리와 협업을 희망하는 기업들을 위해 별도의 관리툴을 솔루션 형태로 제작, '린더 파트너스'라는 기업용 일정 마케팅 솔루션을 바탕으로 롯데자이언츠, 두산베어스, 아디다스 코리아 등 20여 개의 기업과 함께 협업하고 있으며, 빠르고 정확한 일정 데이터 생산을 위해 일정 데이터 형태에 최적화된 데이터 관리툴 '린더 CMS'를 개발하여 최소한의 인력과 비용으로 일정 데이터 생산이 가능케 했다.일정 구독 플랫폼: 린더지난 1년간 우리 팀은 사용자들의 구독 니즈를 충족시키기 위해 밤낮으로 다양한 일정들을 찾아 헤맸고, 어느덧 300여 개가 넘는 여러 캘린더를 운영하게 되었다. 그리고 지속적으로 높은 일정 데이터 생산 비용을 감당해야 했었던 이전에 비해 이제는 20만 명이 넘는 사용자들의 빗발치는 일정 제보와 20여 개가 넘는 파트너들의 일정 공급을 바탕으로 보다 효율적인 운영이 가능해졌다. 밤낮으로 일정을 찾아 헤매던 기존의 과정은 체계화된 시스템 덕분에 상당 부문 개선되어 변동성 높은 일정 데이터의 정확도를 지속적으로 향상 시켜나가고 있다.일정 제보 화면이제 우리는 감히 린더를 단순 구독 '서비스'를 넘어 국내 유일의 일정 구독 '플랫폼'이라고 부를 수 있는 자신감이 생겼다. 사용자들은 하루에도 몇 번씩 새로운 일정을 제보하는 동시에 구독을 희망하는 새로운 캘린더를 요청하고, 마찬가지로 '입점'을 희망하는 기업의 니즈 또한 지속적으로 증가하여 지난주에만 스포츠, 학교, 공연 3개의 각기 다른 분야에서 '일정 구독 제공'에 대한 문의가 들어왔다. 이들은 '일정'이라는 공통된 포맷 하에 각자 자신들의 일정을 팬, 학생, 또는 고객들에게 제공하기를 희망하였다.린더와 VUX(음성 기반 사용자 경험)   최근 AI 스피커 시장이 확장됨에 따라 각 회사들은 VUX기반 컨텐츠 확보에 열을 올리고 있다. 카카오가 NUGU를 운영하는 경쟁사 SKT에 멜론뮤직의 음악 컨텐츠를 공급하지 않을 것은 불 보듯 뻔한 사실이고, 결국 SKT는 자체 음악 서비스인 '뮤직메이트'를 새로이 시작했다. 역으로 네이버에게 배달의민족과의 협력 기회를 뺏긴 카카오는 '주문하기' 기능을 확대하여 자체 배달 서비스를 시작했다. '음악 컨텐츠'가 되었건, '배달 컨텐츠'가 되었건, 날씨 알려주는 것 외에 딱히 할 줄 아는 게 없는 현시대의 인공지능들에게 린더의 일정 컨텐츠는 높은 활용 가치가 있을 수 있다.단순히 내 캘린더와 연동되어 내가 어제 입력했던 일정들을 읊어주는 것이 아니라, 내가 좋아할 만한, 필요로 할만한 일정들을 미리 찾아서 알려줄 수 있다면 정말 멋지지 않을까. 캘린더에 표시도 안 한 2학기 수강신청을 10분 전에 내게 먼저 알려줄 수 있는 앱이 있다면, 아침에 일어나자마자 고대하던 신상 구두가 출시되었음을 알려주는 스피커가 있다면 분명 그 사용자 경험은 어디에서도 쉽게 경험할 수 없는 수준일 것이다.린더의 타이밍 타이밍은 중요하다. 비트, 풀러스 등 높은 제품 퀄리티 및 운영 능력에도 불구하고 시대가 받아들일 준비가 되지 않은 서비스들의 말로를 먼발치에서 지켜보았다. 약 1년 전 내부적으로 우리의 타이밍에 대해 논의를 진행했던 적이 있었고, 당시 우리가 내린 결론은 린더의 타이밍이 결코 늦으면 늦었지 빠르지는 않았다는 것이었다. 이미 사람들은 일정을 받아보는 경험을 받아들일 준비가 되어있으며, 1년 간 린더를 통해 일정을 받아보는 경험을 누리고 있는 20만의 사용자가 이를 방증한다.우리가 생각한 그 '타이밍'이 틀리지 않았다면, 꼭 '린더'라는 이름이 아니더라도 '일정을 받아보는 경험'을 만들어가는 것은 반드시 누군가가 성공해야만 하는 일이다. 지도로 길을 찾으며 불편함을 느끼지 못했던 세상에 누군가가 네비게이션을 선사한것처럼, '일정을 받아보는 경험'은 근 미래에 없어서는 안 될 선물이 될 것이다.    일정 구독 플랫폼은 분명 많은 이들의 삶에 변화를 줄 수 있다. 작게 보면 좋아하는 공연의 티켓팅을 놓쳐 매번 공연에 참여하지 못할뻔한 어느 팬의 하루를 행복하게 바꾸어 놓을 수 있고, 크게 보면 복수전공 신청 기간을 깜빡하고 놓쳐 복수 전공을 하지 못할뻔한 어느 대학생의 삶을 송두리째 바꾸어 놓을 수 있다.이 일은 반드시 누군가가 해내야만 한다. 그냥 있어 보이고 싶어서, 스타트업다워 보이고 싶어서 내뱉는 말이 아니라, 진심으로, 사력을 다해 누군가는 반드시 이 일정 구독 플랫폼을 만들어 내야만 한다. '일정을 받아보는 경험'이 일상화 되었을때 비로소 우리의 삶은 조금 더 질적으로 풍요로워질 수 있다.린더가 앱스토어 10위권에 오른 이번 사건이 완전히 새로운 형태의 일정 구독 플랫폼의 시작을 알리는 출발선이 되었으면 한다. 다시 또 높은 순위권으로 올라오기 위해서는 아마 한동안 많은 노력들이 필요로 될 것으로 예상되기에, 우리는 앞으로도 화장품 세일, 아이돌 스케줄, 대학교 학사일정, 스포츠 경기, 마트 휴무일, 공연, 전시 등을 넘어 사람들이 필요로 하는 새로운 일정 컨텐츠를 찾아 헤맬것이다.세상 사람 모두가 일정을 받아보는 날이 오기를 꿈꾸며, 와, 근데 이번 여름밤은 정말 더워도 너무 덥다.#히든트랙 #챗봇 #기술기업 #개발자 #개발팀 #인사이트 #경험공유

기업문화 엿볼 때, 더팀스

로그인

/